diff --git a/src/App.vue b/src/App.vue index 081e1245a4..9146dd5b26 100644 --- a/src/App.vue +++ b/src/App.vue @@ -14,11 +14,13 @@ import { } from 'vue' import debounce from 'lodash/debounce' import { subscribe, unsubscribe } from '@nextcloud/event-bus' +import { t } from '@nextcloud/l10n' import NcContent from '@nextcloud/vue/components/NcContent' // import UserSettingsDlg from './components/Settings/UserSettingsDlg.vue' +import LoadingOverlay from './components/Base/modules/LoadingOverlay.vue' import { usePollWatcher } from './composables/usePollWatcher' import { useSessionStore } from './stores/session' @@ -86,7 +88,10 @@ function transitionsOff(delay: number) { } } -const debouncedNotify = debounce(async function (payload: { store: string; message: string }) { +const debouncedNotify = debounce(async function (payload: { + store: string + message: string +}) { if (payload.store === 'poll') { showSuccess(payload.message) } @@ -123,6 +128,10 @@ onUnmounted(() => { + diff --git a/src/components/Public/PublicRegisterModal.vue b/src/components/Public/PublicRegisterModal.vue index 07d4ed31a7..6e87ea3648 100644 --- a/src/components/Public/PublicRegisterModal.vue +++ b/src/components/Public/PublicRegisterModal.vue @@ -147,7 +147,8 @@ const emailAddressHint = computed(() => { const validateEmailAddress = debounce(async function (): Promise { if (emailAddress.value.length < 1) { - checkStatus.value.email = sessionStore.share.publicPollEmail === 'mandatory' ? 'missing': 'empty' + checkStatus.value.email = + sessionStore.share.publicPollEmail === 'mandatory' ? 'missing' : 'empty' return } @@ -181,7 +182,7 @@ function routeToPersonalShare(token: string): void { // if share was not a public share, but a personal share // (i.e. email shares allow to change personal data by fist entering of the poll), // just refresh the session and load the poll - sessionStore.load() + sessionStore.loadSession() pollStore.load() } else { // in case of a public share, redirect to the generated share @@ -246,8 +247,10 @@ onMounted(() => { if (route.name === 'publicVote') { // TODO: remove displayName at controller side // this ist just a quick fix - sessionStore.currentUser.displayName = route.query.displayName as string || '' - sessionStore.currentUser.emailAddress = route.query.emailAddress as string || '' + sessionStore.currentUser.displayName = + (route.query.displayName as string) || '' + sessionStore.currentUser.emailAddress = + (route.query.emailAddress as string) || '' } // pre-fill input field with existing data diff --git a/src/router.ts b/src/router.ts index fe9d389012..5a4ecee6dd 100644 --- a/src/router.ts +++ b/src/router.ts @@ -14,10 +14,17 @@ import { generateUrl } from '@nextcloud/router' import { getCookieValue, setCookie } from './helpers/modules/cookieHelper' import { Logger } from './helpers/modules/logger' import { loadContext } from './composables/context' +import { emit } from '@nextcloud/event-bus' +import { Event } from './Types' import Navigation from './views/Navigation.vue' import { useSessionStore } from './stores/session' +import { usePollStore } from './stores/poll' +import { usePollsStore } from './stores/polls' +import { useVotesStore } from './stores/votes' +import { useOptionsStore } from './stores/options' +import { useSubscriptionStore } from './stores/subscription' async function validateToken(to: RouteLocationNormalized) { const sessionStore = useSessionStore() @@ -199,6 +206,20 @@ const router = createRouter({ router.beforeEach( async (to: RouteLocationNormalized, from: RouteLocationNormalized) => { const sessionStore = useSessionStore() + const pollStore = usePollStore() + const votesStore = useVotesStore() + const optionsStore = useOptionsStore() + const subscriptionStore = useSubscriptionStore() + + sessionStore.navigationStatus = 'loading' + emit(Event.TransitionsOff, 0) + + if (from.meta.votePage) { + pollStore.$reset() + votesStore.$reset() + optionsStore.$reset() + subscriptionStore.$reset() + } // if the previous and the requested routes have the same name and // the watcher is active, we can do a cheap loading @@ -227,4 +248,41 @@ router.beforeEach( }, ) +router.beforeResolve(async (to: RouteLocationNormalized) => { + const sessionStore = useSessionStore() + const watcherActive = + sessionStore.watcher.mode !== 'noPolling' + && sessionStore.watcher.status !== 'stopped' + + if (to.meta.listPage) { + const pollsStore = usePollsStore() + await pollsStore.load(!watcherActive) + } + + if (to.meta.votePage) { + const pollStore = usePollStore() + const votesStore = useVotesStore() + const optionsStore = useOptionsStore() + const subscriptionStore = useSubscriptionStore() + + try { + await pollStore.load() + } catch { + return { name: 'notfound' } + } + + await Promise.allSettled([ + votesStore.load(), + optionsStore.load(), + subscriptionStore.load(), + ]) + } +}) + +router.afterEach(() => { + const sessionStore = useSessionStore() + sessionStore.navigationStatus = 'idle' + emit(Event.TransitionsOn, null) +}) + export { router } diff --git a/src/stores/session.ts b/src/stores/session.ts index a329f5ef1c..9ae684d80c 100644 --- a/src/stores/session.ts +++ b/src/stores/session.ts @@ -114,6 +114,7 @@ export const useSessionStore = defineStore('session', { token: null, currentUser: defaultUser, share: defaultShare, + navigationStatus: 'idle', }), getters: { diff --git a/src/stores/session.types.ts b/src/stores/session.types.ts index e9b8ae7f84..3ca81985cb 100644 --- a/src/stores/session.types.ts +++ b/src/stores/session.types.ts @@ -75,4 +75,6 @@ export type Session = { watcher: Watcher } -export type SessionStore = Session +export type SessionStore = Session & { + navigationStatus: 'idle' | 'loading' +} diff --git a/src/views/PollList.vue b/src/views/PollList.vue index 01a5473031..1718f88aa0 100644 --- a/src/views/PollList.vue +++ b/src/views/PollList.vue @@ -4,7 +4,7 @@ -->