new app store assets ready for relese ui updates

This commit is contained in:
Mark Gregory
2026-11-05 09:33:59 +00:00
parent 0cd223cd75
commit e68a6598fc
4 changed files with 43 additions and 12 deletions
+2 -2
View File
@@ -144,12 +144,12 @@ struct TorrentRow: View {
var body: some View {
VStack(alignment: .leading, spacing: 10) {
(dynamicTypeSize.isAccessibilitySize ? AnyLayout(VStackLayout(alignment: .leading, spacing: 6)) : AnyLayout(HStackLayout(alignment: .top))) {
Image(systemName: torrent.complete ? "checkmark.circle.fill" : "arrow.down.circle.fill").foregroundStyle(torrent.complete ? .green : .yellow).font(.title2)
Image(systemName: torrent.complete ? "checkmark.circle.fill" : "arrow.down.circle.fill").foregroundStyle(torrent.statusColor).font(.title2)
Text(torrent.name).font(.headline).lineLimit(dynamicTypeSize.isAccessibilitySize ? nil : 2)
if !dynamicTypeSize.isAccessibilitySize { Spacer() }
Text(torrent.progress, format: .percent.precision(.fractionLength(1))).font(.subheadline.monospacedDigit()).foregroundStyle(.secondary)
}
ProgressView(value: torrent.complete ? 1 : min(max(torrent.progress, 0), 1)).tint(torrent.complete ? .green : .yellow).accessibilityLabel("Download progress")
ProgressView(value: torrent.complete ? 1 : min(max(torrent.progress, 0), 1)).tint(torrent.statusColor).accessibilityLabel("Download progress")
(dynamicTypeSize.isAccessibilitySize ? AnyLayout(VStackLayout(alignment: .leading, spacing: 6)) : AnyLayout(HStackLayout())) {
Label(bytes(torrent.dlspeed) + "/s", systemImage: "arrow.down").accessibilityLabel("Download speed").accessibilityValue(bytes(torrent.dlspeed) + " per second")
Label(bytes(torrent.upspeed) + "/s", systemImage: "arrow.up").accessibilityLabel("Upload speed").accessibilityValue(bytes(torrent.upspeed) + " per second")
+7
View File
@@ -43,6 +43,13 @@ struct Torrent: Decodable, Identifiable, Hashable {
var ratio: Double; var category: String; var tags: String
var id: String { hash }
var complete: Bool { progress >= 1 || ["uploading", "stalledUP", "forcedUP", "queuedUP", "pausedUP", "stoppedUP"].contains(state) }
var statusColor: Color {
if ["error", "missingFiles"].contains(state) || state.hasPrefix("stalled") { return .red }
if paused { return .pink }
if state.hasPrefix("queued") { return .orange }
if ["uploading", "forcedUP"].contains(state) { return .purple }
return complete ? .green : .yellow
}
var paused: Bool { state.hasPrefix("paused") || state.hasPrefix("stopped") }
var active: Bool { ["downloading", "forcedDL", "metaDL", "forcedMetaDL"].contains(state) }
}
+30 -10
View File
@@ -21,10 +21,11 @@ struct DetailView: View {
List {
Section { TorrentRow(torrent: live) }
Section {
ViewThatFits(in: .horizontal) {
HStack { primaryControls }
VStack(alignment: .leading) { primaryControls }
}.buttonStyle(.bordered).controlSize(.regular)
if dynamicTypeSize.isAccessibilitySize {
VStack(spacing: 8) { primaryControls }
} else {
HStack(spacing: 8) { primaryControls }
}
if model.pendingActions.contains(torrent.hash) { ProgressView("Applying action…") }
if let feedback = model.actionFeedback { Text(feedback).font(.callout) }
}
@@ -71,12 +72,15 @@ struct DetailView: View {
}
}
@ViewBuilder var primaryControls: some View {
Button("Resume", systemImage: "play.fill") { Task { await model.action("resume", hash: torrent.hash) } }
.frame(minHeight: 44).disabled(!live.paused || model.pendingActions.contains(torrent.hash))
Button("Pause", systemImage: "pause.fill") { Task { await model.action("pause", hash: torrent.hash) } }
.frame(minHeight: 44).disabled(live.paused || model.pendingActions.contains(torrent.hash))
Menu("More", systemImage: "ellipsis.circle") { controls }
.frame(minHeight: 44).disabled(model.pendingActions.contains(torrent.hash) || !model.connected)
Button("Resume") { Task { await model.action("resume", hash: torrent.hash) } }
.buttonStyle(TorrentActionButtonStyle())
.disabled(!live.paused || model.pendingActions.contains(torrent.hash) || !model.connected)
Button("Pause") { Task { await model.action("pause", hash: torrent.hash) } }
.buttonStyle(TorrentActionButtonStyle())
.disabled(live.paused || model.pendingActions.contains(torrent.hash) || !model.connected)
Menu { controls } label: { Text("More") }
.buttonStyle(TorrentActionButtonStyle())
.disabled(model.pendingActions.contains(torrent.hash) || !model.connected)
}
var controls: some View {
Group {
@@ -194,3 +198,19 @@ struct KeyValues: View {
}
}
import CoreFoundation
// Identical label frames keep the two buttons and the menu the same size.
private struct TorrentActionButtonStyle: ButtonStyle {
@Environment(\.isEnabled) private var isEnabled
func makeBody(configuration: Configuration) -> some View {
configuration.label
.font(.subheadline.weight(.medium))
.multilineTextAlignment(.center)
.padding(.horizontal, 4)
.frame(maxWidth: .infinity, minHeight: 44)
.foregroundStyle(isEnabled ? Color.accentColor : Color.secondary)
.background(Color.accentColor.opacity(configuration.isPressed ? 0.24 : 0.10), in: RoundedRectangle(cornerRadius: 10))
.contentShape(RoundedRectangle(cornerRadius: 10))
.opacity(isEnabled ? 1 : 0.55)
}
}
+4
View File
@@ -105,3 +105,7 @@ Build 7 adds blue/indigo/violet download strokes, teal dashed upload strokes, in
Device acceptance still required: narrow iPhone/iPad widths and largest Dynamic Type, live server actions, Settings navigation under poor connectivity, background/relaunch graph restoration, notification permission denial and successful completion delivery. No signed deployment performed for this update.
Final verification: unsigned generic iOS device Debug build **BUILD SUCCEEDED**; **91 executable model/transport/persistence/formatting contract checks passed**, including Settings view cancellation and real-error reporting; three provisioning-profile tests passed; project/Info.plist validation and diff whitespace checks passed. Logs: ~/Developer/Scratch/Tarnax/build-verified.log and tests-verified.log. Physical-device and live-server verification remain outstanding.
### Status colours and detail controls — 5 November 2026
Shared torrent icons and bars now use yellow for downloads, purple for active seeding, red for stalled/error/missing files, pink for paused/stopped, orange for queued, and green for other completed transfers. Status-specific colours take priority over completion. Detail Resume/Pause/More share one button style with equal widths, 44-point minimum touch height, smaller subheadline labels and pressed feedback. Accessibility text sizes stack the controls vertically. Unsigned generic iOS Debug build succeeded; physical-device visual verification remains outstanding. Temporary build files and log are under ~/Developer/Scratch/Tarnax.