diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 04dbaf6..9ee881c 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -30,7 +30,7 @@
{ + restoreBrowseFocus(targetPath) + }) } - - restoreBrowseFocus(targetPath) } function updateSearchQuery(nextValue: string) { @@ -501,6 +516,15 @@ function handleEscapeKey(event: KeyboardEvent) { } const path = route.path + const activeSearchQuery = getRouteSearchQuery() + + if (route.params.id && activeSearchQuery) { + event.preventDefault() + const targetPath = getBrowsePath() + router.push({ path: targetPath, query: { q: activeSearchQuery } }) + restoreFocusForPage(getBrowseViewFromPath(targetPath)) + return + } // From movie detail -> movies list if (path.startsWith("/movies/") && route.params.id) { @@ -520,6 +544,12 @@ function handleEscapeKey(event: KeyboardEvent) { if (getRouteSearchQuery()) { event.preventDefault() + const target = getSearchExitTargetFromFocusedCard() + if (target) { + lastViewedItemId.value = target.itemId + clearSearch({ preferBack: false, targetPath: target.path }) + return + } clearSearch({ preferBack: true }) return } @@ -552,6 +582,14 @@ onUnmounted(() => { // Handle back navigation (Escape key or Back button) function goBack() { const path = route.path + const activeSearchQuery = getRouteSearchQuery() + + if (route.params.id && activeSearchQuery) { + const targetPath = getBrowsePath() + router.push({ path: targetPath, query: { q: activeSearchQuery } }) + restoreFocusForPage(getBrowseViewFromPath(targetPath)) + return + } // From movie detail -> movies list with focus restoration if (path.startsWith("/movies/") && route.params.id) { @@ -576,6 +614,10 @@ const currentView = computed(() => { return (route.meta.view as "movies" | "series") || "movies" }) +const headerCurrentView = computed<"movies" | "series" | "search">(() => { + return selectedItem.value && searchQuery.value ? "search" : currentView.value +}) + // Header position based on current page const headerPosition = computed(() => { if (selectedItem.value) { @@ -619,7 +661,7 @@ watch(selectedItem, (item) => { } }) -// Show detail by navigating to URL (clears search) +// Show detail by navigating to URL function showDetail(item: MediaItem) { // Save the item ID to restore focus when returning lastViewedItemId.value = item.id @@ -646,17 +688,24 @@ function showDetail(item: MediaItem) { if (playableFile) { handlePlay(playableFile) } else { - router.push(`/series/${epData.series.id}`) + const query = searchQuery.value ? { q: searchQuery.value } : undefined + router.push({ path: `/series/${epData.series.id}`, query }) } } else { - // Push without query to clear search and add to history - router.push({ path: `/${item.type}/${item.id}` }) + const query = searchQuery.value ? { q: searchQuery.value } : undefined + router.push({ path: `/${item.type}/${item.id}`, query }) } } // Close detail by navigating back to list function closeDetail() { - router.push(`/${currentView.value}`) + const activeSearchQuery = getRouteSearchQuery() + const targetPath = getBrowsePath() + if (activeSearchQuery) { + router.push({ path: targetPath, query: { q: activeSearchQuery } }) + } else { + router.push(targetPath) + } } function handleActorSearch(actorName: string) { diff --git a/frontend/src/components/Header.vue b/frontend/src/components/Header.vue index 5316441..27c6737 100644 --- a/frontend/src/components/Header.vue +++ b/frontend/src/components/Header.vue @@ -29,7 +29,7 @@ @@ -163,7 +163,7 @@ interface RootEntry { } const props = defineProps<{ - currentView: "movies" | "series" + currentView: "movies" | "series" | "search" searchQuery: string mpcBeConnected: boolean navRow: number diff --git a/frontend/src/components/MediaCard.vue b/frontend/src/components/MediaCard.vue index 59ec4c7..8da6047 100644 --- a/frontend/src/components/MediaCard.vue +++ b/frontend/src/components/MediaCard.vue @@ -4,6 +4,7 @@ class="media-card" v-bind="navAttributes" :data-item-id="item.id" + :data-item-type="item.type" :href="href || undefined" @click="handleClick" @keydown.enter.prevent="$emit('click')"