mirror of
https://github.com/TheCriicom/omega-dashboard-ps5.git
synced 2026-10-29 04:02:53 +01:00
- Web app su /app (server/api/webapp): installabile, accesso con l'account Omega, funziona anche a console spenta: amici online, chat, party, community, classifiche, record, trofei, profili, Store con desideri, consiglia e «Installa sulla PS5», notifiche e loro impostazioni. - Console collegata: il servizio annuncia ogni 30 s indirizzo e token (POST /api/v1/console/announce); la web app apre la pagina della console in Wi-Fi già abbinata per caricare i giochi e gestire La mia libreria: i file non passano dal server. Coda «Installa sulla PS5» (migrazione 015). - Dash: tessera App mobile con il QR della web app; ovunque si parlava del telefono ora c'è il riquadro con il link; il telecomando in Wi-Fi resta in Sistema come opzione avanzata. - Notifiche per tipo (tutti/solo preferiti/nessuno), amici preferiti o silenziati, orari di silenzio, cosa vedere durante il gioco (migrazione 016); «è online» e «inizia a giocare» di base solo dai preferiti. Pannello nella dash e nella web app; il demone e la UI non mostrano le notifiche silent. - Archivio e spostamenti (storage.c): sposta o copia i giochi in cartella tra memoria interna e dischi, e i .pkg su un disco, con avanzamento e verifica. - Test: notify-console.test.mjs.
54 lines
2.9 KiB
JavaScript
54 lines
2.9 KiB
JavaScript
// Installazione come app: beforeinstallprompt (Android/PC) o istruzioni (iPhone/iPad).
|
|
import { t } from './i18n.js';
|
|
import { h, icon, iconBtn, btn, sheet } from './ui.js';
|
|
import { pref, setPref } from './state.js';
|
|
|
|
let deferred = null;
|
|
window.addEventListener('beforeinstallprompt', (e) => { e.preventDefault(); deferred = e; });
|
|
window.addEventListener('appinstalled', () => { deferred = null; setPref('installed', true); document.querySelector('.install-banner')?.remove(); });
|
|
|
|
export const isStandalone = () => matchMedia('(display-mode: standalone)').matches || navigator.standalone === true;
|
|
export const isIOS = () => /iphone|ipad|ipod/i.test(navigator.userAgent) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
|
|
export const canInstall = () => !isStandalone() && (!!deferred || isIOS());
|
|
|
|
export async function promptInstall() {
|
|
if (deferred) {
|
|
deferred.prompt();
|
|
const r = await deferred.userChoice.catch(() => null);
|
|
deferred = null;
|
|
if (r && r.outcome === 'accepted') setPref('installed', true);
|
|
return;
|
|
}
|
|
if (isIOS()) { iosSheet(); return; }
|
|
sheet({ title: t('pwa.title'), content: h('p', { class: 'muted', text: t('pwa.desktopHint') }) });
|
|
}
|
|
|
|
function iosSheet() {
|
|
sheet({
|
|
title: t('pwa.iosTitle'), subtitle: t('pwa.iosSub'),
|
|
content: h('div', { class: 'ios-steps' },
|
|
h('div', { class: 'ios-step' }, h('span', { class: 'lr-ic c-accent' }, icon('upload', 20)), h('span', { text: t('pwa.ios1') })),
|
|
h('div', { class: 'ios-step' }, h('span', { class: 'lr-ic c-accent' }, icon('plus', 20)), h('span', { text: t('pwa.ios2') })),
|
|
h('div', { class: 'ios-step' }, h('span', { class: 'lr-ic c-accent' }, icon('check', 20)), h('span', { text: t('pwa.ios3') }))),
|
|
});
|
|
}
|
|
|
|
export function installBanner() {
|
|
if (isStandalone() || pref('installed', false)) return;
|
|
const dismissed = pref('installDismissed', 0);
|
|
if (dismissed && Date.now() - dismissed < 14 * 86400000) return;
|
|
// su Android/PC aspetta l'evento; su iOS mostra le istruzioni
|
|
const show = () => {
|
|
if (document.querySelector('.install-banner') || isStandalone()) return;
|
|
const el = h('div', { class: 'install-banner', role: 'region', 'aria-label': t('pwa.title') },
|
|
h('img', { class: 'ib-ic', src: '/app/icons/icon-192.png', alt: '' }),
|
|
h('div', { class: 'ib-txt' }, h('strong', { text: t('pwa.title') }), h('small', { text: isIOS() ? t('pwa.bannerIos') : t('pwa.banner') })),
|
|
btn(isIOS() ? t('pwa.how') : t('pwa.install'), { size: 'sm', onclick: () => { el.remove(); promptInstall(); } }),
|
|
iconBtn('close', t('common.close'), () => { setPref('installDismissed', Date.now()); el.classList.remove('in'); setTimeout(() => el.remove(), 300); }));
|
|
document.body.appendChild(el);
|
|
requestAnimationFrame(() => el.classList.add('in'));
|
|
};
|
|
if (deferred || isIOS()) show();
|
|
else window.addEventListener('beforeinstallprompt', () => setTimeout(show, 800), { once: true });
|
|
}
|