{{
diff --git a/src/router.ts b/src/router.ts
index 97ee88ab5e..c0bec0f850 100644
--- a/src/router.ts
+++ b/src/router.ts
@@ -12,76 +12,82 @@ import {
import { getCurrentUser } from '@nextcloud/auth'
import { generateUrl } from '@nextcloud/router'
import { getCookieValue, Logger, setCookie } from './helpers/index.ts'
-import { PublicAPI } from './Api/index.ts'
import { loadContext } from './composables/context.ts'
-import Vote from './views/Vote.vue'
-import SideBar from './views/SideBar.vue'
+import { AxiosError } from 'axios'
+import Navigation from './views/Navigation.vue'
+
+import Combo from './views/Combo.vue'
+import Forbidden from './views/Forbidden.vue'
import List from './views/PollList.vue'
import NotFound from './views/NotFound.vue'
+import Vote from './views/Vote.vue'
+
+import SideBar from './views/SideBar.vue'
+import SideBarPollGroup from './views/SideBarPollGroup.vue'
import SideBarCombo from './views/SideBarCombo.vue'
-import Navigation from './views/Navigation.vue'
-import Combo from './views/Combo.vue'
+
import { usePollStore } from './stores/poll.ts'
-import { FilterType, usePollsStore } from './stores/polls.ts'
+import { FilterType } from './stores/polls.ts'
import { useSessionStore } from './stores/session.ts'
-import SideBarPollGroup from './views/SideBarPollGroup.vue'
-import { useSharesStore } from './stores/shares.ts'
-import { AxiosError } from 'axios'
-import Forbidden from './views/Forbidden.vue'
+import { ShareType } from './stores/shares.ts'
async function validateToken(to: RouteLocationNormalized) {
- if (getCurrentUser()) {
- try {
- const response = await PublicAPI.getShare(to.params.token as string)
- // if the user is logged in, we diretly route to
- // the internal vote page
+ const sessionStore = useSessionStore()
+
+ try {
+ await sessionStore.loadShare()
+
+ // if the user is logged in, reroute to the vote page
+ if (getCurrentUser()) {
return {
name: 'vote',
params: {
- id: response.data.share.pollId,
+ id: sessionStore.share.pollId,
},
}
- } catch (error) {
- // in case of an error, reroute to the not found page
- return {
- name: 'notfound',
+ }
+ } catch (error) {
+ if (getCurrentUser()) {
+ if ((error as AxiosError).response?.status === 403) {
+ // User has no access
+ return { name: 'forbidden' }
}
+ // in case of other errors, reroute internal user to the not found page
+ return { name: 'notfound' }
}
- }
- // continue for external users
- try {
- // first validate the existence of the public token
- await PublicAPI.getShare(to.params.token as string)
- } catch (error) {
- // in case of an error, reroute to the login page
+ // external users will get redirected to the login page
window.location.replace(generateUrl('login'))
}
- // then look for an existing personal token from
- // the user's client stored cookie
- // matching the public token
- const personalToken = getCookieValue(to.params.token as string)
+ // Continue for external users
+ //
+ if (sessionStore.share.type === ShareType.Public) {
+ // Check, if user has a personal token from the user's client stored cookie
+ // matching the public token
+ const personalToken = getCookieValue(to.params.token as string)
- if (personalToken && personalToken !== to.params.token) {
- // participant has already access to the poll and a private token
- // extend expiry time for 30 days after successful access
- const cookieExpiration = 30 * 24 * 60 * 1000
- setCookie(to.params.token, personalToken, cookieExpiration)
+ if (personalToken) {
+ // participant has already access to the poll and a private token
+ // extend expiry time for 30 days after successful access
+ const cookieExpiration = 30 * 24 * 60 * 1000
+ setCookie(to.params.token as string, personalToken, cookieExpiration)
- // reroute to the public vote page using the personal token
- return {
- name: 'publicVote',
- params: {
- token: personalToken,
- },
+ // reroute to the public vote page using the personal token
+ return {
+ name: 'publicVote',
+ params: {
+ token: personalToken,
+ },
+ }
}
}
- // if no private token is found, load the poll
+ // finally load the poll
const pollStore = usePollStore()
- await pollStore.load()
+
+ pollStore.load()
}
const routes: RouteRecordRaw[] = [
@@ -196,18 +202,15 @@ const router = createRouter({
router.beforeEach(
async (to: RouteLocationNormalized, from: RouteLocationNormalized) => {
const sessionStore = useSessionStore()
- const pollStore = usePollStore()
- const pollsStore = usePollsStore()
- const sharesStore = useSharesStore()
+ // if the previous and the requested routes have the same name and
+ // the watcher is active, we can do a cheap loading
const cheapLoading =
- sessionStore.watcher.mode !== 'noPolling'
+ to.name === from.name
+ && sessionStore.watcher.mode !== 'noPolling'
&& sessionStore.watcher.status !== 'stopped'
- && to.name === from.name
// first load app context -> session and preferences
- // await loading until further execution to ensure,
- // the context is loaded properly
try {
await loadContext(to, cheapLoading)
} catch (error) {
@@ -224,43 +227,6 @@ router.beforeEach(
name: 'notfound',
}
}
-
- try {
- // for public pages we need to load the share first
- if (to.meta.publicPage) {
- await sessionStore.loadShare()
- }
-
- // vote pages load the particular poll
- // or reset the poll store if not a vote page
- if (to.meta.votePage) {
- await pollStore.load()
- } else {
- pollStore.resetPoll()
- }
-
- // load polls at least for navigation
- if (!to.meta.publicPage && !cheapLoading) {
- await pollsStore.load()
- }
-
- // group pages need shares for the current poll group
- if (to.meta.groupPage) {
- sharesStore.load('pollGroup')
- }
- } catch (error) {
- Logger.warn('Could not load poll', { error })
- if ((error as AxiosError).response?.status === 403) {
- // User has no access
- return {
- name: 'forbidden',
- }
- }
- // else let's pretend, the poll does not exist (what will be probably the case)
- return {
- name: 'notfound',
- }
- }
},
)
diff --git a/src/stores/poll.ts b/src/stores/poll.ts
index 8d349360b5..f501913215 100644
--- a/src/stores/poll.ts
+++ b/src/stores/poll.ts
@@ -410,20 +410,25 @@ export const usePollStore = defineStore('poll', {
subscriptionStore.reset()
},
- async load(): Promise {
+ async load(pollId: number | null = null): Promise {
const votesStore = useVotesStore()
const sessionStore = useSessionStore()
const optionsStore = useOptionsStore()
const sharesStore = useSharesStore()
const commentsStore = useCommentsStore()
const subscriptionStore = useSubscriptionStore()
+
+ this.meta.status = StatusResults.Loading
+
try {
const response = await (() => {
if (sessionStore.route.name === 'publicVote') {
return PublicAPI.getPoll(sessionStore.route.params.token)
}
if (sessionStore.route.name === 'vote') {
- return PollsAPI.getFullPoll(sessionStore.currentPollId)
+ return PollsAPI.getFullPoll(
+ pollId ?? sessionStore.currentPollId,
+ )
}
return null
})()
@@ -439,10 +444,13 @@ export const usePollStore = defineStore('poll', {
sharesStore.shares = response.data.shares
commentsStore.comments = response.data.comments
subscriptionStore.subscribed = response.data.subscribed
+
+ this.meta.status = StatusResults.Loaded
} catch (error) {
if ((error as AxiosError)?.code === 'ERR_CANCELED') {
return
}
+ this.meta.status = StatusResults.Error
Logger.error('Error loading poll', { error })
throw error
}
diff --git a/src/stores/polls.ts b/src/stores/polls.ts
index 76d0cf6872..4f19fc3642 100644
--- a/src/stores/polls.ts
+++ b/src/stores/polls.ts
@@ -93,7 +93,7 @@ export const sortTitlesMapping: { [key in SortType]: string } = {
interaction: t('polls', 'Last interaction'),
}
-export const pollCategories: PollCategoryList = {
+const pollCategories: PollCategoryList = {
[FilterType.Relevant]: {
id: FilterType.Relevant,
title: t('polls', 'Relevant'),
@@ -223,7 +223,7 @@ export const usePollsStore = defineStore('polls', {
loaded: 1,
},
maxPollsInNavigation: 6,
- status: StatusResults.Loaded,
+ status: StatusResults.None,
},
sort: {
by: SortType.Created,
@@ -353,12 +353,24 @@ export const usePollsStore = defineStore('polls', {
* This will also set the `meta.status` to `Loading` while the request is in progress,
* and to `Loaded` or `Error` when the request is finished.
*
+ * @param {boolean} forced - If false, loading polls will only be done, when the status is not `Loaded`.
* @throws {Error} If the request fails and is not canceled.
* @return {Promise}
*/
- async load(): Promise {
+ async load(forced: boolean = true): Promise {
const pollGroupsStore = usePollGroupsStore()
+ if (
+ this.meta.status === StatusResults.Loading
+ || (!forced && this.meta.status === StatusResults.Loaded)
+ ) {
+ Logger.debug('Polls already loaded or loading, skipping load', {
+ status: this.meta.status,
+ forced,
+ })
+ return
+ }
+
this.meta.status = StatusResults.Loading
try {
diff --git a/src/views/Dashboard.vue b/src/views/Dashboard.vue
index ba4243915c..2e58a9f99f 100644
--- a/src/views/Dashboard.vue
+++ b/src/views/Dashboard.vue
@@ -31,12 +31,11 @@ const pollsStore = usePollsStore()
*/
function loadPolls(): void {
Logger.debug('Loading polls in dashboard widget')
- pollsStore
- .load()
- .then(() => null)
- .catch(() => {
- showError(t('polls', 'Error loading poll list'))
- })
+ try {
+ pollsStore.load()
+ } catch (error) {
+ showError(t('polls', 'Error setting dashboard list'))
+ }
}
onMounted(() => {
diff --git a/src/views/Navigation.vue b/src/views/Navigation.vue
index 70a470a87b..34cd0fad8e 100644
--- a/src/views/Navigation.vue
+++ b/src/views/Navigation.vue
@@ -4,7 +4,7 @@
-->
diff --git a/src/views/PollList.vue b/src/views/PollList.vue
index 5e90bf82dc..e150ec629a 100644
--- a/src/views/PollList.vue
+++ b/src/views/PollList.vue
@@ -4,16 +4,14 @@
-->
@@ -192,15 +188,15 @@ async function loadMore() {
-
+
-
-
+
+
diff --git a/src/views/SideBar.vue b/src/views/SideBar.vue
index 0652a2cf3c..b554081e80 100644
--- a/src/views/SideBar.vue
+++ b/src/views/SideBar.vue
@@ -53,9 +53,6 @@ onUnmounted(() => {
})
})
-/**
- *
- */
function closeSideBar() {
emit(Event.SidebarToggle, { open: false })
}
diff --git a/src/views/Vote.vue b/src/views/Vote.vue
index b858153919..d4b615849b 100644
--- a/src/views/Vote.vue
+++ b/src/views/Vote.vue
@@ -4,7 +4,7 @@
-->
@@ -135,6 +157,7 @@ onUnmounted(() => {
+
{
-
+