@@ -152,7 +158,12 @@
-
+
>({})
const searchQuery = ref(getRouteSearchQuery())
const searchReturnPath = ref(null)
+const browsePanelRef = ref(null)
+const detailPanelRef = ref(null)
+const browsePanelScrollTop = ref(0)
+const detailPanelScrollTop = ref(0)
const MPC_BE_OPENING_GRACE_MS = 4000
const mpcBeOpeningUntil = ref(0)
let mpcBePollTimer: number | null = null
+function handlePanelScroll(scope: "browse" | "detail") {
+ if (scope === "browse") {
+ browsePanelScrollTop.value = browsePanelRef.value?.scrollTop || 0
+ return
+ }
+ detailPanelScrollTop.value = detailPanelRef.value?.scrollTop || 0
+}
+
function isMpcFamilySelected(): boolean {
// Empty port means Web UI is disabled
if (settings.playerMpcPort === null) return false
@@ -620,6 +643,8 @@ function handleEscapeKey(event: KeyboardEvent) {
onMounted(() => {
void refreshPlayerStatus()
void refreshResumePositions()
+ browsePanelScrollTop.value = browsePanelRef.value?.scrollTop || 0
+ detailPanelScrollTop.value = detailPanelRef.value?.scrollTop || 0
setActiveNavigationScope(isDetailOpen.value ? "detail" : "browse")
document.addEventListener("keydown", handleEscapeKey)
window.addEventListener("mediahive:gamepad-action", onGamepadAction as EventListener)
@@ -707,6 +732,20 @@ const isDetailOpen = computed(() => selectedItem.value !== null)
const lastDetailItem = ref(null)
const detailItemForRender = computed(() => selectedItem.value ?? lastDetailItem.value)
+const activePanelScrollTop = computed(() => {
+ if (loading.value || error.value) return 0
+ return isDetailOpen.value ? detailPanelScrollTop.value : browsePanelScrollTop.value
+})
+
+const headerStyle = computed(() => {
+ if (route.path === "/settings") {
+ return {}
+ }
+ return {
+ transform: `translateY(${-activePanelScrollTop.value}px)`,
+ }
+})
+
watch(selectedItem, (item) => {
if (item) {
lastDetailItem.value = item
@@ -1317,7 +1356,9 @@ async function handleOpenFolder(folderPath: string, explicitRootId?: string | nu