feat: réparation audio, mobile et PWA + charte OKI légère

- Volume propagé en direct sur l'élément audio (le slider ne faisait
  que persister) ; volume 0 respecté (?? 1) ; slider masqué sur iOS
  (can_set_volume) ; mute synchronisé store/élément, persistant entre pistes
- Race condition loadedmetadata, USER_PROGRESS borné à 200 entrées,
  erreurs radio affichées avec bouton Réessayer
- Mobile : barre de progression avec zone tactile 44 px (tap + scrub au doigt),
  boutons 48 px, contrôles wrap, listes paginées 50×50 + content-visibility
- PWA : manifest + icônes 192/512 (any+maskable), service worker manuel
  (shell + pochettes, streams exclus), Media Session API (metadata + 4 handlers)
- SEO : Seo.svelte (canonical, OG, Twitter), footer fédéré OKI + flag-bar
- Mesuré puppeteer 390x844 : seek tactile OK, scrollWidth OK, SW actif
This commit is contained in:
sucupira
2026-07-21 18:57:26 -04:00
parent 4320258468
commit 67c701f85a
22 changed files with 488 additions and 74 deletions
+12
View File
@@ -4,6 +4,7 @@ import { persisted } from 'svelte-local-storage-store';
export interface UserPreferences {
playback_rate: number;
volume: number;
muted: boolean;
}
/**
@@ -12,6 +13,7 @@ export interface UserPreferences {
const DEFAULT_USER_PREFERENCES: UserPreferences = {
playback_rate: 1,
volume: 1,
muted: false,
};
/**
@@ -43,6 +45,15 @@ const set_volume = (value: number) => {
return USER_PREFERENCES_STORE.update((prefs) => ({ ...prefs, volume }));
};
/**
* Sets the muted state for the user. This is the single source of truth
* for mute: the audio element is kept in sync with it.
* @param value - The muted value
*/
const set_muted = (value: boolean) => {
return USER_PREFERENCES_STORE.update((prefs) => ({ ...prefs, muted: value }));
};
/**
* Clears user preferences store
*/
@@ -55,5 +66,6 @@ export const user_preferences = {
subscribe: USER_PREFERENCES_STORE.subscribe,
set_playback_rate,
set_volume,
set_muted,
clear: clear_store,
};