feat: move composables in separate files (#2485)

Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: https://kolaente.dev/vikunja/frontend/pulls/2485
Reviewed-by: konrad <k@knt.li>
Co-authored-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-committed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
This commit is contained in:
Dominik Pschenitschni 2022-10-04 12:10:12 +00:00 committed by konrad
parent 6f2dedcb48
commit c206fc6f34
4 changed files with 106 additions and 93 deletions

View file

@ -60,65 +60,18 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import {watch, computed, shallowRef, watchEffect, type VNode, h} from 'vue' import {watch, computed} from 'vue'
import {useBaseStore} from '@/stores/base' import {useRoute} from 'vue-router'
import {useRoute, useRouter} from 'vue-router'
import {useEventListener} from '@vueuse/core'
import {useLabelStore} from '@/stores/labels'
import Navigation from '@/components/home/navigation.vue' import Navigation from '@/components/home/navigation.vue'
import QuickActions from '@/components/quick-actions/quick-actions.vue' import QuickActions from '@/components/quick-actions/quick-actions.vue'
import BaseButton from '@/components/base/BaseButton.vue' import BaseButton from '@/components/base/BaseButton.vue'
import {useAuthStore} from '@/stores/auth'
function useRouteWithModal() { import {useBaseStore} from '@/stores/base'
const router = useRouter() import {useLabelStore} from '@/stores/labels'
const route = useRoute()
const backdropView = computed(() => route.fullPath && window.history.state.backdropView)
const routeWithModal = computed(() => { import {useRouteWithModal} from '@/composables/useRouteWithModal'
return backdropView.value import {useRenewTokenOnFocus} from '@/composables/useRenewTokenOnFocus'
? router.resolve(backdropView.value)
: route
})
const currentModal = shallowRef<VNode>()
watchEffect(() => {
if (!backdropView.value) {
currentModal.value = undefined
return
}
// logic from vue-router
// https://github.com/vuejs/vue-router-next/blob/798cab0d1e21f9b4d45a2bd12b840d2c7415f38a/src/RouterView.ts#L125
const routePropsOption = route.matched[0]?.props.default
const routeProps = routePropsOption
? routePropsOption === true
? route.params
: typeof routePropsOption === 'function'
? routePropsOption(route)
: routePropsOption
: null
currentModal.value = h(
route.matched[0]?.components.default,
routeProps,
)
})
function closeModal() {
const historyState = computed(() => route.fullPath && window.history.state)
if (historyState.value) {
router.back()
} else {
const backdropRoute = historyState.value?.backdropView && router.resolve(historyState.value.backdropView)
router.push(backdropRoute)
}
}
return {routeWithModal, currentModal, closeModal}
}
const {routeWithModal, currentModal, closeModal} = useRouteWithModal() const {routeWithModal, currentModal, closeModal} = useRouteWithModal()
@ -162,43 +115,8 @@ watch(() => route.name as string, (routeName) => {
// TODO: Reset the title if the page component does not set one itself // TODO: Reset the title if the page component does not set one itself
function useRenewTokenOnFocus() {
const router = useRouter()
const authStore = useAuthStore()
const userInfo = computed(() => authStore.info)
const authenticated = computed(() => authStore.authenticated)
// Try renewing the token every time vikunja is loaded initially
// (When opening the browser the focus event is not fired)
authStore.renewToken()
// Check if the token is still valid if the window gets focus again to maybe renew it
useEventListener('focus', () => {
if (!authenticated.value) {
return
}
const expiresIn = (userInfo.value !== null ? userInfo.value.exp : 0) - +new Date() / 1000
// If the token expiry is negative, it is already expired and we have no choice but to redirect
// the user to the login page
if (expiresIn < 0) {
authStore.checkAuth()
router.push({name: 'user.login'})
return
}
// Check if the token is valid for less than 60 hours and renew if thats the case
if (expiresIn < 60 * 3600) {
authStore.renewToken()
console.debug('renewed token')
}
})
}
useRenewTokenOnFocus() useRenewTokenOnFocus()
const labelStore = useLabelStore() const labelStore = useLabelStore()
labelStore.loadAllLabels() labelStore.loadAllLabels()
</script> </script>

View file

@ -0,0 +1,40 @@
import {computed} from 'vue'
import {useRouter} from 'vue-router'
import {useEventListener} from '@vueuse/core'
import {useAuthStore} from '@/stores/auth'
export function useRenewTokenOnFocus() {
const router = useRouter()
const authStore = useAuthStore()
const userInfo = computed(() => authStore.info)
const authenticated = computed(() => authStore.authenticated)
// Try renewing the token every time vikunja is loaded initially
// (When opening the browser the focus event is not fired)
authStore.renewToken()
// Check if the token is still valid if the window gets focus again to maybe renew it
useEventListener('focus', () => {
if (!authenticated.value) {
return
}
const expiresIn = (userInfo.value !== null ? userInfo.value.exp : 0) - +new Date() / 1000
// If the token expiry is negative, it is already expired and we have no choice but to redirect
// the user to the login page
if (expiresIn < 0) {
authStore.checkAuth()
router.push({name: 'user.login'})
return
}
// Check if the token is valid for less than 60 hours and renew if thats the case
if (expiresIn < 60 * 3600) {
authStore.renewToken()
console.debug('renewed token')
}
})
}

View file

@ -0,0 +1,54 @@
import { computed, shallowRef, watchEffect, h, type VNode } from 'vue'
import { useRoute, useRouter } from 'vue-router'
export function useRouteWithModal() {
const router = useRouter()
const route = useRoute()
const backdropView = computed(() => route.fullPath && window.history.state.backdropView)
const routeWithModal = computed(() => {
return backdropView.value
? router.resolve(backdropView.value)
: route
})
const currentModal = shallowRef<VNode>()
watchEffect(() => {
if (!backdropView.value) {
currentModal.value = undefined
return
}
// logic from vue-router
// https://github.com/vuejs/vue-router-next/blob/798cab0d1e21f9b4d45a2bd12b840d2c7415f38a/src/RouterView.ts#L125
const routePropsOption = route.matched[0]?.props.default
const routeProps = routePropsOption
? routePropsOption === true
? route.params
: typeof routePropsOption === 'function'
? routePropsOption(route)
: routePropsOption
: null
const component = route.matched[0]?.components?.default
if (!component) {
currentModal.value = undefined
return
}
currentModal.value = h(component, routeProps)
})
function closeModal() {
const historyState = computed(() => route.fullPath && window.history.state)
if (historyState.value) {
router.back()
} else {
const backdropRoute = historyState.value?.backdropView && router.resolve(historyState.value.backdropView)
router.push(backdropRoute)
}
}
return {routeWithModal, currentModal, closeModal}
}

View file

@ -12,7 +12,7 @@ import type {IList} from '@/modelTypes/IList'
export interface RootStoreState { export interface RootStoreState {
loading: boolean, loading: boolean,
currentList: IList, currentList: IList | null,
background: string, background: string,
blurHash: string, blurHash: string,
@ -47,12 +47,13 @@ export const useBaseStore = defineStore('base', {
this.loading = loading this.loading = loading
}, },
setCurrentList(currentList: IList) { setCurrentList(currentList: IList | null) {
// Server updates don't return the right. Therefore, the right is reset after updating the list which is // Server updates don't return the right. Therefore, the right is reset after updating the list which is
// confusing because all the buttons will disappear in that case. To prevent this, we're keeping the right // confusing because all the buttons will disappear in that case. To prevent this, we're keeping the right
// when updating the list in global state. // when updating the list in global state.
if ( if (
typeof this.currentList.maxRight !== 'undefined' && typeof this.currentList?.maxRight !== 'undefined' &&
currentList !== null &&
( (
typeof currentList.maxRight === 'undefined' || typeof currentList.maxRight === 'undefined' ||
currentList.maxRight === null currentList.maxRight === null
@ -95,7 +96,7 @@ export const useBaseStore = defineStore('base', {
this.logoVisible = visible this.logoVisible = visible
}, },
async handleSetCurrentList({list, forceUpdate = false} : {list: IList, forceUpdate: boolean}) { async handleSetCurrentList({list, forceUpdate = false} : {list: IList | null, forceUpdate: boolean}) {
if (list === null) { if (list === null) {
this.setCurrentList({}) this.setCurrentList({})
this.setBackground('') this.setBackground('')