feat(app): rewire account footer menu - App Store feedback, support link
Center-aligned TipJarView's "Support Outpost" heading and thank-you/ error text to match the rest of AboutInfoView (was VStack(alignment: .leading), out of place among everything else there being centered). AccountFooter's Documentation/API Documentation/Changelog links pointed at Outpost's own repo or the signed-in Outline server's own /developers page - not actually useful here, removed along with the now-unused repositoryURL/issuesURL/apiDocumentationURL. Send Us Feedback and Report a Bug (previously both just opening the Gitea issues page) collapsed into one "Leave Us Feedback" wired to Apple's native requestReview() prompt - there's no separate Apple-native channel for "bug" vs "feedback", so one button covers both. Added "Support Outpost" near the bottom of the same menu, alongside Profile/Settings (same visual weight, not pinned to the top) - opens Settings -> About, same navigation the app-menu's "About Outpost" command already uses. Also checking in the shared Xcode scheme (previously untracked/ nonexistent) now that it references Configuration.storekit, so the StoreKit testing setup travels with the repo instead of being machine-local. Not compiler-verified - Outpost app target has no CLI build path.
This commit is contained in:
@@ -0,0 +1,101 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Scheme
|
||||||
|
LastUpgradeVersion = "2700"
|
||||||
|
version = "1.7">
|
||||||
|
<BuildAction
|
||||||
|
parallelizeBuildables = "YES"
|
||||||
|
buildImplicitDependencies = "YES"
|
||||||
|
buildArchitectures = "Automatic">
|
||||||
|
<BuildActionEntries>
|
||||||
|
<BuildActionEntry
|
||||||
|
buildForTesting = "YES"
|
||||||
|
buildForRunning = "YES"
|
||||||
|
buildForProfiling = "YES"
|
||||||
|
buildForArchiving = "YES"
|
||||||
|
buildForAnalyzing = "YES">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "FAF99C17302CE96100C9949F"
|
||||||
|
BuildableName = "Outpost.app"
|
||||||
|
ReferencedContainer = "container:Outpost.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildActionEntry>
|
||||||
|
</BuildActionEntries>
|
||||||
|
</BuildAction>
|
||||||
|
<TestAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
|
shouldAutocreateTestPlan = "YES">
|
||||||
|
<Testables>
|
||||||
|
<TestableReference
|
||||||
|
skipped = "NO"
|
||||||
|
parallelizable = "YES">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "FAF99C26302CE96200C9949F"
|
||||||
|
BuildableName = "OutpostTests.xctest"
|
||||||
|
ReferencedContainer = "container:Outpost.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</TestableReference>
|
||||||
|
<TestableReference
|
||||||
|
skipped = "NO"
|
||||||
|
parallelizable = "YES">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "FAF99C30302CE96200C9949F"
|
||||||
|
BuildableName = "OutpostUITests.xctest"
|
||||||
|
ReferencedContainer = "container:Outpost.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</TestableReference>
|
||||||
|
</Testables>
|
||||||
|
</TestAction>
|
||||||
|
<LaunchAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
launchStyle = "0"
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
|
debugDocumentVersioning = "YES"
|
||||||
|
debugServiceExtension = "internal"
|
||||||
|
allowLocationSimulation = "YES"
|
||||||
|
queueDebuggingEnabled = "No">
|
||||||
|
<BuildableProductRunnable
|
||||||
|
runnableDebuggingMode = "0">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "FAF99C17302CE96100C9949F"
|
||||||
|
BuildableName = "Outpost.app"
|
||||||
|
ReferencedContainer = "container:Outpost.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildableProductRunnable>
|
||||||
|
<StoreKitConfigurationFileReference
|
||||||
|
identifier = "../../Outpost/Configuration.storekit">
|
||||||
|
</StoreKitConfigurationFileReference>
|
||||||
|
</LaunchAction>
|
||||||
|
<ProfileAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
|
savedToolIdentifier = ""
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
debugDocumentVersioning = "YES">
|
||||||
|
<BuildableProductRunnable
|
||||||
|
runnableDebuggingMode = "0">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "FAF99C17302CE96100C9949F"
|
||||||
|
BuildableName = "Outpost.app"
|
||||||
|
ReferencedContainer = "container:Outpost.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildableProductRunnable>
|
||||||
|
</ProfileAction>
|
||||||
|
<AnalyzeAction
|
||||||
|
buildConfiguration = "Debug">
|
||||||
|
</AnalyzeAction>
|
||||||
|
<ArchiveAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
revealArchiveInOrganizer = "YES">
|
||||||
|
</ArchiveAction>
|
||||||
|
</Scheme>
|
||||||
@@ -9,7 +9,7 @@ struct TipJarView: View {
|
|||||||
@State private var store = TipJarStore()
|
@State private var store = TipJarStore()
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .leading, spacing: 8) {
|
VStack(spacing: 8) {
|
||||||
Text("Support Outpost")
|
Text("Support Outpost")
|
||||||
.font(.callout.weight(.semibold))
|
.font(.callout.weight(.semibold))
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
import StoreKit
|
||||||
import OutlineKit
|
import OutlineKit
|
||||||
|
|
||||||
/// Uses a plain `Button` + `.popover` rather than `Menu`. A `Menu` whose label
|
/// Uses a plain `Button` + `.popover` rather than `Menu`. A `Menu` whose label
|
||||||
@@ -9,20 +10,13 @@ import OutlineKit
|
|||||||
struct AccountFooter: View {
|
struct AccountFooter: View {
|
||||||
@Environment(SessionStore.self) private var session
|
@Environment(SessionStore.self) private var session
|
||||||
@Environment(AppNavigation.self) private var navigation
|
@Environment(AppNavigation.self) private var navigation
|
||||||
@Environment(\.openURL) private var openURL
|
@Environment(\.requestReview) private var requestReview
|
||||||
@AppStorage("outpost.appearance") private var appearance: AppAppearance = .system
|
@AppStorage("outpost.appearance") private var appearance: AppAppearance = .system
|
||||||
@AppStorage(CachingOutlineAPIClient.offlineModeDefaultsKey) private var isOfflineModeEnabled = false
|
@AppStorage(CachingOutlineAPIClient.offlineModeDefaultsKey) private var isOfflineModeEnabled = false
|
||||||
@State private var isMenuPresented = false
|
@State private var isMenuPresented = false
|
||||||
@State private var isShowingLogoutConfirmation = false
|
@State private var isShowingLogoutConfirmation = false
|
||||||
@State private var isShowingProfile = false
|
@State private var isShowingProfile = false
|
||||||
|
|
||||||
private let repositoryURL = URL(string: "https://git.psmattas.com/psmattas/Outpost")!
|
|
||||||
private let issuesURL = URL(string: "https://git.psmattas.com/psmattas/Outpost/issues")!
|
|
||||||
|
|
||||||
private var apiDocumentationURL: URL? {
|
|
||||||
session.serverURL?.appendingPathComponent("developers")
|
|
||||||
}
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Button {
|
Button {
|
||||||
isMenuPresented = true
|
isMenuPresented = true
|
||||||
@@ -62,16 +56,10 @@ struct AccountFooter: View {
|
|||||||
|
|
||||||
private var menuContent: some View {
|
private var menuContent: some View {
|
||||||
VStack(alignment: .leading, spacing: 2) {
|
VStack(alignment: .leading, spacing: 2) {
|
||||||
menuItem("Documentation") { openURL(repositoryURL) }
|
// Apple's own review/feedback prompt — there's no separate
|
||||||
if let apiDocumentationURL {
|
// native channel for "bug" vs. "feedback", so one button covers
|
||||||
menuItem("API Documentation") { openURL(apiDocumentationURL) }
|
// both.
|
||||||
}
|
menuItem("Leave Us Feedback") { requestReview() }
|
||||||
menuItem("Changelog") { openURL(repositoryURL) }
|
|
||||||
|
|
||||||
Divider()
|
|
||||||
|
|
||||||
menuItem("Send Us Feedback") { openURL(issuesURL) }
|
|
||||||
menuItem("Report a Bug") { openURL(issuesURL) }
|
|
||||||
|
|
||||||
Divider()
|
Divider()
|
||||||
|
|
||||||
@@ -101,6 +89,14 @@ struct AccountFooter: View {
|
|||||||
// as "Invalid attempt to open a new transaction during CA
|
// as "Invalid attempt to open a new transaction during CA
|
||||||
// commit") — letting the popover's dismissal finish first avoids it.
|
// commit") — letting the popover's dismissal finish first avoids it.
|
||||||
menuItem("Settings…") { Task { @MainActor in navigation.isShowingSettings = true } }
|
menuItem("Settings…") { Task { @MainActor in navigation.isShowingSettings = true } }
|
||||||
|
// Same deferred-Task reasoning as Settings… above — this also
|
||||||
|
// sets isShowingSettings synchronously.
|
||||||
|
menuItem("Support Outpost") {
|
||||||
|
Task { @MainActor in
|
||||||
|
navigation.selectedSettingsSection = .about
|
||||||
|
navigation.isShowingSettings = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Divider()
|
Divider()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user