diff --git a/src/main/webapp/src/stores/appStore.ts b/src/main/webapp/src/stores/appStore.ts index 2d6fe746..8179828b 100644 --- a/src/main/webapp/src/stores/appStore.ts +++ b/src/main/webapp/src/stores/appStore.ts @@ -1,45 +1,126 @@ +import { useFileStore } from '@/stores/fileStore.ts'; import type { AppSlug } from '@/types/enums/AppSlug.ts'; import { useSessionStorage } from '@vueuse/core'; -import { defineStore } from 'pinia'; -import { ref } from 'vue'; -import { useRouter } from 'vue-router'; +import { defineStore, storeToRefs } from 'pinia'; +import { computed, ref } from 'vue'; +import { type RouteLocationRaw, useRouter } from 'vue-router'; export const useAppStore = defineStore('app', () => { const router = useRouter(); + const fileStore = useFileStore(); + + /* -- App -- */ /** * App context state */ const isApp = ref(false); - /* -- Rooms -- */ + /** + * Room context state + */ + const isRoom = computed(() => _roomId.value != undefined); + + /** + * Type of app state + */ + const _appType = ref(); + + /** + * File / Room title + */ + const title = computed(() => { + const { file } = storeToRefs(fileStore); + + const fileName = file.value ? file.value.title : ''; + + return isRoom.value ? _roomId.value! : fileName; + }); + + /* -- File -- */ - const ownedRooms = useSessionStorage< + /** + * Current file id + */ + const _fileId = ref(); + + /* -- Room -- */ + + /** + * Current room id + */ + const _roomId = ref(); + + /** + * List of owned rooms + */ + const _ownedRooms = useSessionStorage< Array<{ roomId: string; appType: AppSlug; fileId: number | undefined; saveOnFile: boolean }> >(`${__APP_SLUG__}.owned-rooms`, []); + /** + * Chech if user is the owner of the room + */ + const isRoomOwner = computed(() => { + const room = _ownedRooms.value.find((room) => room.roomId == _roomId.value && room.appType == _appType.value); + + return room != undefined; + }); + /** * Id of file to load in the room */ - const initFileId = ref(); + const initRoomFileId = ref(); + /** + * Initialize room and navigate to it + */ const initRoom = (roomId: string, appType: AppSlug, fileId: number | undefined, saveOnFile: boolean): void => { - initFileId.value = fileId; - ownedRooms.value.push({ roomId, appType, fileId, saveOnFile }); - router.push({ name: `collaborative-${appType}`, params: { roomId } }); + initRoomFileId.value = fileId; + _ownedRooms.value.push({ roomId, appType, fileId, saveOnFile }); + const route: RouteLocationRaw = { name: `collaborative-${appType}`, params: { roomId } }; + isApp.value ? router.replace(route) : router.push(route); }; /* -- Store actions -- */ - const reset = (): void => { - initFileId.value = undefined; + /** + * Initialize app context + */ + const initAppContext = (roomId: string | undefined, fileId: number | undefined, routeName: string): void => { + const { loadFile } = fileStore; + const { file } = storeToRefs(fileStore); + + isApp.value = true; + _fileId.value = fileId; + _roomId.value = roomId; + _appType.value = routeName.startsWith('collaborative-') + ? (routeName.substring('collaborative-'.length) as AppSlug) + : (routeName as AppSlug); + + if (!file.value && fileId != undefined) loadFile(fileId); + }; + + /** + * Exit app context + */ + const exitAppContext = (): void => { + isApp.value = false; + _fileId.value = undefined; + _roomId.value = undefined; + _appType.value = undefined; + initRoomFileId.value = undefined; }; return { isApp, - ownedRooms, - initFileId, + isRoom, + title, + roomId: _roomId, + isRoomOwner, + initRoomFileId, initRoom, - reset, + initAppContext, + exitAppContext, }; }); diff --git a/src/main/webapp/src/views/AppView.vue b/src/main/webapp/src/views/AppView.vue index 660b8e5e..98705e4c 100644 --- a/src/main/webapp/src/views/AppView.vue +++ b/src/main/webapp/src/views/AppView.vue @@ -7,14 +7,15 @@ import { useHomeStore } from '@/stores/homeStore.ts'; import { Navigation } from '@/types/enums/Navigation.ts'; import { Tabs } from '@/types/enums/Tabs.ts'; import { storeToRefs } from 'pinia'; -import { computed, onMounted, onUnmounted, ref } from 'vue'; +import { onUnmounted, ref, watchEffect } from 'vue'; import { useI18n } from 'vue-i18n'; import { useRoute, useRouter } from 'vue-router'; const isDev = import.meta.env.DEV; const appStore = useAppStore(); -const { isApp } = storeToRefs(appStore); +const { initAppContext, exitAppContext } = appStore; +const { isRoom, title } = storeToRefs(appStore); const fileStore = useFileStore(); const { loadFile } = fileStore; @@ -49,21 +50,16 @@ const onShare = async (): Promise => { isDrawer.value = true; }; -const goBack = () => (window.history.length > 2 ? router.back() : router.push({ name: Navigation.projects })); - -const title = computed(() => { - const roomId: string = route.params.roomId != undefined ? (route.params.roomId as string) : ''; - - return file.value ? file.value.title : roomId; -}); +const goBack = (): void => { + window.history.length > 2 ? router.back() : router.push({ name: Navigation.projects }); +}; -onMounted(() => { - isApp.value = true; - if (!file.value && route.params.fileId != undefined) loadFile(parseInt(route.params.fileId as string)); +watchEffect(() => { + initAppContext(route.params.roomId as string, parseInt(route.params.fileId as string), route.name as string); }); onUnmounted(() => { - isApp.value = false; + exitAppContext(); }); diff --git a/src/main/webapp/src/views/app/tldraw/CollaborativeTldrawView.vue b/src/main/webapp/src/views/app/tldraw/CollaborativeTldrawView.vue index 28aaa2fb..ed47b118 100644 --- a/src/main/webapp/src/views/app/tldraw/CollaborativeTldrawView.vue +++ b/src/main/webapp/src/views/app/tldraw/CollaborativeTldrawView.vue @@ -14,8 +14,7 @@ const configurationStore = useConfigurationStore(); const { configuration } = configurationStore; const appStore = useAppStore(); -const { reset: resetApp } = appStore; -const { initFileId } = storeToRefs(appStore); +const { initRoomFileId } = storeToRefs(appStore); const route = useRoute(); const router = useRouter(); @@ -29,7 +28,6 @@ onMounted(() => { }); onUnmounted(() => { - resetApp(); styleObserver.disconnect(); headObserver.disconnect(); router.go(0); // force page reload to disconnect websocket @@ -40,7 +38,7 @@ onUnmounted(() => {