krz/hutch

an ios client for sourcehut

clone: git clone https://gitbay.org/krz/hutch.git

d897109d0d23560bf19ece6ea1122b1229f3b164

verified · cmc

author: Christian Cleberg <hello@cleberg.net> · 2026-03-30T22:20:15Z

Fix nonisolated table alignment lookup in Readme View
 Hutch.xcodeproj/project.pbxproj                    | 54 ++++++++++++++++------
 .../xcshareddata/xcschemes/Hutch.xcscheme          |  2 +-
 .../xcshareddata/xcschemes/HutchTests.xcscheme     |  2 +-
 Hutch/Views/Repositories/ReadmeView.swift          |  9 +++-
 4 files changed, 49 insertions(+), 18 deletions(-)

diff --git a/Hutch.xcodeproj/project.pbxproj b/Hutch.xcodeproj/project.pbxproj
index 087de10..7251561 100644
--- a/Hutch.xcodeproj/project.pbxproj
+++ b/Hutch.xcodeproj/project.pbxproj
@@ -10,7 +10,11 @@
 		8B2F89662F69DEB900FC0253 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 8B2F89632F69DEB900FC0253 /* LICENSE */; };
 		8B2F89672F69DEB900FC0253 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 8B2F89642F69DEB900FC0253 /* README.md */; };
 		8B2F89682F69DEB900FC0253 /* SECURITY.md in Resources */ = {isa = PBXBuildFile; fileRef = 8B2F89652F69DEB900FC0253 /* SECURITY.md */; };
-		8BE082012F80000100000001 /* HutchWidgetExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 8BE081F62F80000100000001 /* HutchWidgetExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
+		8BE082012F80000100000001 /* HutchWidgetExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 8BE081F62F80000100000001 /* HutchWidgetExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
+		8BE09E7F2F7B2CC300F88693 /* storebutton.svg in Resources */ = {isa = PBXBuildFile; fileRef = 8BE09E7C2F7B2CC300F88693 /* storebutton.svg */; };
+		8BE09E802F7B2CC300F88693 /* index.html in Resources */ = {isa = PBXBuildFile; fileRef = 8BE09E7A2F7B2CC300F88693 /* index.html */; };
+		8BE09E812F7B2CC300F88693 /* styles.css in Resources */ = {isa = PBXBuildFile; fileRef = 8BE09E7D2F7B2CC300F88693 /* styles.css */; };
+		8BE09E822F7B2CC300F88693 /* privacy.html in Resources */ = {isa = PBXBuildFile; fileRef = 8BE09E7B2F7B2CC300F88693 /* privacy.html */; };
 		8BF100032F9A000100000001 /* Markdown in Frameworks */ = {isa = PBXBuildFile; productRef = 8BF100022F9A000100000001 /* Markdown */; };
 /* End PBXBuildFile section */
 
