style: clarify queue rows with format labels and current-item highlight
This commit is contained in:
@@ -63,7 +63,7 @@ Use the **Queue** icon immediately left of the compact-mode button in the playba
|
||||
|
||||
The fixed bottom row holds the queue label/count and **+** on the left, with previous/next controls on the right. Its text and icons share a 15-point size. The **+** is a 20-point rounded-square button with an accent-tinted background and an 8-point gap after the queue count.
|
||||
|
||||
Queue rows use equal-width leading and remove-icon slots, with 8-point outer insets matching the gaps between icons and filenames and no additional horizontal scroll-content margin.
|
||||
Queue rows show a medium-weight, two-line filename without its extension, with a smaller format label beneath it. Rows have a 56-point minimum height, 8-point internal padding and separate outer insets; leading and remove icons are smaller and subdued. The current item has an accent play marker and a subtle rounded highlight. Full filenames and paths remain available in row tooltips.
|
||||
|
||||
In a normal window, showing the queue expands the window outward while preserving the video's size; hiding it removes that extra width. The sidebar meets the video directly, without a separate divider gap. The window shifts left when necessary near the screen's right edge. Fullscreen keeps its fixed bounds.
|
||||
|
||||
|
||||
@@ -2289,23 +2289,45 @@ private struct PlayerContent: View {
|
||||
Color.clear.frame(height: 32)
|
||||
List {
|
||||
ForEach(model.queue.items) { item in
|
||||
let isCurrent = item.id == model.queue.currentID
|
||||
HStack(spacing: 8) {
|
||||
Image(systemName: item.id == model.queue.currentID ? "play.fill" : "film")
|
||||
.foregroundStyle(item.id == model.queue.currentID ? Color.accentColor : .secondary)
|
||||
Image(systemName: isCurrent ? "play.fill" : "film")
|
||||
.font(.system(size: 12))
|
||||
.foregroundStyle(isCurrent ? Color(SunsetPalette.accent) : Color(SunsetPalette.secondaryText).opacity(0.6))
|
||||
.frame(width: 20, alignment: .center)
|
||||
.accessibilityLabel(item.id == model.queue.currentID ? "Current item" : "Queued item")
|
||||
Text(item.url.lastPathComponent)
|
||||
.accessibilityLabel(isCurrent ? "Current item" : "Queued item")
|
||||
VStack(alignment: .leading, spacing: 3) {
|
||||
Text(item.url.deletingPathExtension().lastPathComponent)
|
||||
.font(.system(size: 13, weight: .medium))
|
||||
.lineLimit(2)
|
||||
.lineSpacing(2)
|
||||
.truncationMode(.middle)
|
||||
if !item.url.pathExtension.isEmpty {
|
||||
Text(item.url.pathExtension.uppercased())
|
||||
.font(.system(size: 10, weight: .medium))
|
||||
.tracking(0.6)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
Button { model.removeQueueItem(item.id) } label: {
|
||||
Image(systemName: "minus.circle")
|
||||
.frame(width: 20, alignment: .center)
|
||||
.font(.system(size: 12))
|
||||
.foregroundStyle(.secondary)
|
||||
.frame(width: 20, height: 24)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.help("Remove from Queue")
|
||||
.accessibilityLabel("Remove \(item.url.lastPathComponent) from Queue")
|
||||
}
|
||||
.padding(8)
|
||||
.frame(minHeight: 56)
|
||||
.background {
|
||||
if isCurrent {
|
||||
RoundedRectangle(cornerRadius: 8)
|
||||
.fill(Color(SunsetPalette.actionFill))
|
||||
}
|
||||
}
|
||||
.contentShape(Rectangle())
|
||||
.onTapGesture(count: 2) { model.selectQueueItem(item.id) }
|
||||
.help(item.url.path + "\nDouble-click to play; drag to reorder.")
|
||||
@@ -2322,7 +2344,8 @@ private struct PlayerContent: View {
|
||||
}
|
||||
}
|
||||
.accessibilityAction(named: Text("Play")) { model.selectQueueItem(item.id) }
|
||||
.listRowInsets(EdgeInsets(top: 0, leading: 8, bottom: 0, trailing: 8))
|
||||
.listRowInsets(EdgeInsets(top: 2, leading: 8, bottom: 2, trailing: 8))
|
||||
.listRowSeparator(.hidden)
|
||||
}
|
||||
.onMove { model.moveQueueItems(fromOffsets: $0, toOffset: $1) }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user