diff --git a/README.md b/README.md index f8d5b9c..e4ab64f 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ Use the titlebar's **Queue** icon or **View → Show Queue** to show the editabl In a normal window, showing the queue expands the window outward while preserving the video's size; hiding it removes that extra width. The window shifts left when necessary near the screen's right edge. Fullscreen keeps its fixed bounds. -The queue count and window controls share the top bar across the full expanded window; the sidebar starts with queue navigation and Add to Queue. +While the sidebar is open, its persistent top header holds the queue count, queue toggle, pin, Cast and settings controls; these do not fade with the video controls. Closing the sidebar returns those controls to the auto-hiding video titlebar. Playback advances automatically and stops at the end, without wrapping. **Previous Queue Item** and **Next Queue Item** are available in the sidebar and Playback menu and are disabled at their respective ends. Reordering or removing another item does not interrupt playback; removing the current item plays its next neighbor, or stops if there is none. A playback error stays on that item rather than skipping it. diff --git a/Sources/App/TerebiApp.swift b/Sources/App/TerebiApp.swift index eaa720c..faa088f 100644 --- a/Sources/App/TerebiApp.swift +++ b/Sources/App/TerebiApp.swift @@ -2043,16 +2043,9 @@ private struct PlayerContent: View { .frame(height: 24) .background(PlayerGlass(cornerRadius: 8).clipShape(RoundedRectangle(cornerRadius: 8)).allowsHitTesting(false)) Spacer(minLength: 12) - if model.showsQueue { - HStack(spacing: 4) { - Text("Queue").fontWeight(.semibold) - Text("\(model.queue.items.count)").foregroundStyle(.secondary) - } - .font(.system(size: 13)) - .padding(.trailing, 8) - .accessibilityElement(children: .combine) + if !model.showsQueue { + titleControls } - titleControls } .padding(.leading, model.isFullScreen ? 16 : 86) .padding(.trailing, 12) @@ -2249,6 +2242,18 @@ private struct PlayerContent: View { private var queueSidebar: some View { VStack(spacing: 0) { + HStack(spacing: 4) { + HStack(spacing: 4) { + Text("Queue").fontWeight(.semibold) + Text("\(model.queue.items.count)").foregroundStyle(.secondary) + } + .font(.system(size: 13)) + .accessibilityElement(children: .combine) + Spacer(minLength: 4) + titleControls + } + .padding(.horizontal, 12) + .frame(height: 32) HStack { iconButton("backward.end.fill", "Previous Queue Item") { model.advanceQueue(-1) } .disabled(!model.canPreviousQueueItem) @@ -2309,7 +2314,6 @@ private struct PlayerContent: View { } } .frame(width: 260) - .padding(.top, 32) .background(PlayerGlass(cornerRadius: 0)) .dropDestination(for: URL.self) { urls, _ in guard model.canOpen, urls.contains(where: \.isFileURL) else { return false } @@ -2327,12 +2331,6 @@ private struct PlayerContent: View { queueSidebar } } - .overlay(alignment: .top) { - titlebar - .opacity(model.isCompact || model.compactWindow.isTransitioning ? 0 : 1) - .allowsHitTesting(!model.isCompact && !model.compactWindow.isTransitioning && model.controlsVisible) - .accessibilityHidden(model.isCompact || model.compactWindow.isTransitioning || !model.controlsVisible) - } .frame(minWidth: model.isCompact || model.compactWindow.isTransitioning ? 160 : (model.showsQueue ? 660 : 400), minHeight: model.isCompact || model.compactWindow.isTransitioning ? model.compactContentMinimumHeight : 240) .ignoresSafeArea() @@ -2554,7 +2552,11 @@ private struct PlayerContent: View { .allowsHitTesting(model.isCompact) .accessibilityHidden(!model.isCompact) - + titlebar + .frame(width: geometry.size.width) + .opacity(model.isCompact || model.compactWindow.isTransitioning ? 0 : 1) + .allowsHitTesting(!model.isCompact && !model.compactWindow.isTransitioning && model.controlsVisible) + .accessibilityHidden(model.isCompact || model.compactWindow.isTransitioning || !model.controlsVisible) if model.canTogglePlayback { playbackControls .frame(width: 440, height: controlHeight)