PageSourceSearch

https://www.fgpsoftware.it/js/pwa-2026-07-30.js

js fgpsoftware.it collected 2026-09-25 13:21:58 UTC 12,121 bytes, 332 lines download raw bytes

1const divInstall = document.getElementById('installContainer');
2const butInstall = document.getElementById('butInstall');
3
4window.addEventListener("online",  function(){
5	// console.log("Sei online!");
6	document.body.classList.toggle('offline', false);
7});
8window.addEventListener("offline", function(){
9	// console.log("Oh no, connessione persa.");
10	document.body.classList.toggle('offline', true);
11});
12
13window.addEventListener('beforeinstallprompt', (event) => {
14	// Prevent the mini-infobar from appearing on mobile.
15	event.preventDefault();
16	console.log('👍', 'beforeinstallprompt', event);
17	// Stash the event so it can be triggered later.
18	window.deferredPrompt = event;
19	// Remove the 'hidden' class from the install button container.
20	if(divInstall)divInstall.classList.toggle('hidden', false);
21});
22
23if(butInstall)
24	butInstall.addEventListener('click', async () => {
25		console.log('👍', 'butInstall-clicked');
26		const promptEvent = window.deferredPrompt;
27		if (!promptEvent) {
28			// The deferred prompt isn't available.
29			return;
30		}
31		// Show the install prompt.
32		promptEvent.prompt();
33		// Log the result
34		const result = await promptEvent.userChoice;
35		console.log('👍', 'userChoice', result);
36		// Reset the deferred prompt variable, since
37		// prompt() can only be called once.
38		window.deferredPrompt = null;
39		// Hide the install button.
40		if(divInstall)divInstall.classList.toggle('hidden', true);
41	});
42
43window.addEventListener('appinstalled', (event) => {
44	console.log('👍', 'appinstalled', event);
45	// Clear the deferredPrompt so it can be garbage collected
46	window.deferredPrompt = null;
47	if(divInstall)divInstall.classList.toggle('hidden', true);
48});
49
50// const apiKeyNews = 'API-KEY';
51
52const fetchNews = async () => {
53	// const url = `http://newsapi.org/v2/everything?q=bitcoin&sortBy=publishedAt&apiKey=${apiKeyNews}`;
54	// const response = await fetch(url)
55	//response = '{}';
56	//return response.json();
57	console.log('sinc2');
58	return false;
59};
60
61function urlBase64ToUint8Array(base64String) {
62  const padding = '='.repeat((4 - base64String.length % 4) % 4);
63  const base64 = (base64String + padding)
64    .replace(/\-/g, '+')
65    .replace(/_/g, '/');
66
67  const rawData = window.atob(base64);
68  const outputArray = new Uint8Array(rawData.length);
69
70  for (let i = 0; i < rawData.length; ++i) {
71    outputArray[i] = rawData.charCodeAt(i);
72  }
73  return outputArray;
74}
75
76
77const mainApp = async () => {
78	/* Only register a service worker if it's supported */
79	if ('serviceWorker' in navigator) {
80		// navigator.serviceWorker.register('/service-worker.min.js').
81		navigator.serviceWorker.register('/service-worker.js?v=1.8').
82			then(function (registration) {
83				// Registration was successful``
84				console.log('Registrazione ServiceWorker riuscita per: ', registration.scope);
85				const permission = Notification.permission;
86				console.log("fgp - Notifiche: "+permission);
87				if (permission === 'denied') {
88					// L'utente ha bloccato le notifiche in precedenza
89					mostraAvvisoInterfaccia("Hai disattivato le notifiche. Controlla le impostazioni del browser per ricevere gli avvisi.");
90				} else if (permission === 'default') {
91					// L'utente non ha ancora deciso (mostriamo un pulsante nell'app)
92					mostraPulsanteAttivazione();
93				} else if (permission === 'granted') {
94					// Tutto ok, verifichiamo se l'iscrizione sul server è ancora valida
95					gestisciIscrizioneEsistente(registration);
96				}
97				/*const subscribeOptions = {
98					userVisibleOnly: true,
99					applicationServerKey: urlBase64ToUint8Array(
100						'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U',
101					),
102				};
103				registration.pushManager.subscribe(
104					subscribeOptions
105					//{userVisibleOnly: true}
106				
107				).then(
108					function(pushSubscription) {
109						console.log("Push2: "+pushSubscription.endpoint);
110						// The push subscription details needed by the application
111						// server are now available, and can be sent to it using,
112						// for example, an XMLHttpRequest.
113					}, function(error) {
114						// During development it often helps to log errors to the
115						// console. In a production environment it might make sense to
116						// also report information about errors back to the
117						// application server.
118						console.log("Push: "+error);
119					}
120				);*/
121				
122				/*getToken(messaging, { 
123					serviceWorkerRegistration: registration, 
124					vapidKey: 'key' }).then((currentToken) => {
125						if(currentToken){
126							// send token
127							console.log("Token: "+currentToken);
128						} else {
129							console.log('Token non generato. Richiedi permessi');
130						}
131					}).catch((err) => {
132						console.log('Errore generazione token: ',err);
133					});*/
134			}).catch(function (err) {
135				// registration failed :(
136				console.log('Registrazione ServiceWorker non riuscita: ', err);
137			});
138	}
139	
140	const news = await fetchNews();
141	/*if (news.formattedTime) {
142		setLastFetchedDate(news.formattedTime);
143	}*/
144
145	const articles = news.articles;
146	if (articles && articles.length) {
147		const newsElement = document.getElementById('news');
148		if (!newsElement) return;
149
150		articles.forEach(article => {
151			newsElement.appendChild(createArticleElement(article));
152		});
153	}
154	
155	const registration = await navigator.serviceWorker.ready;
156  // Check if periodicSync is supported
157  if ('periodicSync' in registration) {
158    // Request permission
159    const status = await navigator.permissions.query({
160      name: 'periodic-background-sync',
161    });
162
163    if (status.state === 'granted') {
164      try {
165        // Register new sync every 24 hours
166        await registration.periodicSync.register('news', {
167          minInterval: 1 * 1 * 60 * 1000, // 1 minuto
168        });
169        console.log('Sincronizzazione periodica in background attivata'+' '+'news');
170      } catch(e) {
171        console.error(`Periodic background sync failed:\nx${e}`);
172      }
173    } else {
174      console.info('Periodic background sync is not granted.');
175    }
176  } else {
177    console.log('Periodic background sync is not supported.');
178  }
179}
180/*
181navigator.serviceWorker.ready.then(registration => {
182	if (registration.sync) {
183		console.log("Background Sync is supported.");
184	} else {
185		console.log("Background Sync isn't supported.");
186	}
187});
188
189/*async function registerPeriodicNewsCheck() {
190  const registration = await navigator.serviceWorker.ready;
191  try {
192    await registration.periodicSync.register('fetch-news', {
193      minInterval: 24 * 60 * 60 * 1000,
194    });
195  } catch {
196    console.log('Periodic Sync could not be registered!');
197  }
198}*/
199
200/**
201 * Warn the page must be served over HTTPS
202 * The `beforeinstallprompt` event won't fire if the page is served over HTTP.
203 * Installability requires a service worker with a fetch event handler, and
204 * if the page isn't served over HTTPS, the service worker won't load.
205 */
206if (window.location.protocol === 'http:') {
207	const requireHTTPS = document.getElementById('requireHTTPS');
208	if(requireHTTPS){
209		const link = requireHTTPS.querySelector('a');
210		link.href = window.location.href.replace('http://', 'https://');
211		requireHTTPS.classList.remove('hidden');
212	}
213}
214
215function mostraAvvisoInterfaccia(messaggio) {
216	// alert(messaggio);
217	// const alertBox = document.getElementById('alert-notifiche');
218	const alertBox = document.getElementById('container-notifiche');
219	if (alertBox) {
220		alertBox.innerText = messaggio;
221		alertBox.style.display = 'block';
222	}
223}
224function mostraPulsanteAttivazione() {
225	const container = document.getElementById('container-notifiche');
226	const btn = document.getElementById('btn-attiva-push');
227	if (container && btn) {
228		// Mostriamo il banner
229		container.style.display = 'block';
230		// Al click, chiediamo il permesso e iscriviamo l'utente
231		btn.onclick = async () => {
232			const permission = await Notification.requestPermission();
233			if (permission === 'granted') {
234				console.log("Permesso concesso!");
235				// Richiamiamo la funzione di iscrizione che abbiamo creato nei passaggi precedenti
236				const registration = await navigator.serviceWorker.ready;
237				abilitaNotifiche(registration);
238				container.style.display = 'none'; // Nascondiamo il banner
239			} else {
240				alert("Senza permessi non potrai ricevere gli avvisi in tempo reale.");
241			}
242		};
243	}
244}
245
246async function gestisciIscrizioneEsistente(registration) {
247	try {
248		// Verifica se esiste già una sottoscrizione attiva nel browser
249		const subscription = await registration.pushManager.getSubscription();
250		if (subscription) {
251			console.log("Sottoscrizione esistente trovata.");
252			// Opzionale: Invia comunque al server per aggiornare il database 
253			// e assicurarsi che i dati non siano scaduti
254			await inviaSottoscrizioneAlServer(subscription);
255			// Nascondi eventuali pulsanti di attivazione perché siamo già attivi
256			const container = document.getElementById('container-notifiche');
257			if (container) container.style.display = 'none';
258		} else {
259			// Se non c'è una sottoscrizione ma avevamo i permessi, 
260			// potremmo aver bisogno di ri-crearla
261			console.log("Sottoscrizione non trovata, ma i permessi sono attivi.");
262			mostraPulsanteAttivazione(); 
263		}
264	} catch (error) {
265		console.error("Errore nel recupero della sottoscrizione:", error);
266	}
267}
268
269// Questa è la funzione di supporto che invia i dati al tuo file PHP
270async function inviaSottoscrizioneAlServer(subscription) {
271	// La sottoscrizione deve essere trasformata in JSON per essere inviata
272	const subJSON = JSON.stringify(subscription);
273	try {
274		const response = await fetch('/push/salva_iscrizione.php', {
275			method: 'POST',
276			headers: {
277				'Content-Type': 'application/json'
278			},
279			body: subJSON
280		});
281		const result = await response.json();
282		if (result.status === 'success') {
283			console.log("Database sincronizzato con successo.");
284		}
285	} catch (error) {
286		console.error("Impossibile sincronizzare la sottoscrizione col server:", error);
287	}
288}
289
290async function abilitaNotifiche(registration) {
291    // 1. Definiamo la tua Chiave Pubblica VAPID
292    // Sostituisci questa stringa con la chiave reale generata per il tuo server
293	const key = VAPID_PUBLIC_KEY;
294    try {
295        // 2. Creiamo la sottoscrizione verso i server di Google/Mozilla/Apple
296        const subscription = await registration.pushManager.subscribe({
297            userVisibleOnly: true, // Obbligatorio: garantisce che ogni push mostri una notifica visiva
298            applicationServerKey: urlBase64ToUint8Array(key)
299        });
300        console.log("Iscrizione completata nel browser:", subscription);
301        // 3. Inviamo la sottoscrizione al database
302		// await inviaSottoscrizioneAlServer(subscription, CONFIG_PUSH.RUOLO, CONFIG_PUSH.ID_UTENTE);
303        await inviaSottoscrizioneAlServer(subscription);
304        alert("Notifiche attivate! Riceverai gli avvisi in tempo reale.");
305    } catch (error) {
306        if (Notification.permission === 'denied') {
307            console.error("L'utente ha bloccato le notifiche.");
308            alert("Hai bloccato le notifiche. Sbloccale dalle impostazioni del browser (icona lucchetto).");
309        } else {
310            console.error("Errore durante l'abilitazione delle notifiche:", error);
311			alert("Errore durante l'abilitazione delle notifiche:");
312			alert(error);
313        }
314    }
315}
316
317/**
318 * Funzione di utilità necessaria per convertire la chiave VAPID 
319 * dal formato stringa a quello richiesto dal browser (Uint8Array)
320 */
321function urlBase64ToUint8Array(base64String) {
322    const padding = '='.repeat((4 - base64String.length % 4) % 4);
323    const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/');
324    const rawData = window.atob(base64);
325    const outputArray = new Uint8Array(rawData.length);
326    for (let i = 0; i < rawData.length; ++i) {
327        outputArray[i] = rawData.charCodeAt(i);
328    }
329    return outputArray;
330}
331
332mainApp();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.