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)