fix: align queue header and window controls

This commit is contained in:
2026-10-18 01:19:05 +02:00
parent 1d33f5d572
commit fc857870de
2 changed files with 18 additions and 18 deletions
+2
View File
@@ -59,6 +59,8 @@ 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. 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.
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. 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.
The queue contains local files only and lasts until it is replaced, closed or the app quits; it has no persistence, shuffle, repeat or playlist-file import. Opening a YouTube video or resolved stream clears it. The sidebar is hidden in compact mode; Playback-menu queue navigation remains available. Sidebar appearance, drag/drop interaction and physical-receiver queue transitions still need manual verification. The queue contains local files only and lasts until it is replaced, closed or the app quits; it has no persistence, shuffle, repeat or playlist-file import. Opening a YouTube video or resolved stream clears it. The sidebar is hidden in compact mode; Playback-menu queue navigation remains available. Sidebar appearance, drag/drop interaction and physical-receiver queue transitions still need manual verification.
+16 -18
View File
@@ -2043,6 +2043,15 @@ private struct PlayerContent: View {
.frame(height: 24) .frame(height: 24)
.background(PlayerGlass(cornerRadius: 8).clipShape(RoundedRectangle(cornerRadius: 8)).allowsHitTesting(false)) .background(PlayerGlass(cornerRadius: 8).clipShape(RoundedRectangle(cornerRadius: 8)).allowsHitTesting(false))
Spacer(minLength: 12) 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)
}
titleControls titleControls
} }
.padding(.leading, model.isFullScreen ? 16 : 86) .padding(.leading, model.isFullScreen ? 16 : 86)
@@ -2240,17 +2249,6 @@ private struct PlayerContent: View {
private var queueSidebar: some View { private var queueSidebar: some View {
VStack(spacing: 0) { VStack(spacing: 0) {
HStack {
Text("Queue").font(.headline)
Text("\(model.queue.items.count)").foregroundStyle(.secondary)
Spacer()
Button { model.showsQueue = false } label: {
Image(systemName: "sidebar.right")
}
.help("Hide Queue")
.accessibilityLabel("Hide Queue")
}
.padding(12)
HStack { HStack {
iconButton("backward.end.fill", "Previous Queue Item") { model.advanceQueue(-1) } iconButton("backward.end.fill", "Previous Queue Item") { model.advanceQueue(-1) }
.disabled(!model.canPreviousQueueItem) .disabled(!model.canPreviousQueueItem)
@@ -2266,6 +2264,7 @@ private struct PlayerContent: View {
HStack(spacing: 8) { HStack(spacing: 8) {
Image(systemName: item.id == model.queue.currentID ? "play.fill" : "film") Image(systemName: item.id == model.queue.currentID ? "play.fill" : "film")
.foregroundStyle(item.id == model.queue.currentID ? Color.accentColor : .secondary) .foregroundStyle(item.id == model.queue.currentID ? Color.accentColor : .secondary)
.frame(width: 20, alignment: .center)
.accessibilityLabel(item.id == model.queue.currentID ? "Current item" : "Queued item") .accessibilityLabel(item.id == model.queue.currentID ? "Current item" : "Queued item")
Text(item.url.lastPathComponent) Text(item.url.lastPathComponent)
.lineLimit(2) .lineLimit(2)
@@ -2328,6 +2327,12 @@ private struct PlayerContent: View {
queueSidebar 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), .frame(minWidth: model.isCompact || model.compactWindow.isTransitioning ? 160 : (model.showsQueue ? 660 : 400),
minHeight: model.isCompact || model.compactWindow.isTransitioning ? model.compactContentMinimumHeight : 240) minHeight: model.isCompact || model.compactWindow.isTransitioning ? model.compactContentMinimumHeight : 240)
.ignoresSafeArea() .ignoresSafeArea()
@@ -2549,13 +2554,6 @@ private struct PlayerContent: View {
.allowsHitTesting(model.isCompact) .allowsHitTesting(model.isCompact)
.accessibilityHidden(!model.isCompact) .accessibilityHidden(!model.isCompact)
titlebar
.frame(width: geometry.size.width)
.animation(compactChromeAnimation) { content in
content.opacity(model.isCompact ? 0 : 1)
}
.allowsHitTesting(!model.isCompact && model.controlsVisible)
.accessibilityHidden(model.isCompact || !model.controlsVisible)
if model.canTogglePlayback { if model.canTogglePlayback {
playbackControls playbackControls