Commit 77df444b20

77df444b20bc0e380a17abffc9f5688452c7c721

parent: fa8188260f

Unsigned

cmc <hello@cleberg.net> · 2026-03-19 22:05 UTC

fix README height update and settings save alerts

Layout: unified · split

Hutch.xcodeproj/project.pbxproj +4 −4
@@ -359,7 +359,7 @@
359359 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
360360 ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
361361 CODE_SIGN_STYLE = Automatic;
362 CURRENT_PROJECT_VERSION = 5;
362 CURRENT_PROJECT_VERSION = 6;
363363 DEVELOPMENT_TEAM = ZCNAX3VL9D;
364364 ENABLE_PREVIEWS = YES;
365365 GENERATE_INFOPLIST_FILE = YES;
@@ -376,7 +376,7 @@
376376 "$(inherited)",
377377 "@executable_path/Frameworks",
378378 );
379 MARKETING_VERSION = 2.0;
379 MARKETING_VERSION = 2.1;
380380 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch;
381381 PRODUCT_NAME = "$(TARGET_NAME)";
382382 STRING_CATALOG_GENERATE_SYMBOLS = YES;
@@ -395,7 +395,7 @@
395395 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
396396 ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
397397 CODE_SIGN_STYLE = Automatic;
398 CURRENT_PROJECT_VERSION = 5;
398 CURRENT_PROJECT_VERSION = 6;
399399 DEVELOPMENT_TEAM = ZCNAX3VL9D;
400400 ENABLE_PREVIEWS = YES;
401401 GENERATE_INFOPLIST_FILE = YES;
@@ -412,7 +412,7 @@
412412 "$(inherited)",
413413 "@executable_path/Frameworks",
414414 );
415 MARKETING_VERSION = 2.0;
415 MARKETING_VERSION = 2.1;
416416 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch;
417417 PRODUCT_NAME = "$(TARGET_NAME)";
418418 STRING_CATALOG_GENERATE_SYMBOLS = YES;
Hutch/Views/Repositories/HgRepositorySettingsView.swift +29 −2
@@ -9,6 +9,7 @@ struct HgRepositorySettingsView: View {
99 @State private var viewModel: HgRepositorySettingsViewModel?
1010 @State private var showDeleteConfirmation = false
1111 @State private var pendingACLDeletion: HgACLEntry?
12 @State private var saveResultAlert: SaveResultAlert?
1213
1314 var body: some View {
1415 NavigationStack {
@@ -88,6 +89,13 @@ struct HgRepositorySettingsView: View {
8889 Text("\(entry.entity.canonicalName) will lose \(entry.mode) access to this repository.")
8990 }
9091 }
92 .alert(item: $saveResultAlert) { alert in
93 Alert(
94 title: Text(alert.title),
95 message: Text(alert.message),
96 dismissButton: .default(Text("OK"))
97 )
98 }
9199 }
92100
93101 @ViewBuilder
@@ -108,7 +116,13 @@ struct HgRepositorySettingsView: View {
108116 }
109117
110118 Button {
111 Task { await viewModel.saveInfo() }
119 Task {
120 let didSave = await viewModel.saveInfo()
121 saveResultAlert = SaveResultAlert(
122 title: didSave ? "Settings Updated" : "Couldn't Update Settings",
123 message: didSave ? "Repository settings were saved." : (viewModel.error ?? "Please try again.")
124 )
125 }
112126 } label: {
113127 if viewModel.isSavingInfo {
114128 ProgressView()
@@ -188,7 +202,13 @@ struct HgRepositorySettingsView: View {
188202 Toggle("Hide this repository from public listings", isOn: Bindable(viewModel).editedNonPublishing)
189203
190204 Button {
191 Task { await viewModel.saveInfo() }
205 Task {
206 let didSave = await viewModel.saveInfo()
207 saveResultAlert = SaveResultAlert(
208 title: didSave ? "Settings Updated" : "Couldn't Update Settings",
209 message: didSave ? "Repository settings were saved." : (viewModel.error ?? "Please try again.")
210 )
211 }
192212 } label: {
193213 if viewModel.isSavingInfo {
194214 ProgressView()
@@ -236,4 +256,11 @@ struct HgRepositorySettingsView: View {
236256 .disabled(viewModel.isDeleting)
237257 }
238258 }
259
260 private struct SaveResultAlert: Identifiable {
261 let title: String
262 let message: String
263
264 var id: String { "\(title)-\(message)" }
265 }
239266}
Hutch/Views/Repositories/HgRepositorySettingsViewModel.swift +3 −1
@@ -168,7 +168,7 @@ final class HgRepositorySettingsViewModel {
168168 }
169169 }
170170
171 func saveInfo() async {
171 func saveInfo() async -> Bool {
172172 isSavingInfo = true
173173 defer { isSavingInfo = false }
174174 error = nil
@@ -185,8 +185,10 @@ final class HgRepositorySettingsViewModel {
185185 variables: ["id": repositoryId, "input": input],
186186 responseType: HgUpdateRepositoryResponse.self
187187 )
188 return true
188189 } catch {
189190 self.error = error.userFacingMessage
191 return false
190192 }
191193 }
192194
Hutch/Views/Repositories/ReadmeView.swift +5 −1
@@ -1108,7 +1108,11 @@ private struct HTMLWebViewRepresentable: UIViewRepresentable {
11081108 if let cachedHeight = HTMLWebViewCoordinator.heightCache.object(forKey: wrapped as NSString)?.doubleValue {
11091109 let height = CGFloat(cachedHeight)
11101110 if abs(dynamicHeight - height) > 0.5 {
1111 dynamicHeight = height
1111 DispatchQueue.main.async {
1112 if abs(self.dynamicHeight - height) > 0.5 {
1113 self.dynamicHeight = height
1114 }
1115 }
11121116 }
11131117 }
11141118
Hutch/Views/Repositories/RepositorySettingsView.swift +22 −1
@@ -11,6 +11,7 @@ struct RepositorySettingsView: View {
1111 @State private var viewModel: RepositorySettingsViewModel?
1212 @State private var showDeleteConfirmation = false
1313 @State private var pendingACLDeletion: ACLEntry?
14 @State private var saveResultAlert: SaveResultAlert?
1415
1516 var body: some View {
1617 NavigationStack {
@@ -91,6 +92,13 @@ struct RepositorySettingsView: View {
9192 Text("\(entry.entity.canonicalName) will lose \(entry.mode) access to this repository.")
9293 }
9394 }
95 .alert(item: $saveResultAlert) { alert in
96 Alert(
97 title: Text(alert.title),
98 message: Text(alert.message),
99 dismissButton: .default(Text("OK"))
100 )
101 }
94102 }
95103
96104 // MARK: - Info Section
@@ -122,7 +130,13 @@ struct RepositorySettingsView: View {
122130 }
123131
124132 Button {
125 Task { await viewModel.saveInfo() }
133 Task {
134 let didSave = await viewModel.saveInfo()
135 saveResultAlert = SaveResultAlert(
136 title: didSave ? "Settings Updated" : "Couldn't Update Settings",
137 message: didSave ? "Repository settings were saved." : (viewModel.error ?? "Please try again.")
138 )
139 }
126140 } label: {
127141 if viewModel.isSavingInfo {
128142 ProgressView()
@@ -256,4 +270,11 @@ struct RepositorySettingsView: View {
256270 .disabled(viewModel.isDeleting)
257271 }
258272 }
273
274 private struct SaveResultAlert: Identifiable {
275 let title: String
276 let message: String
277
278 var id: String { "\(title)-\(message)" }
279 }
259280}
Hutch/Views/Repositories/RepositorySettingsViewModel.swift +3 −1
@@ -153,7 +153,7 @@ final class RepositorySettingsViewModel {
153153 }
154154 """
155155
156 func saveInfo() async {
156 func saveInfo() async -> Bool {
157157 isSavingInfo = true
158158 defer { isSavingInfo = false }
159159 error = nil
@@ -172,8 +172,10 @@ final class RepositorySettingsViewModel {
172172 variables: ["id": repositoryId, "input": input],
173173 responseType: UpdateRepoInfoResponse.self
174174 )
175 return true
175176 } catch {
176177 self.error = error.userFacingMessage
178 return false
177179 }
178180 }
179181