Merge pull request 'fix: settings form alignment — grouped form, aligned labels' (#13) from fix/settings-form-alignment-20260901 into feat/shotdeck-20260830

This commit was merged in pull request #13.
This commit is contained in:
2026-09-01 09:13:09 +00:00
+64 -24
View File
@@ -5,39 +5,79 @@ import ShotdeckCore
struct SettingsView: View {
@Environment(AppModel.self) private var model
private let labelWidth: CGFloat = 104
var body: some View {
Form {
Section("Hotkey") {
LabeledContent("Capture", value: "⌥⇧2 — fixed in this version")
Grid(alignment: .leading, horizontalSpacing: 12, verticalSpacing: 10) {
GridRow {
Text("Hotkey")
.font(.headline)
.frame(maxWidth: .infinity, alignment: .leading)
.gridCellColumns(2)
}
Section("Folders") {
LabeledContent("Watch folder") {
HStack(spacing: 8) {
Text(model.watchFolderURL.path)
.lineLimit(1)
.truncationMode(.middle)
.foregroundStyle(.secondary)
Button("Choose…") { model.chooseWatchFolder() }
}
}
LabeledContent("Output folder") {
HStack(spacing: 8) {
Text(model.outboxURL.path)
.lineLimit(1)
.truncationMode(.middle)
.foregroundStyle(.secondary)
Button("Choose…") { model.chooseOutboxFolder() }
}
GridRow(alignment: .firstTextBaseline) {
fieldLabel("Capture")
Text("⌥⇧2 — fixed in this version")
.foregroundStyle(.secondary)
.lineLimit(1)
.frame(maxWidth: .infinity, alignment: .leading)
.frame(minHeight: 22, alignment: .leading)
}
GridRow {
Text("Folders")
.font(.headline)
.frame(maxWidth: .infinity, alignment: .leading)
.gridCellColumns(2)
.padding(.top, 6)
}
GridRow(alignment: .center) {
fieldLabel("Watch folder")
folderValue(path: model.watchFolderURL.path) {
model.chooseWatchFolder()
}
}
Section {
GridRow(alignment: .center) {
fieldLabel("Output folder")
folderValue(path: model.outboxURL.path) {
model.chooseOutboxFolder()
}
}
GridRow {
Button("Reveal spool folder") { model.openSpoolFolder() }
.gridCellColumns(2)
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.top, 4)
}
}
.padding()
.frame(width: 360)
.padding(16)
.frame(minWidth: 320, idealWidth: 360, maxWidth: 360, alignment: .leading)
.controlSize(.small)
}
private func fieldLabel(_ title: String) -> some View {
Text(title)
.lineLimit(1)
.frame(width: labelWidth, alignment: .trailing)
.gridColumnAlignment(.trailing)
.frame(minHeight: 22, alignment: .trailing)
}
private func folderValue(path: String, choose: @escaping () -> Void) -> some View {
HStack(spacing: 8) {
Text(path)
.lineLimit(1)
.truncationMode(.middle)
.foregroundStyle(.secondary)
.frame(maxWidth: .infinity, alignment: .leading)
Button("Choose…") { choose() }
}
.frame(minHeight: 22)
}
}
extension AppModel: SettingsWindowPresenting {