diff --git a/frontend/src/components/lib/JTransition.vue b/frontend/src/components/lib/JTransition.vue index eff617a5eb0..d4715f25ea2 100644 --- a/frontend/src/components/lib/JTransition.vue +++ b/frontend/src/components/lib/JTransition.vue @@ -3,14 +3,18 @@ :is="props.group ? TransitionGroup : Transition" class="j-transition" v-bind="$attrs" - :name="prefersNoMotion || disabled || isSlow ? undefined : `j-transition-${props.name}`"> + :name="prefersNoMotion || disabled || isSlow ? undefined : `j-transition-${props.name}`" + @before-leave="leaving = true" + @after-leave="onNoLeave" + @leave-cancelled="onNoLeave"> diff --git a/frontend/src/composables/page-title.ts b/frontend/src/composables/page-title.ts index 1d9b5a93c1b..df3d5b72fa6 100644 --- a/frontend/src/composables/page-title.ts +++ b/frontend/src/composables/page-title.ts @@ -1,5 +1,5 @@ -import { computed, onBeforeUnmount, onMounted, shallowRef, toRef, toValue } from 'vue'; -import { useTitle as _useTitle, watchImmediate, type ReadonlyRefOrGetter } from '@vueuse/core'; +import { computed, onBeforeUnmount, onMounted, shallowRef, toRef, toValue, type MaybeRefOrGetter } from 'vue'; +import { useTitle as _useTitle, watchImmediate } from '@vueuse/core'; import type { BaseItemDto } from '@jellyfin/sdk/lib/generated-client'; import { isNil } from '@/utils/validation'; @@ -21,7 +21,7 @@ _useTitle(_fullTitle); * * Value will be set to default (undefined) when the component consuming this composable is unmounted. */ -export function usePageTitle(title?: ReadonlyRefOrGetter>) { +export function usePageTitle(title?: MaybeRefOrGetter>) { onMounted(() => { if (!isNil(title)) { watchImmediate(toRef(title), val => _title.value = val ?? undefined); @@ -36,6 +36,6 @@ export function usePageTitle(title?: ReadonlyRefOrGetter>) { /** * Same as useTitle, but is a shorthand for items only. */ -export function useItemPageTitle(item: ReadonlyRefOrGetter>) { +export function useItemPageTitle(item: MaybeRefOrGetter>) { usePageTitle(() => toValue(item)?.Name); }; diff --git a/frontend/src/composables/use-pausable-effect.ts b/frontend/src/composables/use-pausable-effect.ts new file mode 100644 index 00000000000..0a5194f53fb --- /dev/null +++ b/frontend/src/composables/use-pausable-effect.ts @@ -0,0 +1,15 @@ +import { getCurrentScope, toRef, watch, type MaybeRefOrGetter } from 'vue'; + +/** + * When the passed argument is truthy, the effect scope of the current component will be paused + * until the argument becomes falsy again. + * + * This is useful for components that need to pause the DOM patching + */ +export function usePausableEffect(signal: MaybeRefOrGetter) { + const scope = getCurrentScope(); + + if (scope) { + watch(toRef(signal), val => val ? scope.pause() : scope.resume(), { immediate: true, flush: 'sync' }); + } +}