@@ -32,15 +36,15 @@
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXCopyFilesBuildPhase section */
-		8BE081FA2F80000100000001 /* Embed App Extensions */ = {
+		8BE081FA2F80000100000001 /* Embed Foundation Extensions */ = {
 			isa = PBXCopyFilesBuildPhase;
 			buildActionMask = 2147483647;
 			dstPath = "";
 			dstSubfolderSpec = 13;
 			files = (
-				8BE082012F80000100000001 /* HutchWidgetExtension.appex in Embed App Extensions */,
+				8BE082012F80000100000001 /* HutchWidgetExtension.appex in Embed Foundation Extensions */,
 			);
-			name = "Embed App Extensions";
+			name = "Embed Foundation Extensions";
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 /* End PBXCopyFilesBuildPhase section */
@@ -54,6 +58,10 @@
 		8B8182C22F6B742B000AE049 /* HutchTests */ = {isa = PBXFileReference; lastKnownFileType = folder; path = HutchTests; sourceTree = "<group>"; };
 		8BDCA5272F6B76B20066AA29 /* HutchTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = HutchTests.xctestplan; sourceTree = "<group>"; };
 		8BE081F62F80000100000001 /* HutchWidgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = HutchWidgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
+		8BE09E7A2F7B2CC300F88693 /* index.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = index.html; sourceTree = "<group>"; };
+		8BE09E7B2F7B2CC300F88693 /* privacy.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = privacy.html; sourceTree = "<group>"; };
+		8BE09E7C2F7B2CC300F88693 /* storebutton.svg */ = {isa = PBXFileReference; lastKnownFileType = text; path = storebutton.svg; sourceTree = "<group>"; };
+		8BE09E7D2F7B2CC300F88693 /* styles.css */ = {isa = PBXFileReference; lastKnownFileType = text.css; path = styles.css; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
@@ -131,6 +139,7 @@
 		8B4B28C82F6704280045FA19 = {
 			isa = PBXGroup;
 			children = (
+				8BE09E7E2F7B2CC300F88693 /* website */,
 				8BDCA5272F6B76B20066AA29 /* HutchTests.xctestplan */,
 				8B8182C22F6B742B000AE049 /* HutchTests */,
 				8B2F89632F69DEB900FC0253 /* LICENSE */,
@@ -154,6 +163,17 @@
 			name = Products;
 			sourceTree = "<group>";
 		};
+		8BE09E7E2F7B2CC300F88693 /* website */ = {
+			isa = PBXGroup;
+			children = (
+				8BE09E7A2F7B2CC300F88693 /* index.html */,
+				8BE09E7B2F7B2CC300F88693 /* privacy.html */,
+				8BE09E7C2F7B2CC300F88693 /* storebutton.svg */,
+				8BE09E7D2F7B2CC300F88693 /* styles.css */,
+			);
+			path = website;
+			sourceTree = "<group>";
+		};
 /* End PBXGroup section */
 
 /* Begin PBXNativeTarget section */
@@ -164,7 +184,7 @@
 				8B4B28CD2F6704280045FA19 /* Sources */,
 				8B4B28CE2F6704280045FA19 /* Frameworks */,
 				8B4B28CF2F6704280045FA19 /* Resources */,
-				8BE081FA2F80000100000001 /* Embed App Extensions */,
+				8BE081FA2F80000100000001 /* Embed Foundation Extensions */,
 			);
 			buildRules = (
 			);
@@ -237,7 +257,7 @@
 			attributes = {
 				BuildIndependentTargetsInParallel = 1;
 				LastSwiftUpdateCheck = 2630;
-				LastUpgradeCheck = 2630;
+				LastUpgradeCheck = 2640;
 				TargetAttributes = {
 					8B4B28D02F6704280045FA19 = {
 						CreatedOnToolsVersion = 26.3;
@@ -280,6 +300,10 @@
 				8B2F89662F69DEB900FC0253 /* LICENSE in Resources */,
 				8B2F89672F69DEB900FC0253 /* README.md in Resources */,
 				8B2F89682F69DEB900FC0253 /* SECURITY.md in Resources */,
+				8BE09E7F2F7B2CC300F88693 /* storebutton.svg in Resources */,
+				8BE09E802F7B2CC300F88693 /* index.html in Resources */,
+				8BE09E812F7B2CC300F88693 /* styles.css in Resources */,
+				8BE09E822F7B2CC300F88693 /* privacy.html in Resources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -396,6 +420,7 @@
 				MTL_FAST_MATH = YES;
 				ONLY_ACTIVE_ARCH = YES;
 				SDKROOT = iphoneos;
+				STRING_CATALOG_GENERATE_SYMBOLS = YES;
 				SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
 				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
 			};
@@ -453,6 +478,7 @@
 				MTL_ENABLE_DEBUG_INFO = NO;
 				MTL_FAST_MATH = YES;
 				SDKROOT = iphoneos;
+				STRING_CATALOG_GENERATE_SYMBOLS = YES;
 				SWIFT_COMPILATION_MODE = wholemodule;
 				VALIDATE_PRODUCT = YES;
 			};
@@ -465,7 +491,7 @@
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
 				CODE_SIGN_ENTITLEMENTS = Hutch/Hutch.entitlements;
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 13;
+				CURRENT_PROJECT_VERSION = 14;
 				DEVELOPMENT_TEAM = ZCNAX3VL9D;
 				ENABLE_PREVIEWS = YES;
 				GENERATE_INFOPLIST_FILE = YES;
@@ -482,7 +508,7 @@
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
-				MARKETING_VERSION = 2.5.1;
+				MARKETING_VERSION = 2.5.2;
 				PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				STRING_CATALOG_GENERATE_SYMBOLS = YES;
@@ -502,7 +528,7 @@
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
 				CODE_SIGN_ENTITLEMENTS = Hutch/Hutch.entitlements;
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 13;
+				CURRENT_PROJECT_VERSION = 14;
 				DEVELOPMENT_TEAM = ZCNAX3VL9D;
 				ENABLE_PREVIEWS = YES;
 				GENERATE_INFOPLIST_FILE = YES;
@@ -519,7 +545,7 @@
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
-				MARKETING_VERSION = 2.5.1;
+				MARKETING_VERSION = 2.5.2;
 				PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				STRING_CATALOG_GENERATE_SYMBOLS = YES;
@@ -582,7 +608,7 @@
 				APPLICATION_EXTENSION_API_ONLY = YES;
 				CODE_SIGN_ENTITLEMENTS = HutchWidgetExtension/HutchWidgetExtension.entitlements;
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 13;
+				CURRENT_PROJECT_VERSION = 14;
 				DEVELOPMENT_TEAM = ZCNAX3VL9D;
 				GENERATE_INFOPLIST_FILE = NO;
 				INFOPLIST_FILE = HutchWidgetExtension/Info.plist;
@@ -592,7 +618,7 @@
 					"@executable_path/Frameworks",
 					"@executable_path/../../Frameworks",
 				);
-				MARKETING_VERSION = 2.5.1;
+				MARKETING_VERSION = 2.5.2;
 				PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch.HutchWidgetExtension;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -611,7 +637,7 @@
 				APPLICATION_EXTENSION_API_ONLY = YES;
 				CODE_SIGN_ENTITLEMENTS = HutchWidgetExtension/HutchWidgetExtension.entitlements;
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 13;
+				CURRENT_PROJECT_VERSION = 14;
 				DEVELOPMENT_TEAM = ZCNAX3VL9D;
 				GENERATE_INFOPLIST_FILE = NO;
 				INFOPLIST_FILE = HutchWidgetExtension/Info.plist;
@@ -621,7 +647,7 @@
 					"@executable_path/Frameworks",
 					"@executable_path/../../Frameworks",
 				);
-				MARKETING_VERSION = 2.5.1;
+				MARKETING_VERSION = 2.5.2;
 				PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch.HutchWidgetExtension;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
diff --git a/Hutch.xcodeproj/xcshareddata/xcschemes/Hutch.xcscheme b/Hutch.xcodeproj/xcshareddata/xcschemes/Hutch.xcscheme
index 4bb83be..d05e796 100644
--- a/Hutch.xcodeproj/xcshareddata/xcschemes/Hutch.xcscheme
+++ b/Hutch.xcodeproj/xcshareddata/xcschemes/Hutch.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "2630"
+   LastUpgradeVersion = "2640"
    version = "1.7">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/Hutch.xcodeproj/xcshareddata/xcschemes/HutchTests.xcscheme b/Hutch.xcodeproj/xcshareddata/xcschemes/HutchTests.xcscheme
index 2cbf63c..f12ca4f 100644
--- a/Hutch.xcodeproj/xcshareddata/xcschemes/HutchTests.xcscheme
+++ b/Hutch.xcodeproj/xcshareddata/xcschemes/HutchTests.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "2630"
+   LastUpgradeVersion = "2640"
    version = "1.7">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/Hutch/Views/Repositories/ReadmeView.swift b/Hutch/Views/Repositories/ReadmeView.swift
index 38c9d18..93fee26 100644
--- a/Hutch/Views/Repositories/ReadmeView.swift
+++ b/Hutch/Views/Repositories/ReadmeView.swift
@@ -1001,7 +1001,7 @@ nonisolated private func renderHTMLTable(
     if hasHeaderSeparator {
         html += "<thead><tr>"
         for (index, cell) in headerRow.enumerated() {
-            html += "<th" + tableAlignmentStyleAttribute(columnAlignments[safe: index] ?? nil) + ">" + inlineRenderer(cell) + "</th>"
+            html += "<th" + tableAlignmentStyleAttribute(columnAlignment(at: index, in: columnAlignments)) + ">" + inlineRenderer(cell) + "</th>"
         }
         html += "</tr></thead>\n"
     }
@@ -1010,7 +1010,7 @@ nonisolated private func renderHTMLTable(
     for row in bodyRows {
         html += "<tr>"
         for (index, cell) in row.enumerated() {
-            html += "<td" + tableAlignmentStyleAttribute(columnAlignments[safe: index] ?? nil) + ">" + inlineRenderer(cell) + "</td>"
+            html += "<td" + tableAlignmentStyleAttribute(columnAlignment(at: index, in: columnAlignments)) + ">" + inlineRenderer(cell) + "</td>"
         }
         html += "</tr>\n"
     }
@@ -1019,6 +1019,11 @@ nonisolated private func renderHTMLTable(
     return html
 }
 
+nonisolated private func columnAlignment(at index: Int, in alignments: [String?]) -> String? {
+    guard alignments.indices.contains(index) else { return nil }
+    return alignments[index]
+}
+
 nonisolated private func tableAlignmentStyleAttribute(_ alignment: String?) -> String {
     guard let alignment, !alignment.isEmpty else { return "" }
     return #" style="text-align: \#(alignment);""#