- check updates
- risolto problema della generazione dei PDF, avevo modificato in CMyPageElem , se si cambia qualcosa occorre stare attenti a mettere !hideHeader
4
.env
@@ -1,6 +1,6 @@
|
||||
VITE_APP_VERSION="1.2.72"
|
||||
VITE_APP_VERSION="1.2.75"
|
||||
VITE_LANG_DEFAULT="it"
|
||||
VITE_PAO_APP_ID="KKPPAA5KJK435J3KSS9F9D8S9F8SD98F9SDF"
|
||||
VITE_SERVICE_WORKER_FILE="sw-1.2.72.js"
|
||||
VITE_SERVICE_WORKER_FILE="sw-1.2.75.js"
|
||||
VITE_PROJECT_ID_MAIN="5cc0a13fe5c9d156728f400a"
|
||||
VITE_VUE_ROUTER_MODE="history"
|
||||
@@ -1,12 +1,12 @@
|
||||
VITE_APP_ID="13"
|
||||
VITE_APP_ID="18"
|
||||
VITE_APP_URL="https://localhost"
|
||||
VITE_MONGODB_HOST="https://localhost:3000"
|
||||
VITE_LOGO_REG='riso-logo-full.png'
|
||||
VITE_LOGO_REG='gruppomacro-logo-full.png'
|
||||
VITE_PUBLICKEY_PUSH='BDncvMiUZmjaCG2Kr1V9N0_33hOG-AuNSbHSvL24y2dzBiUjAxKm02emx5SeJvz2IGmtRf6YqCgopeQwCwUmZw8'
|
||||
VITE_DEBUG="1"
|
||||
VITE_VUE_APP_ISTEST=0
|
||||
VITE_VUE_APP_INLOCALE=1
|
||||
DIRECTORY_LOCAL="myprojplanet_vite"
|
||||
DIRECTORY_LOCAL="newfreeplanet"
|
||||
DIRECTORY_SERVER="freeplanet_serverside"
|
||||
SERVERDIR_WEBSITE=""
|
||||
SERVERPW_WEBSITE=""
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
VITE_APP_ID="13"
|
||||
VITE_APP_URL="https://test.riso.app"
|
||||
VITE_MONGODB_HOST="https://testapi.riso.app"
|
||||
VITE_LOGO_REG="riso-logo-full.png"
|
||||
VITE_PUBLICKEY_PUSH="BGXRf1TgcqocqD6J7qnRgCG7AvM2lxAoW7peb7UEzB4SxBb6DxGRdJ0UvD9ewnrB9KrSrh0-aDCODXBm7sZ1DDs"
|
||||
VITE_DEBUG="1"
|
||||
VITE_VUE_APP_ISTEST="1"
|
||||
VITE_APP_ID="18"
|
||||
VITE_APP_URL="https://gruppomacro.app"
|
||||
VITE_MONGODB_HOST="https://api.gruppomacro.app"
|
||||
VITE_LOGO_REG='gruppomacro-logo-full.png'
|
||||
VITE_PUBLICKEY_PUSH="BJgo8XR_upbnbMLWgCAUELo6DK7dRXffYAnFOxbaMMz5favBgcQBKT-eISqouO-jRad4Sw8l5nd2wCF6KorGiTc"
|
||||
VITE_DEBUG="0"
|
||||
VITE_VUE_APP_ISTEST="0"
|
||||
DIRECTORY_LOCAL="myprojplanet_vite"
|
||||
DIRECTORY_SERVER="/var/www/nodejs_test.riso_server"
|
||||
SERVERDIR_WEBSITE="/var/www/test.riso.app"
|
||||
DIRECTORY_SERVER="/var/www/nodejs_piuchebuono_server"
|
||||
SERVERDIR_WEBSITE="/var/www/gruppomacro.app"
|
||||
SERVERPW_WEBSITE="pwdadmin@1AOK"
|
||||
PORT_SPA="8089"
|
||||
PORT_PWA="8099"
|
||||
@@ -10,7 +10,7 @@
|
||||
<meta name="description" content="<%= productDescription %>">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="msapplication-tap-highlight" content="no">
|
||||
<meta name="version" content="1.2.72">
|
||||
<meta name="version" content="1.2.75">
|
||||
<meta name="viewport"
|
||||
content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width<% if (ctx.mode.cordova || ctx.mode.capacitor) { %>, viewport-fit=cover<% } %>">
|
||||
|
||||
|
||||
20
package.json
@@ -1,28 +1,28 @@
|
||||
{
|
||||
"name": "riso",
|
||||
"version": "1.2.72",
|
||||
"productName": "Riso 💚 - Rete Italiana Scambi Orizzontali",
|
||||
"description": "Progetto RISO (Rete Italiana Scambi Orizzontali) promuove una rete di comunità locali che favoriscono scambi di beni, servizi e ospitalità. Con l'App RISO, sviluppata per facilitare il baratto, il dono e l'uso di monete alternative come i RIS, il progetto crea legami autentici basati sulla fiducia e sostenibilità. Partecipa agli scambi e costruisci una comunità più consapevole e autosufficiente.",
|
||||
"name": "gruppomacro",
|
||||
"version": "1.2.75",
|
||||
"productName": "Gruppo Macro",
|
||||
"description": "Il Gruppo Editoriale Macro, attivo dal 1987, è leader europeo nella pubblicazione di libri per il benessere e la consapevolezza. Con oltre 1.500 titoli, promuove una visione armonica del mondo, offrendo opere di autori internazionali e italiani come Gregg Braden, Bruce Lipton, Joe Dispenza, Louise Hay, Eckhart Tolle e molti altri. Scopri un'editoria che abbraccia il corpo, la mente, lo spirito e l'ecologia.",
|
||||
"author": "Surya",
|
||||
"private": true,
|
||||
"keywords": [],
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "APP_VERSION='1.2.72' PORT=8084 quasar dev",
|
||||
"dev": "PORT=8089 APP_VERSION='1.2.75' quasar dev",
|
||||
"dev_noCheck": "SKIP_TSC=true quasar dev",
|
||||
"build": "quasar build",
|
||||
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.72' quasar build -m pwa",
|
||||
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.72' quasar build -m pwa",
|
||||
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.75' quasar build -m pwa",
|
||||
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.75' quasar build -m pwa",
|
||||
"type-check": "vue-tsc --noEmit",
|
||||
"type-check:watch": "vue-tsc --noEmit --watch",
|
||||
"buildspa": "quasar build -m spa",
|
||||
"buildspa": "APP_VERSION='1.2.75' quasar build -m spa",
|
||||
"lint": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\"",
|
||||
"lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt",
|
||||
"lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt",
|
||||
"fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt",
|
||||
"pwa": "NODE_ENV=development PORT=8094 APP_VERSION='1.2.72' quasar dev -m pwa",
|
||||
"spa": "NODE_ENV=development PORT=8084 APP_VERSION='1.2.72' quasar dev",
|
||||
"pwa": "NODE_ENV=development PORT=8099 APP_VERSION='1.2.75' quasar dev -m pwa",
|
||||
"spa": "NODE_ENV=development PORT=8089 APP_VERSION='1.2.75' quasar dev",
|
||||
"debug": "quasar dev --mode debug",
|
||||
"test": "echo \"No test specified\" && exit 0",
|
||||
"generate-sw": "workbox generateSW workbox-config.js",
|
||||
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
BIN
public/images/bestseller.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
3592316
public/images/comuni_italia.geojson
Normal file
BIN
public/images/foto1.jpg
Executable file
|
After Width: | Height: | Size: 12 KiB |
BIN
public/images/foto2.jpg
Executable file
|
After Width: | Height: | Size: 12 KiB |
BIN
public/images/foto3.jpg
Executable file
|
After Width: | Height: | Size: 12 KiB |
BIN
public/images/gm-android-icon-192x192.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
public/images/gm-android-icon-512x512.png
Normal file
|
After Width: | Height: | Size: 158 KiB |
BIN
public/images/gm-apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
public/images/gruppomacro-logo-full.png
Normal file
|
After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 696 B |
|
Before Width: | Height: | Size: 424 KiB |
|
Before Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
BIN
public/images/novita.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
public/images/ombra.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 138 KiB |
|
Before Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 185 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 7.6 KiB |
|
Before Width: | Height: | Size: 8.1 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 424 KiB |
|
Before Width: | Height: | Size: 279 KiB |
|
Before Width: | Height: | Size: 258 KiB |
|
Before Width: | Height: | Size: 124 KiB |
2
public/js/workbox-sw-6-1.js
Executable file
@@ -0,0 +1,2 @@
|
||||
!function(){'use strict';try{self['workbox:sw:6.1.0']&&_()}catch(t){}const t={backgroundSync:'background-sync',broadcastUpdate:'broadcast-update',cacheableResponse:'cacheable-response',core:'core',expiration:'expiration',googleAnalytics:'offline-ga',navigationPreload:'navigation-preload',precaching:'precaching',rangeRequests:'range-requests',routing:'routing',strategies:'strategies',streams:'streams',recipes:'recipes'};self.workbox=new class{constructor(){return this.v={},this.Pt={debug:'localhost'===self.location.hostname,modulePathPrefix:null,modulePathCb:null},this.$t=this.Pt.debug?'dev':'prod',this.jt=!1,new Proxy(this,{get(e,s){if(e[s])return e[s];const o=t[s];return o&&e.loadModule('workbox-'+o),e[s]}})}setConfig(t={}){if(this.jt)throw new Error('Config must be set before accessing workbox.* modules');Object.assign(this.Pt,t),this.$t=this.Pt.debug?'dev':'prod'}loadModule(t){const e=this.St(t);try{importScripts(e),this.jt=!0}catch(s){throw console.error(`Unable to import module '${t}' from '${e}'.`),s}}St(t){if(this.Pt.modulePathCb)return this.Pt.modulePathCb(t,this.Pt.debug);let e=['https://storage.googleapis.com/workbox-cdn/releases/6.1.0'];const s=`${t}.${this.$t}.js`,o=this.Pt.modulePathPrefix;return o&&(e=o.split('/'),''===e[e.length-1]&&e.splice(e.length-1,1)),e.push(s),e.join('/')}}}();
|
||||
//# sourceMappingURL=workbox-sw.js.map
|
||||
2
public/js/workbox-sw.js
Normal file
@@ -0,0 +1,2 @@
|
||||
!function(){"use strict";try{self["workbox:sw:5.1.4"]&&_()}catch(t){}const t={backgroundSync:"background-sync",broadcastUpdate:"broadcast-update",cacheableResponse:"cacheable-response",core:"core",expiration:"expiration",googleAnalytics:"offline-ga",navigationPreload:"navigation-preload",precaching:"precaching",rangeRequests:"range-requests",routing:"routing",strategies:"strategies",streams:"streams"};self.workbox=new class{constructor(){return this.v={},this.t={debug:"localhost"===self.location.hostname,modulePathPrefix:null,modulePathCb:null},this.s=this.t.debug?"dev":"prod",this.o=!1,new Proxy(this,{get(e,s){if(e[s])return e[s];const o=t[s];return o&&e.loadModule("workbox-"+o),e[s]}})}setConfig(t={}){if(this.o)throw new Error("Config must be set before accessing workbox.* modules");Object.assign(this.t,t),this.s=this.t.debug?"dev":"prod"}loadModule(t){const e=this.i(t);try{importScripts(e),this.o=!0}catch(s){throw console.error(`Unable to import module '${t}' from '${e}'.`),s}}i(t){if(this.t.modulePathCb)return this.t.modulePathCb(t,this.t.debug);let e=["https://storage.googleapis.com/workbox-cdn/releases/5.1.4"];const s=`${t}.${this.s}.js`,o=this.t.modulePathPrefix;return o&&(e=o.split("/"),""===e[e.length-1]&&e.splice(e.length-1,1)),e.push(s),e.join("/")}}}();
|
||||
//# sourceMappingURL=workbox-sw.js.map
|
||||
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 15 KiB |
@@ -1,2 +1,2 @@
|
||||
!function(){"use strict";try{self["workbox:sw:7.3.0"]&&_()}catch(t){}const t={backgroundSync:"background-sync",broadcastUpdate:"broadcast-update",cacheableResponse:"cacheable-response",core:"core",expiration:"expiration",googleAnalytics:"offline-ga",navigationPreload:"navigation-preload",precaching:"precaching",rangeRequests:"range-requests",routing:"routing",strategies:"strategies",streams:"streams",recipes:"recipes"};self.workbox=new class{constructor(){return this.v={},this.Pt={debug:"localhost"===self.location.hostname,modulePathPrefix:null,modulePathCb:null},this.$t=this.Pt.debug?"dev":"prod",this.jt=!1,new Proxy(this,{get(e,s){if(e[s])return e[s];const o=t[s];return o&&e.loadModule(`workbox-${o}`),e[s]}})}setConfig(t={}){if(this.jt)throw new Error("Config must be set before accessing workbox.* modules");Object.assign(this.Pt,t),this.$t=this.Pt.debug?"dev":"prod"}loadModule(t){const e=this.St(t);try{importScripts(e),this.jt=!0}catch(s){throw console.error(`Unable to import module '${t}' from '${e}'.`),s}}St(t){if(this.Pt.modulePathCb)return this.Pt.modulePathCb(t,this.Pt.debug);let e=["https://storage.googleapis.com/workbox-cdn/releases/7.3.0"];const s=`${t}.${this.$t}.js`,o=this.Pt.modulePathPrefix;return o&&(e=o.split("/"),""===e[e.length-1]&&e.splice(e.length-1,1)),e.push(s),e.join("/")}}}();
|
||||
!function(){"use strict";try{self["workbox:sw:5.1.4"]&&_()}catch(t){}const t={backgroundSync:"background-sync",broadcastUpdate:"broadcast-update",cacheableResponse:"cacheable-response",core:"core",expiration:"expiration",googleAnalytics:"offline-ga",navigationPreload:"navigation-preload",precaching:"precaching",rangeRequests:"range-requests",routing:"routing",strategies:"strategies",streams:"streams"};self.workbox=new class{constructor(){return this.v={},this.t={debug:"localhost"===self.location.hostname,modulePathPrefix:null,modulePathCb:null},this.s=this.t.debug?"dev":"prod",this.o=!1,new Proxy(this,{get(e,s){if(e[s])return e[s];const o=t[s];return o&&e.loadModule("workbox-"+o),e[s]}})}setConfig(t={}){if(this.o)throw new Error("Config must be set before accessing workbox.* modules");Object.assign(this.t,t),this.s=this.t.debug?"dev":"prod"}loadModule(t){const e=this.i(t);try{importScripts(e),this.o=!0}catch(s){throw console.error(`Unable to import module '${t}' from '${e}'.`),s}}i(t){if(this.t.modulePathCb)return this.t.modulePathCb(t,this.t.debug);let e=["https://storage.googleapis.com/workbox-cdn/releases/5.1.4"];const s=`${t}.${this.s}.js`,o=this.t.modulePathPrefix;return o&&(e=o.split("/"),""===e[e.length-1]&&e.splice(e.length-1,1)),e.push(s),e.join("/")}}}();
|
||||
//# sourceMappingURL=workbox-sw.js.map
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cnm",
|
||||
"version": "1.2.72",
|
||||
"version": "1.2.75",
|
||||
"description": "Comunita Nuovo Mondo",
|
||||
"productName": "ComunitaNuovoMondo",
|
||||
"author": "Surya",
|
||||
@@ -9,7 +9,7 @@
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "PORT=8083 APP_VERSION='1.2.72' quasar dev",
|
||||
"dev": "PORT=8083 APP_VERSION='1.2.75' quasar dev",
|
||||
"dev_noCheck": "SKIP_TSC=true quasar dev",
|
||||
"build": "quasar build",
|
||||
"buildpwa": "NODE_ENV=production quasar build -m pwa",
|
||||
@@ -21,8 +21,8 @@
|
||||
"lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt",
|
||||
"lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt",
|
||||
"fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt",
|
||||
"pwa": "NODE_ENV=development PORT=8093 APP_VERSION='1.2.72' quasar dev -m pwa",
|
||||
"spa": "NODE_ENV=development PORT=8083 APP_VERSION='1.2.72' quasar dev",
|
||||
"pwa": "NODE_ENV=development PORT=8093 APP_VERSION='1.2.75' quasar dev -m pwa",
|
||||
"spa": "NODE_ENV=development PORT=8083 APP_VERSION='1.2.75' quasar dev",
|
||||
"debug": "quasar dev --mode debug",
|
||||
"test": "echo \"No test specified\" && exit 0",
|
||||
"generate-sw": "workbox generateSW workbox-config.js",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "freeplanet",
|
||||
"version": "1.2.72",
|
||||
"version": "1.2.75",
|
||||
"description": "freeplanet",
|
||||
"productName": "freeplanet",
|
||||
"author": "Surya",
|
||||
@@ -9,11 +9,11 @@
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "PORT=8087 APP_VERSION='1.2.72' quasar dev",
|
||||
"dev": "PORT=8087 APP_VERSION='1.2.75' quasar dev",
|
||||
"dev_noCheck": "SKIP_TSC=true quasar dev",
|
||||
"build": "quasar build",
|
||||
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.72' quasar build -m pwa",
|
||||
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.72' quasar build -m pwa",
|
||||
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.75' quasar build -m pwa",
|
||||
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.75' quasar build -m pwa",
|
||||
"type-check": "vue-tsc --noEmit",
|
||||
"type-check:watch": "vue-tsc --noEmit --watch",
|
||||
"buildspa": "quasar build -m spa",
|
||||
@@ -21,8 +21,8 @@
|
||||
"lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt",
|
||||
"lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt",
|
||||
"fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt",
|
||||
"pwa": "NODE_ENV=development PORT=8097 APP_VERSION='1.2.72' quasar dev -m pwa",
|
||||
"spa": "NODE_ENV=development PORT=8087 APP_VERSION='1.2.72' quasar dev",
|
||||
"pwa": "NODE_ENV=development PORT=8097 APP_VERSION='1.2.75' quasar dev -m pwa",
|
||||
"spa": "NODE_ENV=development PORT=8087 APP_VERSION='1.2.75' quasar dev",
|
||||
"debug": "quasar dev --mode debug",
|
||||
"test": "echo \"No test specified\" && exit 0",
|
||||
"generate-sw": "workbox generateSW workbox-config.js",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gruppomacro",
|
||||
"version": "1.2.72",
|
||||
"version": "1.2.75",
|
||||
"productName": "Gruppo Macro",
|
||||
"description": "Il Gruppo Editoriale Macro, attivo dal 1987, è leader europeo nella pubblicazione di libri per il benessere e la consapevolezza. Con oltre 1.500 titoli, promuove una visione armonica del mondo, offrendo opere di autori internazionali e italiani come Gregg Braden, Bruce Lipton, Joe Dispenza, Louise Hay, Eckhart Tolle e molti altri. Scopri un'editoria che abbraccia il corpo, la mente, lo spirito e l'ecologia.",
|
||||
"author": "Surya",
|
||||
@@ -9,20 +9,20 @@
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "PORT=8089 APP_VERSION='1.2.72' quasar dev",
|
||||
"dev": "PORT=8089 APP_VERSION='1.2.75' quasar dev",
|
||||
"dev_noCheck": "SKIP_TSC=true quasar dev",
|
||||
"build": "quasar build",
|
||||
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.72' quasar build -m pwa",
|
||||
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.72' quasar build -m pwa",
|
||||
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.75' quasar build -m pwa",
|
||||
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.75' quasar build -m pwa",
|
||||
"type-check": "vue-tsc --noEmit",
|
||||
"type-check:watch": "vue-tsc --noEmit --watch",
|
||||
"buildspa": "APP_VERSION='1.2.72' quasar build -m spa",
|
||||
"buildspa": "APP_VERSION='1.2.75' quasar build -m spa",
|
||||
"lint": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\"",
|
||||
"lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt",
|
||||
"lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt",
|
||||
"fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt",
|
||||
"pwa": "NODE_ENV=development PORT=8099 APP_VERSION='1.2.72' quasar dev -m pwa",
|
||||
"spa": "NODE_ENV=development PORT=8089 APP_VERSION='1.2.72' quasar dev",
|
||||
"pwa": "NODE_ENV=development PORT=8099 APP_VERSION='1.2.75' quasar dev -m pwa",
|
||||
"spa": "NODE_ENV=development PORT=8089 APP_VERSION='1.2.75' quasar dev",
|
||||
"debug": "quasar dev --mode debug",
|
||||
"test": "echo \"No test specified\" && exit 0",
|
||||
"generate-sw": "workbox generateSW workbox-config.js",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "nuovomondo",
|
||||
"version": "1.2.72",
|
||||
"version": "1.2.75",
|
||||
"description": "Nuovo Mondo",
|
||||
"productName": "Nuovo Mondo",
|
||||
"author": "Surya",
|
||||
@@ -9,11 +9,11 @@
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "APP_VERSION='1.2.72' PORT=8083 quasar dev",
|
||||
"dev": "APP_VERSION='1.2.75' PORT=8083 quasar dev",
|
||||
"dev_noCheck": "SKIP_TSC=true quasar dev",
|
||||
"build": "quasar build",
|
||||
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.72' quasar build -m pwa",
|
||||
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.72' quasar build -m pwa",
|
||||
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.75' quasar build -m pwa",
|
||||
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.75' quasar build -m pwa",
|
||||
"type-check": "vue-tsc --noEmit",
|
||||
"type-check:watch": "vue-tsc --noEmit --watch",
|
||||
"buildspa": "quasar build -m spa",
|
||||
@@ -21,8 +21,8 @@
|
||||
"lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt",
|
||||
"lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt",
|
||||
"fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt",
|
||||
"pwa": "NODE_ENV=development PORT=8094 APP_VERSION='1.2.72' quasar dev -m pwa",
|
||||
"spa": "NODE_ENV=development PORT=8083 APP_VERSION='1.2.72' quasar dev",
|
||||
"pwa": "NODE_ENV=development PORT=8094 APP_VERSION='1.2.75' quasar dev -m pwa",
|
||||
"spa": "NODE_ENV=development PORT=8083 APP_VERSION='1.2.75' quasar dev",
|
||||
"debug": "quasar dev --mode debug",
|
||||
"test": "echo \"No test specified\" && exit 0",
|
||||
"generate-sw": "workbox generateSW workbox-config.js",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "nutriben",
|
||||
"version": "1.2.72",
|
||||
"version": "1.2.75",
|
||||
"description": "Nutriben",
|
||||
"productName": "Nutriben",
|
||||
"author": "Surya",
|
||||
@@ -9,20 +9,20 @@
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "PORT=8093 APP_VERSION='1.2.72' quasar dev",
|
||||
"dev": "PORT=8093 APP_VERSION='1.2.75' quasar dev",
|
||||
"dev_noCheck": "SKIP_TSC=true quasar dev",
|
||||
"build": "quasar build",
|
||||
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.72' quasar build -m pwa",
|
||||
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.72' quasar build -m pwa",
|
||||
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.75' quasar build -m pwa",
|
||||
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.75' quasar build -m pwa",
|
||||
"type-check": "vue-tsc --noEmit",
|
||||
"type-check:watch": "vue-tsc --noEmit --watch",
|
||||
"buildspa": "APP_VERSION='1.2.72' quasar build -m spa",
|
||||
"buildspa": "APP_VERSION='1.2.75' quasar build -m spa",
|
||||
"lint": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\"",
|
||||
"lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt",
|
||||
"lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt",
|
||||
"fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt",
|
||||
"pwa": "NODE_ENV=development PORT=8099 APP_VERSION='1.2.72' quasar dev -m pwa",
|
||||
"spa": "NODE_ENV=development PORT=8093 APP_VERSION='1.2.72' quasar dev",
|
||||
"pwa": "NODE_ENV=development PORT=8099 APP_VERSION='1.2.75' quasar dev -m pwa",
|
||||
"spa": "NODE_ENV=development PORT=8093 APP_VERSION='1.2.75' quasar dev",
|
||||
"debug": "quasar dev --mode debug",
|
||||
"test": "echo \"No test specified\" && exit 0",
|
||||
"generate-sw": "workbox generateSW workbox-config.js",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "piuchebuono",
|
||||
"version": "1.2.72",
|
||||
"version": "1.2.75",
|
||||
"description": "PiuCheBuono",
|
||||
"productName": "PiuCheBuono",
|
||||
"author": "Surya",
|
||||
@@ -9,11 +9,11 @@
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "PORT=8085 APP_VERSION='1.2.72' quasar dev",
|
||||
"dev": "PORT=8085 APP_VERSION='1.2.75' quasar dev",
|
||||
"dev_noCheck": "SKIP_TSC=true quasar dev",
|
||||
"build": "quasar build",
|
||||
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.72' quasar build -m pwa",
|
||||
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.72' quasar build -m pwa",
|
||||
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.75' quasar build -m pwa",
|
||||
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.75' quasar build -m pwa",
|
||||
"type-check": "vue-tsc --noEmit",
|
||||
"type-check:watch": "vue-tsc --noEmit --watch",
|
||||
"buildspa": "quasar build -m spa",
|
||||
@@ -21,8 +21,8 @@
|
||||
"lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt",
|
||||
"lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt",
|
||||
"fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt",
|
||||
"pwa": "NODE_ENV=development PORT=8085 APP_VERSION='1.2.72' quasar dev -m pwa",
|
||||
"spa": "NODE_ENV=development PORT=8085 APP_VERSION='1.2.72' quasar dev",
|
||||
"pwa": "NODE_ENV=development PORT=8085 APP_VERSION='1.2.75' quasar dev -m pwa",
|
||||
"spa": "NODE_ENV=development PORT=8085 APP_VERSION='1.2.75' quasar dev",
|
||||
"debug": "quasar dev --mode debug",
|
||||
"test": "echo \"No test specified\" && exit 0",
|
||||
"generate-sw": "workbox generateSW workbox-config.js",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "riso",
|
||||
"version": "1.2.72",
|
||||
"version": "1.2.75",
|
||||
"productName": "Riso 💚 - Rete Italiana Scambi Orizzontali",
|
||||
"description": "Progetto RISO (Rete Italiana Scambi Orizzontali) promuove una rete di comunità locali che favoriscono scambi di beni, servizi e ospitalità. Con l'App RISO, sviluppata per facilitare il baratto, il dono e l'uso di monete alternative come i RIS, il progetto crea legami autentici basati sulla fiducia e sostenibilità. Partecipa agli scambi e costruisci una comunità più consapevole e autosufficiente.",
|
||||
"author": "Surya",
|
||||
@@ -9,11 +9,11 @@
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "APP_VERSION='1.2.72' PORT=8084 quasar dev",
|
||||
"dev": "APP_VERSION='1.2.75' PORT=8084 quasar dev",
|
||||
"dev_noCheck": "SKIP_TSC=true quasar dev",
|
||||
"build": "quasar build",
|
||||
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.72' quasar build -m pwa",
|
||||
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.72' quasar build -m pwa",
|
||||
"buildpwa": "NODE_ENV=production APP_VERSION='1.2.75' quasar build -m pwa",
|
||||
"buildpwatest": "NODE_ENV=production APP_VERSION='1.2.75' quasar build -m pwa",
|
||||
"type-check": "vue-tsc --noEmit",
|
||||
"type-check:watch": "vue-tsc --noEmit --watch",
|
||||
"buildspa": "quasar build -m spa",
|
||||
@@ -21,8 +21,8 @@
|
||||
"lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt",
|
||||
"lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt",
|
||||
"fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt",
|
||||
"pwa": "NODE_ENV=development PORT=8094 APP_VERSION='1.2.72' quasar dev -m pwa",
|
||||
"spa": "NODE_ENV=development PORT=8084 APP_VERSION='1.2.72' quasar dev",
|
||||
"pwa": "NODE_ENV=development PORT=8094 APP_VERSION='1.2.75' quasar dev -m pwa",
|
||||
"spa": "NODE_ENV=development PORT=8084 APP_VERSION='1.2.75' quasar dev",
|
||||
"debug": "quasar dev --mode debug",
|
||||
"test": "echo \"No test specified\" && exit 0",
|
||||
"generate-sw": "workbox generateSW workbox-config.js",
|
||||
|
||||
@@ -1 +1 @@
|
||||
TERMINA DI LAVORARE SU gruppomacro.app: (Sovrascrivo!)
|
||||
TERMINA DI LAVORARE SU riso.app: (Sovrascrivo!)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/* global workbox */
|
||||
/* global cfgenv */
|
||||
|
||||
const VITE_APP_VERSION = '1.2.72';
|
||||
const VITE_APP_VERSION = '1.2.75';
|
||||
|
||||
// Costanti di configurazione
|
||||
const DYNAMIC_CACHE = 'dynamic-cache-v2';
|
||||
@@ -38,10 +38,19 @@ const CACHE_NAME = 'pwa-cache-' + VITE_APP_VERSION; // Nome della cache
|
||||
importScripts('workbox/workbox-sw.js');
|
||||
|
||||
import { clientsClaim } from 'workbox-core';
|
||||
import { precacheAndRoute, cleanupOutdatedCaches, createHandlerBoundToURL } from 'workbox-precaching';
|
||||
import {
|
||||
precacheAndRoute,
|
||||
cleanupOutdatedCaches,
|
||||
createHandlerBoundToURL,
|
||||
} from 'workbox-precaching';
|
||||
import { registerRoute, NavigationRoute } from 'workbox-routing';
|
||||
import { setCacheNameDetails } from 'workbox-core';
|
||||
import { NetworkOnly, NetworkFirst, StaleWhileRevalidate, CacheFirst } from 'workbox-strategies';
|
||||
import {
|
||||
NetworkOnly,
|
||||
NetworkFirst,
|
||||
StaleWhileRevalidate,
|
||||
CacheFirst,
|
||||
} from 'workbox-strategies';
|
||||
|
||||
import { CacheableResponsePlugin } from 'workbox-cacheable-response';
|
||||
import { ExpirationPlugin } from 'workbox-expiration';
|
||||
@@ -66,12 +75,15 @@ setCacheNameDetails({
|
||||
runtime: 'runtime',
|
||||
});
|
||||
|
||||
// ✅ SOLUZIONE: Sii più specifico
|
||||
const precacheList = (self.__WB_MANIFEST || []).filter((entry) => {
|
||||
// Esclude tutto ciò che si trova nella cartella 'upload'
|
||||
if (entry.url.includes('/upload/')) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
const url = entry.url;
|
||||
// Escludi file grandi, upload, e risorse dinamiche
|
||||
return (
|
||||
!url.includes('/upload/') &&
|
||||
!url.includes('/assets/videos/') &&
|
||||
!url.match(/\.(mp4|webm|zip|pdf)$/)
|
||||
);
|
||||
});
|
||||
|
||||
// Precache solo i file filtrati
|
||||
@@ -85,6 +97,12 @@ self.addEventListener('install', () => {
|
||||
self.skipWaiting();
|
||||
|
||||
clientsClaim();
|
||||
// Notifica il frontend che c'è un nuovo SW pronto
|
||||
self.clients.matchAll().then((clients) => {
|
||||
clients.forEach((client) => {
|
||||
client.postMessage({ type: 'SW_UPDATED' });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Attivazione del Service Worker
|
||||
@@ -93,13 +111,19 @@ self.addEventListener('activate', (event) => {
|
||||
event.waitUntil(
|
||||
caches.keys().then((cacheNames) => {
|
||||
return Promise.all(
|
||||
cacheNames.filter((name) => name !== CACHE_NAME && name !== DYNAMIC_CACHE).map((name) => caches.delete(name))
|
||||
cacheNames
|
||||
.filter((name) => name !== CACHE_NAME && name !== DYNAMIC_CACHE)
|
||||
.map((name) => caches.delete(name))
|
||||
);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
console.log(' [ VER-' + VITE_APP_VERSION + ' ] _---------________------ PAO: this is my custom service worker: ');
|
||||
console.log(
|
||||
' [ VER-' +
|
||||
VITE_APP_VERSION +
|
||||
' ] _---------________------ PAO: this is my custom service worker: '
|
||||
);
|
||||
|
||||
try {
|
||||
importScripts('/js/idb.js', '/js/storage.js');
|
||||
@@ -170,7 +194,10 @@ if (workbox) {
|
||||
/^https:\/\/fonts\.(?:googleapis|gstatic)\.com/,
|
||||
new StaleWhileRevalidate({
|
||||
cacheName: `${CACHE_PREFIX}-google-fonts-${CACHE_VERSION}`,
|
||||
plugins: [new CacheableResponsePlugin({ statuses: [0, 200] }), new ExpirationPlugin({ maxEntries: 30 })],
|
||||
plugins: [
|
||||
new CacheableResponsePlugin({ statuses: [0, 200] }),
|
||||
new ExpirationPlugin({ maxEntries: 30 }),
|
||||
],
|
||||
})
|
||||
);
|
||||
|
||||
@@ -179,7 +206,7 @@ if (workbox) {
|
||||
({ request }) => request.destination === 'document',
|
||||
new NetworkFirst({
|
||||
cacheName: `${CACHE_PREFIX}-html-cache-${CACHE_VERSION}`,
|
||||
networkTimeoutSeconds: 5, // timeout rapido
|
||||
networkTimeoutSeconds: 10, // timeout rapido
|
||||
plugins: [
|
||||
new CacheableResponsePlugin({ statuses: [0, 200] }),
|
||||
new ExpirationPlugin({ maxEntries: 20, maxAgeSeconds: 24 * 60 * 60 }), // 1 giorno
|
||||
@@ -192,7 +219,7 @@ if (workbox) {
|
||||
({ url }) => url.hostname === API_DOMAIN,
|
||||
new NetworkFirst({
|
||||
cacheName: `${CACHE_PREFIX}-api-cache-${CACHE_VERSION}`,
|
||||
networkTimeoutSeconds: 5,
|
||||
networkTimeoutSeconds: 10,
|
||||
fetchOptions: { credentials: 'include' },
|
||||
plugins: [
|
||||
new CacheableResponsePlugin({ statuses: [0, 200] }),
|
||||
@@ -211,8 +238,15 @@ if (workbox) {
|
||||
|
||||
const syncStore = {};
|
||||
self.addEventListener('message', (event) => {
|
||||
if (event.data && (event.data.type === 'SKIP_WAITING' || event.data.action === 'skipWaiting')) {
|
||||
if (
|
||||
event.data &&
|
||||
(event.data.type === 'SKIP_WAITING' || event.data.action === 'skipWaiting')
|
||||
) {
|
||||
self.skipWaiting();
|
||||
// Opzionale: rispondi al client
|
||||
if (event.ports && event.ports[0]) {
|
||||
event.ports[0].postMessage({ success: true });
|
||||
}
|
||||
}
|
||||
if (event.data.type === 'sync') {
|
||||
console.log('addEventListener - message');
|
||||
@@ -445,7 +479,9 @@ if (workbox) {
|
||||
|
||||
self.addEventListener('push', (event) => {
|
||||
console.log('Push Notification received', event);
|
||||
let data = event.data ? event.data.json() : { title: 'New!', content: 'Something new happened!', url: '/' };
|
||||
let data = event.data
|
||||
? event.data.json()
|
||||
: { title: 'New!', content: 'Something new happened!', url: '/' };
|
||||
|
||||
const options = {
|
||||
body: data.content,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "Riso",
|
||||
"short_name": "Riso",
|
||||
"description": "Siamo la Rete Italiana di Scambio Orizzontale, abbiamo creato questa piattaforma per metterla al servizio di chi vuole riscoprire il valore della condivisione e della cooperazione. Valori semplici e profondi che ci aiutano a ritrovare il Senso della Vita, perduto in questa società consumista, e riporti quei Sani Pricìpi Naturali ed Umani di Fratellanza che intere popolazioni antiche conoscevano bene.",
|
||||
"name": "Gruppo Macro",
|
||||
"short_name": "GruppoMacro",
|
||||
"description": "",
|
||||
"display": "standalone",
|
||||
"orientation": "portrait",
|
||||
"background_color": "#fff",
|
||||
@@ -11,47 +11,17 @@
|
||||
"start_url": "/?homescreen=1",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/images/riso-android-icon-512x512.png",
|
||||
"src": "/images/gm-android-icon-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/images/riso-android-icon-384x384.png",
|
||||
"sizes": "384x384",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/images/riso-android-icon-192x192.png",
|
||||
"src": "/images/gm-android-icon-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/images/riso-android-icon-144x144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/images/riso-android-icon-96x96.png",
|
||||
"sizes": "96x96",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/images/riso-apple-icon-120x120.png",
|
||||
"sizes": "120x120",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/images/riso-apple-icon-144x144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/images/riso-apple-icon-152x152.png",
|
||||
"sizes": "152x152",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/images/riso-apple-icon-180x180.png",
|
||||
"src": "/images/gm-apple-touch-icon.png",
|
||||
"sizes": "180x180",
|
||||
"type": "image/png"
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import { useGlobalStore } from '@store/globalStore';
|
||||
import { useUserStore } from '@store/UserStore';
|
||||
import { MyHeader } from '@src/components/MyHeader';
|
||||
import { MyFooter } from '@src/components/MyFooter';
|
||||
import { CCheckUpdatesPWA } from '@src/components/CCheckUpdatesPWA';
|
||||
import { CFirstPageApp } from '@src/components/CFirstPageApp';
|
||||
import { computed, onMounted, ref, watch } from 'vue';
|
||||
import { CProvaPao } from '@src/components/CProvaPao';
|
||||
@@ -22,6 +23,7 @@ export default {
|
||||
MyFooter,
|
||||
CFirstPageApp,
|
||||
CProvaPao,
|
||||
CCheckUpdatesPWA,
|
||||
BannerCookies /* , CPreloadImages */,
|
||||
},
|
||||
setup() {
|
||||
@@ -161,6 +163,7 @@ export default {
|
||||
return {
|
||||
finishLoading,
|
||||
darkcookie,
|
||||
tools,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
24
src/App.vue
@@ -3,8 +3,7 @@
|
||||
<q-layout
|
||||
view="hHh LpR fFf"
|
||||
:class="
|
||||
`shadow-2 rounded-borders ` +
|
||||
(darkcookie && !finishLoading ? `bg-black` : ``)
|
||||
`shadow-2 rounded-borders ` + (darkcookie && !finishLoading ? `bg-black` : ``)
|
||||
"
|
||||
>
|
||||
<app-header></app-header>
|
||||
@@ -16,10 +15,24 @@
|
||||
>
|
||||
<div v-if="finishLoading">
|
||||
<CFirstPageApp></CFirstPageApp>
|
||||
|
||||
<!-- 🔥 Aggiungi qui il componente PWA Updater -->
|
||||
<CCheckUpdatesPWA
|
||||
:showManualCheckButton="tools.isDebug()"
|
||||
:autoCheckInterval="60"
|
||||
:showSuccessNotification="true"
|
||||
/>
|
||||
<router-view />
|
||||
</div>
|
||||
<q-inner-loading id="spinner" :showing="!finishLoading">
|
||||
<q-spinner-tail color="primary" size="4em"> </q-spinner-tail>
|
||||
<q-inner-loading
|
||||
id="spinner"
|
||||
:showing="!finishLoading"
|
||||
>
|
||||
<q-spinner-tail
|
||||
color="primary"
|
||||
size="4em"
|
||||
>
|
||||
</q-spinner-tail>
|
||||
</q-inner-loading>
|
||||
</q-page-container>
|
||||
|
||||
@@ -28,5 +41,4 @@
|
||||
</div>
|
||||
<BannerCookies urlInfo="/policy"></BannerCookies>
|
||||
</template>
|
||||
<script lang="ts" src="./App.ts">
|
||||
</script>
|
||||
<script lang="ts" src="./App.ts"></script>
|
||||
|
||||
46
src/components/CCheckUpdatesPWA/CCheckUpdatesPWA.scss
Executable file
@@ -0,0 +1,46 @@
|
||||
.pwa-updater {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.pwa-update-badge {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
z-index: 9999;
|
||||
padding: 8px 16px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
animation: pulse 2s infinite;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.05);
|
||||
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
.pwa-manual-check {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
left: 20px;
|
||||
z-index: 9998;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 600px) {
|
||||
.pwa-update-badge {
|
||||
bottom: 80px; // Sposta su per evitare FAB buttons
|
||||
right: 16px;
|
||||
font-size: 12px;
|
||||
padding: 6px 12px;
|
||||
}
|
||||
}
|
||||
401
src/components/CCheckUpdatesPWA/CCheckUpdatesPWA.ts
Executable file
@@ -0,0 +1,401 @@
|
||||
import { defineComponent, ref, onMounted, onBeforeUnmount } from 'vue';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { tools } from '@tools'
|
||||
import { useGlobalStore } from 'app/src/store';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'CCheckUpdatesPWA',
|
||||
|
||||
props: {
|
||||
// Mostra pulsante per check manuale
|
||||
showManualCheckButton: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// Intervallo check automatico (in minuti)
|
||||
autoCheckInterval: {
|
||||
type: Number,
|
||||
default: 60 // 60 minuti
|
||||
},
|
||||
// Mostra notifica successo dopo reload
|
||||
showSuccessNotification: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
|
||||
setup(props) {
|
||||
const $q = useQuasar();
|
||||
|
||||
const globalStore = useGlobalStore();
|
||||
|
||||
// State
|
||||
const refreshing = ref(false);
|
||||
const swRegistration = ref<ServiceWorkerRegistration | null>(null);
|
||||
const updateAvailable = ref(false);
|
||||
const dialogVisible = ref(false);
|
||||
let updateCheckInterval: NodeJS.Timeout | null = null;
|
||||
|
||||
/**
|
||||
* Mostra dialog di conferma aggiornamento
|
||||
*/
|
||||
const showUpdateDialog = () => {
|
||||
if (!swRegistration.value) {
|
||||
console.error('❌ No service worker registration available');
|
||||
return;
|
||||
}
|
||||
|
||||
dialogVisible.value = true;
|
||||
|
||||
$q.dialog({
|
||||
title: '🎉 Nuova Versione Disponibile',
|
||||
message: 'È disponibile un aggiornamento dell\'applicazione. Vuoi installarlo ora?',
|
||||
html: true,
|
||||
persistent: false,
|
||||
ok: {
|
||||
label: 'Aggiorna Ora',
|
||||
color: 'primary',
|
||||
icon: 'system_update',
|
||||
noCaps: true
|
||||
},
|
||||
cancel: {
|
||||
label: 'Più Tardi',
|
||||
color: 'grey',
|
||||
flat: true,
|
||||
noCaps: true
|
||||
}
|
||||
}).onOk(() => {
|
||||
applyUpdate();
|
||||
}).onCancel(() => {
|
||||
dialogVisible.value = false;
|
||||
console.log('ℹ️ Aggiornamento rimandato dall\'utente');
|
||||
showPersistentNotification();
|
||||
}).onDismiss(() => {
|
||||
dialogVisible.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Mostra notifica persistente per aggiornamento rimandato
|
||||
*/
|
||||
const showPersistentNotification = () => {
|
||||
$q.notify({
|
||||
message: 'Aggiornamento disponibile',
|
||||
caption: 'Clicca per installare',
|
||||
icon: 'info',
|
||||
color: 'info',
|
||||
position: 'bottom-right',
|
||||
timeout: 0, // Persistente
|
||||
actions: [
|
||||
{
|
||||
label: 'Aggiorna',
|
||||
color: 'white',
|
||||
handler: () => {
|
||||
applyUpdate();
|
||||
}
|
||||
},
|
||||
{
|
||||
icon: 'close',
|
||||
color: 'white',
|
||||
round: true
|
||||
}
|
||||
]
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Applica l'aggiornamento
|
||||
*/
|
||||
const applyUpdate = () => {
|
||||
if (!swRegistration.value?.waiting) {
|
||||
console.error('❌ No waiting service worker found');
|
||||
$q.notify({
|
||||
message: 'Errore: aggiornamento non disponibile',
|
||||
icon: 'error',
|
||||
color: 'negative',
|
||||
timeout: 3000
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('✅ Applying update...');
|
||||
dialogVisible.value = false;
|
||||
|
||||
// Mostra loading
|
||||
$q.loading.show({
|
||||
message: 'Aggiornamento in corso...<br/>Non chiudere l\'app',
|
||||
html: true,
|
||||
spinnerColor: 'primary',
|
||||
backgroundColor: 'dark',
|
||||
messageColor: 'white'
|
||||
});
|
||||
|
||||
// Salva stato prima del reload
|
||||
saveStateBeforeUpdate();
|
||||
|
||||
// Invia messaggio al SW per attivare skipWaiting
|
||||
swRegistration.value.waiting.postMessage({
|
||||
action: 'skipWaiting',
|
||||
type: 'SKIP_WAITING'
|
||||
});
|
||||
|
||||
console.log('📤 Skip waiting message sent to service worker');
|
||||
};
|
||||
|
||||
/**
|
||||
* Salva stato dell'app prima dell'aggiornamento
|
||||
*/
|
||||
const saveStateBeforeUpdate = () => {
|
||||
try {
|
||||
sessionStorage.setItem('pwa_updating', 'true');
|
||||
sessionStorage.setItem('pwa_update_timestamp', Date.now().toString());
|
||||
|
||||
// Salva posizione scroll
|
||||
const scrollPos = window.scrollY || document.documentElement.scrollTop;
|
||||
sessionStorage.setItem('pwa_scroll_position', scrollPos.toString());
|
||||
|
||||
// Salva percorso corrente
|
||||
sessionStorage.setItem('pwa_current_path', window.location.pathname);
|
||||
|
||||
console.log('💾 State saved before update');
|
||||
} catch (e) {
|
||||
console.error('Failed to save state:', e);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Ripristina stato dopo l'aggiornamento
|
||||
*/
|
||||
const restoreStateAfterUpdate = () => {
|
||||
try {
|
||||
if (sessionStorage.getItem('pwa_updating') === 'true') {
|
||||
sessionStorage.removeItem('pwa_updating');
|
||||
|
||||
if (props.showSuccessNotification) {
|
||||
$q.notify({
|
||||
message: 'App aggiornata con successo!',
|
||||
caption: 'Stai usando l\'ultima versione',
|
||||
icon: 'check_circle',
|
||||
color: 'positive',
|
||||
timeout: 4000,
|
||||
position: 'top'
|
||||
});
|
||||
}
|
||||
|
||||
// Ripristina scroll position con delay
|
||||
const scrollPos = sessionStorage.getItem('pwa_scroll_position');
|
||||
if (scrollPos) {
|
||||
setTimeout(() => {
|
||||
window.scrollTo({
|
||||
top: parseInt(scrollPos),
|
||||
behavior: 'smooth'
|
||||
});
|
||||
sessionStorage.removeItem('pwa_scroll_position');
|
||||
}, 300);
|
||||
}
|
||||
|
||||
sessionStorage.removeItem('pwa_current_path');
|
||||
sessionStorage.removeItem('pwa_update_timestamp');
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Failed to restore state:', e);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handler per evento swUpdated
|
||||
*/
|
||||
const handleSwUpdated = (event: Event) => {
|
||||
const customEvent = event as CustomEvent<ServiceWorkerRegistration>;
|
||||
console.log('🔄 SW Update detected:', customEvent.detail);
|
||||
|
||||
swRegistration.value = customEvent.detail;
|
||||
updateAvailable.value = true;
|
||||
|
||||
// Mostra dialog automaticamente
|
||||
setTimeout(() => {
|
||||
showUpdateDialog();
|
||||
}, 500);
|
||||
};
|
||||
|
||||
/**
|
||||
* Handler per cambio controller (SW attivato)
|
||||
*/
|
||||
const handleControllerChange = () => {
|
||||
if (refreshing.value) {
|
||||
console.log('⏭️ Already refreshing, skipping...');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('🔄 Service Worker controller changed, reloading...');
|
||||
refreshing.value = true;
|
||||
|
||||
// Nascondi loading
|
||||
$q.loading.hide();
|
||||
|
||||
// Reload con delay per smooth transition
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
}, 300);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check manuale per aggiornamenti
|
||||
*/
|
||||
const checkForUpdates = async () => {
|
||||
if (!('serviceWorker' in navigator)) {
|
||||
console.warn('⚠️ Service Worker not supported in this browser');
|
||||
$q.notify({
|
||||
message: 'Service Worker non supportato',
|
||||
icon: 'warning',
|
||||
color: 'warning',
|
||||
timeout: 3000
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
console.log('🔍 Checking for updates...');
|
||||
|
||||
$q.loading.show({
|
||||
message: 'Controllo aggiornamenti...',
|
||||
spinnerColor: 'primary'
|
||||
});
|
||||
|
||||
const registration = await navigator.serviceWorker.ready;
|
||||
|
||||
if (!registration) {
|
||||
throw new Error('No service worker registration found');
|
||||
}
|
||||
|
||||
// Forza check aggiornamenti
|
||||
await registration.update();
|
||||
|
||||
$q.loading.hide();
|
||||
|
||||
// Se c'è un SW in waiting, mostra dialog
|
||||
if (registration.waiting) {
|
||||
swRegistration.value = registration;
|
||||
updateAvailable.value = true;
|
||||
showUpdateDialog();
|
||||
} else {
|
||||
$q.notify({
|
||||
message: 'Nessun aggiornamento disponibile',
|
||||
caption: 'Stai usando l\'ultima versione',
|
||||
icon: 'check_circle',
|
||||
color: 'positive',
|
||||
timeout: 3000
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('❌ Error checking for updates:', error);
|
||||
|
||||
$q.loading.hide();
|
||||
|
||||
$q.notify({
|
||||
message: 'Errore nel controllo aggiornamenti',
|
||||
caption: (error as Error).message || 'Errore sconosciuto',
|
||||
icon: 'error',
|
||||
color: 'negative',
|
||||
timeout: 4000
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handler per messaggi dal Service Worker
|
||||
*/
|
||||
const handleSwMessage = (event: MessageEvent) => {
|
||||
console.log('📨 Message from Service Worker:', event.data);
|
||||
|
||||
if (event.data?.type === 'SW_UPDATED') {
|
||||
console.log('✅ SW updated to version:', event.data.version);
|
||||
}
|
||||
|
||||
if (event.data?.type === 'SW_INSTALLED') {
|
||||
console.log('✅ SW installed for the first time');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Setup automatico check aggiornamenti
|
||||
*/
|
||||
const setupAutoUpdateCheck = () => {
|
||||
if (props.autoCheckInterval <= 0) return;
|
||||
|
||||
const intervalMs = props.autoCheckInterval * 60 * 1000;
|
||||
console.log(`⏰ Setting up auto-update check every ${props.autoCheckInterval} minutes`);
|
||||
|
||||
updateCheckInterval = setInterval(() => {
|
||||
console.log('⏰ Periodic update check triggered');
|
||||
checkForUpdates();
|
||||
}, intervalMs);
|
||||
};
|
||||
|
||||
/**
|
||||
* Cleanup
|
||||
*/
|
||||
const cleanup = () => {
|
||||
console.log('🧹 Cleaning up PWA Updater');
|
||||
|
||||
// Rimuovi listeners
|
||||
window.removeEventListener('swUpdated', handleSwUpdated);
|
||||
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.removeEventListener('controllerchange', handleControllerChange);
|
||||
navigator.serviceWorker.removeEventListener('message', handleSwMessage);
|
||||
}
|
||||
|
||||
// Clearinterval
|
||||
if (updateCheckInterval) {
|
||||
clearInterval(updateCheckInterval);
|
||||
updateCheckInterval = null;
|
||||
}
|
||||
};
|
||||
|
||||
// Lifecycle Hooks
|
||||
onMounted(() => {
|
||||
console.log('🚀 PWA Updater component mounted');
|
||||
|
||||
// Listener per evento custom swUpdated
|
||||
window.addEventListener('swUpdated', handleSwUpdated);
|
||||
|
||||
// Setup Service Worker listeners
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.addEventListener('controllerchange', handleControllerChange);
|
||||
navigator.serviceWorker.addEventListener('message', handleSwMessage);
|
||||
|
||||
// Check se c'è già un SW in waiting al mount
|
||||
navigator.serviceWorker.ready.then((registration) => {
|
||||
if (registration.waiting) {
|
||||
console.log('⚠️ Service Worker already waiting at mount');
|
||||
swRegistration.value = registration;
|
||||
updateAvailable.value = true;
|
||||
showUpdateDialog();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.warn('⚠️ Service Workers not supported in this browser');
|
||||
}
|
||||
|
||||
// Ripristina stato dopo aggiornamento
|
||||
restoreStateAfterUpdate();
|
||||
|
||||
// Setup check automatico
|
||||
setupAutoUpdateCheck();
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
cleanup();
|
||||
});
|
||||
|
||||
return {
|
||||
updateAvailable,
|
||||
dialogVisible,
|
||||
checkForUpdates,
|
||||
showUpdateDialog,
|
||||
tools,
|
||||
globalStore,
|
||||
};
|
||||
}
|
||||
});
|
||||
35
src/components/CCheckUpdatesPWA/CCheckUpdatesPWA.vue
Executable file
@@ -0,0 +1,35 @@
|
||||
|
||||
<template>
|
||||
<div v-if="globalStore.showHeader" class="pwa-updater">
|
||||
<!-- Badge floating per aggiornamento disponibile -->
|
||||
<q-badge
|
||||
v-if="updateAvailable && !dialogVisible"
|
||||
color="primary"
|
||||
floating
|
||||
class="pwa-update-badge cursor-pointer"
|
||||
@click="showUpdateDialog"
|
||||
>
|
||||
<q-icon name="system_update" size="sm" class="q-mr-xs" />
|
||||
Aggiorna
|
||||
</q-badge>
|
||||
|
||||
<!-- Pulsante manuale (opzionale - rimuovi se non serve) -->
|
||||
<q-btn
|
||||
v-if="showManualCheckButton"
|
||||
round
|
||||
dense
|
||||
icon="refresh"
|
||||
color="grey-7"
|
||||
class="pwa-manual-check"
|
||||
@click="checkForUpdates"
|
||||
>
|
||||
<q-tooltip>Controlla Aggiornamenti</q-tooltip>
|
||||
</q-btn>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" src="./CCheckUpdatesPWA.ts">
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './CCheckUpdatesPWA.scss';
|
||||
</style>
|
||||
1
src/components/CCheckUpdatesPWA/index.ts
Executable file
@@ -0,0 +1 @@
|
||||
export {default as CCheckUpdatesPWA} from './CCheckUpdatesPWA.vue'
|
||||
@@ -1,5 +1,14 @@
|
||||
import type { PropType } from 'vue';
|
||||
import { computed, defineComponent, onMounted, ref, toRef, watch, nextTick } from 'vue';
|
||||
import {
|
||||
computed,
|
||||
defineComponent,
|
||||
onMounted,
|
||||
ref,
|
||||
toRef,
|
||||
watch,
|
||||
nextTick,
|
||||
onUnmounted,
|
||||
} from 'vue';
|
||||
|
||||
import type { IOptCatalogo, ICoordGPS, IMyElem, ISocial } from '@src/model';
|
||||
import { IMyCard, IMyPage, IOperators } from '@src/model';
|
||||
@@ -195,6 +204,8 @@ export default defineComponent({
|
||||
|
||||
const newtype = ref(<any>'');
|
||||
|
||||
const canShowVersion = ref(false);
|
||||
|
||||
const isAppRunning = computed(() => globalStore.isAppRunning);
|
||||
|
||||
const cardGroupMaxWidth = computed(() => {
|
||||
@@ -307,6 +318,10 @@ export default defineComponent({
|
||||
myel.value = props.myelem;
|
||||
neworder.value = props.myelem.order;
|
||||
|
||||
setTimeout(() => {
|
||||
canShowVersion.value = true;
|
||||
}, 60000);
|
||||
|
||||
if (props.myelem) newtype.value = props.myelem.type;
|
||||
|
||||
nextTick(() => {
|
||||
@@ -394,8 +409,23 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
|
||||
const updateApp = async () => {
|
||||
// Invia il messaggio al Service Worker per saltare l'attesa
|
||||
const registration = await navigator.serviceWorker.getRegistration();
|
||||
if (registration?.waiting) {
|
||||
registration.waiting.postMessage({ type: 'SKIP_WAITING' });
|
||||
}
|
||||
|
||||
// Ricarica la pagina
|
||||
window.location.reload();
|
||||
};
|
||||
|
||||
onMounted(mounted);
|
||||
|
||||
const isNewVersionAvailable = computed(() => {
|
||||
return canShowVersion.value ? globalStore.isNewVersionAvailable : false;
|
||||
});
|
||||
|
||||
return {
|
||||
tools,
|
||||
shared_consts,
|
||||
@@ -444,6 +474,7 @@ export default defineComponent({
|
||||
cardGroupMaxWidth,
|
||||
cardScroller,
|
||||
scrollCards,
|
||||
isNewVersionAvailable,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
@@ -196,7 +196,7 @@
|
||||
>
|
||||
<CTitle
|
||||
:imgbackground="myel.imgback"
|
||||
:headtitle="myel.title"
|
||||
:headtitle="myel.container"
|
||||
:sizes="myel.size"
|
||||
:styleadd="myel.styleadd"
|
||||
>
|
||||
@@ -1086,7 +1086,7 @@
|
||||
Controllo Nuova Versione
|
||||
</div>
|
||||
<q-banner
|
||||
v-if="globalStore.isNewVersionAvailable"
|
||||
v-if="isNewVersionAvailable"
|
||||
rounded
|
||||
dense
|
||||
class="bg-green text-white"
|
||||
@@ -1107,7 +1107,7 @@
|
||||
</div>
|
||||
<div v-else>
|
||||
<span class="mybanner"
|
||||
>Aggiornamento APP in corso ... Se dopo 1 minuto non dovesse scomparire
|
||||
>* Aggiornamento APP in corso ... Se dopo 1 minuto non dovesse scomparire
|
||||
questo messaggio, chiudere e riaprire la pagina.</span
|
||||
>
|
||||
</div>
|
||||
|
||||
@@ -590,6 +590,7 @@ export default defineComponent({
|
||||
openAdd,
|
||||
addAtEnd,
|
||||
showOrder,
|
||||
globalStore,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
@@ -65,9 +65,10 @@
|
||||
|
||||
<!-- Contenuto pagina -->
|
||||
<div
|
||||
:class="[{ 'q-gutter-xs': !hideHeader }, 'q-mx-auto', 'q-pb-lg']"
|
||||
:style="containerStyle"
|
||||
:class="[{ 'q-gutter-xs': !hideHeader, 'q-mx-auto': !hideHeader, 'q-pb-lg': !hideHeader}]"
|
||||
:style="hideHeader ? [{ 'margin-left': 0, 'margin-right': 0 }] : containerStyle"
|
||||
>
|
||||
<div v-if="globalStore.showHeader">
|
||||
<!-- Media/Content blocks (1..3) -->
|
||||
<section
|
||||
v-for="(blk, i) in mediaBlocks"
|
||||
@@ -97,10 +98,11 @@
|
||||
class="q-mb-md"
|
||||
/>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<!-- Contenuti extra HTML -->
|
||||
<div
|
||||
v-if="rec.content4"
|
||||
v-if="rec.content4 && globalStore.showHeader"
|
||||
v-html="rec.content4"
|
||||
class="q-mb-md content-html"
|
||||
></div>
|
||||
@@ -109,7 +111,6 @@
|
||||
<div
|
||||
v-for="myelem in myelems"
|
||||
:key="myelem._id"
|
||||
class="q-mb-lg"
|
||||
>
|
||||
<transition
|
||||
appear
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
:strfido="t('account.fido_casa', { fido: account ? account.fidoConcesso : '', symbol })"
|
||||
:color="color"
|
||||
v-model="saldo"
|
||||
:before_str="t('account.saldo') + `:`"
|
||||
:before_str="$q.screen.lt.sm ? '' : t('account.saldo') + `:`"
|
||||
:valueextra="
|
||||
account && account.notifspending && account.notifspending.length > 0
|
||||
? `* `
|
||||
|
||||
@@ -85,6 +85,8 @@ export default defineComponent({
|
||||
const products = useProducts();
|
||||
const notifStore = useNotifStore();
|
||||
|
||||
const canShowVersion = ref(false);
|
||||
|
||||
const { getnumItemsCart } = MixinUsers();
|
||||
|
||||
const site = computed(() => globalStore.site);
|
||||
@@ -116,7 +118,8 @@ export default defineComponent({
|
||||
});
|
||||
|
||||
const getColorText = computed(() => {
|
||||
if (globalStore.site && globalStore.site.confpages?.col_toolbar === 'white') return 'black';
|
||||
if (globalStore.site && globalStore.site.confpages?.col_toolbar === 'white')
|
||||
return 'black';
|
||||
else return 'white';
|
||||
});
|
||||
|
||||
@@ -158,11 +161,46 @@ export default defineComponent({
|
||||
|
||||
const stateconn = ref(globalStore.stateConnection);
|
||||
|
||||
function refreshApp() {
|
||||
// ✅ 1. Se siamo su iOS: NON toccare il Service Worker!
|
||||
if (Platform.is.ios) {
|
||||
// Su iOS, Safari non risponde bene a unregister() o skipWaiting()
|
||||
// L'unico modo affidabile è: forzare un reload con cache busting
|
||||
console.log('[PWA] iOS: Forzo reload senza toccare il Service Worker...');
|
||||
|
||||
// Aggiungi un parametro casuale per bypassare la cache del browser
|
||||
const url = new URL(window.location.href);
|
||||
url.searchParams.set('refresh', Date.now().toString());
|
||||
window.location.href = url.toString();
|
||||
|
||||
return; // ✅ Esce subito — non esegue altro
|
||||
}
|
||||
|
||||
// ✅ 2. Se siamo su Android / Chrome / Desktop: usa SKIP_WAITING
|
||||
if (data.value.registration && data.value.registration.waiting) {
|
||||
console.log('[PWA] Invio SKIP_WAITING al Service Worker...');
|
||||
data.value.registration.waiting.postMessage({ type: 'SKIP_WAITING' });
|
||||
|
||||
// ✅ Aspetta che il nuovo SW diventi attivo prima di ricaricare
|
||||
navigator.serviceWorker.addEventListener('controllerchange', () => {
|
||||
console.log('[PWA] Nuovo Service Worker attivo — ricarico la pagina...');
|
||||
window.location.reload();
|
||||
});
|
||||
|
||||
// ✅ Imposta lo stato come risolto
|
||||
data.value.updateExists = false;
|
||||
} else {
|
||||
// Se non c'è un SW in attesa, forza un semplice reload (caso raro)
|
||||
console.log('[PWA] Nessun SW in attesa — ricarico comunque...');
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
|
||||
function updateAvailable(event: any) {
|
||||
console.log(event);
|
||||
data.value.registration = event.detail;
|
||||
data.value.updateExists = true;
|
||||
RefreshApp(); // update automatically
|
||||
refreshApp(); // update automatically
|
||||
}
|
||||
|
||||
function created() {
|
||||
@@ -173,16 +211,19 @@ export default defineComponent({
|
||||
try {
|
||||
if (window) {
|
||||
// Ascolta evento custom 'swUpdated' per notifica aggiornamento
|
||||
/*
|
||||
window.addEventListener(
|
||||
'swUpdated',
|
||||
async (event) => {
|
||||
async (event: any) => {
|
||||
// Chiedi conferma all’utente (qui con confirm, sostituisci con dialog Quasar se vuoi)
|
||||
const doUpdate = confirm('È disponibile una nuova versione. Vuoi aggiornare ora?');
|
||||
const doUpdate = confirm(
|
||||
'È disponibile una nuova versione. Vuoi aggiornare ora?'
|
||||
);
|
||||
|
||||
if (doUpdate) {
|
||||
// Invia messaggio al service worker per skipWaiting
|
||||
if (event.detail?.swWaiting) {
|
||||
event.detail.swWaiting.postMessage({ action: 'skipWaiting' });
|
||||
if (event.detail?.waiting) {
|
||||
event.detail.waiting.postMessage({ action: 'skipWaiting' });
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -196,9 +237,10 @@ export default defineComponent({
|
||||
window.location.reload();
|
||||
});
|
||||
}
|
||||
*/
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Err', e.message);
|
||||
console.error('Error in created() function:', e.message ? e.message : e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,11 +323,15 @@ export default defineComponent({
|
||||
});
|
||||
}
|
||||
|
||||
function isNewVersionAvailable() {
|
||||
return globalStore.isNewVersionAvailable;
|
||||
}
|
||||
const isNewVersionAvailable = computed(() => {
|
||||
return canShowVersion.value ? globalStore.isNewVersionAvailable : false;
|
||||
});
|
||||
|
||||
function closeAll() {
|
||||
/*if (timeoutId) {
|
||||
window.clearTimeout(timeoutId);
|
||||
timeoutId = null;
|
||||
}*/
|
||||
globalStore.rightNotifOpen = false;
|
||||
globalStore.rightCartOpen = false;
|
||||
globalStore.rightDrawerOpen = false;
|
||||
@@ -363,10 +409,14 @@ export default defineComponent({
|
||||
);
|
||||
|
||||
watch(conndata_changed, (value, oldValue) => {
|
||||
clCloudUpload.value = value.uploading_server === 1 ? 'clCloudUpload send' : 'clCloudUpload';
|
||||
clCloudUpload.value = value.downloading_server === 1 ? 'clCloudUpload receive' : 'clCloudUpload';
|
||||
clCloudUp_Indexeddb.value = value.uploading_indexeddb === 1 ? 'clIndexeddb send' : 'clIndexeddb';
|
||||
clCloudUp_Indexeddb.value = value.downloading_indexeddb === 1 ? 'clIndexeddb receive' : 'clIndexeddb';
|
||||
clCloudUpload.value =
|
||||
value.uploading_server === 1 ? 'clCloudUpload send' : 'clCloudUpload';
|
||||
clCloudUpload.value =
|
||||
value.downloading_server === 1 ? 'clCloudUpload receive' : 'clCloudUpload';
|
||||
clCloudUp_Indexeddb.value =
|
||||
value.uploading_indexeddb === 1 ? 'clIndexeddb send' : 'clIndexeddb';
|
||||
clCloudUp_Indexeddb.value =
|
||||
value.downloading_indexeddb === 1 ? 'clIndexeddb receive' : 'clIndexeddb';
|
||||
|
||||
/* clCloudUpload.value = (value.uploading_server === -1) ? 'clCloudUpload error' : clCloudUpload
|
||||
clCloudUpload.value = (value.downloading_server === -1) ? 'clCloudUpload error' : clCloudDownload
|
||||
@@ -402,30 +452,10 @@ export default defineComponent({
|
||||
|
||||
*/
|
||||
|
||||
function RefreshApp() {
|
||||
if (Platform.is.ios) {
|
||||
// Unregister Service Worker
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.getRegistrations().then((registrations) => {
|
||||
for (const registration of registrations) {
|
||||
registration.unregister();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// window.location.reload()
|
||||
} else {
|
||||
data.value.updateExists = false;
|
||||
// Make sure we only send a 'skip waiting' message if the SW is waiting
|
||||
if (!data.value.registration || !data.value.registration.waiting) return;
|
||||
// Send message to SW to skip the waiting and activate the new SW
|
||||
data.value.registration.waiting.postMessage({ type: 'SKIP_WAITING' });
|
||||
}
|
||||
}
|
||||
|
||||
function changeIconConn() {
|
||||
iconConn.value = globalStore.stateConnection === 'online' ? 'wifi' : 'wifi_off';
|
||||
clIconConn.value = globalStore.stateConnection === 'online' ? 'clIconOnline' : 'clIconOffline';
|
||||
clIconConn.value =
|
||||
globalStore.stateConnection === 'online' ? 'clIconOnline' : 'clIconOffline';
|
||||
}
|
||||
|
||||
function getAppVersion() {
|
||||
@@ -475,6 +505,10 @@ export default defineComponent({
|
||||
// Test this by running the code snippet below and then
|
||||
// use the "TableOnlyView" checkbox in DevTools Network panel
|
||||
|
||||
setTimeout(() => {
|
||||
canShowVersion.value = true;
|
||||
}, 60000);
|
||||
|
||||
// console.log('Event LOAD')
|
||||
if (window) {
|
||||
window.addEventListener('load', () => {
|
||||
@@ -560,11 +594,6 @@ export default defineComponent({
|
||||
return 0;
|
||||
}
|
||||
|
||||
function getcart() {
|
||||
// return Products.cart
|
||||
return null;
|
||||
}
|
||||
|
||||
function toHome() {
|
||||
$router.push('/');
|
||||
}
|
||||
@@ -581,7 +610,6 @@ export default defineComponent({
|
||||
tools.setCookie('menu3oriz', globalStore.leftDrawerOpen ? '1' : '0');
|
||||
}
|
||||
|
||||
|
||||
onBeforeMount(BeforeMount);
|
||||
onMounted(mounted);
|
||||
|
||||
@@ -608,13 +636,12 @@ export default defineComponent({
|
||||
getcolormenu,
|
||||
isNewVersionAvailable,
|
||||
getAppVersion,
|
||||
RefreshApp,
|
||||
refreshApp,
|
||||
changecmd,
|
||||
imglogo,
|
||||
getappname,
|
||||
toggleanimation,
|
||||
getClassColorHeader,
|
||||
getcart,
|
||||
getnumItemsCart,
|
||||
isFacilitatore,
|
||||
isZoomeri,
|
||||
@@ -654,6 +681,7 @@ export default defineComponent({
|
||||
clickMenu3Orizz,
|
||||
isEditor,
|
||||
editOn,
|
||||
canShowVersion,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
@@ -38,12 +38,12 @@
|
||||
<q-btn
|
||||
size="md"
|
||||
id="newvers"
|
||||
v-if="isNewVersionAvailable() || data.updateExists"
|
||||
v-if="isNewVersionAvailable || data.updateExists"
|
||||
color="secondary"
|
||||
rounded
|
||||
icon="refresh"
|
||||
class="btnNewVersShow"
|
||||
@click="RefreshApp()"
|
||||
@click="refreshApp()"
|
||||
:label="t('notification.newVersionAvailable')"
|
||||
>
|
||||
</q-btn>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
const msg_website_it = {
|
||||
ws: {
|
||||
sitename: 'RISO',
|
||||
siteshortname: 'RISO',
|
||||
description: 'Siamo la Rete Italiana di Scambio Orizzontale, abbiamo creato questa piattaforma per metterla al servizio di chi vuole riscoprire il valore della condivisione e della cooperazione. Valori semplici e profondi che ci aiutano a ritrovare il Senso della Vita, perduto in questa società consumista, e riporti quei Sani Pricìpi Naturali ed Umani di Fratellanza che intere popolazioni antiche conoscevano bene.',
|
||||
keywords: 'riso, piattaforma di scambio, rete italiana scambio orizzontale, riso app, riso piattaforma, scambio e baratto, momenta RIS',
|
||||
sitename: 'Gruppo Macro',
|
||||
siteshortname: 'Gruppo Macro',
|
||||
description: '',
|
||||
keywords: '',
|
||||
},
|
||||
hours: {
|
||||
descr: 'Descrizione',
|
||||
@@ -16,29 +16,20 @@ const msg_website_it = {
|
||||
pages: {
|
||||
home: 'Home',
|
||||
profile: 'Profilo',
|
||||
install_site: 'Installa Sito',
|
||||
profile2: 'ProfiloU',
|
||||
mypage2: 'mypage2',
|
||||
myservice2: 'myservice2',
|
||||
myhosps2: 'myhosps2',
|
||||
mygood2: 'mygood2',
|
||||
catalogo: 'Catalogo',
|
||||
fundraising: 'Sostieni il Progetto',
|
||||
notifs: 'Configura le Notifiche',
|
||||
unsubscribe: 'Disiscriviti',
|
||||
unsubscribe_user: 'Disiscriviti User',
|
||||
test: 'Test',
|
||||
projects: 'Progetti',
|
||||
report: 'Report Ore',
|
||||
producer: 'Produttore',
|
||||
orderinfo: 'Ordini Effettuati',
|
||||
products: 'Prodotti',
|
||||
productslist: 'Lista Prodotti',
|
||||
collabora: 'Collabora',
|
||||
storehouses: 'Magazzino',
|
||||
departments: 'Uffici',
|
||||
orders: 'Ordini Ricevuti',
|
||||
orders2: 'Ordini Ricevuti',
|
||||
sharewithus: 'Condividi con Noi',
|
||||
checkout: 'Carrello',
|
||||
payment: 'Pagamenti',
|
||||
regok: 'Registrazione Confermata',
|
||||
presentazione: 'Presentazione',
|
||||
presentazione2: 'Presentazione',
|
||||
@@ -84,14 +75,12 @@ const msg_website_it = {
|
||||
eventodef: 'Evento:',
|
||||
prova: 'prova',
|
||||
dbop: 'Operazioni',
|
||||
dbopmacro: 'Operazioni Macro',
|
||||
projall: 'Comunitari',
|
||||
groups: 'Lista Gruppi',
|
||||
projectsShared: 'Condivisi da me',
|
||||
myprojects: 'Privati',
|
||||
favproj: 'Favoriti',
|
||||
admin_ecommerce: 'ECommerce',
|
||||
ecommerce: 'Prodotti',
|
||||
ecommerce_menu: 'ECommerce1',
|
||||
hours: 'Ore',
|
||||
department: 'Uffici',
|
||||
title: 'Titolo',
|
||||
@@ -120,16 +109,11 @@ const msg_website_it = {
|
||||
onlyif_logged: 'Solo se Loggati',
|
||||
only_residenti: 'Solo Residenti',
|
||||
only_consiglio: 'Solo Consiglieri',
|
||||
only_collab: 'Solo Collaboratori',
|
||||
color: 'Colore',
|
||||
mainMenu: 'Menu Principale',
|
||||
subtitle: 'Sottotitolo',
|
||||
lang: 'Lingua',
|
||||
keywords: 'Parole Chiave',
|
||||
desctiption: 'Descrizione',
|
||||
heightimg: 'Altezza Immagine',
|
||||
},
|
||||
msg: {
|
||||
myAppName: 'Riso',
|
||||
myAppName: 'Più che Buono',
|
||||
myAppDescription: 'Il primo Vero Social Libero, Equo e Solidale, dove Vive Consapevolezza e Aiuto Comunitario. Gratuito',
|
||||
underconstruction: 'App in costruzione...',
|
||||
myDescriz: '',
|
||||
@@ -188,7 +172,18 @@ const msg_website_it = {
|
||||
descr: '<ul class="mylist" style="padding-left: 20px;">'
|
||||
+ '<li>📱<strong>Condividendo la APP</strong> a tutti coloro che vogliono far parte insieme della crescita e sviluppo di una Nuova Era</li>'
|
||||
+ '<li>👥 Aiutando a creare Gruppi Territoriali nella vostra città, impegnandosi a realizzare progetti per il Bene Comune, in onore ai principi Amorevoli e di condivisione.</li>'
|
||||
+ '<li>🌱 Sostenendo le persone attorno a voi, e rispettando la nostra vera Casa: Madre Natura e Tutti gli Esseri Viventi. ❤️</li>' +
|
||||
+ '<li>🌱 Sostenendo le persone attorno a voi, e rispettando la nostra vera Casa: Madre Natura e Tutti gli Esseri Viventi. ❤️</li>'
|
||||
+ '<li>👨🏻💻 Con una <strong>piccola donazione</strong> per le spese dei Server, manutenzione e per i continui sviluppi e miglioramenti</li></ul>' +
|
||||
'1) Tramite <strong><a href="https://paypal.me/paoloarena" target="_blank">Paypal</a></strong>:<br>' +
|
||||
'<br>2) Tramite <strong>Satispay</strong>: <a href="https://www.satispay.com/app/match/link/money-box/S6Y-SVN--62712D42-35B0-4BB9-8511-410C2AB8CD45" target="_blank">Clicca qui</a><br>' +
|
||||
'<div style="font-size: 1rem; background-color: white; color: blue; border: solid 2px #f00; margin: 5px; padding: 5px; border-radius: 10px; " ' +
|
||||
'class="row justify-around">' +
|
||||
'Se ancora non hai Satispay <a href="https://www.satispay.com/promo/PAOLOARENA4">Richiedila cliccando qui</a></br>' +
|
||||
'</div>' +
|
||||
'<br>3) Tramite <strong>Bonifico Bancario</strong>:<br>' +
|
||||
'(Scrivi a Surya (<a href="https://t.me/surya1977">@surya1977</a>) per le coordinate</br>' +
|
||||
'' +
|
||||
'4) In alternativa scegli tu una forma di Dono <br />' +
|
||||
'Grazie Mille per l\'Aiuto ed il Supporto' +
|
||||
'<br>',
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* RISO APP
|
||||
/* GRUPPOMACRO APP
|
||||
*/
|
||||
import type {
|
||||
import {
|
||||
IListRoutes,
|
||||
ILang,
|
||||
IPreloadImages,
|
||||
@@ -44,6 +44,7 @@ const firstPage = {
|
||||
infooter: true,
|
||||
}
|
||||
|
||||
|
||||
function getDynamicPages(site: ISites): IListRoutes[] {
|
||||
|
||||
const baseroutes: IListRoutes[] = [
|
||||
@@ -70,34 +71,11 @@ function getDynamicPages(site: ISites): IListRoutes[] {
|
||||
},
|
||||
{
|
||||
active: true,
|
||||
order: 12,
|
||||
path: '/goods',
|
||||
materialIcon: 'fas fa-tshirt',
|
||||
name: 'mypages.goods',
|
||||
component: () => import('@src/root/goods/goods.vue'),
|
||||
meta: { requiresAuth: true },
|
||||
inmenu: true,
|
||||
infooter: true,
|
||||
},
|
||||
{
|
||||
active: true,
|
||||
order: 15,
|
||||
path: '/services',
|
||||
materialIcon: 'fas fa-house-user',
|
||||
name: 'mypages.services',
|
||||
component: () => import('@src/root/services/services.vue'),
|
||||
meta: { requiresAuth: true },
|
||||
inmenu: true,
|
||||
infooter: true,
|
||||
},
|
||||
{
|
||||
active: true,
|
||||
order: 15,
|
||||
path: '/activities',
|
||||
materialIcon: 'fas fa-house-user',
|
||||
name: 'mypages.activities',
|
||||
component: () => import('@src/root/activities/activities.vue'),
|
||||
meta: { requiresAuth: true },
|
||||
order: 400,
|
||||
path: '/test-lungo',
|
||||
materialIcon: 'fas fa-test',
|
||||
name: 'mypages.test_lungo',
|
||||
component: () => import('@src/views/testLungo/testLungo.vue'),
|
||||
inmenu: false,
|
||||
infooter: false,
|
||||
},
|
||||
@@ -112,17 +90,6 @@ function getDynamicPages(site: ISites): IListRoutes[] {
|
||||
inmenu: false,
|
||||
infooter: false,
|
||||
},
|
||||
{
|
||||
active: true,
|
||||
order: 15,
|
||||
path: '/hosps',
|
||||
materialIcon: 'fas fa-bed',
|
||||
name: 'mypages.hosp',
|
||||
component: () => import('@src/root/hosp/hosp.vue'),
|
||||
meta: { requiresAuth: true },
|
||||
inmenu: true,
|
||||
infooter: true,
|
||||
},
|
||||
{
|
||||
active: site.confpages && site.confpages.enableCircuits,
|
||||
order: 16,
|
||||
@@ -135,7 +102,7 @@ function getDynamicPages(site: ISites): IListRoutes[] {
|
||||
infooter: true,
|
||||
},
|
||||
{
|
||||
active: true,
|
||||
active: site.confpages && site.confpages.enableEvents,
|
||||
order: 20,
|
||||
path: '/events',
|
||||
materialIcon: 'fas fa-bullhorn',
|
||||
@@ -157,7 +124,7 @@ function getDynamicPages(site: ISites): IListRoutes[] {
|
||||
infooter: false,
|
||||
},
|
||||
{
|
||||
active: true,
|
||||
active: site.confpages && site.confpages.showProfile,
|
||||
order: 120,
|
||||
path: '/myprofile',
|
||||
materialIcon: 'fas fa-user',
|
||||
@@ -168,7 +135,7 @@ function getDynamicPages(site: ISites): IListRoutes[] {
|
||||
infooter: true,
|
||||
},
|
||||
{
|
||||
active: true,
|
||||
active: site.confpages && site.confpages.showProfile,
|
||||
order: 120,
|
||||
path: '/editprofile',
|
||||
materialIcon: 'fas fa-user',
|
||||
@@ -179,7 +146,7 @@ function getDynamicPages(site: ISites): IListRoutes[] {
|
||||
infooter: false,
|
||||
},
|
||||
{
|
||||
active: true,
|
||||
active: site.confpages && site.confpages.showiscrittiMenu,
|
||||
order: 130,
|
||||
path: '/friends',
|
||||
materialIcon: 'fas fa-user-friends',
|
||||
@@ -274,16 +241,6 @@ function getDynamicPages(site: ISites): IListRoutes[] {
|
||||
inmenu: false,
|
||||
infooter: false,
|
||||
},
|
||||
{
|
||||
active: true,
|
||||
order: 150,
|
||||
path: '/sostieniilprogetto',
|
||||
materialIcon: 'fas fa-hand-holding-heart',
|
||||
name: 'pages.fundraising',
|
||||
component: () => import('@src/root/fundraising/fundraising.vue'),
|
||||
inmenu: false,
|
||||
infooter: false,
|
||||
},
|
||||
{
|
||||
active: true,
|
||||
order: 80,
|
||||
@@ -302,7 +259,7 @@ function getDynamicPages(site: ISites): IListRoutes[] {
|
||||
|
||||
export function firstimagehome() {
|
||||
|
||||
const img = 'statics/images/background.jpg'
|
||||
let img = 'statics/images/background.jpg'
|
||||
return img
|
||||
}
|
||||
|
||||
|
||||
@@ -110,12 +110,6 @@
|
||||
v-for="(notif, index) in getlasts_coins"
|
||||
:key="index"
|
||||
>
|
||||
<!--<q-item-section avatar>
|
||||
<q-avatar>
|
||||
<q-item-label lines="1">{{ getTypeDirNotif(notif) }}</q-item-label>
|
||||
</q-avatar>
|
||||
</q-item-section>-->
|
||||
|
||||
<q-item-section avatar>
|
||||
<q-avatar>
|
||||
<img :src="notif.myimgsender" :alt="notif.sender" />
|
||||
|
||||
@@ -70,7 +70,7 @@ export default defineComponent({
|
||||
return props.modelValue
|
||||
},
|
||||
|
||||
set(value) {s
|
||||
set(value) {
|
||||
return emit('update:modelValue', value)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -264,7 +264,7 @@ async function Request(
|
||||
if (import.meta.env.DEV) {
|
||||
console.log('ERROR using', path);
|
||||
if (error && error.response) {
|
||||
console.log('error.response=', JSON.stringify(error.response, null, 2));
|
||||
// console.log('error.response=', JSON.stringify(error.response, null, 2));
|
||||
}
|
||||
}
|
||||
let mycode = 0;
|
||||
|
||||
@@ -27,7 +27,8 @@ export const serv_constants = {
|
||||
RIS_CODE_OK: 1,
|
||||
RIS_CODE_LOGIN_OK: 1,
|
||||
RIS_ISCRIZIONE_OK: 5,
|
||||
RIS_CODE__HTTP_FORBIDDEN_INVALID_TOKEN: 403,
|
||||
RIS_CODE__HTTP_FORBIDDEN_INVALID_TOKEN: 401,
|
||||
RIS_CODE__HTTP_FORBIDDEN_PERMESSI: 403,
|
||||
RIS_CODE__HTTP_FORBIDDEN_TOKEN_EXPIRED: 408,
|
||||
|
||||
RIS_CODE_TOKEN_RESETPASSWORD_NOT_FOUND: -23,
|
||||
|
||||
@@ -2668,13 +2668,14 @@ export const useGlobalStore = defineStore('GlobalStore', {
|
||||
getMsgServerError() {
|
||||
if (this.serverError) {
|
||||
if (this.serverMsgError) {
|
||||
let mymsg = this.serverMsgError.msgerr || this.serverMsgError.data!.msgerr || this.serverMsgError.msgerr!.message
|
||||
if (this.serverMsgError.status === 500) {
|
||||
return 'Errore Interno del Server';
|
||||
} else if (this.serverMsgError.msgerr === '') {
|
||||
} else if (mymsg === '') {
|
||||
return 'Codice Errore ' + this.serverMsgError.status;
|
||||
}
|
||||
try {
|
||||
return this.serverMsgError.msgerr.message;
|
||||
return mymsg
|
||||
} catch (e) {
|
||||
return this.serverMsgError.msgerr;
|
||||
}
|
||||
|
||||