crossmate

A collaborative crossword app for iOS
Log | Files | Refs | LICENSE

commit 155be03f2175684e59741415de897d959eab6e9c
parent 98a6960605bc992ac070d7dae996293d0c881e83
Author: Michael Camilleri <[email protected]>
Date:   Thu,  7 May 2026 13:41:43 +0900

Add About screen to Settings

Diffstat:
MCrossmate.xcodeproj/project.pbxproj | 4++++
ACrossmate/Media.xcassets/AboutIcon.imageset/Contents.json | 12++++++++++++
ACrossmate/Media.xcassets/AboutIcon.imageset/Icon.png | 0
ACrossmate/Views/AboutView.swift | 83+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MCrossmate/Views/SettingsView.swift | 13++++++++++++-
5 files changed, 111 insertions(+), 1 deletion(-)

diff --git a/Crossmate.xcodeproj/project.pbxproj b/Crossmate.xcodeproj/project.pbxproj @@ -61,6 +61,7 @@ AA28425BD26F72A9E2B58742 /* BundledBrowseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A4B7C6A8A23C6E4CCEC759F /* BundledBrowseView.swift */; }; AA38A51862FC0AB8F7D34899 /* NYTToXDConverterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C54223FED97577A593B7964E /* NYTToXDConverterTests.swift */; }; AA992F67F509EC8EFDDFC7CB /* morning.xd in Resources */ = {isa = PBXBuildFile; fileRef = 0B73A791FD061430AE286E11 /* morning.xd */; }; + AB05765D2C3F4841026344E5 /* AboutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AF633D73818BD59F759FAC4 /* AboutView.swift */; }; AF4F1AE2A1F94E92C785C524 /* Square.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB851649DE78AAAC5A928C52 /* Square.swift */; }; B42454D72FAA219D60DEA334 /* garden.xd in Resources */ = {isa = PBXBuildFile; fileRef = 50992CDA4082429EBB17F65C /* garden.xd */; }; B762200F54C52E8377A80D15 /* NYTToXDConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF6F111BE8750697C4BC7A17 /* NYTToXDConverter.swift */; }; @@ -128,6 +129,7 @@ 465F2BB469EFE84CF3733398 /* Game.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Game.swift; sourceTree = "<group>"; }; 47532AED239AEF476D8E9206 /* NotificationStateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationStateTests.swift; sourceTree = "<group>"; }; 4803C2E84FC5B3BFE593171D /* NameBroadcaster.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NameBroadcaster.swift; sourceTree = "<group>"; }; + 4AF633D73818BD59F759FAC4 /* AboutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutView.swift; sourceTree = "<group>"; }; 4DC7784917397BCD6B8D679D /* PuzzleCatalog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PuzzleCatalog.swift; sourceTree = "<group>"; }; 4F4EBC0F07FF815274C028CA /* XDAcceptTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XDAcceptTests.swift; sourceTree = "<group>"; }; 50992CDA4082429EBB17F65C /* garden.xd */ = {isa = PBXFileReference; path = garden.xd; sourceTree = "<group>"; }; @@ -312,6 +314,7 @@ 84445EA9CACB6AAAEDE6965F /* Views */ = { isa = PBXGroup; children = ( + 4AF633D73818BD59F759FAC4 /* AboutView.swift */, 9A4B7C6A8A23C6E4CCEC759F /* BundledBrowseView.swift */, C0CAA5E17BD406AFEEF96196 /* CalendarDayCell.swift */, F8E50E7BA98C88B4CAB39DC1 /* CellView.swift */, @@ -517,6 +520,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + AB05765D2C3F4841026344E5 /* AboutView.swift in Sources */, 78802AFDF6273231781CC0DC /* AppServices.swift in Sources */, 197DDF45C36B9570BB9AE4B5 /* AuthorIdentity.swift in Sources */, AA28425BD26F72A9E2B58742 /* BundledBrowseView.swift in Sources */, diff --git a/Crossmate/Media.xcassets/AboutIcon.imageset/Contents.json b/Crossmate/Media.xcassets/AboutIcon.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "Icon.png", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Crossmate/Media.xcassets/AboutIcon.imageset/Icon.png b/Crossmate/Media.xcassets/AboutIcon.imageset/Icon.png Binary files differ. diff --git a/Crossmate/Views/AboutView.swift b/Crossmate/Views/AboutView.swift @@ -0,0 +1,83 @@ +import SwiftUI + +struct AboutView: View { + private var appVersion: String { + Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "Unknown" + } + + private var buildNumber: String { + Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "Unknown" + } + + var body: some View { + List { + Section { + VStack(spacing: 8) { + Image("AboutIcon") + .resizable() + .scaledToFit() + .frame(width: 100, height: 100) + .clipShape(RoundedRectangle(cornerRadius: 22)) + + Text("Crossmate") + .font(.title2) + .fontWeight(.bold) + + Text("Version \(appVersion) (\(buildNumber))") + .font(.subheadline) + .foregroundStyle(.secondary) + .padding(.bottom, 20) + + VStack(spacing: 4) { + Text("Programming") + .font(.caption) + .textCase(.uppercase) + .tracking(0.8) + .foregroundStyle(.secondary) + Text("Claude Code and OpenAI Codex") + .font(.subheadline) + .foregroundStyle(.primary) + } + .padding(.bottom, 8) + + VStack(spacing: 4) { + Text("Direction") + .font(.caption) + .textCase(.uppercase) + .tracking(0.8) + .foregroundStyle(.secondary) + Text("Michael Camilleri") + .font(.subheadline) + .foregroundStyle(.primary) + } + } + .frame(maxWidth: .infinity) + .padding(.bottom, 4) + .listRowBackground(Color.clear) + .listRowSeparator(.hidden) + } + + Section { + Link(destination: URL(string: "https://apps.inqk.net/crossmate")!) { + Label("Website", systemImage: "globe") + } + Link(destination: URL(string: "https://code.inqk.net/crossmate")!) { + Label("Source Code", systemImage: "chevron.left.forwardslash.chevron.right") + } + } + + Section { + Text("Thank you to my wife, daughter and sons for their love and inspiration.") + .font(.subheadline) + .foregroundStyle(.secondary) + .multilineTextAlignment(.center) + .frame(maxWidth: .infinity) + .listRowBackground(Color.clear) + .listRowSeparator(.hidden) + } + } + .contentMargins(.top, 0, for: .scrollContent) + .navigationTitle("About") + .navigationBarTitleDisplayMode(.inline) + } +} diff --git a/Crossmate/Views/SettingsView.swift b/Crossmate/Views/SettingsView.swift @@ -30,7 +30,7 @@ struct SettingsView: View { NavigationLink("Share Diagnostics") { ShareDiagnosticsView() } - NavigationLink("CloudKit Record") { + NavigationLink("Record Editor") { RecordEditorView() } @@ -49,6 +49,17 @@ struct SettingsView: View { Text("This removes every game and clears the sync state on this device. Games on other devices and in iCloud are not affected.") } } + + Section { + NavigationLink("About") { + AboutView() + } + } footer: { + Text("Made in Tokyo from natural ones and zeros") + .frame(maxWidth: .infinity) + .multilineTextAlignment(.center) + .padding(.top, 24) + } } .navigationTitle("Settings") .navigationBarTitleDisplayMode(.inline)