From 6c524ba8552060a086aada827ab94dfc739aa34d Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 27 Jan 2026 20:23:34 -0600 Subject: [PATCH] Signed-off-by: Matt Bruce --- .../xcshareddata/xcschemes/Andromida.xcscheme | 78 +++++++++++ .../AndromidaWidgetExtension.xcscheme | 124 ++++++++++++++++++ .../xcschemes/xcschememanagement.plist | 15 ++- .../App/Localization/Localizable.xcstrings | 88 +++++++++++++ .../Views/Onboarding/WhatsNextStepView.swift | 90 +++++++++++++ 5 files changed, 394 insertions(+), 1 deletion(-) create mode 100644 Andromida.xcodeproj/xcshareddata/xcschemes/Andromida.xcscheme create mode 100644 Andromida.xcodeproj/xcshareddata/xcschemes/AndromidaWidgetExtension.xcscheme diff --git a/Andromida.xcodeproj/xcshareddata/xcschemes/Andromida.xcscheme b/Andromida.xcodeproj/xcshareddata/xcschemes/Andromida.xcscheme new file mode 100644 index 0000000..3cf4e0b --- /dev/null +++ b/Andromida.xcodeproj/xcshareddata/xcschemes/Andromida.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Andromida.xcodeproj/xcshareddata/xcschemes/AndromidaWidgetExtension.xcscheme b/Andromida.xcodeproj/xcshareddata/xcschemes/AndromidaWidgetExtension.xcscheme new file mode 100644 index 0000000..d761e6c --- /dev/null +++ b/Andromida.xcodeproj/xcshareddata/xcschemes/AndromidaWidgetExtension.xcscheme @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Andromida.xcodeproj/xcuserdata/mattbruce.xcuserdatad/xcschemes/xcschememanagement.plist b/Andromida.xcodeproj/xcuserdata/mattbruce.xcuserdatad/xcschemes/xcschememanagement.plist index 9ef0618..16ae3f5 100644 --- a/Andromida.xcodeproj/xcuserdata/mattbruce.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Andromida.xcodeproj/xcuserdata/mattbruce.xcuserdatad/xcschemes/xcschememanagement.plist @@ -7,7 +7,7 @@ Andromida.xcscheme_^#shared#^_ orderHint - 1 + 2 AndromidaWidgetExtension.xcscheme_^#shared#^_ @@ -15,5 +15,18 @@ 1 + SuppressBuildableAutocreation + + EAC04A972F26BAE8007F87EA + + primary + + + EAC04D2E2F298D9B007F87EA + + primary + + + diff --git a/Andromida/App/Localization/Localizable.xcstrings b/Andromida/App/Localization/Localizable.xcstrings index e56d0a7..ba0c9e2 100644 --- a/Andromida/App/Localization/Localizable.xcstrings +++ b/Andromida/App/Localization/Localizable.xcstrings @@ -2734,6 +2734,94 @@ } } } + }, + "Widgets" : { + "comment" : "Title for the widgets discovery card in onboarding.", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Widgets" + } + } + } + }, + "Add Andromida to your Home Screen for quick check-ins." : { + "comment" : "Description on the widget discovery card in onboarding.", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Add Andromida to your Home Screen for quick check-ins." + } + } + } + }, + "How to add" : { + "comment" : "CTA button label to show widget setup steps.", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "How to add" + } + } + } + }, + "Add the widget" : { + "comment" : "Title for the widget setup sheet in onboarding.", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Add the widget" + } + } + } + }, + "Keep your rituals visible at a glance." : { + "comment" : "Subtitle for the widget setup sheet in onboarding.", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Keep your rituals visible at a glance." + } + } + } + }, + "Touch and hold your Home Screen." : { + "comment" : "Widget setup step: long-press Home Screen.", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Touch and hold your Home Screen." + } + } + } + }, + "Tap Edit, then Add Widget." : { + "comment" : "Widget setup step: tap Edit and Add Widget.", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Tap Edit, then Add Widget." + } + } + } + }, + "Search for Andromida and pick a size." : { + "comment" : "Widget setup step: search for the app and choose size.", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Search for Andromida and pick a size." + } + } + } } }, "version" : "1.1" diff --git a/Andromida/App/Views/Onboarding/WhatsNextStepView.swift b/Andromida/App/Views/Onboarding/WhatsNextStepView.swift index 2aebab6..eb8260a 100644 --- a/Andromida/App/Views/Onboarding/WhatsNextStepView.swift +++ b/Andromida/App/Views/Onboarding/WhatsNextStepView.swift @@ -6,6 +6,7 @@ struct WhatsNextStepView: View { let onComplete: () -> Void @State private var animateContent = false + @State private var isShowingWidgetHelp = false var body: some View { VStack(spacing: Design.Spacing.xxLarge) { @@ -55,6 +56,11 @@ struct WhatsNextStepView: View { .opacity(animateContent ? 1 : 0) .offset(y: animateContent ? 0 : 20) .animation(.easeOut(duration: 0.4).delay(0.3), value: animateContent) + + WidgetDiscoveryCard(onLearnMore: { isShowingWidgetHelp = true }) + .opacity(animateContent ? 1 : 0) + .offset(y: animateContent ? 0 : 20) + .animation(.easeOut(duration: 0.4).delay(0.4), value: animateContent) } .padding(.horizontal, Design.Spacing.large) @@ -80,6 +86,9 @@ struct WhatsNextStepView: View { animateContent = true } } + .sheet(isPresented: $isShowingWidgetHelp) { + WidgetSetupSheet() + } } } @@ -112,6 +121,87 @@ private struct FeatureHelpCard: View { } } +/// A feature card with a CTA to learn how to add widgets. +private struct WidgetDiscoveryCard: View { + let onLearnMore: () -> Void + + var body: some View { + VStack(alignment: .leading, spacing: Design.Spacing.small) { + HStack(spacing: Design.Spacing.medium) { + SymbolIcon("square.grid.2x2.fill", size: .row, color: AppAccent.primary) + .frame(width: 44, height: 44) + .background(AppAccent.primary.opacity(0.15)) + .clipShape(.rect(cornerRadius: Design.CornerRadius.medium)) + + VStack(alignment: .leading, spacing: Design.Spacing.xSmall) { + Text(String(localized: "Widgets")).styled(.heading, emphasis: .primary) + Text(String(localized: "Add Andromida to your Home Screen for quick check-ins.")) + .styled(.caption, emphasis: .secondary) + } + + Spacer() + } + + Button(action: onLearnMore) { + Text(String(localized: "How to add")).styled(.caption, emphasis: .primary) + .padding(.vertical, Design.Spacing.xSmall) + .padding(.horizontal, Design.Spacing.small) + .background(AppAccent.primary.opacity(0.15)) + .clipShape(.capsule) + } + .buttonStyle(.plain) + } + .padding(Design.Spacing.medium) + .background(AppSurface.card) + .clipShape(.rect(cornerRadius: Design.CornerRadius.large)) + } +} + +private struct WidgetSetupSheet: View { + var body: some View { + VStack(spacing: Design.Spacing.large) { + VStack(spacing: Design.Spacing.small) { + Text(String(localized: "Add the widget")).styled(.title2Bold, emphasis: .primary) + Text(String(localized: "Keep your rituals visible at a glance.")) + .styled(.subheading, emphasis: .secondary) + .multilineTextAlignment(.center) + } + + VStack(alignment: .leading, spacing: Design.Spacing.medium) { + WidgetStepRow(number: "1", text: String(localized: "Touch and hold your Home Screen.")) + WidgetStepRow(number: "2", text: String(localized: "Tap Edit, then Add Widget.")) + WidgetStepRow(number: "3", text: String(localized: "Search for Andromida and pick a size.")) + } + .padding(.horizontal, Design.Spacing.large) + + Spacer() + } + .padding(.top, Design.Spacing.xxLarge) + .presentationDetents([.medium]) + } +} + +private struct WidgetStepRow: View { + let number: String + let text: String + + var body: some View { + HStack(alignment: .top, spacing: Design.Spacing.medium) { + Text(number).styled(.caption, emphasis: .inverse) + .frame(width: 28, height: 28) + .background(AppAccent.primary) + .clipShape(.circle) + + Text(text).styled(.body, emphasis: .primary) + + Spacer() + } + .padding(Design.Spacing.medium) + .background(AppSurface.card) + .clipShape(.rect(cornerRadius: Design.CornerRadius.large)) + } +} + #Preview { ZStack { LinearGradient(