Merge pull request #65 from kristianwind/maerket-paa-ikonet
feat(beskeder): appens ikon bærer tallet på ulæste
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Mærket på appens ikon — tallet i Dock'en på en Mac, på proceslinjen på en pc.
|
||||
*
|
||||
* Klokken i hovedet siger det samme, men kun til den, der kigger på fanen. Det
|
||||
* halve af pointen med at få besked er at få den, mens man laver noget andet, og
|
||||
* det eneste sted, appen kan sige noget dér, er på sit eget ikon.
|
||||
*
|
||||
* Sat to steder, fordi der er to tilstande: her, mens appen er åben og selv ved
|
||||
* hvor mange ulæste der er, og i service-workeren, når den ikke er — se `push`-
|
||||
* lytteren i service-worker.js, som får tallet med i beskeden.
|
||||
*
|
||||
* Ét tal, ikke en optælling. Mærket sættes til hvad der *er*, aldrig til hvad der
|
||||
* lige er kommet, så det kommer ned igen af sig selv, når beskederne bliver læst.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Kan browseren mærke sit ikon? Safari og Chrome kan, når appen er lagt i Dock'en
|
||||
* eller installeret; en almindelig fane har intet ikon at mærke, og kaldet gør
|
||||
* ingenting. Firefox kan ikke endnu.
|
||||
*/
|
||||
export function supported() {
|
||||
return typeof navigator !== 'undefined' && 'setAppBadge' in navigator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sætter mærket til `n`, eller fjerner det ved nul.
|
||||
*
|
||||
* Tavs, når det ikke kan lade sig gøre. Et mærke er en venlighed oven på klokken,
|
||||
* der allerede står i fladen — ikke noget at afbryde nogen med, hvis browseren
|
||||
* siger nej.
|
||||
*/
|
||||
export function setBadge(n) {
|
||||
if (!supported()) return;
|
||||
const count = Number(n) || 0;
|
||||
try {
|
||||
const done = count > 0 ? navigator.setAppBadge(count) : navigator.clearAppBadge();
|
||||
done?.catch?.(() => {});
|
||||
} catch {
|
||||
// Nogle browsere kaster i stedet for at afvise. Det er det samme svar.
|
||||
}
|
||||
}
|
||||
|
||||
/** Fjerner mærket helt. Brugt ved log ud: den næste, der lander her, er en anden. */
|
||||
export function clearBadge() {
|
||||
setBadge(0);
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
<script>
|
||||
import { app, sidebar, projectName } from '$lib/stores.svelte.js';
|
||||
import { api } from '$lib/api.js';
|
||||
import { clearBadge } from '$lib/badge.js';
|
||||
import { TASK, PROJECT, GROUP, NOTE, startDrag, carries, dragged, accept } from '$lib/dnd.js';
|
||||
import { COLORS, colorVar } from '$lib/colors.js';
|
||||
import { focusOnMount } from '$lib/focus.js';
|
||||
@@ -31,6 +32,9 @@
|
||||
|
||||
async function signOut() {
|
||||
await api.logout();
|
||||
// Mærket på ikonet er den forriges ulæste. Det står i Dock'en, også når
|
||||
// ingen er logget ind, så det skal væk sammen med resten af dem.
|
||||
clearBadge();
|
||||
// Empty the offline data cache before leaving: the service worker keeps the
|
||||
// last-seen task and note lists so a network drop does not blank the app, and
|
||||
// the next person to sign in on this browser must not find them.
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
import SignIn from '$lib/components/SignIn.svelte';
|
||||
import TaskDetail from '$lib/components/TaskDetail.svelte';
|
||||
import { t } from '$lib/i18n.svelte.js';
|
||||
import { setBadge } from '$lib/badge.js';
|
||||
|
||||
let { children } = $props();
|
||||
|
||||
@@ -53,6 +54,13 @@
|
||||
app.load();
|
||||
});
|
||||
|
||||
// Tallet på appens ikon følger klokken. Ét sted, fordi der er ét tal: hentet,
|
||||
// skubbet over websocket'en eller læst væk — mærket er det samme svar på alle
|
||||
// tre, og en optælling pr. vej ville være tre, der kan blive uenige.
|
||||
$effect(() => {
|
||||
setBadge(app.unread);
|
||||
});
|
||||
|
||||
/**
|
||||
* Global keys.
|
||||
*
|
||||
|
||||
@@ -145,6 +145,19 @@ self.addEventListener('push', (event) => {
|
||||
}
|
||||
|
||||
const title = payload.title || 'verdande';
|
||||
// Mærket på appens ikon — i Dock'en på en Mac, på proceslinjen på en pc.
|
||||
//
|
||||
// Sat her, fordi det her er det eneste, der kører, når appen ikke er åben: det
|
||||
// er netop dér, et tal på ikonet er det, der siger, at der er noget nyt. Tallet
|
||||
// kommer med beskeden frem for at blive talt op her; en service-worker husker
|
||||
// ingenting mellem to opvågninger, så et mærke, den selv talte, ville kun kunne
|
||||
// gå opad.
|
||||
//
|
||||
// Kan browseren ikke sætte mærker, sker der ingenting. Det er ikke en fejl at
|
||||
// melde om: beskeden selv kom frem, og den er hovedsagen.
|
||||
if (typeof payload.unread === 'number' && 'setAppBadge' in self.navigator) {
|
||||
self.navigator.setAppBadge(payload.unread).catch(() => {});
|
||||
}
|
||||
event.waitUntil(
|
||||
self.registration.showNotification(title, {
|
||||
body: payload.body || '',
|
||||
|
||||
Reference in New Issue
Block a user