9696 </div >
9797
9898 <Divider />
99+ <div
100+ v-if =" pushEnabled"
101+ class =" mt-4 w-full text-center"
102+ >
103+ <p
104+ v-if =" loading || isSubscribed === null"
105+ class =" text-gray-500 text-sm"
106+ >
107+ <i class =" mdi mdi-loading mdi-spin mr-2" ></i >
108+ {{ t("Checking push subscription...") }}
109+ </p >
110+
111+ <div v-else >
112+ <template v-if =" isSubscribed " >
113+ <div class =" flex flex-col items-center text-green-700" >
114+ <i class =" mdi mdi-bell-ring-outline text-4xl mb-2" ></i >
115+ <p class =" text-sm font-semibold" >
116+ {{ t("You're subscribed to push notifications in this browser.") }}
117+ </p >
118+ <BaseButton
119+ :label =" t('Unsubscribe')"
120+ class =" mt-2"
121+ icon =" bell-off"
122+ type =" danger"
123+ size =" small"
124+ @click =" handleUnsubscribe"
125+ :loading =" loading"
126+ />
127+ <div
128+ v-if =" showDetails"
129+ class =" mt-2 bg-gray-100 rounded p-2 text-gray-800 text-xs break-all max-w-full"
130+ >
131+ <strong >{{ t("Endpoint") }}:</strong >
132+ <br />
133+ {{ subscriptionInfo?.endpoint }}
134+ </div >
135+ </div >
136+ </template >
137+
138+ <template v-else >
139+ <div class =" flex flex-col items-center text-red-700" >
140+ <i class =" mdi mdi-bell-off-outline text-4xl mb-2" ></i >
141+ <p class =" text-sm" >
142+ {{ t("Push notifications are not enabled in this browser.") }}
143+ </p >
144+ <BaseButton
145+ :label =" t('Enable notifications')"
146+ class =" mt-2"
147+ icon =" bell"
148+ type =" primary"
149+ size =" small"
150+ @click =" handleSubscribe"
151+ :loading =" loading"
152+ />
153+ </div >
154+ </template >
155+ </div >
156+ </div >
157+
99158 <BaseButton
100159 v-if =" isCurrentUser || securityStore.isAdmin"
101160 :label =" t('Edit profile')"
117176</template >
118177
119178<script setup>
120- import { computed , inject , ref , watchEffect } from " vue"
179+ import { computed , inject , onMounted , ref , watchEffect } from " vue"
121180import BaseCard from " ../basecomponents/BaseCard.vue"
122181import BaseButton from " ../basecomponents/BaseButton.vue"
123182import { useI18n } from " vue-i18n"
124183import Divider from " primevue/divider"
125184import axios from " axios"
126185import { useSecurityStore } from " ../../store/securityStore"
127186import BaseUserAvatar from " ../basecomponents/BaseUserAvatar.vue"
187+ import { usePushSubscription } from " ../../composables/usePushSubscription"
128188
129189const { t } = useI18n ()
130190const securityStore = useSecurityStore ()
@@ -138,17 +198,31 @@ const showFullProfile = computed(() => isCurrentUser.value || securityStore.isAd
138198const languageInfo = ref (null )
139199const vCardUserLink = ref (" " )
140200const visibility = ref ({})
141- watchEffect (() => {
142- if (user .value && user .value .id ) {
143- fetchUserProfile (user .value .id )
144- }
145- })
146201
147- const editProfile = () => {
202+ const {
203+ isSubscribed ,
204+ subscriptionInfo ,
205+ subscribe ,
206+ unsubscribe ,
207+ loading ,
208+ checkSubscription ,
209+ loadVapidKey ,
210+ vapidPublicKey ,
211+ pushEnabled ,
212+ registerServiceWorker ,
213+ } = usePushSubscription ()
214+
215+ const showDetails = ref (false )
216+
217+ function toggleDetails () {
218+ showDetails .value = ! showDetails .value
219+ }
220+
221+ function editProfile () {
148222 window .location = " /account/edit"
149223}
150224
151- const changePassword = () => {
225+ function changePassword () {
152226 window .location = " /account/change-password"
153227}
154228
@@ -170,8 +244,33 @@ async function fetchUserProfile(userId) {
170244
171245function flagIconExists (code ) {
172246 const mdiFlagIcons = [" us" , " fr" , " de" , " es" , " it" , " pl" ]
173- return mdiFlagIcons .includes (code .toLowerCase ())
247+ return mdiFlagIcons .includes (code? .toLowerCase ())
174248}
175249
176250function chatWith (userId , completeName , isOnline , avatarSmall ) {}
251+
252+ watchEffect (async () => {
253+ if (user .value && user .value .id ) {
254+ fetchUserProfile (user .value .id )
255+ loadVapidKey ()
256+ await registerServiceWorker ()
257+ await checkSubscription (user .value .id )
258+ }
259+ })
260+
261+ async function handleSubscribe () {
262+ if (user .value ? .id ) {
263+ await subscribe (user .value .id )
264+ } else {
265+ console .error (" [Push] No user id for subscription." )
266+ }
267+ }
268+
269+ async function handleUnsubscribe () {
270+ if (user .value ? .id ) {
271+ await unsubscribe (user .value .id )
272+ } else {
273+ console .error (" [Push] No user id for unsubscription." )
274+ }
275+ }
177276< / script>
0 commit comments