From 449e36e9a136454058f8af55f34c437ada540847 Mon Sep 17 00:00:00 2001 From: Varun Patil Date: Mon, 16 Oct 2023 11:08:23 -0700 Subject: [PATCH] refactor: move route checkers out of global mixin Signed-off-by: Varun Patil --- src/globals.d.ts | 20 +-- src/mixins/GlobalMixin.ts | 51 ------ src/router.ts | 320 +++++++++++++++++++++----------------- 3 files changed, 175 insertions(+), 216 deletions(-) diff --git a/src/globals.d.ts b/src/globals.d.ts index d262596b..987c85ce 100644 --- a/src/globals.d.ts +++ b/src/globals.d.ts @@ -8,6 +8,7 @@ import type videojsType from 'video.js'; import type { IPhoto, IRow } from './types'; import type { c, initState } from './services/utils'; +import type { GlobalRouteCheckers } from './router'; // Global exposed variables declare global { @@ -96,29 +97,12 @@ declare global { // GlobalMixin.ts types, present on all components declare module 'vue' { - interface ComponentCustomProperties { + interface ComponentCustomProperties extends GlobalRouteCheckers { t: typeof translate; n: typeof translatePlural; c: typeof c; initState: typeof initState; - - routeIsBase: boolean; - routeIsFavorites: boolean; - routeIsVideos: boolean; - routeIsFolders: boolean; - routeIsAlbums: boolean; - routeIsPeople: boolean; - routeIsRecognize: boolean; - routeIsRecognizeUnassigned: boolean; - routeIsFaceRecognition: boolean; - routeIsArchive: boolean; - routeIsPlaces: boolean; - routeIsMap: boolean; - routeIsTags: boolean; - routeIsExplore: boolean; - routeIsAlbumShare: boolean; - routeIsPublic: boolean; } } diff --git a/src/mixins/GlobalMixin.ts b/src/mixins/GlobalMixin.ts index d46154f4..ac017ea9 100644 --- a/src/mixins/GlobalMixin.ts +++ b/src/mixins/GlobalMixin.ts @@ -10,57 +10,6 @@ export default defineComponent({ initState, }), - computed: { - routeIsBase(): boolean { - return this.$route.name === 'timeline'; - }, - routeIsFavorites(): boolean { - return this.$route.name === 'favorites'; - }, - routeIsVideos(): boolean { - return this.$route.name === 'videos'; - }, - routeIsFolders(): boolean { - return this.$route.name === 'folders'; - }, - routeIsAlbums(): boolean { - return this.$route.name === 'albums'; - }, - routeIsPeople(): boolean { - return ['recognize', 'facerecognition'].includes(this.$route.name); - }, - routeIsRecognize(): boolean { - return this.$route.name === 'recognize'; - }, - routeIsRecognizeUnassigned(): boolean { - return this.routeIsRecognize && this.$route.params.name === c.FACE_NULL; - }, - routeIsFaceRecognition(): boolean { - return this.$route.name === 'facerecognition'; - }, - routeIsArchive(): boolean { - return this.$route.name === 'archive'; - }, - routeIsPlaces(): boolean { - return this.$route.name === 'places'; - }, - routeIsMap(): boolean { - return this.$route.name === 'map'; - }, - routeIsTags(): boolean { - return this.$route.name === 'tags'; - }, - routeIsExplore(): boolean { - return this.$route.name === 'explore'; - }, - routeIsAlbumShare(): boolean { - return this.$route.name === 'album-share'; - }, - routeIsPublic(): boolean { - return this.$route.name?.endsWith('-share') ?? false; - }, - }, - methods: { t, n, diff --git a/src/router.ts b/src/router.ts index 9e09c4c0..29667b3d 100644 --- a/src/router.ts +++ b/src/router.ts @@ -1,13 +1,150 @@ +import Router, { Route, RouteConfig } from 'vue-router'; +import Vue from 'vue'; + import { generateUrl } from '@nextcloud/router'; import { translate as t } from '@nextcloud/l10n'; -import Router from 'vue-router'; -import Vue from 'vue'; + import Timeline from './components/Timeline.vue'; import Explore from './components/Explore.vue'; import SplitTimeline from './components/SplitTimeline.vue'; import ClusterView from './components/ClusterView.vue'; import NativeXSetup from './native/Setup.vue'; +import { c } from './services/utils'; + +// Routes are defined here +export type RouteId = + | 'Base' + | 'Folders' + | 'Favorites' + | 'Videos' + | 'Albums' + | 'Archive' + | 'ThisDay' + | 'Recognize' + | 'FaceRecognition' + | 'Places' + | 'Tags' + | 'FolderShare' + | 'AlbumShare' + | 'Map' + | 'Explore' + | 'NxSetup'; + +const routes: { [key in RouteId]: RouteConfig } = { + Base: { + path: '/', + component: Timeline, + name: 'timeline', + props: (route: Route) => ({ rootTitle: t('memories', 'Timeline') }), + }, + + Folders: { + path: '/folders/:path*', + component: Timeline, + name: 'folders', + props: (route: Route) => ({ rootTitle: t('memories', 'Folders') }), + }, + + Favorites: { + path: '/favorites', + component: Timeline, + name: 'favorites', + props: (route: Route) => ({ rootTitle: t('memories', 'Favorites') }), + }, + + Videos: { + path: '/videos', + component: Timeline, + name: 'videos', + props: (route: Route) => ({ rootTitle: t('memories', 'Videos') }), + }, + + Albums: { + path: '/albums/:user?/:name?', + component: ClusterView, + name: 'albums', + props: (route: Route) => ({ rootTitle: t('memories', 'Albums') }), + }, + + Archive: { + path: '/archive', + component: Timeline, + name: 'archive', + props: (route: Route) => ({ rootTitle: t('memories', 'Archive') }), + }, + + ThisDay: { + path: '/thisday', + component: Timeline, + name: 'thisday', + props: (route: Route) => ({ rootTitle: t('memories', 'On this day') }), + }, + + Recognize: { + path: '/recognize/:user?/:name?', + component: ClusterView, + name: 'recognize', + props: (route: Route) => ({ rootTitle: t('memories', 'People') }), + }, + + FaceRecognition: { + path: '/facerecognition/:user?/:name?', + component: ClusterView, + name: 'facerecognition', + props: (route: Route) => ({ rootTitle: t('memories', 'People') }), + }, + + Places: { + path: '/places/:name*', + component: ClusterView, + name: 'places', + props: (route: Route) => ({ rootTitle: t('memories', 'Places') }), + }, + + Tags: { + path: '/tags/:name*', + component: ClusterView, + name: 'tags', + props: (route: Route) => ({ rootTitle: t('memories', 'Tags') }), + }, + + FolderShare: { + path: '/s/:token', + component: Timeline, + name: 'folder-share', + props: (route: Route) => ({ rootTitle: t('memories', 'Shared Folder') }), + }, + + AlbumShare: { + path: '/a/:token', + component: Timeline, + name: 'album-share', + props: (route: Route) => ({ rootTitle: t('memories', 'Shared Album') }), + }, + + Map: { + path: '/map', + component: SplitTimeline, + name: 'map', + props: (route: Route) => ({ rootTitle: t('memories', 'Map') }), + }, + + Explore: { + path: '/explore', + component: Explore, + name: 'explore', + props: (route: Route) => ({ rootTitle: t('memories', 'Explore') }), + }, + + NxSetup: { + path: '/nxsetup', + component: NativeXSetup, + name: 'nxsetup', + props: (route: Route) => ({ rootTitle: t('memories', 'Setup') }), + }, +}; + Vue.use(Router); export default new Router({ @@ -16,149 +153,38 @@ export default new Router({ // let's keep using index.php in the url base: generateUrl('/apps/memories'), linkActiveClass: 'active', - routes: [ - { - path: '/', - component: Timeline, - name: 'timeline', - props: (route) => ({ - rootTitle: t('memories', 'Timeline'), - }), - }, - - { - path: '/folders/:path*', - component: Timeline, - name: 'folders', - props: (route) => ({ - rootTitle: t('memories', 'Folders'), - }), - }, - - { - path: '/favorites', - component: Timeline, - name: 'favorites', - props: (route) => ({ - rootTitle: t('memories', 'Favorites'), - }), - }, - - { - path: '/videos', - component: Timeline, - name: 'videos', - props: (route) => ({ - rootTitle: t('memories', 'Videos'), - }), - }, - - { - path: '/albums/:user?/:name?', - component: ClusterView, - name: 'albums', - props: (route) => ({ - rootTitle: t('memories', 'Albums'), - }), - }, - - { - path: '/archive', - component: Timeline, - name: 'archive', - props: (route) => ({ - rootTitle: t('memories', 'Archive'), - }), - }, - - { - path: '/thisday', - component: Timeline, - name: 'thisday', - props: (route) => ({ - rootTitle: t('memories', 'On this day'), - }), - }, - - { - path: '/recognize/:user?/:name?', - component: ClusterView, - name: 'recognize', - props: (route) => ({ - rootTitle: t('memories', 'People'), - }), - }, - - { - path: '/facerecognition/:user?/:name?', - component: ClusterView, - name: 'facerecognition', - props: (route) => ({ - rootTitle: t('memories', 'People'), - }), - }, - - { - path: '/places/:name*', - component: ClusterView, - name: 'places', - props: (route) => ({ - rootTitle: t('memories', 'Places'), - }), - }, - - { - path: '/tags/:name*', - component: ClusterView, - name: 'tags', - props: (route) => ({ - rootTitle: t('memories', 'Tags'), - }), - }, - - { - path: '/s/:token', - component: Timeline, - name: 'folder-share', - props: (route) => ({ - rootTitle: t('memories', 'Shared Folder'), - }), - }, - - { - path: '/a/:token', - component: Timeline, - name: 'album-share', - props: (route) => ({ - rootTitle: t('memories', 'Shared Album'), - }), - }, - - { - path: '/map', - component: SplitTimeline, - name: 'map', - props: (route) => ({ - rootTitle: t('memories', 'Map'), - }), - }, - - { - path: '/explore', - component: Explore, - name: 'explore', - props: (route) => ({ - rootTitle: t('memories', 'Explore'), - }), - }, - - { - path: '/nxsetup', - component: NativeXSetup, - name: 'nxsetup', - props: (route) => ({ - rootTitle: t('memories', 'Setup'), - }), - }, - ], + routes: Object.values(routes), }); + +// Define global route checkers +// Injected through globals.d.ts +export type GlobalRouteCheckers = { + [key in `routeIs${RouteId}`]: boolean; +} & { + // Extra, special route checkers + routeIsPublic: boolean; + routeIsPeople: boolean; + routeIsRecognizeUnassigned: boolean; +}; + +// Implement getters for route checkers +function defineRouteChecker(key: keyof GlobalRouteCheckers, condition: (route?: Route) => boolean) { + Object.defineProperty(Vue.prototype, key, { + get() { + return condition(this.$route); + }, + }); +} + +// Defined routes +for (const [key, value] of Object.entries(routes)) { + defineRouteChecker(`routeIs${key}`, (route) => route?.name === value.name); +} + +// Extra route checkers +defineRouteChecker('routeIsPublic', (route) => route?.name?.endsWith('-share') ?? false); +defineRouteChecker('routeIsPeople', (route) => ['recognize', 'facerecognition'].includes(route?.name ?? '')); +defineRouteChecker( + 'routeIsRecognizeUnassigned', + (route) => route?.name === 'recognize' && route.params.name === c.FACE_NULL, +);