Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -123,6 +128,10 @@ onUnmounted(() => {
<router-view />
<router-view v-if="useSidebar" name="sidebar" />
<UserSettingsDlg />
<LoadingOverlay
:show="sessionStore.navigationStatus === 'loading'"
:name="t('polls', 'Loading…')"
teleport-to="#content" />
</NcContent>
</template>

Expand Down
11 changes: 7 additions & 4 deletions src/components/Public/PublicRegisterModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ const emailAddressHint = computed(() => {

const validateEmailAddress = debounce(async function (): Promise<void> {
if (emailAddress.value.length < 1) {
checkStatus.value.email = sessionStore.share.publicPollEmail === 'mandatory' ? 'missing': 'empty'
checkStatus.value.email =
sessionStore.share.publicPollEmail === 'mandatory' ? 'missing' : 'empty'
return
}

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
58 changes: 58 additions & 0 deletions src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 }
1 change: 1 addition & 0 deletions src/stores/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ export const useSessionStore = defineStore('session', {
token: null,
currentUser: defaultUser,
share: defaultShare,
navigationStatus: 'idle',
}),

getters: {
Expand Down
4 changes: 3 additions & 1 deletion src/stores/session.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,6 @@ export type Session = {
watcher: Watcher
}

export type SessionStore = Session
export type SessionStore = Session & {
navigationStatus: 'idle' | 'loading'
}
6 changes: 1 addition & 5 deletions src/views/PollList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
-->

<script setup lang="ts">
import { computed, onMounted } from 'vue'
import { computed } from 'vue'
import { useRouter, useRoute } from 'vue-router'

import { showError } from '@nextcloud/dialogs'
Expand Down Expand Up @@ -121,10 +121,6 @@ async function loadMore() {
showError(t('polls', 'Error loading more polls'))
}
}

onMounted(() => {
pollsStore.load(false)
})
</script>

<template>
Expand Down
53 changes: 1 addition & 52 deletions src/views/Vote.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
-->

<script setup lang="ts">
import { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'
import { computed, nextTick, onMounted, ref, watch } from 'vue'

import { showError } from '@nextcloud/dialogs'
import { emit } from '@nextcloud/event-bus'
Expand Down Expand Up @@ -36,17 +35,13 @@ import { usePollStore } from '../stores/poll'
import { useOptionsStore } from '../stores/options'
import { usePreferencesStore } from '../stores/preferences'
import { useVotesStore } from '../stores/votes'
import { useSubscriptionStore } from '../stores/subscription'

import type { CollapsibleProps } from '../components/Base/modules/Collapsible.vue'
import { Event } from '../Types'
import { loadContext } from '../composables/context'

const pollStore = usePollStore()
const optionsStore = useOptionsStore()
const preferencesStore = usePreferencesStore()
const votesStore = useVotesStore()
const subscriptionStore = useSubscriptionStore()

const voteMainId = 'vote-view'
const topObserverVisible = ref(false)
Expand Down Expand Up @@ -138,56 +133,10 @@ const showBottomObserver = computed(
&& pollStore.viewMode === 'table-view',
)

async function loadPoll(isChanging: boolean = false) {
try {
await pollStore.load(isChanging)
} catch {
showError(t('polls', 'Error loading poll'))
votesStore.$reset()
optionsStore.$reset()
subscriptionStore.$reset()
return
}

const results = await Promise.allSettled([
votesStore.load(),
optionsStore.load(),
subscriptionStore.load(),
])

if (results.some((result) => result.status === 'rejected')) {
showError(t('polls', 'Error loading poll data'))
}
}

async function resetPoll() {
pollStore.$reset()
votesStore.$reset()
optionsStore.$reset()
subscriptionStore.$reset()
}

onBeforeRouteUpdate(async (to, from) => {
if (to.name === 'publicVote' && to.params.token !== from.params.token) {
loadContext(to)
// Same poll, no need to reload
}
loadPoll(true)
})

onBeforeRouteLeave(() => {
resetPoll()
})

onMounted(() => {
loadPoll(true)
emit(Event.TransitionsOff, 500)
})

onUnmounted(() => {
resetPoll()
})

watch(
[
() => pollStore.permissions.seeUsernames,
Expand Down
Loading