From 73fbe89a4b4e545796e9cc6aae707de0a4eed3a1 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Wed, 25 Oct 2023 18:58:33 +0300 Subject: initial work on showing notifications through serviceworkers --- .../desktop_notification_utils.js | 7 +- src/services/push/push.js | 111 ------------------ src/services/sw/sw.js | 124 +++++++++++++++++++++ 3 files changed, 127 insertions(+), 115 deletions(-) delete mode 100644 src/services/push/push.js create mode 100644 src/services/sw/sw.js (limited to 'src/services') diff --git a/src/services/desktop_notification_utils/desktop_notification_utils.js b/src/services/desktop_notification_utils/desktop_notification_utils.js index b84a1f75..c31a1030 100644 --- a/src/services/desktop_notification_utils/desktop_notification_utils.js +++ b/src/services/desktop_notification_utils/desktop_notification_utils.js @@ -1,9 +1,8 @@ +import { showDesktopNotification as swDesktopNotification } from '../sw/sw.js' + export const showDesktopNotification = (rootState, desktopNotificationOpts) => { if (!('Notification' in window && window.Notification.permission === 'granted')) return if (rootState.statuses.notifications.desktopNotificationSilence) { return } - const desktopNotification = new window.Notification(desktopNotificationOpts.title, desktopNotificationOpts) - // Chrome is known for not closing notifications automatically - // according to MDN, anyway. - setTimeout(desktopNotification.close.bind(desktopNotification), 5000) + swDesktopNotification(desktopNotificationOpts) } diff --git a/src/services/push/push.js b/src/services/push/push.js deleted file mode 100644 index 1787ac36..00000000 --- a/src/services/push/push.js +++ /dev/null @@ -1,111 +0,0 @@ -import runtime from 'serviceworker-webpack5-plugin/lib/runtime' - -function urlBase64ToUint8Array (base64String) { - const padding = '='.repeat((4 - base64String.length % 4) % 4) - const base64 = (base64String + padding) - .replace(/-/g, '+') - .replace(/_/g, '/') - - const rawData = window.atob(base64) - return Uint8Array.from([...rawData].map((char) => char.charCodeAt(0))) -} - -function isPushSupported () { - return 'serviceWorker' in navigator && 'PushManager' in window -} - -function getOrCreateServiceWorker () { - return runtime.register() - .catch((err) => console.error('Unable to get or create a service worker.', err)) -} - -function subscribePush (registration, isEnabled, vapidPublicKey) { - if (!isEnabled) return Promise.reject(new Error('Web Push is disabled in config')) - if (!vapidPublicKey) return Promise.reject(new Error('VAPID public key is not found')) - - const subscribeOptions = { - userVisibleOnly: true, - applicationServerKey: urlBase64ToUint8Array(vapidPublicKey) - } - return registration.pushManager.subscribe(subscribeOptions) -} - -function unsubscribePush (registration) { - return registration.pushManager.getSubscription() - .then((subscribtion) => { - if (subscribtion === null) { return } - return subscribtion.unsubscribe() - }) -} - -function deleteSubscriptionFromBackEnd (token) { - return window.fetch('/api/v1/push/subscription/', { - method: 'DELETE', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${token}` - } - }).then((response) => { - if (!response.ok) throw new Error('Bad status code from server.') - return response - }) -} - -function sendSubscriptionToBackEnd (subscription, token, notificationVisibility) { - return window.fetch('/api/v1/push/subscription/', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${token}` - }, - body: JSON.stringify({ - subscription, - data: { - alerts: { - follow: notificationVisibility.follows, - favourite: notificationVisibility.likes, - mention: notificationVisibility.mentions, - reblog: notificationVisibility.repeats, - move: notificationVisibility.moves - } - } - }) - }).then((response) => { - if (!response.ok) throw new Error('Bad status code from server.') - return response.json() - }).then((responseData) => { - if (!responseData.id) throw new Error('Bad response from server.') - return responseData - }) -} - -export function registerPushNotifications (isEnabled, vapidPublicKey, token, notificationVisibility) { - if (isPushSupported()) { - getOrCreateServiceWorker() - .then((registration) => subscribePush(registration, isEnabled, vapidPublicKey)) - .then((subscription) => sendSubscriptionToBackEnd(subscription, token, notificationVisibility)) - .catch((e) => console.warn(`Failed to setup Web Push Notifications: ${e.message}`)) - } -} - -export function unregisterPushNotifications (token) { - if (isPushSupported()) { - Promise.all([ - deleteSubscriptionFromBackEnd(token), - getOrCreateServiceWorker() - .then((registration) => { - return unsubscribePush(registration).then((result) => [registration, result]) - }) - .then(([registration, unsubResult]) => { - if (!unsubResult) { - console.warn('Push subscription cancellation wasn\'t successful, killing SW anyway...') - } - return registration.unregister().then((result) => { - if (!result) { - console.warn('Failed to kill SW') - } - }) - }) - ]).catch((e) => console.warn(`Failed to disable Web Push Notifications: ${e.message}`)) - } -} diff --git a/src/services/sw/sw.js b/src/services/sw/sw.js new file mode 100644 index 00000000..b13c9a1b --- /dev/null +++ b/src/services/sw/sw.js @@ -0,0 +1,124 @@ +import runtime from 'serviceworker-webpack5-plugin/lib/runtime' + +function urlBase64ToUint8Array (base64String) { + const padding = '='.repeat((4 - base64String.length % 4) % 4) + const base64 = (base64String + padding) + .replace(/-/g, '+') + .replace(/_/g, '/') + + const rawData = window.atob(base64) + return Uint8Array.from([...rawData].map((char) => char.charCodeAt(0))) +} + +function isSWSupported () { + return 'serviceWorker' in navigator +} + +function isPushSupported () { + return 'PushManager' in window +} + +function getOrCreateServiceWorker () { + return runtime.register() + .catch((err) => console.error('Unable to get or create a service worker.', err)) +} + +function subscribePush (registration, isEnabled, vapidPublicKey) { + if (!isEnabled) return Promise.reject(new Error('Web Push is disabled in config')) + if (!vapidPublicKey) return Promise.reject(new Error('VAPID public key is not found')) + + const subscribeOptions = { + userVisibleOnly: true, + applicationServerKey: urlBase64ToUint8Array(vapidPublicKey) + } + return registration.pushManager.subscribe(subscribeOptions) +} + +function unsubscribePush (registration) { + return registration.pushManager.getSubscription() + .then((subscribtion) => { + if (subscribtion === null) { return } + return subscribtion.unsubscribe() + }) +} + +function deleteSubscriptionFromBackEnd (token) { + return fetch('/api/v1/push/subscription/', { + method: 'DELETE', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }).then((response) => { + if (!response.ok) throw new Error('Bad status code from server.') + return response + }) +} + +function sendSubscriptionToBackEnd (subscription, token, notificationVisibility) { + return window.fetch('/api/v1/push/subscription/', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + subscription, + data: { + alerts: { + follow: notificationVisibility.follows, + favourite: notificationVisibility.likes, + mention: notificationVisibility.mentions, + reblog: notificationVisibility.repeats, + move: notificationVisibility.moves + } + } + }) + }).then((response) => { + if (!response.ok) throw new Error('Bad status code from server.') + return response.json() + }).then((responseData) => { + if (!responseData.id) throw new Error('Bad response from server.') + return responseData + }) +} +export function initServiceWorker () { + if (!isSWSupported()) return + getOrCreateServiceWorker() +} + +export async function showDesktopNotification (content) { + const { active: sw } = await window.navigator.serviceWorker.getRegistration() + sw.postMessage({ type: 'desktopNotification', content }) +} + +export async function updateFocus () { + const { active: sw } = await window.navigator.serviceWorker.getRegistration() + sw.postMessage({ type: 'updateFocus' }) +} + +export function registerPushNotifications (isEnabled, vapidPublicKey, token, notificationVisibility) { + if (isPushSupported()) { + getOrCreateServiceWorker() + .then((registration) => subscribePush(registration, isEnabled, vapidPublicKey)) + .then((subscription) => sendSubscriptionToBackEnd(subscription, token, notificationVisibility)) + .catch((e) => console.warn(`Failed to setup Web Push Notifications: ${e.message}`)) + } +} + +export function unregisterPushNotifications (token) { + if (isPushSupported()) { + Promise.all([ + deleteSubscriptionFromBackEnd(token), + getOrCreateServiceWorker() + .then((registration) => { + return unsubscribePush(registration).then((result) => [registration, result]) + }) + .then(([registration, unsubResult]) => { + if (!unsubResult) { + console.warn('Push subscription cancellation wasn\'t successful') + } + }) + ]).catch((e) => console.warn(`Failed to disable Web Push Notifications: ${e.message}`)) + } +} -- cgit v1.2.3-70-g09d2 From 0628aac664be4ccce361d319fad201c44d9257fe Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Thu, 26 Oct 2023 15:42:21 +0300 Subject: fallback to old notification method, don't spam if old way of creating notification fails, try to use favicon --- .../desktop_notification_utils.js | 14 ++++++++++++-- src/services/notification_utils/notification_utils.js | 6 +++++- src/services/sw/sw.js | 2 +- src/sw.js | 15 +++++++++------ 4 files changed, 27 insertions(+), 10 deletions(-) (limited to 'src/services') diff --git a/src/services/desktop_notification_utils/desktop_notification_utils.js b/src/services/desktop_notification_utils/desktop_notification_utils.js index c31a1030..eb58f39b 100644 --- a/src/services/desktop_notification_utils/desktop_notification_utils.js +++ b/src/services/desktop_notification_utils/desktop_notification_utils.js @@ -1,8 +1,18 @@ -import { showDesktopNotification as swDesktopNotification } from '../sw/sw.js' +import { showDesktopNotification as swDesktopNotification, isSWSupported } from '../sw/sw.js' +const state = { failCreateNotif: false } export const showDesktopNotification = (rootState, desktopNotificationOpts) => { if (!('Notification' in window && window.Notification.permission === 'granted')) return if (rootState.statuses.notifications.desktopNotificationSilence) { return } - swDesktopNotification(desktopNotificationOpts) + if (isSWSupported()) { + swDesktopNotification(desktopNotificationOpts) + } else if (!state.failCreateNotif) { + try { + const desktopNotification = new window.Notification(desktopNotificationOpts.title, desktopNotificationOpts) + setTimeout(desktopNotification.close.bind(desktopNotification), 5000) + } catch { + state.failCreateNotif = true + } + } } diff --git a/src/services/notification_utils/notification_utils.js b/src/services/notification_utils/notification_utils.js index 0f8b9b02..ede1cc3d 100644 --- a/src/services/notification_utils/notification_utils.js +++ b/src/services/notification_utils/notification_utils.js @@ -76,8 +76,12 @@ export const unseenNotificationsFromStore = store => filter(filteredNotificationsFromStore(store), ({ seen }) => !seen) export const prepareNotificationObject = (notification, i18n) => { + const nodes = document.querySelectorAll('link[rel="icon"]') + const icon = nodes[0].href + const notifObj = { - tag: notification.id + tag: notification.id, + icon } const status = notification.status const title = notification.from_profile.name diff --git a/src/services/sw/sw.js b/src/services/sw/sw.js index b13c9a1b..3b62bac8 100644 --- a/src/services/sw/sw.js +++ b/src/services/sw/sw.js @@ -10,7 +10,7 @@ function urlBase64ToUint8Array (base64String) { return Uint8Array.from([...rawData].map((char) => char.charCodeAt(0))) } -function isSWSupported () { +export function isSWSupported () { return 'serviceWorker' in navigator } diff --git a/src/sw.js b/src/sw.js index 1889d15f..1b08fe69 100644 --- a/src/sw.js +++ b/src/sw.js @@ -59,16 +59,19 @@ self.addEventListener('message', async (event) => { console.log(event) if (type === 'desktopNotification') { - const { title, body, icon, id } = content - if (state.notificationIds.has(id)) return - state.notificationIds.add(id) - setTimeout(() => state.notificationIds.delete(id), 10000) - self.registration.showNotification('SWTEST: ' + title, { body, icon }) + const { title, ...rest } = content + const { tag } = rest + if (state.notificationIds.has(tag)) return + state.notificationIds.add(tag) + setTimeout(() => state.notificationIds.delete(tag), 10000) + self.registration.showNotification(title, rest) } if (type === 'updateFocus') { state.lastFocused = event.source.id - console.log(state) + + const notifications = await self.registration.getNotifications() + notifications.forEach(n => n.close()) } }) -- cgit v1.2.3-70-g09d2 From e3bf9a518574b19877a308b7331994b68ca5ef5b Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Thu, 26 Oct 2023 15:47:58 +0300 Subject: wrong key --- src/services/notification_utils/notification_utils.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/services') diff --git a/src/services/notification_utils/notification_utils.js b/src/services/notification_utils/notification_utils.js index ede1cc3d..8842b8e4 100644 --- a/src/services/notification_utils/notification_utils.js +++ b/src/services/notification_utils/notification_utils.js @@ -77,11 +77,11 @@ export const unseenNotificationsFromStore = store => export const prepareNotificationObject = (notification, i18n) => { const nodes = document.querySelectorAll('link[rel="icon"]') - const icon = nodes[0].href + const badge = nodes[0].href const notifObj = { tag: notification.id, - icon + badge } const status = notification.status const title = notification.from_profile.name -- cgit v1.2.3-70-g09d2 From f449bfe2f1d77172aee0433f63ec4a82bcc7ea1e Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Thu, 9 Nov 2023 01:52:39 +0200 Subject: SW-to-window communication --- src/services/sw/sw.js | 8 ++++++-- src/sw.js | 6 +++++- 2 files changed, 11 insertions(+), 3 deletions(-) (limited to 'src/services') diff --git a/src/services/sw/sw.js b/src/services/sw/sw.js index 3b62bac8..7de490fe 100644 --- a/src/services/sw/sw.js +++ b/src/services/sw/sw.js @@ -82,9 +82,13 @@ function sendSubscriptionToBackEnd (subscription, token, notificationVisibility) return responseData }) } -export function initServiceWorker () { +export async function initServiceWorker () { if (!isSWSupported()) return - getOrCreateServiceWorker() + await getOrCreateServiceWorker() + navigator.serviceWorker.addEventListener('message', (event) => { + console.log('SW MESSAGE', event) + // TODO actually act upon click (open drawer on mobile for now) + }) } export async function showDesktopNotification (content) { diff --git a/src/sw.js b/src/sw.js index 1b08fe69..b95d56a4 100644 --- a/src/sw.js +++ b/src/sw.js @@ -56,7 +56,6 @@ self.addEventListener('push', async (event) => { self.addEventListener('message', async (event) => { const { type, content } = event.data - console.log(event) if (type === 'desktopNotification') { const { title, ...rest } = content @@ -79,6 +78,11 @@ self.addEventListener('notificationclick', (event) => { event.notification.close() event.waitUntil(getWindowClients().then((list) => { + for (let i = 0; i < list.length; i++) { + const client = list[i] + client.postMessage({ type: 'notificationClicked', id: event.notification.tag }) + } + for (let i = 0; i < list.length; i++) { const client = list[i] if (state.lastFocused === null || client.id === state.lastFocused) { -- cgit v1.2.3-70-g09d2 From 77e270ef58750bb06955b7f45bd63382704928a5 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Thu, 9 Nov 2023 01:53:48 +0200 Subject: Don't use notification-badge'd favicon for badges in notifications --- src/services/favicon_service/favicon_service.js | 5 ++++- src/services/notification_utils/notification_utils.js | 11 ++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) (limited to 'src/services') diff --git a/src/services/favicon_service/favicon_service.js b/src/services/favicon_service/favicon_service.js index 7e19629d..df603bb4 100644 --- a/src/services/favicon_service/favicon_service.js +++ b/src/services/favicon_service/favicon_service.js @@ -55,10 +55,13 @@ const createFaviconService = () => { }) } + const getOriginalFavicons = () => [...favicons] + return { initFaviconService, clearFaviconBadge, - drawFaviconBadge + drawFaviconBadge, + getOriginalFavicons } } diff --git a/src/services/notification_utils/notification_utils.js b/src/services/notification_utils/notification_utils.js index 8842b8e4..4c6c4d8a 100644 --- a/src/services/notification_utils/notification_utils.js +++ b/src/services/notification_utils/notification_utils.js @@ -1,6 +1,9 @@ import { filter, sortBy, includes } from 'lodash' import { muteWordHits } from '../status_parser/status_parser.js' import { showDesktopNotification } from '../desktop_notification_utils/desktop_notification_utils.js' +import FaviconService from 'src/services/favicon_service/favicon_service.js' + +let cachedBadgeUrl = null export const notificationsFromStore = store => store.state.statuses.notifications.data @@ -76,12 +79,14 @@ export const unseenNotificationsFromStore = store => filter(filteredNotificationsFromStore(store), ({ seen }) => !seen) export const prepareNotificationObject = (notification, i18n) => { - const nodes = document.querySelectorAll('link[rel="icon"]') - const badge = nodes[0].href + if (cachedBadgeUrl === null) { + const favicon = FaviconService.getOriginalFavicons()[0] + cachedBadgeUrl = favicon.favcanvas.toDataURL() + } const notifObj = { tag: notification.id, - badge + badge: cachedBadgeUrl } const status = notification.status const title = notification.from_profile.name -- cgit v1.2.3-70-g09d2 From e0b8ad9f141f418ab3d8ebc7a9e68bcb755c820a Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Thu, 9 Nov 2023 01:58:33 +0200 Subject: add initial structure for notification settings --- src/modules/config.js | 3 +++ src/services/sw/sw.js | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src/services') diff --git a/src/modules/config.js b/src/modules/config.js index 56f8cba5..83d34fc9 100644 --- a/src/modules/config.js +++ b/src/modules/config.js @@ -65,6 +65,9 @@ export const defaultState = { chatMention: true, polls: true }, + notificationSettings: { + nativeNotifications: ['follows', 'mentions', 'followRequest', 'reports', 'chatMention', 'polls'] + }, webPushNotifications: false, muteWords: [], highlight: {}, diff --git a/src/services/sw/sw.js b/src/services/sw/sw.js index 7de490fe..2875d36e 100644 --- a/src/services/sw/sw.js +++ b/src/services/sw/sw.js @@ -87,7 +87,7 @@ export async function initServiceWorker () { await getOrCreateServiceWorker() navigator.serviceWorker.addEventListener('message', (event) => { console.log('SW MESSAGE', event) - // TODO actually act upon click (open drawer on mobile for now) + // TODO actually act upon click (open drawer on mobile, open chat/thread etc) }) } -- cgit v1.2.3-70-g09d2 From ec2937ec1f3b0ae153f79604eb35b57ffe0f9af2 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Mon, 13 Nov 2023 17:29:25 +0200 Subject: add options for marking single notification as read --- src/components/notification/notification.js | 6 ++++++ src/components/notification/notification.vue | 1 + src/components/notifications/notifications.js | 20 ++++++++++++++++++++ src/components/notifications/notifications.vue | 6 +++++- src/components/status/status.js | 3 +++ src/components/status/status.vue | 3 +++ src/modules/statuses.js | 8 ++++++++ .../desktop_notification_utils.js | 22 +++++++++++++++++++++- .../notification_utils/notification_utils.js | 5 +++-- src/services/sw/sw.js | 9 +++++++++ src/sw.js | 6 ++++++ 11 files changed, 85 insertions(+), 4 deletions(-) (limited to 'src/services') diff --git a/src/components/notification/notification.js b/src/components/notification/notification.js index 420db4f0..0e938c42 100644 --- a/src/components/notification/notification.js +++ b/src/components/notification/notification.js @@ -50,6 +50,7 @@ const Notification = { } }, props: ['notification'], + emits: ['interacted'], components: { StatusContent, UserAvatar, @@ -72,6 +73,9 @@ const Notification = { getUser (notification) { return this.$store.state.users.usersObject[notification.from_profile.id] }, + interacted () { + this.$emit('interacted') + }, toggleMute () { this.unmuted = !this.unmuted }, @@ -95,6 +99,7 @@ const Notification = { } }, doApprove () { + this.$emit('interacted') this.$store.state.api.backendInteractor.approveUser({ id: this.user.id }) this.$store.dispatch('removeFollowRequest', this.user) this.$store.dispatch('markSingleNotificationAsSeen', { id: this.notification.id }) @@ -114,6 +119,7 @@ const Notification = { } }, doDeny () { + this.$emit('interacted') this.$store.state.api.backendInteractor.denyUser({ id: this.user.id }) .then(() => { this.$store.dispatch('dismissNotificationLocal', { id: this.notification.id }) diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue index 6b3315f9..01ad395f 100644 --- a/src/components/notification/notification.vue +++ b/src/components/notification/notification.vue @@ -6,6 +6,7 @@ class="Notification" :compact="true" :statusoid="notification.status" + @interacted="interacted" />
diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js index 571df0f1..4cbe8093 100644 --- a/src/components/notifications/notifications.js +++ b/src/components/notifications/notifications.js @@ -159,6 +159,26 @@ const Notifications = { updateScrollPosition () { this.showScrollTop = this.$refs.root.offsetTop < this.scrollerRef.scrollTop }, + notificationClicked (notification) { + const { type, id, seen } = notification + if (!seen) { + switch (type) { + case 'mention': + case 'pleroma:report': + case 'follow_request': + break + default: + this.markOneAsSeen(id) + } + } + }, + notificationInteracted (notification) { + const { id, seen } = notification + if (!seen) this.markOneAsSeen(id) + }, + markOneAsSeen (id) { + this.$store.dispatch('markSingleNotificationAsSeen', { id }) + }, markAsSeen () { this.$store.dispatch('markNotificationsAsSeen') this.seenToDisplayCount = DEFAULT_SEEN_TO_DISPLAY_COUNT diff --git a/src/components/notifications/notifications.vue b/src/components/notifications/notifications.vue index 999f8e9c..27ae23cf 100644 --- a/src/components/notifications/notifications.vue +++ b/src/components/notifications/notifications.vue @@ -67,9 +67,13 @@ role="listitem" class="notification" :class="{unseen: !minimalMode && !notification.seen}" + @click="e => notificationClicked(notification)" >
- +
diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js index 4cbe8093..a1088dff 100644 --- a/src/components/notifications/notifications.js +++ b/src/components/notifications/notifications.js @@ -65,7 +65,7 @@ const Notifications = { return notificationsFromStore(this.$store) }, error () { - return this.$store.state.statuses.notifications.error + return this.$store.state.notifications.error }, unseenNotifications () { return unseenNotificationsFromStore(this.$store) @@ -86,7 +86,7 @@ const Notifications = { return this.unseenNotifications.length + (this.unreadChatCount) + this.unreadAnnouncementCount }, loading () { - return this.$store.state.statuses.notifications.loading + return this.$store.state.notifications.loading }, noHeading () { const { layoutType } = this.$store.state.interface @@ -160,17 +160,7 @@ const Notifications = { this.showScrollTop = this.$refs.root.offsetTop < this.scrollerRef.scrollTop }, notificationClicked (notification) { - const { type, id, seen } = notification - if (!seen) { - switch (type) { - case 'mention': - case 'pleroma:report': - case 'follow_request': - break - default: - this.markOneAsSeen(id) - } - } + // const { type, id, seen } = notification }, notificationInteracted (notification) { const { id, seen } = notification diff --git a/src/main.js b/src/main.js index 0b7c7674..85eb1f4c 100644 --- a/src/main.js +++ b/src/main.js @@ -6,6 +6,7 @@ import './lib/event_target_polyfill.js' import interfaceModule from './modules/interface.js' import instanceModule from './modules/instance.js' import statusesModule from './modules/statuses.js' +import notificationsModule from './modules/notifications.js' import listsModule from './modules/lists.js' import usersModule from './modules/users.js' import apiModule from './modules/api.js' @@ -78,6 +79,7 @@ const persistedStateOptions = { // TODO refactor users/statuses modules, they depend on each other users: usersModule, statuses: statusesModule, + notifications: notificationsModule, lists: listsModule, api: apiModule, config: configModule, diff --git a/src/modules/notifications.js b/src/modules/notifications.js new file mode 100644 index 00000000..03f220c7 --- /dev/null +++ b/src/modules/notifications.js @@ -0,0 +1,158 @@ +import apiService from '../services/api/api.service.js' + +import { + isStatusNotification, + isValidNotification, + maybeShowNotification +} from '../services/notification_utils/notification_utils.js' + +import { + closeDesktopNotification, + closeAllDesktopNotifications +} from '../services/desktop_notification_utils/desktop_notification_utils.js' + +const emptyNotifications = () => ({ + desktopNotificationSilence: true, + maxId: 0, + minId: Number.POSITIVE_INFINITY, + data: [], + idStore: {}, + loading: false +}) + +export const defaultState = () => ({ + ...emptyNotifications() +}) + +export const notifications = { + state: defaultState(), + mutations: { + addNewNotifications (state, { notifications }) { + notifications.forEach(notification => { + state.data.push(notification) + state.idStore[notification.id] = notification + }) + }, + clearNotifications (state) { + state = emptyNotifications() + }, + updateNotificationsMinMaxId (state, id) { + state.maxId = id > state.maxId ? id : state.maxId + state.minId = id < state.minId ? id : state.minId + }, + setNotificationsLoading (state, { value }) { + state.loading = value + }, + setNotificationsSilence (state, { value }) { + state.desktopNotificationSilence = value + }, + markNotificationsAsSeen (state) { + state.data.forEach((notification) => { + notification.seen = true + }) + }, + markSingleNotificationAsSeen (state, { id }) { + const notification = find(state.data, n => n.id === id) + if (notification) notification.seen = true + }, + dismissNotification (state, { id }) { + state.data = state.data.filter(n => n.id !== id) + }, + dismissNotifications (state, { finder }) { + state.data = state.data.filter(n => finder) + }, + updateNotification (state, { id, updater }) { + const notification = find(state.data, n => n.id === id) + notification && updater(notification) + } + }, + actions: { + addNewNotifications (store, { notifications, older }) { + const { commit, dispatch, state, rootState } = store + const validNotifications = notifications.filter((notification) => { + // If invalid notification, update ids but don't add it to store + if (!isValidNotification(notification)) { + console.error('Invalid notification:', notification) + commit('updateNotificationsMinMaxId', notification.id) + return false + } + return true + }) + + const statusNotifications = validNotifications.filter(notification => isStatusNotification(notification.type) && notification.status) + + // Synchronous commit to add all the statuses + commit('addNewStatuses', { statuses: statusNotifications.map(notification => notification.status) }) + + // Update references to statuses in notifications to ones in the store + statusNotifications.forEach(notification => { + const id = notification.status.id + const referenceStatus = rootState.statuses.allStatusesObject[id] + console.log() + + if (referenceStatus) { + notification.status = referenceStatus + } + }) + + validNotifications.forEach(notification => { + if (notification.type === 'pleroma:report') { + dispatch('addReport', notification.report) + } + + if (notification.type === 'pleroma:emoji_reaction') { + dispatch('fetchEmojiReactionsBy', notification.status.id) + } + + // Only add a new notification if we don't have one for the same action + // eslint-disable-next-line no-prototype-builtins + if (!state.idStore.hasOwnProperty(notification.id)) { + commit('updateNotificationsMinMaxId', notification.id) + + maybeShowNotification(store, notification) + } else if (notification.seen) { + state.idStore[notification.id].seen = true + } + }) + + commit('addNewNotifications', { notifications }) + }, + setNotificationsLoading ({ rootState, commit }, { value }) { + commit('setNotificationsLoading', { value }) + }, + setNotificationsSilence ({ rootState, commit }, { value }) { + commit('setNotificationsSilence', { value }) + }, + markNotificationsAsSeen ({ rootState, state, commit }) { + commit('markNotificationsAsSeen') + apiService.markNotificationsAsSeen({ + id: state.maxId, + credentials: rootState.users.currentUser.credentials + }).then(() => { + closeAllDesktopNotifications(rootState) + }) + }, + markSingleNotificationAsSeen ({ rootState, commit }, { id }) { + commit('markSingleNotificationAsSeen', { id }) + apiService.markNotificationsAsSeen({ + single: true, + id, + credentials: rootState.users.currentUser.credentials + }).then(() => { + closeDesktopNotification(rootState, id) + }) + }, + dismissNotificationLocal ({ rootState, commit }, { id }) { + commit('dismissNotification', { id }) + }, + dismissNotification ({ rootState, commit }, { id }) { + commit('dismissNotification', { id }) + rootState.api.backendInteractor.dismissNotification({ id }) + }, + updateNotification ({ rootState, commit }, { id, updater }) { + commit('updateNotification', { id, updater }) + } + } +} + +export default notifications diff --git a/src/modules/statuses.js b/src/modules/statuses.js index 6e331d16..d6f19589 100644 --- a/src/modules/statuses.js +++ b/src/modules/statuses.js @@ -12,15 +12,6 @@ import { isArray, omitBy } from 'lodash' -import { - isStatusNotification, - isValidNotification, - maybeShowNotification -} from '../services/notification_utils/notification_utils.js' -import { - closeDesktopNotification, - closeAllDesktopNotifications -} from '../services/desktop_notification_utils/desktop_notification_utils.js' import apiService from '../services/api/api.service.js' const emptyTl = (userId = 0) => ({ @@ -40,22 +31,12 @@ const emptyTl = (userId = 0) => ({ flushMarker: 0 }) -const emptyNotifications = () => ({ - desktopNotificationSilence: true, - maxId: 0, - minId: Number.POSITIVE_INFINITY, - data: [], - idStore: {}, - loading: false -}) - export const defaultState = () => ({ allStatuses: [], scrobblesNextFetch: {}, allStatusesObject: {}, conversationsObject: {}, maxId: 0, - notifications: emptyNotifications(), favorites: new Set(), timelines: { mentions: emptyTl(), @@ -164,9 +145,6 @@ const removeStatusFromGlobalStorage = (state, status) => { // TODO: Need to remove from allStatusesObject? - // Remove possible notification - remove(state.notifications.data, ({ action: { id } }) => id === status.id) - // Remove from conversation const conversationId = status.statusnet_conversation_id if (state.conversationsObject[conversationId]) { @@ -342,52 +320,6 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us } } -const updateNotificationsMinMaxId = (state, notification) => { - state.notifications.maxId = notification.id > state.notifications.maxId - ? notification.id - : state.notifications.maxId - state.notifications.minId = notification.id < state.notifications.minId - ? notification.id - : state.notifications.minId -} - -const addNewNotifications = (state, { dispatch, notifications, older, visibleNotificationTypes, rootGetters, newNotificationSideEffects }) => { - each(notifications, (notification) => { - // If invalid notification, update ids but don't add it to store - if (!isValidNotification(notification)) { - console.error('Invalid notification:', notification) - updateNotificationsMinMaxId(state, notification) - return - } - - if (isStatusNotification(notification.type)) { - notification.action = addStatusToGlobalStorage(state, notification.action).item - notification.status = notification.status && addStatusToGlobalStorage(state, notification.status).item - } - - if (notification.type === 'pleroma:report') { - dispatch('addReport', notification.report) - } - - if (notification.type === 'pleroma:emoji_reaction') { - dispatch('fetchEmojiReactionsBy', notification.status.id) - } - - // Only add a new notification if we don't have one for the same action - // eslint-disable-next-line no-prototype-builtins - if (!state.notifications.idStore.hasOwnProperty(notification.id)) { - updateNotificationsMinMaxId(state, notification) - - state.notifications.data.push(notification) - state.notifications.idStore[notification.id] = notification - - newNotificationSideEffects(notification) - } else if (notification.seen) { - state.notifications.idStore[notification.id].seen = true - } - }) -} - const removeStatus = (state, { timeline, userId }) => { const timelineObject = state.timelines[timeline] if (userId) { @@ -400,7 +332,6 @@ const removeStatus = (state, { timeline, userId }) => { export const mutations = { addNewStatuses, - addNewNotifications, removeStatus, showNewStatuses (state, { timeline }) { const oldTimeline = (state.timelines[timeline]) @@ -422,9 +353,6 @@ export const mutations = { const userId = excludeUserId ? state.timelines[timeline].userId : undefined state.timelines[timeline] = emptyTl(userId) }, - clearNotifications (state) { - state.notifications = emptyNotifications() - }, setFavorited (state, { status, value }) { const newStatus = state.allStatusesObject[status.id] @@ -507,31 +435,6 @@ export const mutations = { const newStatus = state.allStatusesObject[id] newStatus.nsfw = nsfw }, - setNotificationsLoading (state, { value }) { - state.notifications.loading = value - }, - setNotificationsSilence (state, { value }) { - state.notifications.desktopNotificationSilence = value - }, - markNotificationsAsSeen (state) { - each(state.notifications.data, (notification) => { - notification.seen = true - }) - }, - markSingleNotificationAsSeen (state, { id }) { - const notification = find(state.notifications.data, n => n.id === id) - if (notification) notification.seen = true - }, - dismissNotification (state, { id }) { - state.notifications.data = state.notifications.data.filter(n => n.id !== id) - }, - dismissNotifications (state, { finder }) { - state.notifications.data = state.notifications.data.filter(n => finder) - }, - updateNotification (state, { id, updater }) { - const notification = find(state.notifications.data, n => n.id === id) - notification && updater(notification) - }, queueFlush (state, { timeline, id }) { state.timelines[timeline].flushMarker = id }, @@ -615,20 +518,9 @@ const statuses = { actions: { addNewStatuses ({ rootState, commit }, { statuses, showImmediately = false, timeline = false, noIdUpdate = false, userId, pagination }) { commit('addNewStatuses', { statuses, showImmediately, timeline, noIdUpdate, user: rootState.users.currentUser, userId, pagination }) - }, - addNewNotifications (store, { notifications, older }) { - const { commit, dispatch, rootGetters } = store - const newNotificationSideEffects = (notification) => { - maybeShowNotification(store, notification) - } - commit('addNewNotifications', { dispatch, notifications, older, rootGetters, newNotificationSideEffects }) - }, - setNotificationsLoading ({ rootState, commit }, { value }) { - commit('setNotificationsLoading', { value }) - }, - setNotificationsSilence ({ rootState, commit }, { value }) { - commit('setNotificationsSilence', { value }) + const deletions = statuses.filter(status => status.type === 'deletion') + console.log(deletions) }, fetchStatus ({ rootState, dispatch }, id) { return rootState.api.backendInteractor.fetchStatus({ id }) @@ -725,35 +617,6 @@ const statuses = { queueFlushAll ({ rootState, commit }) { commit('queueFlushAll') }, - markNotificationsAsSeen ({ rootState, commit }) { - commit('markNotificationsAsSeen') - apiService.markNotificationsAsSeen({ - id: rootState.statuses.notifications.maxId, - credentials: rootState.users.currentUser.credentials - }).then(() => { - closeAllDesktopNotifications(rootState) - }) - }, - markSingleNotificationAsSeen ({ rootState, commit }, { id }) { - commit('markSingleNotificationAsSeen', { id }) - apiService.markNotificationsAsSeen({ - single: true, - id, - credentials: rootState.users.currentUser.credentials - }).then(() => { - closeDesktopNotification(rootState, id) - }) - }, - dismissNotificationLocal ({ rootState, commit }, { id }) { - commit('dismissNotification', { id }) - }, - dismissNotification ({ rootState, commit }, { id }) { - commit('dismissNotification', { id }) - rootState.api.backendInteractor.dismissNotification({ id }) - }, - updateNotification ({ rootState, commit }, { id, updater }) { - commit('updateNotification', { id, updater }) - }, fetchFavsAndRepeats ({ rootState, commit }, id) { Promise.all([ rootState.api.backendInteractor.fetchFavoritedByUsers({ id }), diff --git a/src/modules/users.js b/src/modules/users.js index 79268bc3..6669d623 100644 --- a/src/modules/users.js +++ b/src/modules/users.js @@ -498,7 +498,7 @@ const users = { store.commit('addNewUsers', users) store.commit('addNewUsers', targetUsers) - const notificationsObject = store.rootState.statuses.notifications.idStore + const notificationsObject = store.rootState.notifications.idStore const relevantNotifications = Object.entries(notificationsObject) .filter(([k, val]) => notificationIds.includes(k)) .map(([k, val]) => val) diff --git a/src/services/desktop_notification_utils/desktop_notification_utils.js b/src/services/desktop_notification_utils/desktop_notification_utils.js index dbca4173..bde9f18c 100644 --- a/src/services/desktop_notification_utils/desktop_notification_utils.js +++ b/src/services/desktop_notification_utils/desktop_notification_utils.js @@ -7,7 +7,7 @@ const state = { failCreateNotif: false } export const showDesktopNotification = (rootState, desktopNotificationOpts) => { if (!('Notification' in window && window.Notification.permission === 'granted')) return - if (rootState.statuses.notifications.desktopNotificationSilence) { return } + if (rootState.notifications.desktopNotificationSilence) { return } if (isSWSupported()) { swDesktopNotification(desktopNotificationOpts) diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js index 610ba1ab..85da5223 100644 --- a/src/services/entity_normalizer/entity_normalizer.service.js +++ b/src/services/entity_normalizer/entity_normalizer.service.js @@ -439,7 +439,6 @@ export const parseNotification = (data) => { output.type = mastoDict[data.type] || data.type output.seen = data.pleroma.is_seen output.status = isStatusNotification(output.type) ? parseStatus(data.status) : null - output.action = output.status // TODO: Refactor, this is unneeded output.target = output.type !== 'move' ? null : parseUser(data.target) diff --git a/src/services/notification_utils/notification_utils.js b/src/services/notification_utils/notification_utils.js index 01cbd5f1..2c25000e 100644 --- a/src/services/notification_utils/notification_utils.js +++ b/src/services/notification_utils/notification_utils.js @@ -6,7 +6,7 @@ import FaviconService from 'src/services/favicon_service/favicon_service.js' let cachedBadgeUrl = null -export const notificationsFromStore = store => store.state.statuses.notifications.data +export const notificationsFromStore = store => store.state.notifications.data export const visibleTypes = store => { const rootState = store.rootState || store.state diff --git a/src/services/notifications_fetcher/notifications_fetcher.service.js b/src/services/notifications_fetcher/notifications_fetcher.service.js index 6c247210..3c280b74 100644 --- a/src/services/notifications_fetcher/notifications_fetcher.service.js +++ b/src/services/notifications_fetcher/notifications_fetcher.service.js @@ -21,7 +21,7 @@ const fetchAndUpdate = ({ store, credentials, older = false, since }) => { const args = { credentials } const { getters } = store const rootState = store.rootState || store.state - const timelineData = rootState.statuses.notifications + const timelineData = rootState.notifications const hideMutedPosts = getters.mergedConfig.hideMutedPosts args.includeTypes = mastoApiNotificationTypes -- cgit v1.2.3-70-g09d2 From a17defc5abfe60b6aa0dc3275dac2cbec507472a Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Thu, 16 Nov 2023 20:41:41 +0200 Subject: handle desktop notifications clicks --- src/boot/after_store.js | 2 +- src/components/notifications/notifications.js | 12 +++++++----- src/modules/notifications.js | 15 +++++++++++++++ src/services/sw/sw.js | 10 ++++++++-- 4 files changed, 31 insertions(+), 8 deletions(-) (limited to 'src/services') diff --git a/src/boot/after_store.js b/src/boot/after_store.js index 6489ef87..84fea954 100644 --- a/src/boot/after_store.js +++ b/src/boot/after_store.js @@ -345,7 +345,7 @@ const afterStoreSetup = async ({ store, i18n }) => { store.dispatch('setLayoutHeight', windowHeight()) FaviconService.initFaviconService() - initServiceWorker() + initServiceWorker(store) window.addEventListener('focus', () => updateFocus()) diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js index a1088dff..a210e19d 100644 --- a/src/components/notifications/notifications.js +++ b/src/components/notifications/notifications.js @@ -159,14 +159,16 @@ const Notifications = { updateScrollPosition () { this.showScrollTop = this.$refs.root.offsetTop < this.scrollerRef.scrollTop }, + /* "Interacted" really refers to "actionable" notifications that require user input, + * everything else (likes/repeats/reacts) cannot be acted and therefore we just clear + * the "seen" status upon any clicks on them + */ notificationClicked (notification) { - // const { type, id, seen } = notification + const { id } = notification + this.$store.dispatch('notificationClicked', { id }) }, notificationInteracted (notification) { - const { id, seen } = notification - if (!seen) this.markOneAsSeen(id) - }, - markOneAsSeen (id) { + const { id } = notification this.$store.dispatch('markSingleNotificationAsSeen', { id }) }, markAsSeen () { diff --git a/src/modules/notifications.js b/src/modules/notifications.js index 9b91f291..febff488 100644 --- a/src/modules/notifications.js +++ b/src/modules/notifications.js @@ -113,6 +113,21 @@ export const notifications = { } }) }, + notificationClicked ({ state, commit }, id) { + const notification = state.idStore[id] + const { type, seen } = notification + + if (!seen) { + switch (type) { + case 'mention': + case 'pleroma:report': + case 'follow_request': + break + default: + commit('markSingleNotificationAsSeen', { id }) + } + } + }, setNotificationsLoading ({ rootState, commit }, { value }) { commit('setNotificationsLoading', { value }) }, diff --git a/src/services/sw/sw.js b/src/services/sw/sw.js index d4ae8f4f..e28f9168 100644 --- a/src/services/sw/sw.js +++ b/src/services/sw/sw.js @@ -82,12 +82,18 @@ function sendSubscriptionToBackEnd (subscription, token, notificationVisibility) return responseData }) } -export async function initServiceWorker () { +export async function initServiceWorker (store) { if (!isSWSupported()) return await getOrCreateServiceWorker() navigator.serviceWorker.addEventListener('message', (event) => { + const { dispatch } = store console.log('SW MESSAGE', event) - // TODO actually act upon click (open drawer on mobile, open chat/thread etc) + const { type, ...rest } = event + + switch (type) { + case 'notificationClicked': + dispatch('notificationClicked', { id: rest.id }) + } }) } -- cgit v1.2.3-70-g09d2 From ce17ebd3d00841d72cd9e4541cc73620849ef836 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Thu, 16 Nov 2023 20:45:07 +0200 Subject: use URL for original favicon instead of canvas --- src/services/notification_utils/notification_utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/services') diff --git a/src/services/notification_utils/notification_utils.js b/src/services/notification_utils/notification_utils.js index 2c25000e..675e744e 100644 --- a/src/services/notification_utils/notification_utils.js +++ b/src/services/notification_utils/notification_utils.js @@ -82,7 +82,7 @@ export const unseenNotificationsFromStore = store => export const prepareNotificationObject = (notification, i18n) => { if (cachedBadgeUrl === null) { const favicon = FaviconService.getOriginalFavicons()[0] - cachedBadgeUrl = favicon.favcanvas.toDataURL() + cachedBadgeUrl = favicon.favimg.href } const notifObj = { -- cgit v1.2.3-70-g09d2 From c216340001f1b019b58a075c173b78ff9f4dafa7 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Thu, 16 Nov 2023 22:08:51 +0200 Subject: use dispatch instead of commmit, fix bad copypasta --- src/modules/notifications.js | 8 ++++---- src/services/notification_utils/notification_utils.js | 6 +++++- 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'src/services') diff --git a/src/modules/notifications.js b/src/modules/notifications.js index a3cf76ef..9bd38220 100644 --- a/src/modules/notifications.js +++ b/src/modules/notifications.js @@ -52,7 +52,7 @@ export const notifications = { }) }, markSingleNotificationAsSeen (state, { id }) { - const notification = find(state.data, n => n.id === id) + const notification = state.idStore[id] if (notification) notification.seen = true }, dismissNotification (state, { id }) { @@ -60,7 +60,7 @@ export const notifications = { delete state.idStore[id] }, updateNotification (state, { id, updater }) { - const notification = find(state.data, n => n.id === id) + const notification = state.idStore[id] notification && updater(notification) } }, @@ -113,7 +113,7 @@ export const notifications = { } }) }, - notificationClicked ({ state, commit }, { id }) { + notificationClicked ({ state, dispatch }, { id }) { const notification = state.idStore[id] const { type, seen } = notification @@ -124,7 +124,7 @@ export const notifications = { case 'follow_request': break default: - commit('markSingleNotificationAsSeen', { id }) + dispatch('markSingleNotificationAsSeen', { id }) } } }, diff --git a/src/services/notification_utils/notification_utils.js b/src/services/notification_utils/notification_utils.js index 675e744e..342fe6ef 100644 --- a/src/services/notification_utils/notification_utils.js +++ b/src/services/notification_utils/notification_utils.js @@ -82,7 +82,11 @@ export const unseenNotificationsFromStore = store => export const prepareNotificationObject = (notification, i18n) => { if (cachedBadgeUrl === null) { const favicon = FaviconService.getOriginalFavicons()[0] - cachedBadgeUrl = favicon.favimg.href + if (!favicon) { + cachedBadgeUrl = 'about:blank' + } else { + cachedBadgeUrl = favicon.favimg.href + } } const notifObj = { -- cgit v1.2.3-70-g09d2 From a564fc1a1f91faf2a418fd6affadbd42c98825d8 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Sun, 19 Nov 2023 13:54:26 +0200 Subject: consistentcy and bugfix --- src/modules/notifications.js | 2 +- src/services/desktop_notification_utils/desktop_notification_utils.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/services') diff --git a/src/modules/notifications.js b/src/modules/notifications.js index 9bd38220..c1f5a63e 100644 --- a/src/modules/notifications.js +++ b/src/modules/notifications.js @@ -150,7 +150,7 @@ export const notifications = { id, credentials: rootState.users.currentUser.credentials }).then(() => { - closeDesktopNotification(rootState, id) + closeDesktopNotification(rootState, { id }) }) }, dismissNotificationLocal ({ rootState, commit }, { id }) { diff --git a/src/services/desktop_notification_utils/desktop_notification_utils.js b/src/services/desktop_notification_utils/desktop_notification_utils.js index bde9f18c..80b8c6e0 100644 --- a/src/services/desktop_notification_utils/desktop_notification_utils.js +++ b/src/services/desktop_notification_utils/desktop_notification_utils.js @@ -21,7 +21,7 @@ export const showDesktopNotification = (rootState, desktopNotificationOpts) => { } } -export const closeDesktopNotification = (rootState, id) => { +export const closeDesktopNotification = (rootState, { id }) => { if (!('Notification' in window && window.Notification.permission === 'granted')) return if (isSWSupported()) { @@ -33,6 +33,6 @@ export const closeAllDesktopNotifications = (rootState) => { if (!('Notification' in window && window.Notification.permission === 'granted')) return if (isSWSupported()) { - swCloseDesktopNotification() + swCloseDesktopNotification({}) } } -- cgit v1.2.3-70-g09d2 From 2f90c629b8e765cbc2ab024aa856d9a3e810d8f5 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Sun, 19 Nov 2023 13:57:47 +0200 Subject: fix messages from sw not really being acted upon on mainland --- src/services/sw/sw.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/services') diff --git a/src/services/sw/sw.js b/src/services/sw/sw.js index e28f9168..dd1edf61 100644 --- a/src/services/sw/sw.js +++ b/src/services/sw/sw.js @@ -88,7 +88,7 @@ export async function initServiceWorker (store) { navigator.serviceWorker.addEventListener('message', (event) => { const { dispatch } = store console.log('SW MESSAGE', event) - const { type, ...rest } = event + const { type, ...rest } = event.data switch (type) { case 'notificationClicked': -- cgit v1.2.3-70-g09d2 From 072a06fc89844a5ed2f557634b7e04c1ef63041d Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Sun, 19 Nov 2023 16:40:30 +0200 Subject: reports visibility setting + actual filtering for desktop notifs --- .../settings_modal/tabs/notifications_tab.vue | 15 +++++++ src/i18n/en.json | 1 + .../notification_utils/notification_utils.js | 1 + src/sw.js | 51 ++++++++++++++++++---- 4 files changed, 59 insertions(+), 9 deletions(-) (limited to 'src/services') diff --git a/src/components/settings_modal/tabs/notifications_tab.vue b/src/components/settings_modal/tabs/notifications_tab.vue index ffaa5723..a6f0cba2 100644 --- a/src/components/settings_modal/tabs/notifications_tab.vue +++ b/src/components/settings_modal/tabs/notifications_tab.vue @@ -114,6 +114,21 @@ +
  • +

    {{ $t('settings.notification_visibility_follow_requests') }}

    +
      +
    • + + {{ $t('settings.notification_visibility_in_column') }} + +
    • +
    • + + {{ $t('settings.notification_visibility_native_notifications') }} + +
    • +
    +
  • {{ $t('settings.notification_visibility_moves') }}

      diff --git a/src/i18n/en.json b/src/i18n/en.json index 658e3b8e..40da7155 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -564,6 +564,7 @@ "notification_visibility_in_column": "Show in notifications column/drawer", "notification_visibility_native_notifications": "Show a native notification", "notification_visibility_follows": "Follows", + "notification_visibility_follow_requests": "Follow requests", "notification_visibility_likes": "Favorites", "notification_visibility_mentions": "Mentions", "notification_visibility_repeats": "Repeats", diff --git a/src/services/notification_utils/notification_utils.js b/src/services/notification_utils/notification_utils.js index 342fe6ef..cc7e6817 100644 --- a/src/services/notification_utils/notification_utils.js +++ b/src/services/notification_utils/notification_utils.js @@ -91,6 +91,7 @@ export const prepareNotificationObject = (notification, i18n) => { const notifObj = { tag: notification.id, + type: notification.type, badge: cachedBadgeUrl } const status = notification.status diff --git a/src/sw.js b/src/sw.js index f5fccc6a..469291b9 100644 --- a/src/sw.js +++ b/src/sw.js @@ -15,7 +15,8 @@ const i18n = createI18n({ const state = { lastFocused: null, - notificationIds: new Set() + notificationIds: new Set(), + allowedNotificationTypes: null } function getWindowClients () { @@ -23,15 +24,43 @@ function getWindowClients () { .then((clientList) => clientList.filter(({ type }) => type === 'window')) } -const setLocale = async () => { - const state = await localForage.getItem('vuex-lz') - const locale = state.config.interfaceLanguage || 'en' +const setSettings = async () => { + const vuexState = await localForage.getItem('vuex-lz') + const locale = vuexState.config.interfaceLanguage || 'en' i18n.locale = locale + const notificationsNativeArray = Object.entries(vuexState.config.notificationNative) + + state.allowedNotificationTypes = new Set( + notificationsNativeArray + .filter(([k, v]) => v) + .map(([k]) => { + switch (k) { + case 'mentions': + return 'mention' + case 'likes': + return 'like' + case 'repeats': + return 'repeat' + case 'emojiReactions': + return 'pleroma:emoji_reaction' + case 'reports': + return 'pleroma:report' + case 'followRequest': + return 'follow_request' + case 'follows': + return 'follow' + case 'polls': + return 'poll' + default: + return k + } + }) + ) } const showPushNotification = async (event) => { const activeClients = await getWindowClients() - await setLocale() + await setSettings() // Only show push notifications if all tabs/windows are closed if (activeClients.length === 0) { const data = event.data.json() @@ -43,27 +72,31 @@ const showPushNotification = async (event) => { const res = prepareNotificationObject(parsedNotification, i18n) - self.registration.showNotification(res.title, res) + if (state.allowedNotificationTypes.has(parsedNotification.type)) { + self.registration.showNotification(res.title, res) + } } } self.addEventListener('push', async (event) => { - console.log(event) if (event.data) { event.waitUntil(showPushNotification(event)) } }) self.addEventListener('message', async (event) => { + await setSettings() const { type, content } = event.data if (type === 'desktopNotification') { const { title, ...rest } = content - const { tag } = rest + const { tag, type } = rest if (state.notificationIds.has(tag)) return state.notificationIds.add(tag) setTimeout(() => state.notificationIds.delete(tag), 10000) - self.registration.showNotification(title, rest) + if (state.allowedNotificationTypes.has(type)) { + self.registration.showNotification(title, rest) + } } if (type === 'desktopNotificationClose') { -- cgit v1.2.3-70-g09d2 From 38b6f0a013ec09b4c54bfe830a92bde46290bda1 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Mon, 20 Nov 2023 00:14:56 +0200 Subject: fix notification dot in favicon and mobile nav, minor refactor --- src/components/notifications/notifications.js | 10 +++------- src/services/notification_utils/notification_utils.js | 18 +++++++++++++----- 2 files changed, 16 insertions(+), 12 deletions(-) (limited to 'src/services') diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js index 00d3a511..a9fa8455 100644 --- a/src/components/notifications/notifications.js +++ b/src/components/notifications/notifications.js @@ -8,7 +8,8 @@ import { notificationsFromStore, filteredNotificationsFromStore, unseenNotificationsFromStore, - countExtraNotifications + countExtraNotifications, + ACTIONABLE_NOTIFICATION_TYPES } from '../../services/notification_utils/notification_utils.js' import FaviconService from '../../services/favicon_service/favicon_service.js' import { library } from '@fortawesome/fontawesome-svg-core' @@ -21,7 +22,6 @@ library.add( ) const DEFAULT_SEEN_TO_DISPLAY_COUNT = 30 -const ACTIONABLE_NOTIFICATION_TYPES = new Set(['mention', 'pleroma:report', 'follow_request']) const Notifications = { components: { @@ -85,11 +85,7 @@ const Notifications = { return `${this.unseenCount ? this.unseenCount : ''}${this.extraNotificationsCount ? '*' : ''}` }, unseenCount () { - if (this.ignoreInactionableSeen) { - return this.unseenNotifications.filter(n => ACTIONABLE_NOTIFICATION_TYPES.has(n.type)).length - } else { - return this.unseenNotifications.length - } + return this.unseenNotifications.length }, ignoreInactionableSeen () { return this.$store.getters.mergedConfig.ignoreInactionableSeen }, extraNotificationsCount () { diff --git a/src/services/notification_utils/notification_utils.js b/src/services/notification_utils/notification_utils.js index cc7e6817..f19cd565 100644 --- a/src/services/notification_utils/notification_utils.js +++ b/src/services/notification_utils/notification_utils.js @@ -1,9 +1,10 @@ -import { filter, includes } from 'lodash' import { muteWordHits } from '../status_parser/status_parser.js' import { showDesktopNotification } from '../desktop_notification_utils/desktop_notification_utils.js' import FaviconService from 'src/services/favicon_service/favicon_service.js' +export const ACTIONABLE_NOTIFICATION_TYPES = new Set(['mention', 'pleroma:report', 'follow_request']) + let cachedBadgeUrl = null export const notificationsFromStore = store => store.state.notifications.data @@ -24,9 +25,9 @@ export const visibleTypes = store => { ].filter(_ => _)) } -const statusNotifications = ['like', 'mention', 'repeat', 'pleroma:emoji_reaction', 'poll'] +const statusNotifications = new Set(['like', 'mention', 'repeat', 'pleroma:emoji_reaction', 'poll']) -export const isStatusNotification = (type) => includes(statusNotifications, type) +export const isStatusNotification = (type) => statusNotifications.has(type) export const isValidNotification = (notification) => { if (isStatusNotification(notification.type) && !notification.status) { @@ -76,8 +77,15 @@ export const filteredNotificationsFromStore = (store, types) => { ) } -export const unseenNotificationsFromStore = store => - filter(filteredNotificationsFromStore(store), ({ seen }) => !seen) +export const unseenNotificationsFromStore = store => { + const ignoreInactionableSeen = store.getters.mergedConfig.ignoreInactionableSeen + + return filteredNotificationsFromStore(store).filter(({ seen, type }) => { + if (!ignoreInactionableSeen) return !seen + if (seen) return false + return ACTIONABLE_NOTIFICATION_TYPES.has(type) + }) +} export const prepareNotificationObject = (notification, i18n) => { if (cachedBadgeUrl === null) { -- cgit v1.2.3-70-g09d2 From 1931e7c3ba49a68586a31661f34da4cfc722ddf4 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Mon, 20 Nov 2023 00:17:09 +0200 Subject: temp console log for mobile debug --- src/services/notification_utils/notification_utils.js | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/services') diff --git a/src/services/notification_utils/notification_utils.js b/src/services/notification_utils/notification_utils.js index f19cd565..cf2a26aa 100644 --- a/src/services/notification_utils/notification_utils.js +++ b/src/services/notification_utils/notification_utils.js @@ -90,10 +90,12 @@ export const unseenNotificationsFromStore = store => { export const prepareNotificationObject = (notification, i18n) => { if (cachedBadgeUrl === null) { const favicon = FaviconService.getOriginalFavicons()[0] + console.log('TEST FAVICON', favicon) if (!favicon) { cachedBadgeUrl = 'about:blank' } else { cachedBadgeUrl = favicon.favimg.href + console.log('TEST FAVICON', cachedBadgeUrl) } } -- cgit v1.2.3-70-g09d2 From 37e3a23f2a25120e13aa4f1ff65e444060d24abb Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Mon, 20 Nov 2023 00:19:51 +0200 Subject: fix badge --- src/services/notification_utils/notification_utils.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/services') diff --git a/src/services/notification_utils/notification_utils.js b/src/services/notification_utils/notification_utils.js index cf2a26aa..959d28db 100644 --- a/src/services/notification_utils/notification_utils.js +++ b/src/services/notification_utils/notification_utils.js @@ -90,12 +90,10 @@ export const unseenNotificationsFromStore = store => { export const prepareNotificationObject = (notification, i18n) => { if (cachedBadgeUrl === null) { const favicon = FaviconService.getOriginalFavicons()[0] - console.log('TEST FAVICON', favicon) if (!favicon) { cachedBadgeUrl = 'about:blank' } else { - cachedBadgeUrl = favicon.favimg.href - console.log('TEST FAVICON', cachedBadgeUrl) + cachedBadgeUrl = favicon.favimg.src } } -- cgit v1.2.3-70-g09d2 From e36548579fb179d0431591529158a65f85e5b134 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Tue, 21 Nov 2023 15:26:31 +0200 Subject: fix notifications not catching up with "read" status as intended --- changelog.d/unreads-sync.fix | 1 + src/services/api/api.service.js | 4 ++++ .../notifications_fetcher/notifications_fetcher.service.js | 8 +++++--- 3 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 changelog.d/unreads-sync.fix (limited to 'src/services') diff --git a/changelog.d/unreads-sync.fix b/changelog.d/unreads-sync.fix new file mode 100644 index 00000000..1eac3364 --- /dev/null +++ b/changelog.d/unreads-sync.fix @@ -0,0 +1 @@ +unread notifications should now properly catch up (eventually) in polling mode diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index f45e3958..bde2e163 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -671,6 +671,7 @@ const fetchTimeline = ({ timeline, credentials, since = false, + minId = false, until = false, userId = false, listId = false, @@ -705,6 +706,9 @@ const fetchTimeline = ({ url = url(listId) } + if (minId) { + params.push(['min_id', minId]) + } if (since) { params.push(['since_id', since]) } diff --git a/src/services/notifications_fetcher/notifications_fetcher.service.js b/src/services/notifications_fetcher/notifications_fetcher.service.js index 3c280b74..21540845 100644 --- a/src/services/notifications_fetcher/notifications_fetcher.service.js +++ b/src/services/notifications_fetcher/notifications_fetcher.service.js @@ -49,9 +49,11 @@ const fetchAndUpdate = ({ store, credentials, older = false, since }) => { // The normal maxId-check does not tell if older notifications have changed const notifications = timelineData.data const readNotifsIds = notifications.filter(n => n.seen).map(n => n.id) - const numUnseenNotifs = notifications.length - readNotifsIds.length - if (numUnseenNotifs > 0 && readNotifsIds.length > 0) { - args.since = Math.max(...readNotifsIds) + const unreadNotifsIds = notifications.filter(n => !n.seen).map(n => n.id) + if (readNotifsIds.length > 0 && readNotifsIds.length > 0) { + const minId = Math.min(...unreadNotifsIds) // Oldest known unread notification + args.since = false // Don't use since_id since it sorta conflicts with min_id + args.minId = minId - 1 // go beyond fetchNotifications({ store, args, older }) } -- cgit v1.2.3-70-g09d2 From 92685e37b61d27cfd964c000f45331535d97de39 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Tue, 21 Nov 2023 15:29:49 +0200 Subject: fix infinity case --- .../notifications_fetcher/notifications_fetcher.service.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/services') diff --git a/src/services/notifications_fetcher/notifications_fetcher.service.js b/src/services/notifications_fetcher/notifications_fetcher.service.js index 21540845..c91a86c8 100644 --- a/src/services/notifications_fetcher/notifications_fetcher.service.js +++ b/src/services/notifications_fetcher/notifications_fetcher.service.js @@ -52,9 +52,11 @@ const fetchAndUpdate = ({ store, credentials, older = false, since }) => { const unreadNotifsIds = notifications.filter(n => !n.seen).map(n => n.id) if (readNotifsIds.length > 0 && readNotifsIds.length > 0) { const minId = Math.min(...unreadNotifsIds) // Oldest known unread notification - args.since = false // Don't use since_id since it sorta conflicts with min_id - args.minId = minId - 1 // go beyond - fetchNotifications({ store, args, older }) + if (minId !== Infinity) { + args.since = false // Don't use since_id since it sorta conflicts with min_id + args.minId = minId - 1 // go beyond + fetchNotifications({ store, args, older }) + } } return result -- cgit v1.2.3-70-g09d2 From 33564d8ccc859a87580c27c832e9b2fd69361c84 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Wed, 22 Nov 2023 13:17:55 +0200 Subject: handle no sw registration gracefully --- src/services/sw/sw.js | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/services') diff --git a/src/services/sw/sw.js b/src/services/sw/sw.js index dd1edf61..247eaf94 100644 --- a/src/services/sw/sw.js +++ b/src/services/sw/sw.js @@ -99,11 +99,13 @@ export async function initServiceWorker (store) { export async function showDesktopNotification (content) { const { active: sw } = await window.navigator.serviceWorker.getRegistration() + if (!sw) return console.error('No serviceworker found!') sw.postMessage({ type: 'desktopNotification', content }) } export async function closeDesktopNotification ({ id }) { const { active: sw } = await window.navigator.serviceWorker.getRegistration() + if (!sw) return console.error('No serviceworker found!') if (id >= 0) { sw.postMessage({ type: 'desktopNotificationClose', content: { id } }) } else { @@ -113,6 +115,7 @@ export async function closeDesktopNotification ({ id }) { export async function updateFocus () { const { active: sw } = await window.navigator.serviceWorker.getRegistration() + if (!sw) return console.error('No serviceworker found!') sw.postMessage({ type: 'updateFocus' }) } -- cgit v1.2.3-70-g09d2 From a5f09b726307367c31c0efdf365eb9b02a852eb5 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Wed, 22 Nov 2023 21:38:54 +0200 Subject: don't communicate with serviceworker if there's no support for it --- src/services/sw/sw.js | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/services') diff --git a/src/services/sw/sw.js b/src/services/sw/sw.js index 247eaf94..4516c813 100644 --- a/src/services/sw/sw.js +++ b/src/services/sw/sw.js @@ -98,12 +98,14 @@ export async function initServiceWorker (store) { } export async function showDesktopNotification (content) { + if (!isSWSupported) return const { active: sw } = await window.navigator.serviceWorker.getRegistration() if (!sw) return console.error('No serviceworker found!') sw.postMessage({ type: 'desktopNotification', content }) } export async function closeDesktopNotification ({ id }) { + if (!isSWSupported) return const { active: sw } = await window.navigator.serviceWorker.getRegistration() if (!sw) return console.error('No serviceworker found!') if (id >= 0) { @@ -114,6 +116,7 @@ export async function closeDesktopNotification ({ id }) { } export async function updateFocus () { + if (!isSWSupported) return const { active: sw } = await window.navigator.serviceWorker.getRegistration() if (!sw) return console.error('No serviceworker found!') sw.postMessage({ type: 'updateFocus' }) -- cgit v1.2.3-70-g09d2 From c25170d7d9cb35d7209a63628905136e5fcab80a Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Wed, 22 Nov 2023 21:56:48 +0200 Subject: fix tests and make utils consistent in where they pull configuration from --- .../notification_utils/notification_utils.js | 41 +++++++++++++--------- .../notification_utils/notification_utils.spec.js | 12 ++++--- 2 files changed, 32 insertions(+), 21 deletions(-) (limited to 'src/services') diff --git a/src/services/notification_utils/notification_utils.js b/src/services/notification_utils/notification_utils.js index 959d28db..5ec98d9f 100644 --- a/src/services/notification_utils/notification_utils.js +++ b/src/services/notification_utils/notification_utils.js @@ -10,18 +10,21 @@ let cachedBadgeUrl = null export const notificationsFromStore = store => store.state.notifications.data export const visibleTypes = store => { - const rootState = store.rootState || store.state + // When called from within a module we need rootGetters to access wider scope + // however when called from a component (i.e. this.$store) we already have wider scope + const rootGetters = store.rootGetters || store.getters + const { notificationVisibility } = rootGetters.mergedConfig return ([ - rootState.config.notificationVisibility.likes && 'like', - rootState.config.notificationVisibility.mentions && 'mention', - rootState.config.notificationVisibility.repeats && 'repeat', - rootState.config.notificationVisibility.follows && 'follow', - rootState.config.notificationVisibility.followRequest && 'follow_request', - rootState.config.notificationVisibility.moves && 'move', - rootState.config.notificationVisibility.emojiReactions && 'pleroma:emoji_reaction', - rootState.config.notificationVisibility.reports && 'pleroma:report', - rootState.config.notificationVisibility.polls && 'poll' + notificationVisibility.likes && 'like', + notificationVisibility.mentions && 'mention', + notificationVisibility.repeats && 'repeat', + notificationVisibility.follows && 'follow', + notificationVisibility.followRequest && 'follow_request', + notificationVisibility.moves && 'move', + notificationVisibility.emojiReactions && 'pleroma:emoji_reaction', + notificationVisibility.reports && 'pleroma:report', + notificationVisibility.polls && 'poll' ].filter(_ => _)) } @@ -54,17 +57,19 @@ const sortById = (a, b) => { const isMutedNotification = (store, notification) => { if (!notification.status) return - return notification.status.muted || muteWordHits(notification.status, store.rootGetters.mergedConfig.muteWords).length > 0 + const rootGetters = store.rootGetters || store.getters + return notification.status.muted || muteWordHits(notification.status, rootGetters.mergedConfig.muteWords).length > 0 } export const maybeShowNotification = (store, notification) => { const rootState = store.rootState || store.state + const rootGetters = store.rootGetters || store.getters if (notification.seen) return if (!visibleTypes(store).includes(notification.type)) return if (notification.type === 'mention' && isMutedNotification(store, notification)) return - const notificationObject = prepareNotificationObject(notification, store.rootGetters.i18n) + const notificationObject = prepareNotificationObject(notification, rootGetters.i18n) showDesktopNotification(rootState, notificationObject) } @@ -78,7 +83,8 @@ export const filteredNotificationsFromStore = (store, types) => { } export const unseenNotificationsFromStore = store => { - const ignoreInactionableSeen = store.getters.mergedConfig.ignoreInactionableSeen + const rootGetters = store.rootGetters || store.getters + const ignoreInactionableSeen = rootGetters.mergedConfig.ignoreInactionableSeen return filteredNotificationsFromStore(store).filter(({ seen, type }) => { if (!ignoreInactionableSeen) return !seen @@ -149,15 +155,16 @@ export const prepareNotificationObject = (notification, i18n) => { } export const countExtraNotifications = (store) => { - const mergedConfig = store.getters.mergedConfig + const rootGetters = store.rootGetters || store.getters + const mergedConfig = rootGetters.mergedConfig if (!mergedConfig.showExtraNotifications) { return 0 } return [ - mergedConfig.showChatsInExtraNotifications ? store.getters.unreadChatCount : 0, - mergedConfig.showAnnouncementsInExtraNotifications ? store.getters.unreadAnnouncementCount : 0, - mergedConfig.showFollowRequestsInExtraNotifications ? store.getters.followRequestCount : 0 + mergedConfig.showChatsInExtraNotifications ? rootGetters.unreadChatCount : 0, + mergedConfig.showAnnouncementsInExtraNotifications ? rootGetters.unreadAnnouncementCount : 0, + mergedConfig.showFollowRequestsInExtraNotifications ? rootGetters.followRequestCount : 0 ].reduce((a, c) => a + c, 0) } diff --git a/test/unit/specs/services/notification_utils/notification_utils.spec.js b/test/unit/specs/services/notification_utils/notification_utils.spec.js index ba7f7d75..60db7380 100644 --- a/test/unit/specs/services/notification_utils/notification_utils.spec.js +++ b/test/unit/specs/services/notification_utils/notification_utils.spec.js @@ -23,8 +23,10 @@ describe('NotificationUtils', () => { type: 'repeat' } ] - }, - config: { + } + }, + getters: { + mergedConfig: { notificationVisibility: { likes: true, repeats: true, @@ -66,8 +68,10 @@ describe('NotificationUtils', () => { seen: true } ] - }, - config: { + } + }, + getters: { + mergedConfig: { notificationVisibility: { likes: true, repeats: true, -- cgit v1.2.3-70-g09d2 From 51f1f05b2d17ac1b1471d84481683909c61c373e Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Wed, 22 Nov 2023 22:06:56 +0200 Subject: use last favicon instead of first for consistency with browsers --- src/services/notification_utils/notification_utils.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/services') diff --git a/src/services/notification_utils/notification_utils.js b/src/services/notification_utils/notification_utils.js index 5ec98d9f..7b705e65 100644 --- a/src/services/notification_utils/notification_utils.js +++ b/src/services/notification_utils/notification_utils.js @@ -95,7 +95,8 @@ export const unseenNotificationsFromStore = store => { export const prepareNotificationObject = (notification, i18n) => { if (cachedBadgeUrl === null) { - const favicon = FaviconService.getOriginalFavicons()[0] + const favicons = FaviconService.getOriginalFavicons() + const favicon = favicons[favicons.length - 1] if (!favicon) { cachedBadgeUrl = 'about:blank' } else { -- cgit v1.2.3-70-g09d2 From 99d04bed2bf96cade48c99bae8fcf154bd769998 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Wed, 13 Dec 2023 22:04:00 +0200 Subject: attempt at fixing the extra notification again --- src/services/sw/sw.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/services') diff --git a/src/services/sw/sw.js b/src/services/sw/sw.js index 4516c813..98dc7294 100644 --- a/src/services/sw/sw.js +++ b/src/services/sw/sw.js @@ -28,7 +28,7 @@ function subscribePush (registration, isEnabled, vapidPublicKey) { if (!vapidPublicKey) return Promise.reject(new Error('VAPID public key is not found')) const subscribeOptions = { - userVisibleOnly: true, + userVisibleOnly: false, applicationServerKey: urlBase64ToUint8Array(vapidPublicKey) } return registration.pushManager.subscribe(subscribeOptions) -- cgit v1.2.3-70-g09d2 From ff10834f1a152041f43e7d611730bc7184c5097a Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Thu, 14 Dec 2023 00:14:06 +0200 Subject: cleanup stray console logs --- src/components/quick_view_settings/quick_view_settings.js | 1 - src/components/report/report.js | 1 - src/components/settings_modal/tabs/theme_tab/theme_tab.js | 1 - src/lib/persisted_state.js | 8 ++++---- src/modules/adminSettings.js | 2 -- src/modules/serverSideStorage.js | 1 - src/modules/users.js | 2 +- src/services/sw/sw.js | 1 - 8 files changed, 5 insertions(+), 12 deletions(-) (limited to 'src/services') diff --git a/src/components/quick_view_settings/quick_view_settings.js b/src/components/quick_view_settings/quick_view_settings.js index 2798f37a..67aa6713 100644 --- a/src/components/quick_view_settings/quick_view_settings.js +++ b/src/components/quick_view_settings/quick_view_settings.js @@ -52,7 +52,6 @@ const QuickViewSettings = { get () { return this.mergedConfig.mentionLinkShowAvatar }, set () { const value = !this.showUserAvatars - console.log(value) this.$store.dispatch('setOption', { name: 'mentionLinkShowAvatar', value }) } }, diff --git a/src/components/report/report.js b/src/components/report/report.js index 5685aa25..f8675c0f 100644 --- a/src/components/report/report.js +++ b/src/components/report/report.js @@ -16,7 +16,6 @@ const Report = { }, computed: { report () { - console.log(this.$store.state.reports.reports[this.reportId] || {}) return this.$store.state.reports.reports[this.reportId] || {} }, state: { diff --git a/src/components/settings_modal/tabs/theme_tab/theme_tab.js b/src/components/settings_modal/tabs/theme_tab/theme_tab.js index 4a739f73..58f8d44a 100644 --- a/src/components/settings_modal/tabs/theme_tab/theme_tab.js +++ b/src/components/settings_modal/tabs/theme_tab/theme_tab.js @@ -755,7 +755,6 @@ export default { selected () { this.selectedTheme = Object.entries(this.availableStyles).find(([k, s]) => { if (Array.isArray(s)) { - console.log(s[0] === this.selected, this.selected) return s[0] === this.selected } else { return s.name === this.selected diff --git a/src/lib/persisted_state.js b/src/lib/persisted_state.js index 6d59c595..22ba1e7f 100644 --- a/src/lib/persisted_state.js +++ b/src/lib/persisted_state.js @@ -38,7 +38,7 @@ export default function createPersistedState ({ }, setState = (key, state, storage) => { if (!loaded) { - console.log('waiting for old state to be loaded...') + console.info('waiting for old state to be loaded...') return Promise.resolve() } else { return storage.setItem(key, state) @@ -65,7 +65,7 @@ export default function createPersistedState ({ } loaded = true } catch (e) { - console.log("Couldn't load state") + console.error("Couldn't load state") console.error(e) loaded = true } @@ -86,8 +86,8 @@ export default function createPersistedState ({ }) } } catch (e) { - console.log("Couldn't persist state:") - console.log(e) + console.error("Couldn't persist state:") + console.error(e) } }) } diff --git a/src/modules/adminSettings.js b/src/modules/adminSettings.js index cad9c0ca..e775eb12 100644 --- a/src/modules/adminSettings.js +++ b/src/modules/adminSettings.js @@ -104,7 +104,6 @@ const adminSettingsStorage = { } set(config, path, convert(c.value)) }) - console.log(config[':pleroma']) commit('updateAdminSettings', { config, modifiedPaths }) commit('resetAdminDraft') }, @@ -122,7 +121,6 @@ const adminSettingsStorage = { const descriptions = {} backendDescriptions.forEach(d => convert(d, '', descriptions)) - console.log(descriptions[':pleroma']['Pleroma.Captcha']) commit('updateAdminDescriptions', { descriptions }) }, diff --git a/src/modules/serverSideStorage.js b/src/modules/serverSideStorage.js index c933ce8d..c55f54fd 100644 --- a/src/modules/serverSideStorage.js +++ b/src/modules/serverSideStorage.js @@ -419,7 +419,6 @@ const serverSideStorage = { actions: { pushServerSideStorage ({ state, rootState, commit }, { force = false } = {}) { const needPush = state.dirty || force - console.log(needPush) if (!needPush) return commit('updateCache', { username: rootState.users.currentUser.fqn }) const params = { pleroma_settings_store: { 'pleroma-fe': state.cache } } diff --git a/src/modules/users.js b/src/modules/users.js index 6669d623..6467d732 100644 --- a/src/modules/users.js +++ b/src/modules/users.js @@ -667,7 +667,7 @@ const users = { resolve() }) .catch((error) => { - console.log(error) + console.error(error) commit('endLogin') reject(new Error('Failed to connect to server, try again')) }) diff --git a/src/services/sw/sw.js b/src/services/sw/sw.js index 98dc7294..554cc7b8 100644 --- a/src/services/sw/sw.js +++ b/src/services/sw/sw.js @@ -87,7 +87,6 @@ export async function initServiceWorker (store) { await getOrCreateServiceWorker() navigator.serviceWorker.addEventListener('message', (event) => { const { dispatch } = store - console.log('SW MESSAGE', event) const { type, ...rest } = event.data switch (type) { -- cgit v1.2.3-70-g09d2