diff --git a/containers/libreportal/frontend/components/tasks/js/tasks-manager.js b/containers/libreportal/frontend/components/tasks/js/tasks-manager.js index 2a89bfc..bbafde5 100755 --- a/containers/libreportal/frontend/components/tasks/js/tasks-manager.js +++ b/containers/libreportal/frontend/components/tasks/js/tasks-manager.js @@ -411,6 +411,30 @@ class TasksManager { // and backup-manager so started/completed look like a matched pair. if (window.notificationSystem && task) { const { appName, actionTitle, displayName, icon, typeIcon } = this._taskNotificationDescriptor(task); + + // Background (self-surfacing) task — e.g. the updater check repaints its + // own page, so the standard "View Task" completion toast is just noise. + // Drop it; if the user launched this run by hand (executeTask marked its + // id pending) show one small plain result line instead. Backend/auto runs + // aren't pending, so they finish silently. + const bg = window.LP_BACKGROUND_TASKS; + if (bg && bg.match(task.type, task.command)) { + const handLaunched = bg.pending.delete(String(task.id)); + if (handLaunched && (task.status === 'completed' || task.status === 'failed')) { + const m = bg.messages(task.type); + window.notificationSystem.show( + task.status === 'completed' ? m.done : m.fail, + task.status === 'completed' ? 'success' : 'error' + ); + } + // Still re-enable app buttons defensively (a no-op for the updater's + // pseudo-app), matching the standard path below. + if (appName && window.appTabbedManager && typeof window.appTabbedManager.enableAppButtons === 'function') { + try { window.appTabbedManager.enableAppButtons(appName); } catch {} + } + return; + } + const onAppPage = window.location.pathname.startsWith('/app') && !window.location.pathname.startsWith('/apps'); const url = (onAppPage && appName) ? window.appPath(appName, 'tasks', null, taskId) diff --git a/containers/libreportal/frontend/core/tasks/js/task-actions.js b/containers/libreportal/frontend/core/tasks/js/task-actions.js index 8864be0..dfcf5cd 100755 --- a/containers/libreportal/frontend/core/tasks/js/task-actions.js +++ b/containers/libreportal/frontend/core/tasks/js/task-actions.js @@ -438,7 +438,16 @@ async configUpdate(changes) { taskUrl = window.taskPath('all', task.id); } - if (window.notificationSystem) { + // Background (self-surfacing) tasks — e.g. the updater check — skip the + // standard "View Task" started toast. The launcher already showed a small + // "…" line and the result repaints its own page; remember the id so the + // completion handler can show one small plain result line for this + // hand-launched run. + const bg = window.LP_BACKGROUND_TASKS; + const isBackgroundTask = !!(bg && bg.match(action, command)); + if (isBackgroundTask) { + if (task && task.id != null) bg.pending.add(String(task.id)); + } else if (window.notificationSystem) { // `appName === 'system'` is a category sentinel (config_update, // system_update — no real app). Resolve it to the LibrePortal // logo + name so the toast doesn't read "App: System" with a @@ -496,3 +505,32 @@ async configUpdate(changes) { // Export for use window.TaskActions = TaskActions; + +// --------------------------------------------------------------------------- +// Background (self-surfacing) task notifications +// +// A "background" task is a scan/refresh whose result lands back in the page it +// was launched from — e.g. the updater check repaints the Updates/Overview tab +// on its own. For those the standard "View Task" started/finished toasts are +// pure noise: there is no reason to open the Tasks page. So we drop the standard +// task toasts for them and — ONLY when the user launched it by hand — show one +// small plain result line instead. The launcher keeps its own small "…" start +// line (e.g. the updater's "Checking apps for updates…"). Backend-initiated runs +// (the periodic auto-scan) never enter `pending`, so they stay fully silent. +// +// Classified by task action/type; the command regex also catches backend +// variants (e.g. `libreportal updater check auto`). Add a `byAction` entry to +// make another self-surfacing action quiet — the mechanism is generic. +window.LP_BACKGROUND_TASKS = window.LP_BACKGROUND_TASKS || { + byAction: { + updater_check: { done: 'Apps checked for updates & vulnerabilities.', fail: 'Update check failed.' }, + }, + commandRe: /^libreportal\s+updater\s+check\b/, + pending: new Set(), // ids of hand-launched background tasks awaiting a quiet finish toast + match(action, command) { + return !!((action && this.byAction[action]) || (command && this.commandRe.test(command))); + }, + messages(action) { + return this.byAction[action] || { done: 'Done.', fail: 'Failed.' }; + }, +};