From 3ad766fe1226a9be27cec29833400b452ec924e9 Mon Sep 17 00:00:00 2001 From: 10G Meow <10gmeow@gmail.com> Date: Thu, 7 Dec 2023 20:53:24 +0200 Subject: [PATCH] Profile settings: add global Notification toggle --- src/App.vue | 6 +- src/assets/translations/en.json | 6 +- src/components/ActionRow.vue | 11 +- src/components/Chat.vue | 61 +---------- src/components/ChatHeader.vue | 5 - src/components/Profile.vue | 108 +++++++++++++++++++- src/plugins/notificationAndServiceWorker.js | 6 +- src/store/index.js | 4 + 8 files changed, 128 insertions(+), 79 deletions(-) diff --git a/src/App.vue b/src/App.vue index e174786..fde972f 100644 --- a/src/App.vue +++ b/src/App.vue @@ -33,6 +33,7 @@ import stickers from "./plugins/stickers"; import { registerServiceWorker, notificationCount, windowNotificationPermission } from "./plugins/notificationAndServiceWorker.js" import logoMixin from "./components/logoMixin"; +import { mapState } from 'vuex' export default { name: "App", @@ -175,13 +176,16 @@ export default { } return favicon; }, + ...mapState([ + 'globalNotification' + ]) }, watch: { notificationCount: { handler(nCount) { // windowNotificationPermission // return value: 'granted', 'default', 'denied' - if (nCount > 0 && this.windowNotificationPermission() === "granted") { + if (this.globalNotification && nCount > 0 && this.windowNotificationPermission() === "granted") { this.showNotification() } } diff --git a/src/assets/translations/en.json b/src/assets/translations/en.json index c4398ae..84f83f7 100644 --- a/src/assets/translations/en.json +++ b/src/assets/translations/en.json @@ -218,7 +218,8 @@ "password_new": "New password", "password_repeat": "Repeat new password", "display_name": "Display name", - "display_name_required": "Display name is required" + "display_name_required": "Display name is required", + "notification_label": "Notification" }, "profile_info_popup": { "you_are": "You are", @@ -382,7 +383,8 @@ "body": "Never miss a message or important conversation again! Be notified whenever someone sends you a message or replies to your chat.", "enable": "Enable" }, - "blocked_message": "Notifications blocked. Please reset the permissions" + "blocked_message": "Notification is blocked. Go to your device or browser settings to enable Notification", + "not_supported": "Notification is not yet supported in Mobile" }, "emoji": { "search": "Search...", diff --git a/src/components/ActionRow.vue b/src/components/ActionRow.vue index c175c7d..25e64da 100644 --- a/src/components/ActionRow.vue +++ b/src/components/ActionRow.vue @@ -4,18 +4,16 @@ no-gutters align-content="center" v-on="$listeners" - v-show="icon === 'notifications_active' ? this.windowNotificationPermission() !== 'granted' : true" > - + {{ icon }} - {{ text }} + {{ text }} + diff --git a/src/components/Chat.vue b/src/components/Chat.vue index 857ae52..c9a5fb0 100644 --- a/src/components/Chat.vue +++ b/src/components/Chat.vue @@ -3,12 +3,10 @@ - - -
- notifications_active -

- {{ $t("notification.dialog.title") }} -

-
{{ $t("notification.dialog.body") }}
- - - - {{ $t("global.close") }} - - - {{ $t("notification.dialog.enable") }} - - - -
-
@@ -388,7 +347,6 @@ import chatMixin from "./chatMixin"; import sendAttachmentsMixin from "./sendAttachmentsMixin"; import AudioLayout from "./AudioLayout.vue"; import FileDropLayout from "./file_mode/FileDropLayout"; -import { requestNotificationPermission, windowNotificationPermission } from "../plugins/notificationAndServiceWorker.js" import roomTypeMixin from "./roomTypeMixin"; import roomMembersMixin from "./roomMembersMixin"; @@ -525,7 +483,6 @@ export default { Places: this.$t("emoji.categories.places") } }, - notificationDialog: false }; }, @@ -914,18 +871,6 @@ export default { this.initialLoadDone = true; console.log("Loading finished!"); }, - windowNotificationPermission, - onNotificationDialog() { - if(this.windowNotificationPermission() === 'denied') { - alert(this.$t("notification.blocked_message")); - } else if(this.windowNotificationPermission() === 'default') { - this.notificationDialog = true; - } - }, - onNotifyRequest() { - requestNotificationPermission() - this.notificationDialog = false; - }, onRoomJoined(initialEventId) { // Listen to events this.$matrix.on("Room.timeline", this.onEvent); @@ -1157,7 +1102,7 @@ export default { this.onLayoutChange(fn, element); } else { fn(); - } + } } else { fn(); } diff --git a/src/components/ChatHeader.vue b/src/components/ChatHeader.vue index f54610f..c9b4f8d 100644 --- a/src/components/ChatHeader.vue +++ b/src/components/ChatHeader.vue @@ -177,11 +177,6 @@ export default { this.$emit("view-room-details", { event: this.event }); } }); - items.push({ - icon: 'notifications_active', text: this.$t('global.notify'), handler: () => { - this.$emit("notify"); - } - }); items.push({ icon: '$vuetify.icons.ic_member-leave', text: this.$t('leave.leave'), handler: () => { this.leaveRoom(); diff --git a/src/components/Profile.vue b/src/components/Profile.vue index 88caea1..e5d8dba 100644 --- a/src/components/Profile.vue +++ b/src/components/Profile.vue @@ -89,6 +89,16 @@ :icon="'$vuetify.icons.globe'" :text="$t('profile.select_language')" /> + + + @@ -197,6 +207,45 @@ v-model="showSelectLanguageDialog" v-on:close="showSelectLanguageDialog = false" /> + + +
+ notifications_active +

+ {{ $t("notification.dialog.title") }} +

+
{{ $t("notification.dialog.body") }}
+ + + + {{ $t("global.close") }} + + + {{ $t("notification.dialog.enable") }} + + + +
+
@@ -207,6 +256,8 @@ import util from "../plugins/utils"; import profileInfoMixin from "./profileInfoMixin"; import LogoutRoomDialog from './LogoutRoomDialog.vue'; import CopyLink from "./CopyLink.vue" +import { requestNotificationPermission, windowNotificationPermission } from "../plugins/notificationAndServiceWorker.js" +import { mapState } from 'vuex' export default { name: "Profile", @@ -234,7 +285,8 @@ export default { passwordErrorMessage: null, isAvatarLoaded: true, loadValue: 0, - newPasswordHasError: false + newPasswordHasError: false, + notificationDialog: false }; }, @@ -252,7 +304,13 @@ export default { this.newPassword2 && this.newPassword1 == this.newPassword2 ); - } + }, + notificationIcon() { + return this.globalNotification ? 'notifications_active' : 'notifications_off'; + }, + ...mapState([ + 'globalNotification' + ]) }, methods: { @@ -306,7 +364,53 @@ export default { console.log("Progress: " + JSON.stringify(progress)); }); }, + updateGlobalNotificationStore(flag) { + this.$store.commit('setGlobalNotification', flag); + }, + windowNotificationPermission, + onUpdateGlobalNotification(showAlertOrDialog = true) { + const permission = this.windowNotificationPermission(); + + switch (permission) { + case 'denied': + this.updateGlobalNotificationStore(false); + if (showAlertOrDialog) { + alert(this.$t("notification.blocked_message")); + } + break; + case 'granted': + this.updateGlobalNotificationStore(!this.globalNotification); + break; + case 'default': + if (showAlertOrDialog) { + this.notificationDialog = true; + } + this.updateGlobalNotificationStore(!this.globalNotification); + break; + default: + alert(this.$t("notification.not_supported")); + } + }, + async onNotifyDialog() { + const permission = await requestNotificationPermission() + if(permission === 'denied') { + this.updateGlobalNotificationStore(false); + alert(this.$t("notification.blocked_message")); + } else { + this.updateGlobalNotificationStore(true); + } + this.notificationDialog = false; + }, + onNotifyDialogClosed() { + this.updateGlobalNotificationStore(false); + this.notificationDialog = false; + } }, + mounted() { + if(this.globalNotification && this.windowNotificationPermission() !== 'granted') { + this.onUpdateGlobalNotification(false); + } + } }; diff --git a/src/plugins/notificationAndServiceWorker.js b/src/plugins/notificationAndServiceWorker.js index 117c97d..b97af51 100644 --- a/src/plugins/notificationAndServiceWorker.js +++ b/src/plugins/notificationAndServiceWorker.js @@ -6,16 +6,16 @@ export function registerServiceWorker() { } } -export function requestNotificationPermission() { +export async function requestNotificationPermission() { if("PushManager" in window) { - window.Notification.requestPermission(); + return Notification?.requestPermission().then((permission) => permission); } else { console.log("No Push API Support!"); } } export function windowNotificationPermission() { - return window.Notification.permission + return window?.Notification?.permission ?? 'Not_supported' } export function notificationCount() { diff --git a/src/store/index.js b/src/store/index.js index 9024acc..4da7ecc 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -41,6 +41,7 @@ const vuexPersistLocalStorage = new VuexPersist({ language: state.language, currentRoomId: state.currentRoomId, hasShownMissedItemsHint: state.hasShownMissedItemsHint, + globalNotification: state.globalNotification, }; } else { return {}; @@ -98,6 +99,9 @@ export default new Vuex.Store({ }, setHasShownMissedItemsHint(state, flag) { state.hasShownMissedItemsHint = flag; + }, + setGlobalNotification(state, flag) { + state.globalNotification = flag; } }, actions: {