From 3f247d628f015d13592cb0b1877549bb369fc03b Mon Sep 17 00:00:00 2001 From: Max Goedjen Date: Sun, 14 Sep 2025 14:39:20 -0700 Subject: [PATCH] About screen. (#707) --- .github/workflows/release.yml | 2 +- Sources/Config/Config.xcconfig | 1 + .../Packages/Resources/Localizable.xcstrings | 67 ++++++++++++++++++ Sources/Secretive.xcodeproj/project.pbxproj | 8 +-- Sources/Secretive/App.swift | 9 +++ Sources/Secretive/Credits.rtf | 36 ---------- Sources/Secretive/Info.plist | 2 + Sources/Secretive/Views/Views/AboutView.swift | 69 +++++++++++++++++++ 8 files changed, 153 insertions(+), 41 deletions(-) delete mode 100644 Sources/Secretive/Credits.rtf create mode 100644 Sources/Secretive/Views/Views/AboutView.swift diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 91ddbc7..6446ae4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -55,7 +55,7 @@ jobs: export CLEAN_TAG=$(echo $TAG_NAME | sed -e 's/refs\/tags\/v//') sed -i '' -e "s/GITHUB_CI_VERSION/$CLEAN_TAG/g" Sources/Config/Config.xcconfig sed -i '' -e "s/GITHUB_BUILD_NUMBER/1.$RUN_ID/g" Sources/Config/Config.xcconfig - sed -i '' -e "s/GITHUB_BUILD_URL/https:\/\/github.com\/maxgoedjen\/secretive\/actions\/runs\/$RUN_ID/g" Sources/Secretive/Credits.rtf + sed -i '' -e "s/GITHUB_BUILD_URL/https:\/\/github.com\/maxgoedjen\/secretive\/actions\/runs\/$RUN_ID/g" Sources/Config/Config.xcconfig - name: Build run: xcrun xcodebuild -project Sources/Secretive.xcodeproj -scheme Secretive -configuration Release -archivePath Archive.xcarchive archive - name: Create ZIP diff --git a/Sources/Config/Config.xcconfig b/Sources/Config/Config.xcconfig index 9c18c35..e81adaa 100644 --- a/Sources/Config/Config.xcconfig +++ b/Sources/Config/Config.xcconfig @@ -1,2 +1,3 @@ CI_VERSION = GITHUB_CI_VERSION CI_BUILD_NUMBER = GITHUB_BUILD_NUMBER +CI_BUILD_LINK = GITHUB_BUILD_URL diff --git a/Sources/Packages/Resources/Localizable.xcstrings b/Sources/Packages/Resources/Localizable.xcstrings index ad12584..923c3d6 100644 --- a/Sources/Packages/Resources/Localizable.xcstrings +++ b/Sources/Packages/Resources/Localizable.xcstrings @@ -177,6 +177,73 @@ "value" : "" } } + }, + "shouldTranslate" : false + }, + "**%@** (%@)" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "**%1$@** (%2$@)" + } + } + }, + "shouldTranslate" : false + }, + "about_build_log_button" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Build Log" + } + } + } + }, + "about_menu_bar_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "About Secretive" + } + } + } + }, + "about_open_source_notice" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Secretive is Open Source and MIT Licensed" + } + } + } + }, + "about_thanks" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Special thanks our [Contributors](%1$(contributorsLink)@) and [Sponsors](%2$(sponsorsLink)@)" + } + } + } + }, + "about_view_on_github_button" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "View on GitHub" + } + } } }, "agent_details_could_not_start_error" : { diff --git a/Sources/Secretive.xcodeproj/project.pbxproj b/Sources/Secretive.xcodeproj/project.pbxproj index 04f9427..a7ae662 100644 --- a/Sources/Secretive.xcodeproj/project.pbxproj +++ b/Sources/Secretive.xcodeproj/project.pbxproj @@ -42,7 +42,6 @@ 5065E313295517C500E16645 /* ToolbarButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5065E312295517C500E16645 /* ToolbarButtonStyle.swift */; }; 5066A6C22516F303004B5A36 /* SetupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5066A6C12516F303004B5A36 /* SetupView.swift */; }; 5066A6C82516FE6E004B5A36 /* CopyableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5066A6C72516FE6E004B5A36 /* CopyableView.swift */; }; - 506772C72424784600034DED /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 506772C62424784600034DED /* Credits.rtf */; }; 506772C92425BB8500034DED /* NoStoresView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 506772C82425BB8500034DED /* NoStoresView.swift */; }; 50692D1D2E6FDB880043C7BB /* SecretiveUpdater.xpc in Embed XPC Services */ = {isa = PBXBuildFile; fileRef = 50692D122E6FDB880043C7BB /* SecretiveUpdater.xpc */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 50692D282E6FDB8D0043C7BB /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50692D242E6FDB8D0043C7BB /* main.swift */; }; @@ -74,6 +73,7 @@ 50C385A52407A76D00AF2719 /* SecretDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C385A42407A76D00AF2719 /* SecretDetailView.swift */; }; 50CF4ABC2E601B0F005588DC /* ActionButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50CF4ABB2E601B0F005588DC /* ActionButtonStyle.swift */; }; 50E4C4532E73C78C00C73783 /* WindowBackgroundStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50E4C4522E73C78900C73783 /* WindowBackgroundStyle.swift */; }; + 50E4C4C32E7765DF00C73783 /* AboutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50E4C4C22E7765DF00C73783 /* AboutView.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -206,7 +206,6 @@ 5065E312295517C500E16645 /* ToolbarButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToolbarButtonStyle.swift; sourceTree = ""; }; 5066A6C12516F303004B5A36 /* SetupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetupView.swift; sourceTree = ""; }; 5066A6C72516FE6E004B5A36 /* CopyableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CopyableView.swift; sourceTree = ""; }; - 506772C62424784600034DED /* Credits.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = Credits.rtf; sourceTree = ""; }; 506772C82425BB8500034DED /* NoStoresView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoStoresView.swift; sourceTree = ""; }; 50692BA52E6D5CC90043C7BB /* InternetAccessPolicy.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = InternetAccessPolicy.plist; sourceTree = ""; }; 50692D122E6FDB880043C7BB /* SecretiveUpdater.xpc */ = {isa = PBXFileReference; explicitFileType = "wrapper.xpc-service"; includeInIndex = 0; path = SecretiveUpdater.xpc; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -241,6 +240,7 @@ 50C385A42407A76D00AF2719 /* SecretDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretDetailView.swift; sourceTree = ""; }; 50CF4ABB2E601B0F005588DC /* ActionButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionButtonStyle.swift; sourceTree = ""; }; 50E4C4522E73C78900C73783 /* WindowBackgroundStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowBackgroundStyle.swift; sourceTree = ""; }; + 50E4C4C22E7765DF00C73783 /* AboutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutView.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -338,6 +338,7 @@ 504788F02E681F0100B4556F /* Views */ = { isa = PBXGroup; children = ( + 50E4C4C22E7765DF00C73783 /* AboutView.swift */, 50BDCB712E63BAF20072D2E7 /* AgentStatusView.swift */, 50617D8423FCE48E0099B055 /* ContentView.swift */, 5066A6C72516FE6E004B5A36 /* CopyableView.swift */, @@ -382,7 +383,6 @@ 50617D8E23FCE48E0099B055 /* Info.plist */, 508BF28D25B4F005009EFB7E /* InternetAccessPolicy.plist */, 50617D8F23FCE48E0099B055 /* Secretive.entitlements */, - 506772C62424784600034DED /* Credits.rtf */, 5008C23D2E525D8200507AC2 /* Localizable.xcstrings */, 50617D8823FCE48E0099B055 /* Preview Content */, ); @@ -648,7 +648,6 @@ 50617D8A23FCE48E0099B055 /* Preview Assets.xcassets in Resources */, 5008C23E2E525D8900507AC2 /* Localizable.xcstrings in Resources */, 50617D8723FCE48E0099B055 /* Assets.xcassets in Resources */, - 506772C72424784600034DED /* Credits.rtf in Resources */, 508BF28E25B4F005009EFB7E /* InternetAccessPolicy.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -688,6 +687,7 @@ files = ( 504788F22E681F3A00B4556F /* Instructions.swift in Sources */, 50BDCB742E6436CA0072D2E7 /* ErrorStyle.swift in Sources */, + 50E4C4C32E7765DF00C73783 /* AboutView.swift in Sources */, 2C4A9D2F2636FFD3008CC8E2 /* EditSecretView.swift in Sources */, 50E4C4532E73C78C00C73783 /* WindowBackgroundStyle.swift in Sources */, 5091D2BC25183B830049FD9B /* ApplicationDirectoryController.swift in Sources */, diff --git a/Sources/Secretive/App.swift b/Sources/Secretive/App.swift index d88ce53..10d5d18 100644 --- a/Sources/Secretive/App.swift +++ b/Sources/Secretive/App.swift @@ -32,6 +32,10 @@ struct Secretive: App { WindowGroup(id: String(describing: IntegrationsView.self)) { IntegrationsView() } + WindowGroup(id: String(describing: AboutView.self)) { + AboutView() + } + .windowStyle(.hiddenTitleBar) } } @@ -45,6 +49,11 @@ extension Secretive { @FocusedValue(\.showCreateSecret) var showCreateSecret var body: some Commands { + CommandGroup(replacing: .appInfo) { + Button(.aboutMenuBarTitle, systemImage: "info.circle") { + openWindow(id: String(describing: AboutView.self)) + } + } CommandGroup(before: CommandGroupPlacement.appSettings) { Button(.integrationsMenuBarTitle, systemImage: "app.connected.to.app.below.fill") { openWindow(id: String(describing: IntegrationsView.self)) diff --git a/Sources/Secretive/Credits.rtf b/Sources/Secretive/Credits.rtf deleted file mode 100644 index 70bdc54..0000000 --- a/Sources/Secretive/Credits.rtf +++ /dev/null @@ -1,36 +0,0 @@ -{\rtf1\ansi\ansicpg1252\cocoartf2580 -\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -{\*\expandedcolortbl;;} -\margl1440\margr1440\vieww9000\viewh8400\viewkind0 -\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6119\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0 -{\field{\*\fldinst{HYPERLINK "https://github.com/maxgoedjen/secretive"}}{\fldrslt -\f0\fs24 \cf0 GitHub Repository}} -\f0\fs24 \ -\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0 -\cf0 \ -{\field{\*\fldinst{HYPERLINK "GITHUB_BUILD_URL"}}{\fldrslt Build Log}}\ -\ -Special Thanks To:\ -\ -{\field{\*\fldinst{HYPERLINK "https://github.com/maxgoedjen/secretive/graphs/contributors"}}{\fldrslt Contributors}}:\ -{\field{\*\fldinst{HYPERLINK "https://github.com/0xflotus"}}{\fldrslt 0xflotus}}\ -{\field{\*\fldinst{HYPERLINK "https://github.com/aaron-trout"}}{\fldrslt Aaron Trout}}\ -\pard\pardeftab720\partightenfactor0 -{\field{\*\fldinst{HYPERLINK "https://github.com/EppO"}}{\fldrslt \cf0 Florent Monbillard}}\ -{\field{\*\fldinst{HYPERLINK "https://github.com/vladimyr"}}{\fldrslt Dario Vladovi\uc0\u263 }}\ -{\field{\*\fldinst{HYPERLINK "https://github.com/lavalleeale"}}{\fldrslt Alex Lavallee}}\ -{\field{\*\fldinst{HYPERLINK "https://github.com/joshheyse"}}{\fldrslt Josh}}\ -{\field{\*\fldinst{HYPERLINK "https://github.com/diesal11"}}{\fldrslt Dylan Lundy}}\ -\ -\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0 -\cf0 Testers:\ -{\field{\*\fldinst{HYPERLINK "https://github.com/bdash"}}{\fldrslt Mark Rowe}}\ -{\field{\*\fldinst{HYPERLINK "https://github.com/danielctull"}}{\fldrslt Daniel Tull}}\ -{\field{\*\fldinst{HYPERLINK "https://github.com/davedelong"}}{\fldrslt Dave DeLong}}\ -{\field{\*\fldinst{HYPERLINK "https://github.com/esttorhe"}}{\fldrslt Esteban Torres}}\ -{\field{\*\fldinst{HYPERLINK "https://github.com/joeblau"}}{\fldrslt Joe Blau}}\ -{\field{\*\fldinst{HYPERLINK "https://github.com/marksands"}}{\fldrslt Mark Sands}}\ -{\field{\*\fldinst{HYPERLINK "https://github.com/mergesort"}}{\fldrslt Joe Fabisevich}}\ -{\field{\*\fldinst{HYPERLINK "https://github.com/phillco"}}{\fldrslt Phil Cohen}}\ -{\field{\*\fldinst{HYPERLINK "https://github.com/zackdotcomputer"}}{\fldrslt Zack Sheppard}}} \ No newline at end of file diff --git a/Sources/Secretive/Info.plist b/Sources/Secretive/Info.plist index beb76e8..0a06b50 100644 --- a/Sources/Secretive/Info.plist +++ b/Sources/Secretive/Info.plist @@ -24,6 +24,8 @@ $(MACOSX_DEPLOYMENT_TARGET) NSHumanReadableCopyright $(PRODUCT_NAME) is MIT Licensed. + GitHubBuildLog + $(CI_BUILD_LINK) NSPrincipalClass NSApplication NSSupportsAutomaticTermination diff --git a/Sources/Secretive/Views/Views/AboutView.swift b/Sources/Secretive/Views/Views/AboutView.swift new file mode 100644 index 0000000..a9708ab --- /dev/null +++ b/Sources/Secretive/Views/Views/AboutView.swift @@ -0,0 +1,69 @@ +import SwiftUI + +struct AboutView: View { + var body: some View { + if #available(macOS 15.0, *) { + AboutViewContent() + .containerBackground( + .thinMaterial, for: .window + ) + } else { + AboutViewContent() + } + } +} + +struct AboutViewContent: View { + + @Environment(\.openURL) var openURL + var body: some View { + VStack(spacing: 10) { + HStack { + Image(nsImage: NSApplication.shared.applicationIconImage) + VStack(alignment: .leading) { + Text(verbatim: "Secretive") + .font(.system(.largeTitle, weight: .bold)) + Text("**\(Bundle.main.versionNumber)** (\(Bundle.main.buildNumber))") + .fixedSize(horizontal: true, vertical: false) + HStack { + Button(.aboutViewOnGithubButton) { + openURL(URL(string: "https://github.com/maxgoedjen/secretive")!) + } + .normalButton() + Button(.aboutBuildLogButton) { + openURL(Bundle.main.buildLog) + } + .normalButton() + } + } + } + Text(.aboutThanks(contributorsLink: "https://github.com/maxgoedjen/secretive/graphs/contributors", sponsorsLink: "https://github.com/sponsors/maxgoedjen")) + .font(.headline) + Text(.aboutOpenSourceNotice) + .font(.subheadline) + } + .padding(EdgeInsets(top: 10, leading: 30, bottom: 30, trailing: 30)) + } + +} + +private extension Bundle { + + var buildLog: URL { + URL(string: infoDictionary!["GitHubBuildLog"] as! String)! + } + + var versionNumber: String { + infoDictionary?["CFBundleShortVersionString"] as? String ?? "0.0.0" + } + + var buildNumber: String { + infoDictionary?["CFBundleVersion"] as? String ?? "0.0" + } + +} + +#Preview { + AboutView() + .frame(width: 500, height: 250) +}