diff --git a/app/library/Download.py b/app/library/Download.py
index a69a1a97..28c50df4 100644
--- a/app/library/Download.py
+++ b/app/library/Download.py
@@ -287,7 +287,8 @@ class Download:
f"Live stream detected for '{self.info.title}', The following opts '{deletedOpts=}' have been deleted."
)
- if isinstance(self.info_dict, dict) and len(self.info_dict.get("formats", [])) < 1:
+ hasFormats: bool = len(self.info_dict.get("formats", [])) > 0 or self.info_dict.get("url")
+ if isinstance(self.info_dict, dict) and not hasFormats:
msg: str = f"Failed to extract any formats for '{self.info.url}'."
if filtered_logs := extract_ytdlp_logs(self.logs):
msg += " " + ", ".join(filtered_logs)
diff --git a/app/library/DownloadQueue.py b/app/library/DownloadQueue.py
index 89c154f3..b3d04546 100644
--- a/app/library/DownloadQueue.py
+++ b/app/library/DownloadQueue.py
@@ -513,6 +513,7 @@ class DownloadQueue(metaclass=Singleton):
nTitle: str | None = None
nMessage: str | None = None
nStore: str = "queue"
+ hasFormats: bool = len(entry.get("formats", [])) > 0 or entry.get("url")
text_logs: str = ""
if filtered_logs := extract_ytdlp_logs(logs):
@@ -534,7 +535,7 @@ class DownloadQueue(metaclass=Singleton):
)
itemDownload: Download = self.done.put(dlInfo)
- elif len(entry.get("formats", [])) < 1:
+ elif not hasFormats:
ava: str = entry.get("availability", "public")
nTitle = "Download Error"
nMessage: str = f"No formats for '{dl.title}'."
diff --git a/ui/app/components/NotifyDropdown.vue b/ui/app/components/NotifyDropdown.vue
index 8ff79681..ed3df1c2 100644
--- a/ui/app/components/NotifyDropdown.vue
+++ b/ui/app/components/NotifyDropdown.vue
@@ -45,11 +45,12 @@
-
- {{ store.unreadCount }}
+
+ {{ store.unreadCount }}
/
{{ store.notifications.length }}
+
diff --git a/ui/app/pages/index.vue b/ui/app/pages/index.vue
index fb91ba69..727512af 100644
--- a/ui/app/pages/index.vue
+++ b/ui/app/pages/index.vue
@@ -204,7 +204,7 @@ const pauseDownload = () => {
dialog_confirm.value.visible = true
dialog_confirm.value.html_message = `
-
+
Pause All non-active downloads?
diff --git a/ui/app/stores/NotificationStore.ts b/ui/app/stores/NotificationStore.ts
index 3a8bef71..3bbc2225 100644
--- a/ui/app/stores/NotificationStore.ts
+++ b/ui/app/stores/NotificationStore.ts
@@ -2,10 +2,46 @@ import { defineStore } from 'pinia'
import { useStorage } from '@vueuse/core'
import type { notification, notificationType } from '~/composables/useNotification'
+const _map: Record = {
+ 'error': { level: 3, color: 'is-danger', icon: 'fas fa-circle-exclamation' },
+ 'warning': { level: 2, color: 'is-warning', icon: 'fas fa-triangle-exclamation' },
+ 'success': { level: 1, color: 'is-primary', icon: 'fas fa-circle-check' },
+ 'info': { level: 0, color: 'is-info', icon: 'fas fa-circle-info' }
+}
+
export const useNotificationStore = defineStore('notifications', () => {
const notifications = useStorage('notifications', [])
const unreadCount = computed(() => notifications.value.filter(n => !n.seen).length)
+ const severityLevel = computed(() => {
+ const unread = notifications.value.filter(n => !n.seen)
+ if (0 === unread.length) {
+ return null
+ }
+
+ return unread.reduce((h, n) => _map[n.level].level > _map[h.level].level ? n : h).level
+ })
+
+ const severityColor = computed(() => {
+ const level = severityLevel.value
+ return level ? _map[level].color : ''
+ })
+
+ const severityIcon = computed(() => {
+ const level = severityLevel.value
+ return level ? _map[level].icon : ''
+ })
+
+ const sortedNotifications = computed(() => {
+ return [...notifications.value].sort((a, b) => {
+ const severityDiff = _map[b.level].level - _map[a.level].level
+ if (0 !== severityDiff) {
+ return severityDiff
+ }
+ return (new Date(b.created).getTime()) - (new Date(a.created).getTime())
+ })
+ })
+
const add = (level: notificationType, message: string, seen: boolean = false): string => {
const id = Array.from(
window.crypto.getRandomValues(new Uint8Array(14 / 2)),
@@ -43,5 +79,18 @@ export const useNotificationStore = defineStore('notifications', () => {
const remove = (id: string) => notifications.value = notifications.value.filter(n => n.id !== id)
- return { notifications, unreadCount, add, get, markAllRead, clear, markRead, remove }
+ return {
+ notifications,
+ unreadCount,
+ severityLevel,
+ severityColor,
+ severityIcon,
+ sortedNotifications,
+ add,
+ get,
+ markAllRead,
+ clear,
+ markRead,
+ remove
+ }
})