summaryrefslogtreecommitdiff
path: root/Hutch/Views/More
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-04-13 19:06:54 -0500
committerChristian Cleberg <[email protected]>2026-04-13 19:06:54 -0500
commita6ad2b9815d72575206bdca860eef9db850cdf1c (patch)
treeb4d5f27aa1655e5e40bab178550d6e2576d7df8b /Hutch/Views/More
parent02a44d115b3784231cad640e992d9c18a7f67b40 (diff)
downloadhutch-a6ad2b9815d72575206bdca860eef9db850cdf1c.tar.gz
hutch-a6ad2b9815d72575206bdca860eef9db850cdf1c.tar.bz2
hutch-a6ad2b9815d72575206bdca860eef9db850cdf1c.zip
feat(theme): AMOLED true-black rows via themedRow()
Apply listRowBackground(Color.black) per row in AMOLED mode using ThemedRowStyle and themedRow() across Lists and Forms. Use themedList() for scroll/grouped backgrounds. Treat segmented and clear list rows with isAMOLED-aware listRowBackground where Color.clear was required. Removes reliance on UIKit appearance for list cells on iOS 16+. Implements: https://todo.sr.ht/~ccleberg/hutch/24
Diffstat (limited to 'Hutch/Views/More')
-rw-r--r--Hutch/Views/More/AccountSwitcherView.swift3
-rw-r--r--Hutch/Views/More/AddAccountView.swift3
-rw-r--r--Hutch/Views/More/ManPageBrowserView.swift2
-rw-r--r--Hutch/Views/More/MoreView.swift9
-rw-r--r--Hutch/Views/More/ProfileView.swift31
5 files changed, 46 insertions, 2 deletions
diff --git a/Hutch/Views/More/AccountSwitcherView.swift b/Hutch/Views/More/AccountSwitcherView.swift
index 5fde9c5..ce69279 100644
--- a/Hutch/Views/More/AccountSwitcherView.swift
+++ b/Hutch/Views/More/AccountSwitcherView.swift
@@ -48,6 +48,7 @@ struct AccountSwitcherView: View {
pendingRemoval = appState.accounts[index]
}
}
+ .themedRow()
}
Section {
@@ -57,8 +58,10 @@ struct AccountSwitcherView: View {
Label("Add Account", systemImage: "plus.circle")
}
.disabled(isSwitching)
+ .themedRow()
}
}
+ .themedList()
.navigationTitle("Accounts")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
diff --git a/Hutch/Views/More/AddAccountView.swift b/Hutch/Views/More/AddAccountView.swift
index cfaa2b2..c15db09 100644
--- a/Hutch/Views/More/AddAccountView.swift
+++ b/Hutch/Views/More/AddAccountView.swift
@@ -15,6 +15,7 @@ struct AddAccountView: View {
SecureField("Personal Access Token", text: $token)
.autocorrectionDisabled()
.textInputAutocapitalization(.never)
+ .themedRow()
} footer: {
Text("Generate a token at meta.sr.ht → OAuth2 clients.")
}
@@ -23,9 +24,11 @@ struct AddAccountView: View {
Section {
Text(errorMessage)
.foregroundStyle(.red)
+ .themedRow()
}
}
}
+ .themedList()
.navigationTitle("Add Account")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
diff --git a/Hutch/Views/More/ManPageBrowserView.swift b/Hutch/Views/More/ManPageBrowserView.swift
index f854c79..c22eafe 100644
--- a/Hutch/Views/More/ManPageBrowserView.swift
+++ b/Hutch/Views/More/ManPageBrowserView.swift
@@ -25,8 +25,10 @@ struct ManPageBrowserView: View {
Text(doc.title)
}
}
+ .themedRow()
}
}
+ .themedList()
.navigationTitle("Man Pages")
.navigationBarTitleDisplayMode(.inline)
}
diff --git a/Hutch/Views/More/MoreView.swift b/Hutch/Views/More/MoreView.swift
index 8be25ca..4666e53 100644
--- a/Hutch/Views/More/MoreView.swift
+++ b/Hutch/Views/More/MoreView.swift
@@ -16,24 +16,29 @@ struct MoreView: View {
NavigationLink(value: MoreRoute.lookup) {
Label("Look Up", systemImage: "magnifyingglass")
}
+ .themedRow()
}
Section("Other Services") {
NavigationLink(value: MoreRoute.projects) {
Label("Projects", systemImage: "square.stack.3d.up")
}
+ .themedRow()
NavigationLink(value: MoreRoute.lists) {
Label("Mailing Lists", systemImage: "list.bullet.rectangle")
}
+ .themedRow()
NavigationLink(value: MoreRoute.manPageBrowser) {
Label("Man Pages", systemImage: "book")
}
+ .themedRow()
NavigationLink(value: MoreRoute.pastes) {
Label("Pastes", systemImage: "doc.on.clipboard")
}
+ .themedRow()
NavigationLink(value: MoreRoute.systemStatus) {
SystemStatusSummaryRow(
@@ -43,16 +48,19 @@ struct MoreView: View {
isShowingStaleData: viewModel?.isShowingStaleSystemStatus ?? false
)
}
+ .themedRow()
}
Section("Meta") {
NavigationLink(value: MoreRoute.profile) {
Label("Profile", systemImage: "person.text.rectangle")
}
+ .themedRow()
NavigationLink(value: MoreRoute.settings) {
Label("Settings", systemImage: "gear")
}
+ .themedRow()
}
Section {
@@ -61,6 +69,7 @@ struct MoreView: View {
Label(item.title, systemImage: "safari")
}
}
+ .themedRow()
} header: {
Text("External Links")
} footer: {
diff --git a/Hutch/Views/More/ProfileView.swift b/Hutch/Views/More/ProfileView.swift
index db3cb53..c53a89d 100644
--- a/Hutch/Views/More/ProfileView.swift
+++ b/Hutch/Views/More/ProfileView.swift
@@ -79,6 +79,7 @@ struct ProfileView: View {
error: contributionViewModel.contributionsError ?? contributionViewModel.contributionStatusText,
isIndexedButEmpty: contributionViewModel.isContributionActivityIndexedButEmpty
)
+ .themedRow()
}
}
@@ -185,6 +186,7 @@ struct ProfileView: View {
}
}
.padding(.vertical, 4)
+ .themedRow()
if let bio = profile.bio, !bio.isEmpty {
VStack(alignment: .leading, spacing: 2) {
@@ -193,36 +195,44 @@ struct ProfileView: View {
.foregroundStyle(.secondary)
ProfileBioView(markdown: bio)
}
+ .themedRow()
}
if let location = profile.location, !location.isEmpty {
LabeledContent("Location", value: location)
+ .themedRow()
}
if let url = profile.url, !url.isEmpty {
LabeledContent("URL", value: url)
+ .themedRow()
}
if let status = profile.paymentStatus {
LabeledContent("Payment", value: status.capitalized)
+ .themedRow()
}
if let sub = profile.subscription {
if let status = sub.status {
LabeledContent("Subscription", value: status.capitalized)
+ .themedRow()
}
if let interval = sub.interval {
LabeledContent("Interval", value: interval.capitalized)
+ .themedRow()
}
}
Button("Edit Profile") {
viewModel.isEditingProfile = true
}
+ .themedRow()
SRHTShareButton(url: SRHTWebURL.profile(canonicalName: profile.canonicalName), target: .profile) {
SwiftUI.Label("Share Profile", systemImage: "square.and.arrow.up")
}
+ .themedRow()
}
}
@@ -262,11 +272,13 @@ struct ProfileView: View {
}
}
}
+ .themedRow()
if viewModel.isAddingSSHKey {
TextField("Paste SSH public key", text: $vm.newSSHKey, axis: .vertical)
.font(.caption.monospaced())
.lineLimit(3...6)
+ .themedRow()
HStack {
Button("Cancel") {
@@ -280,12 +292,14 @@ struct ProfileView: View {
.buttonStyle(.borderedProminent)
.disabled(viewModel.newSSHKey.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty)
}
+ .themedRow()
} else {
Button {
viewModel.isAddingSSHKey = true
} label: {
SwiftUI.Label("Add SSH Key", systemImage: "key")
}
+ .themedRow()
}
} header: {
Text("SSH Keys")
@@ -316,11 +330,13 @@ struct ProfileView: View {
}
}
}
+ .themedRow()
if viewModel.isAddingPGPKey {
TextField("Paste PGP public key", text: $vm.newPGPKey, axis: .vertical)
.font(.caption.monospaced())
.lineLimit(3...6)
+ .themedRow()
HStack {
Button("Cancel") {
@@ -334,12 +350,14 @@ struct ProfileView: View {
.buttonStyle(.borderedProminent)
.disabled(viewModel.newPGPKey.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty)
}
+ .themedRow()
} else {
Button {
viewModel.isAddingPGPKey = true
} label: {
SwiftUI.Label("Add PGP Key", systemImage: "key.fill")
}
+ .themedRow()
}
} header: {
Text("PGP Keys")
@@ -357,10 +375,12 @@ struct ProfileView: View {
ProgressView()
Spacer()
}
+ .themedRow()
} else if viewModel.personalAccessTokens.isEmpty {
Button("Load Tokens") {
Task { await viewModel.loadPersonalAccessTokens() }
}
+ .themedRow()
} else {
ForEach(viewModel.personalAccessTokens) { token in
VStack(alignment: .leading, spacing: 4) {
@@ -390,6 +410,7 @@ struct ProfileView: View {
}
}
}
+ .themedRow()
}
} header: {
Text("Personal Access Tokens")
@@ -426,6 +447,7 @@ private struct EditProfileSheet: View {
let profile: UserProfile
let viewModel: SettingsViewModel
+ @Environment(\.isAMOLEDTheme) private var isAMOLED
@State private var email: String
@State private var url: String
@State private var location: String
@@ -492,7 +514,7 @@ private struct EditProfileSheet: View {
}
Spacer()
}
- .listRowBackground(Color.clear)
+ .listRowBackground(isAMOLED ? Color.black : Color.clear)
if profile.avatar != nil || avatarPreview != nil {
HStack {
@@ -506,7 +528,7 @@ private struct EditProfileSheet: View {
.disabled(viewModel.isUploadingAvatar)
Spacer()
}
- .listRowBackground(Color.clear)
+ .listRowBackground(isAMOLED ? Color.black : Color.clear)
.listRowSeparator(.hidden)
}
}
@@ -522,6 +544,7 @@ private struct EditProfileSheet: View {
.autocorrectionDisabled()
.textInputAutocapitalization(.never)
}
+ .themedRow()
VStack(alignment: .leading, spacing: 4) {
Text("URL")
@@ -533,6 +556,7 @@ private struct EditProfileSheet: View {
.autocorrectionDisabled()
.textInputAutocapitalization(.never)
}
+ .themedRow()
VStack(alignment: .leading, spacing: 4) {
Text("Location")
@@ -540,6 +564,7 @@ private struct EditProfileSheet: View {
.foregroundStyle(.secondary)
TextField("Enter location", text: $location)
}
+ .themedRow()
VStack(alignment: .leading, spacing: 4) {
Text("Bio")
@@ -548,8 +573,10 @@ private struct EditProfileSheet: View {
TextField("Enter bio", text: $bio, axis: .vertical)
.lineLimit(3...6)
}
+ .themedRow()
}
}
+ .themedList()
.navigationTitle("Edit Profile")
.navigationBarTitleDisplayMode(.inline)
.onChange(of: selectedPhoto) { _, newItem in