From 7e75f6c8de4a00602164d80c4ddc1cab6de4c4c7 Mon Sep 17 00:00:00 2001 From: Olivier Savignac <1275666+sircharlo@users.noreply.github.com> Date: Wed, 16 Oct 2024 10:24:46 -0400 Subject: [PATCH 01/11] feat: add button to go from co date notification to setting directly --- src/helpers/notifications.ts | 3 ++- src/i18n/en.json | 2 ++ src/pages/CongregationSelectorPage.vue | 15 ++++++++++++- src/pages/SettingsPage.vue | 29 ++++++++++++++++++++++++++ src/router/routes.ts | 2 +- 5 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/helpers/notifications.ts b/src/helpers/notifications.ts index 1465eeaa..7921b1d3 100644 --- a/src/helpers/notifications.ts +++ b/src/helpers/notifications.ts @@ -3,6 +3,7 @@ import { Notify, type QNotifyCreateOptions } from 'quasar'; import { errorCatcher } from './error-catcher'; const createTemporaryNotification = ({ + actions, badgeStyle, caption, color, @@ -35,7 +36,7 @@ const createTemporaryNotification = ({ ...(group && { group }), ...(badgeStyle && { badgeStyle }), ...(!noClose && { - actions: [ + actions: actions || [ { color: 'white', icon: 'close', diff --git a/src/i18n/en.json b/src/i18n/en.json index e090aadd..c21ea2ac 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -125,6 +125,7 @@ "full-screen": "Full screen", "github-repo": "GitHub repo", "go-home": "Go Home", + "go-to-settings": "Go to Settings", "got-it": "Got it", "hide-image-for-zoom-participants": "Hide image for Zoom participants", "hide-media-display": "Hide media display", @@ -261,6 +262,7 @@ "question-mark": "?", "refresh": "Refresh", "regular": "Regular", + "remind-me-later": "Remind me later", "remove-all-cache": "Remove all files from cache", "remove-unused-cache": "Remove unused items from cache", "replace": "Replace", diff --git a/src/pages/CongregationSelectorPage.vue b/src/pages/CongregationSelectorPage.vue index bee43992..7b354d71 100644 --- a/src/pages/CongregationSelectorPage.vue +++ b/src/pages/CongregationSelectorPage.vue @@ -183,6 +183,19 @@ const checkCoDate = () => { date.getDateDiff(new Date(), currentSettings.value?.coWeek, 'months') > 2 ) { createTemporaryNotification({ + actions: [ + { + color: 'white', + label: t('remind-me-later'), + }, + { + color: 'white', + handler: () => { + router.push('/settings/coWeek'); + }, + label: t('go-to-settings'), + }, + ], caption: t('dont-forget-to-add-circuit-overseer-date', { congregationMeetings: t('congregationMeetings'), settings: t('titles.settings'), @@ -191,7 +204,7 @@ const checkCoDate = () => { icon: 'mmm-error', message: t('no-circuit-overseer-date-set'), textColor: 'white', - timeout: 10000, + timeout: 30000, }); } }; diff --git a/src/pages/SettingsPage.vue b/src/pages/SettingsPage.vue index 60e84d21..50c7f4fc 100644 --- a/src/pages/SettingsPage.vue +++ b/src/pages/SettingsPage.vue @@ -66,10 +66,12 @@ !invalidSettingsLength || invalidSettings.includes(settingId as keyof SettingsItems)) " + :id="settingId" :class="{ 'bg-error': invalidSettings.includes( settingId as keyof SettingsItems, ), + 'bg-accent-300': route.params.setting === settingId, 'q-mt-sm': index === 0, 'rounded-borders': true, }" @@ -166,6 +168,9 @@ import { errorCatcher } from 'src/helpers/error-catcher'; import { useCurrentStateStore } from 'src/stores/current-state'; import { useJwStore } from 'src/stores/jw'; import { computed, onMounted, ref, watch } from 'vue'; +import { useRoute } from 'vue-router'; + +const route = useRoute(); // Store initializations const currentState = useCurrentStateStore(); @@ -207,6 +212,30 @@ const validateSettingsLocal = () => { // Lifecycle hooks onMounted(() => { validateSettingsLocal(); + watch( + () => route.params.setting, + (newWatchedSettings) => { + if (!newWatchedSettings) return; + if (!Array.isArray(newWatchedSettings)) + newWatchedSettings = [newWatchedSettings]; + newWatchedSettings.forEach((setting) => { + if (setting) + expansionState.value[ + settingsDefinitions[setting as keyof SettingsItems] + .group as keyof SettingsItems + ] = true; + }); + setTimeout(() => { + if (!newWatchedSettings[0]) return; + document.getElementById(newWatchedSettings[0])?.scrollIntoView({ + behavior: 'smooth', + block: 'start', + inline: 'nearest', + }); + }, 500); + }, + { immediate: true }, + ); }); watch( diff --git a/src/router/routes.ts b/src/router/routes.ts index 394de648..c7680195 100644 --- a/src/router/routes.ts +++ b/src/router/routes.ts @@ -51,7 +51,7 @@ const routes: RouteRecordRaw[] = [ children: [{ component: () => import('pages/SettingsPage.vue'), path: '' }], component: () => import('layouts/MainLayout.vue'), meta: { icon: 'mmm-settings', title: 'titles.settings' }, - path: '/settings', + path: '/settings/:setting?', }, // Always leave this as last one, From f445e6b55e3fb41370574dfafee615c16e07db2d Mon Sep 17 00:00:00 2001 From: Olivier Savignac <1275666+sircharlo@users.noreply.github.com> Date: Wed, 16 Oct 2024 10:32:15 -0400 Subject: [PATCH 02/11] fix: make media tags a bit wider to accommodate the improved paragraph display --- src/css/app.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/css/app.scss b/src/css/app.scss index 9fe8a280..89cdb623 100644 --- a/src/css/app.scss +++ b/src/css/app.scss @@ -485,7 +485,7 @@ a { } .media-tag { - min-width: 70px; + min-width: 80px; border-radius: 6px; } From bd36af4d46b883b8aa59475f06147d25c118505d Mon Sep 17 00:00:00 2001 From: Olivier Savignac <1275666+sircharlo@users.noreply.github.com> Date: Wed, 16 Oct 2024 11:06:00 -0400 Subject: [PATCH 03/11] fix: auto start background music only if meeting is in less than two hours --- src/components/media/MusicButton.vue | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/components/media/MusicButton.vue b/src/components/media/MusicButton.vue index bdfcbff1..1667939f 100644 --- a/src/components/media/MusicButton.vue +++ b/src/components/media/MusicButton.vue @@ -464,10 +464,11 @@ onMounted(() => { try { meetingDay.value = !!newToday && !!newMeeting; if ( - currentSettings.value?.enableMusicButton && - currentSettings.value?.autoStartMusic && - meetingDay.value && - remainingTimeBeforeMeetingStart() > 90 + currentSettings.value?.enableMusicButton && // background music feature is enabled + currentSettings.value?.autoStartMusic && // auto-start music is enabled + meetingDay.value && // today is a meeting day + remainingTimeBeforeMeetingStart() > 90 && // meeting is starting in at least 90 seconds + remainingTimeBeforeMeetingStart() < 60 * 60 * 2 // meeting is starting in less than 2 hours ) { playMusic(); } From 2c9cd83e043fda1832dccd43976c13a9d656e6b4 Mon Sep 17 00:00:00 2001 From: Olivier Savignac <1275666+sircharlo@users.noreply.github.com> Date: Wed, 16 Oct 2024 11:19:05 -0400 Subject: [PATCH 04/11] fix: clean up error code checks; prevent OBS error unless there's an actual error code --- src/boot/axios.ts | 2 +- src/components/media/ObsStatus.vue | 10 +--------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/boot/axios.ts b/src/boot/axios.ts index c1c1a5ab..30f8b279 100644 --- a/src/boot/axios.ts +++ b/src/boot/axios.ts @@ -9,7 +9,7 @@ const get = async (url: string, params?: AxiosRequestConfig) => { returnVal = await axios.get(url, { params }).catch((error) => { if ( !(error instanceof AxiosError) || - (error.status !== 400 && error.status !== 404) + ![400, 404].includes(error.status ?? 0) ) errorCatcher(error); return { data: undefined }; diff --git a/src/components/media/ObsStatus.vue b/src/components/media/ObsStatus.vue index e2551402..0bf1a088 100644 --- a/src/components/media/ObsStatus.vue +++ b/src/components/media/ObsStatus.vue @@ -158,16 +158,8 @@ const obsCloseHandler = () => { const obsErrorHandler = (err: OBSWebSocketError) => { obsMessage.value = 'obs.error'; - if ( - !( - err?.code === -1 || - err?.code === 1001 || - err?.code === 1006 || - err?.code === 4009 - ) - ) { + if (err?.code && ![-1, 1001, 1006, 4009].includes(err.code)) errorCatcher(err); - } }; const obsConnect = async (setup?: boolean) => { From 0bc941f26a91ed69015437988801d5e8b4ad24c9 Mon Sep 17 00:00:00 2001 From: Olivier Savignac <1275666+sircharlo@users.noreply.github.com> Date: Wed, 16 Oct 2024 11:24:42 -0400 Subject: [PATCH 05/11] fix: better catch OBS connection errors --- src/components/media/ObsStatus.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/media/ObsStatus.vue b/src/components/media/ObsStatus.vue index 0bf1a088..e568f319 100644 --- a/src/components/media/ObsStatus.vue +++ b/src/components/media/ObsStatus.vue @@ -194,7 +194,7 @@ const obsConnect = async (setup?: boolean) => { break; } } catch (err) { - errorCatcher(err); + obsErrorHandler(err); } finally { attempt++; if (attempt < maxAttempts) { From 8d498fbfa9001d7ba239fbc01f7c69b57f9705e6 Mon Sep 17 00:00:00 2001 From: Olivier Savignac <1275666+sircharlo@users.noreply.github.com> Date: Wed, 16 Oct 2024 13:10:25 -0400 Subject: [PATCH 06/11] chore: add more debug info to error catcher --- src/helpers/error-catcher.ts | 25 ++++++++++++++++++++++--- src/pages/MediaCalendarPage.vue | 4 ++-- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/helpers/error-catcher.ts b/src/helpers/error-catcher.ts index ccc9e0fe..a7d0a828 100644 --- a/src/helpers/error-catcher.ts +++ b/src/helpers/error-catcher.ts @@ -1,10 +1,29 @@ +import type { SettingsValues } from 'src/types'; + import * as Sentry from '@sentry/vue'; +import { extend } from 'quasar'; -const errorCatcher = (error: Error | string | unknown) => { +const errorCatcher = async (originalError: Error | string | unknown) => { + if (!originalError) return; + const currentSettingsSnapshot = {} as SettingsValues; + try { + const { useCurrentStateStore } = await import('src/stores/current-state'); + const currentState = useCurrentStateStore(); + const { currentSettings } = currentState; + extend(true, currentSettingsSnapshot, currentSettings) as SettingsValues; + if (currentSettingsSnapshot.obsPassword?.length) + currentSettingsSnapshot.obsPassword = '*'.repeat( + currentSettingsSnapshot.obsPassword.length, + ); + } catch (error) { + console.error(error); + } if (process.env.NODE_ENV === 'production') { - Sentry.captureException(error); + if (Object.keys(currentSettingsSnapshot).length) + Sentry.setContext('currentSettings', currentSettingsSnapshot); + Sentry.captureException(originalError); } else { - console.error(error); + console.error(originalError); } }; diff --git a/src/pages/MediaCalendarPage.vue b/src/pages/MediaCalendarPage.vue index b19cb65a..cfc0698e 100644 --- a/src/pages/MediaCalendarPage.vue +++ b/src/pages/MediaCalendarPage.vue @@ -156,13 +156,13 @@ class="media-section additional" > -