From c6a4b2266a9206597a67ad6185940eba1cc35d31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Fern=C3=A1ndez?= Date: Tue, 14 May 2024 18:47:08 +0200 Subject: [PATCH] fix: items changing on navigation, library page reactivity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fernando Fernández --- frontend/src/App.vue | 2 +- frontend/src/composables/apis.ts | 53 +++++++++++++++---------- frontend/src/pages/item/[itemId].vue | 16 +++----- frontend/src/pages/library/[itemId].vue | 28 +++++-------- 4 files changed, 50 insertions(+), 49 deletions(-) diff --git a/frontend/src/App.vue b/frontend/src/App.vue index eddfb247f6c..89b46f26486 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -15,7 +15,7 @@ :mode="defaultTransitionMode ?? route.meta.layout.transition.mode"> diff --git a/frontend/src/composables/apis.ts b/frontend/src/composables/apis.ts index 16b0bc1770c..809663c6c7a 100644 --- a/frontend/src/composables/apis.ts +++ b/frontend/src/composables/apis.ts @@ -2,7 +2,7 @@ import type { Api } from '@jellyfin/sdk'; import type { BaseItemDto, BaseItemDtoQueryResult } from '@jellyfin/sdk/lib/generated-client'; import type { AxiosResponse } from 'axios'; import { deepEqual } from 'fast-equals'; -import { computed, getCurrentScope, isRef, shallowRef, toValue, unref, watch, type ComputedRef, type Ref } from 'vue'; +import { computed, effectScope, getCurrentScope, isRef, shallowRef, toValue, unref, watch, type ComputedRef, type Ref } from 'vue'; import { until } from '@vueuse/core'; import { useLoading } from '@/composables/use-loading'; import { useSnackbar } from '@/composables/use-snackbar'; @@ -11,6 +11,7 @@ import { remote } from '@/plugins/remote'; import { isConnectedToServer } from '@/store'; import { apiStore } from '@/store/api'; import { isArray, isNil } from '@/utils/validation'; +import { router } from '@/plugins/router'; /* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-return */ type OmittedKeys = 'fields' | 'userId' | 'enableImages' | 'enableTotalRecordCount' | 'enableImageTypes'; @@ -191,6 +192,7 @@ function _sharedInternalLogic any>, K ex const stringArgs = computed(() => { return JSON.stringify(argsRef.value); }); + /** * TODO: Check why previous returns unknown by default without the type annotation */ @@ -275,29 +277,38 @@ function _sharedInternalLogic any>, K ex argsRef.value = normalizeArgs(); if (getCurrentScope() !== undefined) { - if (args.length) { - watch(args, async (_newVal, oldVal) => { - const normalizedArgs = normalizeArgs(); - - /** - * Does a deep comparison to avoid useless double requests - */ - if (!normalizedArgs.every((a, index) => deepEqual(a, toValue(oldVal[index])))) { - argsRef.value = normalizedArgs; - await runNormally(); - } - }); - } + const handleArgsChange = async (_: typeof args, old: typeof args | undefined): Promise => { + const normalizedArgs = normalizeArgs(); + + /** + * Does a deep comparison to avoid useless double requests + */ + if (old && !normalizedArgs.every((a, index) => deepEqual(a, toValue(old[index])))) { + argsRef.value = normalizedArgs; + await runNormally(); + } + }; + const scope = effectScope(); - watch(isConnectedToServer, runWithRetry); + scope.run(() => { + if (args.length) { + watch(args, handleArgsChange); + } - if (isRef(api)) { - watch(api, runNormally); - } + watch(isConnectedToServer, runWithRetry); - if (isRef(methodName)) { - watch(methodName, runNormally); - } + if (isRef(api)) { + watch(api, runNormally); + } + + if (isRef(methodName)) { + watch(methodName, runNormally); + } + }); + + watch(() => router.currentRoute.value.name, () => scope.stop(), + { once: true, flush: 'sync' } + ); } /** diff --git a/frontend/src/pages/item/[itemId].vue b/frontend/src/pages/item/[itemId].vue index 5e48c987e26..80527ae637c 100644 --- a/frontend/src/pages/item/[itemId].vue +++ b/frontend/src/pages/item/[itemId].vue @@ -321,16 +321,12 @@ const { data: relatedItems } = await useBaseItem(getLibraryApi, 'getSimilarItems itemId: route.params.itemId, limit: 12 })); -const { data: currentSeries } = await useBaseItem(getUserLibraryApi, 'getItem')( - () => ({ - itemId: item.value.SeriesId ?? '' - }) -); -const { data: childItems } = await useBaseItem(getItemsApi, 'getItems')( - () => ({ - parentId: item.value.Id - }) -); +const { data: currentSeries } = await useBaseItem(getUserLibraryApi, 'getItem')(() => ({ + itemId: item.value.SeriesId ?? '' +})); +const { data: childItems } = await useBaseItem(getItemsApi, 'getItems')(() => ({ + parentId: item.value.Id +})); const selectedSource = ref(); const currentVideoTrack = ref(); diff --git a/frontend/src/pages/library/[itemId].vue b/frontend/src/pages/library/[itemId].vue index e9d356643bc..e0ba58dc611 100644 --- a/frontend/src/pages/library/[itemId].vue +++ b/frontend/src/pages/library/[itemId].vue @@ -9,11 +9,16 @@ -