Sliding layout between details and category views.
This commit is contained in:
+64
-15
@@ -59,21 +59,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<!-- Detail page (movie or series) -->
|
<div v-else class="page-slider">
|
||||||
<MediaDetail
|
<div class="page-slider-track" :class="{ 'is-detail-open': isDetailOpen }">
|
||||||
v-else-if="selectedItem"
|
<!-- Browse/Search page (left panel) -->
|
||||||
:item="selectedItem"
|
<main class="main-content page-slider-panel">
|
||||||
:focus-episode="focusEpisode"
|
|
||||||
:has-resume-position="hasResumePosition"
|
|
||||||
:get-root-name="getRootName"
|
|
||||||
@close="closeDetail"
|
|
||||||
@play="handlePlay"
|
|
||||||
@open-folder="handleOpenFolder"
|
|
||||||
@search-actor="handleActorSearch"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- Browse/Search pages -->
|
|
||||||
<main v-else class="main-content">
|
|
||||||
<!-- Movies and Series views - both always rendered for smooth transitions -->
|
<!-- Movies and Series views - both always rendered for smooth transitions -->
|
||||||
<div v-if="!searchQuery" class="view-container">
|
<div v-if="!searchQuery" class="view-container">
|
||||||
<Transition name="view-zoom" mode="out-in">
|
<Transition name="view-zoom" mode="out-in">
|
||||||
@@ -161,6 +150,24 @@
|
|||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
<!-- Detail page (right panel) -->
|
||||||
|
<main class="main-content page-slider-panel page-slider-detail-panel">
|
||||||
|
<MediaDetail
|
||||||
|
v-if="detailItemForRender"
|
||||||
|
v-show="isDetailOpen"
|
||||||
|
:item="detailItemForRender"
|
||||||
|
:focus-episode="focusEpisode"
|
||||||
|
:has-resume-position="hasResumePosition"
|
||||||
|
:get-root-name="getRootName"
|
||||||
|
@close="closeDetail"
|
||||||
|
@play="handlePlay"
|
||||||
|
@open-folder="handleOpenFolder"
|
||||||
|
@search-actor="handleActorSearch"
|
||||||
|
/>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -602,6 +609,16 @@ const selectedItem = computed(() => {
|
|||||||
return null
|
return null
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const isDetailOpen = computed(() => selectedItem.value !== null)
|
||||||
|
const lastDetailItem = ref<MediaItem | null>(null)
|
||||||
|
const detailItemForRender = computed(() => selectedItem.value ?? lastDetailItem.value)
|
||||||
|
|
||||||
|
watch(selectedItem, (item) => {
|
||||||
|
if (item) {
|
||||||
|
lastDetailItem.value = item
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// Show detail by navigating to URL (clears search)
|
// Show detail by navigating to URL (clears search)
|
||||||
function showDetail(item: MediaItem) {
|
function showDetail(item: MediaItem) {
|
||||||
// Save the item ID to restore focus when returning
|
// Save the item ID to restore focus when returning
|
||||||
@@ -1237,4 +1254,36 @@ async function handleOpenFolder(folderPath: string, explicitRootId?: string | nu
|
|||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.page-slider {
|
||||||
|
width: 100vw;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-slider-track {
|
||||||
|
display: flex;
|
||||||
|
width: 200vw;
|
||||||
|
transition: transform 420ms cubic-bezier(0.22, 0.61, 0.36, 1);
|
||||||
|
will-change: transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-slider-track.is-detail-open {
|
||||||
|
transform: translate3d(-100vw, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-slider-panel {
|
||||||
|
flex: 0 0 100vw;
|
||||||
|
width: 100vw;
|
||||||
|
min-width: 100vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-slider-detail-panel {
|
||||||
|
background: var(--bg-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.page-slider-track {
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user