From 5af052b428312c14f263dc9347c45548e7fb362c Mon Sep 17 00:00:00 2001 From: Arkadiusz Fal Date: Fri, 25 Sep 2026 21:44:43 +0200 Subject: [PATCH] Jump panel pages to the top and clear stale chapters when the video changes Tapping a related video kept the panel scrolled where it was, so the new title was out of view, and the chapters section kept showing the previous video's chapters until the new ones resolved. The scroll config now carries the video identity and the shared page scroll view scrolls to the top (without animation, resetting the reported offset) whenever it changes. PlayerState.setCurrentVideo clears chapters on a video id change, alongside comments and storyboards. --- Yattee/Services/Player/PlayerState.swift | 3 +++ Yattee/Views/Player/Panels/PanelPageContext.swift | 13 +++++++++++++ .../Player/Panels/PlayerPanelContentView.swift | 9 +++++++++ 3 files changed, 25 insertions(+) diff --git a/Yattee/Services/Player/PlayerState.swift b/Yattee/Services/Player/PlayerState.swift index f53c7b9c..1af8d9a2 100644 --- a/Yattee/Services/Player/PlayerState.swift +++ b/Yattee/Services/Player/PlayerState.swift @@ -483,6 +483,9 @@ final class PlayerState { commentsContinuation = nil // Reset storyboards to prevent previous video's storyboards from appearing storyboards = [] + // Reset chapters so the panel doesn't show the previous video's + // chapters while the new one loads + chapters = [] } currentVideo = video currentStream = stream diff --git a/Yattee/Views/Player/Panels/PanelPageContext.swift b/Yattee/Views/Player/Panels/PanelPageContext.swift index 7d883ae1..e8625308 100644 --- a/Yattee/Views/Player/Panels/PanelPageContext.swift +++ b/Yattee/Views/Player/Panels/PanelPageContext.swift @@ -38,6 +38,11 @@ struct PanelScrollConfig { /// Toggling this scrolls the page back to the top. var scrollToTopTrigger: Bool = false + /// Identity of the content being shown (the video). When it changes the + /// page jumps back to the top without animation so the new title is + /// visible. Set by `PlayerPanelContentView`. + var contentID: AnyHashable? + /// Disables scrolling (while the portrait drag handle is active). var isScrollDisabled: Bool = false @@ -163,6 +168,14 @@ struct PanelPageScrollView: View { proxy.scrollTo("panelPageTop", anchor: .top) } } + .onChange(of: config.contentID) { _, _ in + var transaction = Transaction() + transaction.disablesAnimations = true + withTransaction(transaction) { + proxy.scrollTo("panelPageTop", anchor: .top) + } + config.scrollOffsetChanged?(0) + } } } } diff --git a/Yattee/Views/Player/Panels/PlayerPanelContentView.swift b/Yattee/Views/Player/Panels/PlayerPanelContentView.swift index 008a14fc..c72b71a3 100644 --- a/Yattee/Views/Player/Panels/PlayerPanelContentView.swift +++ b/Yattee/Views/Player/Panels/PlayerPanelContentView.swift @@ -159,8 +159,17 @@ struct PlayerPanelContentView: View { case .info: InfoPanelPage( context: context, + /// The host's scroll config keyed to the current video so pages jump to + /// the top when the video changes. + private var pageScrollConfig: PanelScrollConfig { + var config = scrollConfig + config.contentID = AnyHashable(context.video.id) + return config + } + settings: page.infoSettings, scrollConfig: scrollConfig, + let scrollConfig = pageScrollConfig inlineSections: inlineInfoSections ) .id(PanelPageType.info)