Notification with Service Workers now is working!

When a Notification arrives, it save into the IndexDb,
then in Vue.js call a polling to check in the db if there is a different record count.
If is different then call a get to update the notification.
This commit is contained in:
paoloar77
2022-08-07 02:01:20 +02:00
parent 66ee007e92
commit ce20daed6d
27 changed files with 411 additions and 232 deletions

View File

@@ -36,7 +36,7 @@ export const shared_consts = {
FILTER_ASK_ZOOM_VISTO: 32768,
FILTER_HOURS_MYLIST: 65536,
FILTER_HOURS_ALL: 131072,
FILTER_MISSING_PAYMENT: 262144,
FILTER_REPORTED: 262144,
FILTER_TO_MAKE_MEMBERSHIP_CARD: 524288,
FILTER_MEMBERSHIP_CARD_OK: 1048576,
FILTER_USER_NO_VERIFIED_APORTADOR: 2097152,

View File

@@ -78,14 +78,6 @@ export default defineComponent({
}
}
function getenv(myvar: any) {
try {
return process.env[myvar]
} catch (e) {
return ''
}
}
function getPermission() {
return Notification.permission
}
@@ -123,7 +115,6 @@ export default defineComponent({
appname,
meta,
mystilecard,
getenv,
getPermission,
NotServiceWorker,
PagLogin,

View File

@@ -131,10 +131,6 @@ export default defineComponent({
}
}
function getenv(myvar: any) {
return process.env[myvar]
}
function initprompt() {
window.addEventListener('beforeinstallprompt', function (event) {
// console.log('******************************** beforeinstallprompt fired')
@@ -232,7 +228,6 @@ export default defineComponent({
getappname,
appname,
mystilecard,
getenv,
getPermission,
NotServiceWorker,
PagLogin,

View File

@@ -78,14 +78,6 @@ export default defineComponent({
}
}
function getenv(myvar: any) {
try {
return process.env[myvar]
} catch (e) {
return ''
}
}
function getPermission() {
return Notification.permission
}
@@ -123,7 +115,6 @@ export default defineComponent({
appname,
meta,
mystilecard,
getenv,
getPermission,
NotServiceWorker,
PagLogin,

View File

@@ -1,11 +1,11 @@
// import { useGlobalStore } from '@store/globalStore'
// import indexdb from './indexdb'
import indexdb from './indexdb'
import { idbKeyval as storage } from '@src/js/storage'
export default async (cmd: string, table: string, data: any = null, id = '') => {
export default async (cmd: string, table: string, data: any = null, id: any = '') => {
// const globalStore = useGlobalStore()
// const descr = data !== null ? data.descr : ''

View File

@@ -6,13 +6,13 @@ import { useUserStore } from '@store/UserStore'
import { useGlobalStore } from '@store/globalStore'
import { idbKeyval as storage } from '../js/storage.js'
function writeConfigIndexDb(context: any, data: any) {
function writeConfigIndexDb(data: any) {
// console.log('writeConfigIndexDb', data)
storage.setdata('config', data)
}
function saveConfigIndexDb(context: any) {
function saveConfigIndexDb() {
const userStore = useUserStore()
const data: ICfgData = {
@@ -22,10 +22,10 @@ function saveConfigIndexDb(context: any) {
userId: userStore.my._id,
}
writeConfigIndexDb('config', data)
writeConfigIndexDb(data)
}
async function readfromIndexDbToState(context: any, table: string) {
async function readfromIndexDbToState(table: string) {
console.log('*** readfromIndexDbToState ***', table)
return storage.getalldata(table)
@@ -79,13 +79,13 @@ function consolelogpao(str: string, str2 = '', str3 = '') {
// Todos.mutations.setTestpao(str + str2 + str3)
}
export default async (context: any, cmd: string, table: string, datakey: any = null, id = '') => {
export default async (cmd: string, table: string, datakey: any = null, id: any = '') => {
const globalStore = useGlobalStore()
try {
// console.log('TABLE', table, 'cmd', cmd)
if (cmd === 'loadapp') {
// ****** LOAD APP AL CARICAMENTO ! *******
return saveConfigIndexDb(context)
return saveConfigIndexDb()
}
if (cmd === 'write') {
if (globalStore) {
@@ -94,7 +94,7 @@ export default async (context: any, cmd: string, table: string, datakey: any = n
return await storage.setdata(table, datakey)
}
if (cmd === 'updatefromIndexedDbToState') {
return await readfromIndexDbToState(context, table)
return await readfromIndexDbToState(table)
}
if (cmd === 'readall') {
if (globalStore) {
@@ -104,7 +104,9 @@ export default async (context: any, cmd: string, table: string, datakey: any = n
return await storage.getalldata(table)
}
if (cmd === 'count') {
return await storage.count(table)
let contatore = await storage.count(table)
// console.log('COUNT:', table, contatore)
return contatore
}
if (cmd === 'read') {
if (globalStore) {

View File

@@ -8,7 +8,7 @@ export let idbKeyval = (() => {
// console.log('CREO DB STORAGE JS !')
db = new Promise((resolve, reject) => {
// console.log('open mydb3')
const openreq = indexedDB.open('mydb3', 12);
const openreq = indexedDB.open('mydb3', 13);
openreq.onerror = () => {
reject(openreq.error);
@@ -50,7 +50,7 @@ export let idbKeyval = (() => {
return {
async get(key) {
let req;
withStore('readonly', 'keyval', store => {
await withStore('readonly', 'keyval', store => {
req = store.get(key);
});
return req.result;
@@ -62,30 +62,49 @@ export let idbKeyval = (() => {
async getdata(table, key) {
let req;
withStore('readonly', table, store => {
await withStore('readonly', table, store => {
// console.log('getdata', table, key)
req = store.get(key);
// console.log(' req', req)
});
return req.result;
if (req) {
console.log('getdata', table, key, req.result)
return req.result;
} else {
return null;
}
},
async getalldata(table) {
let req;
withStore('readonly', table, store => {
await withStore('readonly', table, store => {
req = store.getAll();
console.log(' req', req)
});
return req.result;
if (req) {
return req.result;
} else {
return null;
}
},
async count(table) {
let req;
withStore('readonly', table, store => {
await withStore('readonly', table, store => {
req = store.count();
});
return req.result;
// console.log('req', req)
if (req) {
// console.log('COUNT:', table, req.result)
return req.result;
} else {
return 0;
}
},
async set(key, value) {
let req;
withStore('readwrite', 'keyval', store => {
await withStore('readwrite', 'keyval', store => {
req = store.put(value, key);
});
return req.result;
@@ -94,7 +113,7 @@ export let idbKeyval = (() => {
let req;
// console.log('setdata', table, value)
withStore('readwrite', table, store => {
await withStore('readwrite', table, store => {
req = store.put(value);
});
return req.result;
@@ -121,6 +140,7 @@ export let idbKeyval = (() => {
// iOS add-to-homescreen is missing IDB, or at least it used to.
// I haven't tested this in a while.
if (!self.indexedDB) {
console.log('NO indexedDB')
idbKeyval = {
get: key => Promise.resolve(localStorage.getItem(key)),
set: (key, val) => Promise.resolve(localStorage.setItem(key, val)),

View File

@@ -21,6 +21,7 @@ import { shared_consts } from '@/common/shared_vuejs'
import { useI18n } from '@/boot/i18n'
import { useQuasar } from 'quasar'
import { costanti } from '@costanti'
import { waitAndcheckPendingNotif } from '../../../store/Modules/ApiTables'
const namespace = 'notifModule'
@@ -50,6 +51,9 @@ export default defineComponent({
const userId = ref('')
const open = ref(false)
const polling = ref(<any> null)
const eseguipolling = ref(true)
const notifsel = ref(<INotif>{
dest: '',
datenotif: new Date()
@@ -61,6 +65,30 @@ export default defineComponent({
//
// }
function checkIfArrivedSomeNotif() {
waitAndcheckPendingNotif()
return true
}
function checkifpolling() {
console.log('checkifpolling')
if (eseguipolling.value) {
if (!polling.value) {
console.log('esegui POLLING....')
polling.value = setInterval(() => {
checkIfArrivedSomeNotif()
}, 3000)
}
}
}
function beforeDestroy() {
console.log('beforeDestroy')
if (polling.value)
clearInterval(polling.value)
}
watch(() => usernotifs.value, async (to: any, from: any) => {
if (usernotifs.value) {
@@ -152,6 +180,7 @@ export default defineComponent({
async function mounted() {
myuser.value = userStore.my
await refreshdata(userStore.my.username)
checkifpolling()
}
onMounted(mounted)
@@ -177,7 +206,6 @@ export default defineComponent({
notifStore,
show_all,
t,
$q,
username,
userStore,
}

View File

@@ -77,7 +77,7 @@ export interface IMessage {
read?: boolean
deleted?: boolean
status?: StatusMessage
options?: number
typesend?: number
}
export interface INotif {
@@ -120,4 +120,5 @@ export interface INotifState {
last_notifs: INotif[]
show_all: boolean
updateNotification: boolean
countNotif: number
}

View File

@@ -2,7 +2,9 @@
<CMyPage img="" :title="$t('otherpages.admin.userpanel')" keywords="" :description="$t('otherpages.admin.userpanel')">
<q-btn color="green" label="Esporta Lista Email" @click="exportListaEmail"></q-btn>
<div class="q-ma-sm row bordo_stondato" style="min-width: 300px; ">
<br>
<div v-if="myuser.username" class="q-ma-sm row bordo_stondato" style="min-width: 300px; ">
<div class="row">
<q-select rounded outlined v-model="notifdirtype" :options="listnotiftype" label="Tipo" emit-value map-options>
@@ -65,7 +67,7 @@
</div>
<div v-if="!!myuser && search">
<div v-if="myuser.username">
username cercato: <em>"{{ search }}"</em><br>
<br>

View File

@@ -30,6 +30,10 @@ export default defineComponent({
label: 'Non hanno l\'Invitante',
value: shared_consts.FILTER_USER_NO_INVITANTE
},
{
label: 'Segnalati',
value: shared_consts.FILTER_REPORTED
},
{
label: 'No Approv. Invitante',
value: shared_consts.FILTER_USER_NO_VERIFIED_APORTADOR

View File

@@ -415,6 +415,9 @@ const msg_it = {
verified_by_aportador: 'Verificato',
notAsk_ToVerify: 'No Verif. Reg',
trust_modified: 'Fiducia Modificata',
reported: 'Segnalato',
username_who_reported: 'Segnal da',
date_reported: 'Data Segnal.',
blocked: 'Bloccato',
username_who_block: 'Bloccato da',
username_regala_invitato: 'Username del Destinatario del regalo',

View File

@@ -5,7 +5,7 @@ import { Api } from '@api'
import * as Types from '@src/store/Api/ApiTypes'
async function sendRequest(url: string, method: string, mydata: any) {
if (!process.env.DEBUG) console.log('sendRequest', method, url)
if (process.env.DEBUG) console.log('sendRequest', method, url)
let request
if (method === 'GET') request = Api.get(url, mydata)

View File

@@ -7,7 +7,7 @@ import { useUserStore } from '@store/UserStore'
import { tools } from '@src/store/Modules/tools'
import * as Types from './ApiTypes'
export let API_URL = process.env.MONGODB_HOST
export let API_URL = ''
export const axiosInstance: AxiosInstance = axios.create({
baseURL: API_URL,
headers: {
@@ -18,14 +18,14 @@ export const axiosInstance: AxiosInstance = axios.create({
axiosInstance.interceptors.response.use(
(response) => {
if (process.env.DEBUG === '1') console.log(response)
if (process.env.DEBUGGING === '1') console.log(response)
return response
},
(error) => {
const globalStore = useGlobalStore()
// console.log('error', error)
if (error.response) {
if (process.env.DEBUG === '1') console.log('Status = ', error.response.status)
if (process.env.DEBUGGING === '1') console.log('Status = ', error.response.status)
console.log('Request Error: ', error.response)
if (error.response.status !== 0) {
globalStore.setStateConnection('online')

View File

@@ -92,7 +92,7 @@ export const Api = {
idapp: process.env.APP_ID,
}
console.log('INIZIO - SendReq', url)
// console.log('INIZIO - SendReq', url)
// console.log('mydata', mydata)
const userStore = useUserStore()
@@ -145,7 +145,7 @@ export const Api = {
},
async syncAlternative(mystrparam: string) {
// console.log('[ALTERNATIVE Background syncing', mystrparam)
console.log('[ALTERNATIVE Background syncing', mystrparam)
const multiparams = mystrparam.split('|')
if (multiparams) {

View File

@@ -106,8 +106,8 @@ export const useMessageStore = defineStore('MessageStore', {
data.datemsg = tools.getDateNow()
data.status = StatusMessage.WaitingToSend
// Options
data.options = tools.SetBit(data.options, shared_consts.MessageOptions.Notify_ByEmail)
data.options = tools.SetBit(data.options, shared_consts.MessageOptions.Notify_ByPushNotification)
data.typesend = tools.SetBit(data.typesend, shared_consts.MessageOptions.Notify_ByEmail)
data.typesend = tools.SetBit(data.typesend, shared_consts.MessageOptions.Notify_ByPushNotification)
// console.log('DOPO:')
// console.table(data)

View File

@@ -9,12 +9,12 @@ import { useGlobalStore } from '@store/globalStore'
import globalroutines from '../../globalroutines/index'
import { useProjectStore } from '@store/Projects'
import { useTodoStore } from '@store/Todos'
import { useNotifStore } from '@store/NotifStore'
export function getLinkByTableName(nametable: string) {
if (nametable === 'todos') {
return 'todos'
}
if (nametable === 'projects') {
} else if (nametable === 'projects') {
return 'projects'
}
return ''
@@ -34,13 +34,13 @@ export const DB = {
}
export function allTables() {
/* const myarr = OtherTables
for (const tab of costanti.MainTables) {
for (const method of costanti.allMethod) {
const myarr = OtherTables
for (const tab of MainTables) {
for (const method of allMethod) {
myarr.push(method + tab)
}
} */
return costanti.OtherTables
}
return myarr
}
async function updatefromIndexedDbToState(nametab: string) {
@@ -52,7 +52,7 @@ async function updatefromIndexedDbToState(nametab: string) {
}
async function checkPendingMsg() {
// console.log('checkPendingMsg')
console.log('checkPendingMsg')
const globalStore = useGlobalStore()
const config = await globalroutines('read', 'config', null, '1')
@@ -82,8 +82,26 @@ async function checkPendingMsg() {
}).catch(() => reject()))
}
async function checkPendingNotif() {
const notifStore = useNotifStore()
const howmanybefore = notifStore.countNotif
// eslint-disable-next-line @typescript-eslint/no-misused-promises
return new Promise((resolve, reject) => globalroutines('count', 'notifications')
.then((count) => {
if (count !== howmanybefore) {
notifStore.setCountNotifs(count)
return resolve(true)
}
return resolve(false)
}).catch(() => reject()))
}
function useServiceWorker() {
return false // return 'serviceWorker' in navigator
return 'serviceWorker' in navigator
// return false //
}
// If something in the call of Service Worker went wrong (Network or Server Down), then retry !
@@ -99,7 +117,7 @@ async function sendSwMsgIfAvailable() {
.then(() => globalroutines('readall', 'swmsg')
.then((arr_recmsg) => {
if (arr_recmsg.length > 0) {
// console.log('---------------------- 2) navigator (2) .serviceWorker.ready')
console.log('---------------------- 2) navigator (2) .serviceWorker.ready')
let promiseChain = Promise.resolve()
for (const rec of arr_recmsg) {
@@ -130,6 +148,14 @@ export async function waitAndRefreshData() {
return await todos.dbLoad({ checkPending: false })
}
export function waitAndRefreshNotif() {
const notifStore = useNotifStore()
notifStore.updateNotification = true
}
export async function waitAndcheckPendingMsg() {
// await aspettansec(1000)
const globalStore = useGlobalStore()
@@ -157,6 +183,21 @@ export async function waitAndcheckPendingMsg() {
})
}
export async function waitAndcheckPendingNotif() {
// await aspettansec(1000)
const globalStore = useGlobalStore()
return checkPendingNotif()
.then((ris) => {
if (ris) {
if (globalStore.isOnline()) { // If is Offline, then check
return waitAndRefreshNotif()
}
}
})
}
async function dbInsertSave(call: string, item: any, method: string) {
let ret = true
const userStore = useUserStore()

View File

@@ -231,7 +231,7 @@ export const costanti = {
MAX_PHASES: 5,
OtherTables: ['config', 'swmsg'],
OtherTables: ['config', 'swmsg', 'notifications'],
// export const MainTables = ['todos', 'projects']
MainTables: [],
allMethod: ['sync_post_', 'sync_patch_', 'delete_', 'hide_'],

View File

@@ -2156,8 +2156,8 @@ export const colTableUsersISP = [
AddCol({ name: 'username_who_block', label_trans: 'reg.username_who_block' }),
AddCol({ name: 'date_blocked', label_trans: 'reg.date_blocked', fieldtype: costanti.FieldType.date }),
AddCol({ name: 'reported', label_trans: 'reg.reported', fieldtype: costanti.FieldType.boolean }),
AddCol({ name: 'username_who_reported', label_trans: 'reg.username_who_reported' }),
AddCol({ name: 'date_reported', label_trans: 'reg.date_reported', fieldtype: costanti.FieldType.date }),
AddCol({ name: 'username_who_report', label_trans: 'reg.username_who_reported' }),
AddCol({ name: 'date_report', label_trans: 'reg.date_reported', fieldtype: costanti.FieldType.date }),
AddCol({
name: 'profile.resplist',
field: 'profile',

View File

@@ -56,6 +56,7 @@ export const tools = {
TABBED_HOME: 't-home',
TABBED_NAVE: 't-nave',
FILTER_ALL: 0,
FILTER_MYREC: 1,
FILTER_MYFOLLOW: 2,
@@ -5627,6 +5628,14 @@ export const tools = {
}
},
getEnv(name: string) {
const config: any = {
// @ts-ignore
VUE_APP_BACKEND_API_URL: window?.appConfig?.VUE_APP_BACKEND_API_URL || process.env.VUE_APP_BACKEND_API_URL
}
return config[name];
},
// getLocale() {
// if (navigator.languages && navigator.languages.length > 0) {

View File

@@ -14,6 +14,7 @@ export const useNotifStore = defineStore('NotifStore', {
last_notifs: [],
show_all: true,
updateNotification: false,
countNotif: 0,
}),
getters: {
@@ -32,11 +33,17 @@ export const useNotifStore = defineStore('NotifStore', {
},
actions: {
updateArrNotif() {
this.setBadgeIconApp()
},
setNotif(notif: INotif) {
console.log('setNotif', notif)
if (notif) {
this.last_notifs = [notif, ...this.last_notifs]
}
this.updateArrNotif()
},
setAsRead(idnotif: string) {
@@ -44,6 +51,18 @@ export const useNotifStore = defineStore('NotifStore', {
if (rec) {
rec.read = true
}
this.updateArrNotif()
},
async setBadgeIconApp(){
// Get our dummy count and update it,
// just to give more context for this demo.
const countNow = this.getnumNotifUnread()
// @ts-ignore
await navigator.setAppBadge(countNow)
.catch((error: any) => { /* ... */ });
},
setAllRead(username: string) {
@@ -55,6 +74,7 @@ export const useNotifStore = defineStore('NotifStore', {
rec.read = true
}
}
this.updateArrNotif()
})
.catch((error) => {
@@ -71,6 +91,7 @@ export const useNotifStore = defineStore('NotifStore', {
this.last_notifs = this.last_notifs.filter((rec) => rec._id !== id)
}
this.updateArrNotif()
})
.catch((error) => {
console.error(error)
@@ -85,6 +106,7 @@ export const useNotifStore = defineStore('NotifStore', {
// console.log('res', res)
if (res) {
this.last_notifs = []
this.updateArrNotif()
}
})
@@ -110,6 +132,7 @@ export const useNotifStore = defineStore('NotifStore', {
} else {
this.last_notifs = []
}
this.updateArrNotif()
return true
})
.catch((error) => {
@@ -157,5 +180,10 @@ export const useNotifStore = defineStore('NotifStore', {
return false
})
},
setCountNotifs(num: number) {
this.countNotif = num
},
},
})

View File

@@ -25,6 +25,8 @@ import { shared_consts } from '@/common/shared_vuejs'
import { costanti } from '@costanti'
import { IMyGroup } from '@model/UserStore'
import globalroutines from '../globalroutines/index'
export const DefaultUser: IUserFields = {
_id: '',
email: '',
@@ -955,6 +957,7 @@ export const useUserStore = defineStore('UserStore', {
return await this.setGlobal($router, isLogged)
.then((loadstorage: any) => {
console.log('RISULT setGlobal:', loadstorage)
if (loadstorage) {
if ($q.screen.gt.sm) {
@@ -969,7 +972,7 @@ export const useUserStore = defineStore('UserStore', {
}*/
//++Todo PWA: globalroutines('loadapp', '')
globalroutines('loadapp', '')
// Create Subscription to Push Notification
globalStore.createPushSubscription()

View File

@@ -564,6 +564,7 @@ export const useGlobalStore = defineStore('GlobalStore', {
async createPushSubscription() {
// console.log('ENTER TO createPushSubscription')
// If Already subscribed, don't send to the Server DB
// if (state.wasAlreadySubOnDb) {
// // console.log('wasAlreadySubOnDb!')
@@ -574,10 +575,12 @@ export const useGlobalStore = defineStore('GlobalStore', {
return
if (!('serviceWorker' in navigator)) {
console.log('serviceWorker not present !')
return
}
if (!('PushManager' in window)) {
console.log('PushManager not present !')
return
}
@@ -1657,12 +1660,23 @@ export const useGlobalStore = defineStore('GlobalStore', {
getServerHost() {
if (this.serverHost) {
return this.serverHost
} else {
return process.env.MONGODB_HOST
let myserv = ''
myserv = window.location.host
if (process.env.DEBUGGING) {
myserv = 'http://192.168.1.54:3000'
}
if (!myserv) {
if (this.serverHost) {
myserv = this.serverHost
} else {
myserv = process.env.MONGODB_HOST!
}
}
return myserv
},

View File

@@ -32,7 +32,7 @@
</div>
<div v-if="myuser.reported">
<CTitleBanner title="L'utente è stato Segnalato per comportamento non idoneo." bgcolor="bg-red" clcolor="text-white">
<CTitleBanner title="⚠️ L'utente è stato Segnalato per comportamento non idoneo." bgcolor="bg-red" clcolor="text-white">
</CTitleBanner>
</div>