Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure welcome screen shown before menu popover tip #411

Merged
merged 1 commit into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions FiveCalls/FiveCalls/Actions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import Foundation

enum Action {
case ShowWelcomeScreen
case FetchStats(Int?)
case SetGlobalCallCount(Int)
case SetIssueCallCount(Int,Int)
Expand Down
8 changes: 3 additions & 5 deletions FiveCalls/FiveCalls/App.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,21 @@ import SwiftUI

@main
struct FiveCallsApp: App {
@StateObject var store: Store = Store(state: AppState(), middlewares: [appMiddleware()])
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

let store = Store(state: AppState(), middlewares: [appMiddleware()])
@AppStorage(UserDefaultsKey.hasShownWelcomeScreen.rawValue) var hasShownWelcomeScreen = false
@State var showWelcomeScreen = false

var body: some Scene {
WindowGroup {
IssueSplitView()
.environmentObject(store)
.sheet(isPresented: $showWelcomeScreen) {
.sheet(isPresented: $store.state.showWelcomeScreen) {
Welcome().environmentObject(store)
}
.onAppear {
if !hasShownWelcomeScreen {
showWelcomeScreen = true
hasShownWelcomeScreen = true
store.dispatch(action: .ShowWelcomeScreen)
}
}
}
Expand Down
1 change: 1 addition & 0 deletions FiveCalls/FiveCalls/AppState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import CoreLocation
import os

class AppState: ObservableObject, ReduxState {
@Published var showWelcomeScreen = false
@Published var globalCallCount: Int = 0
@Published var issueCallCounts: [Int: Int] = [:]
// issueCompletion is a local cache of completed calls: an array of contact id and outcomes (B0001234-contact) keyed by an issue id
Expand Down
4 changes: 3 additions & 1 deletion FiveCalls/FiveCalls/Dashboard.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ struct Dashboard: View {
var body: some View {
VStack(alignment: .leading, spacing: 10) {
HStack {
MenuView()
MenuView(showingWelcomeScreen: store.state.showWelcomeScreen)

LocationHeader(location: store.state.location, fetchingContacts: store.state.fetchingContacts)
.padding(.bottom, 10)
Expand Down Expand Up @@ -104,6 +104,7 @@ struct MenuView: View {
@State var showRemindersSheet = false
@State var showYourImpact = false
@State var showAboutSheet = false
var showingWelcomeScreen: Bool

var body: some View {
Menu {
Expand All @@ -124,6 +125,7 @@ struct MenuView: View {
.accessibilityLabel(Text(R.string.localizable.menuName))
}
.popoverTipIfApplicable(
showingWelcomeScreen: showingWelcomeScreen,
title: Text(R.string.localizable.menuTipTitle()),
message: Text(R.string.localizable.menuTipMessage()))
.sheet(isPresented: $showRemindersSheet) {
Expand Down
5 changes: 3 additions & 2 deletions FiveCalls/FiveCalls/Middleware.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ func appMiddleware() -> Middleware<AppState> {
}
AnalyticsManager.shared.trackEvent(name: "Outcome-\(outcome.status)", path: "/issues/\(issue.slug)/")
reportOutcome(log: contactLog, outcome: outcome)
case .SetGlobalCallCount, .SetIssueCallCount, .SetDonateOn, .SetIssueContactCompletion, .SetContacts, .SetFetchingContacts, .SetIssues,
.SetLoadingStatsError, .SetLoadingIssuesError, .SetLoadingContactsError, .GoBack, .GoToRoot, .GoToNext:
case .SetGlobalCallCount, .SetIssueCallCount, .SetDonateOn, .SetIssueContactCompletion, .SetContacts,
.SetFetchingContacts, .SetIssues, .SetLoadingStatsError, .SetLoadingIssuesError, .SetLoadingContactsError,
.GoBack, .GoToRoot, .GoToNext, .ShowWelcomeScreen:
// no middleware actions for these, including for completeness
break
}
Expand Down
34 changes: 21 additions & 13 deletions FiveCalls/FiveCalls/PopoverTip.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,26 @@ struct PopoverTip: Tip {
}

extension View {
func popoverTipIfApplicable(title: Text, message: Text?) -> some View {
if #available(iOS 17, *) {
return self
.popoverTip(
PopoverTip(
title: title,
message: message
),
arrowEdge: .top
)
} else {
return self
func popoverTipIfApplicable(showingWelcomeScreen: Bool,
title: Text,
message: Text?)
-> some View
{
if #available(iOS 17, *) {
if showingWelcomeScreen {
AnyView(self)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I spent a good hour trying to debug this method. If I kept the return's, it compiled, but crashed without a helpful debug message which took me a while to track down. Adding AnyView seems to be required once I introduced the additional conditional 🤷🏻‍♂️

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ran into this before but didn't figure out how to get it working, AnyView to the rescue!

} else {
AnyView(self
.popoverTip(
PopoverTip(
title: title,
message: message
),
arrowEdge: .top
))
}
} else {
AnyView(self)
}
}
}
}
2 changes: 2 additions & 0 deletions FiveCalls/FiveCalls/Store.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ class Store: ObservableObject {
func reduce(_ oldState: AppState, _ action: Action) -> AppState {
let state = oldState
switch action {
case .ShowWelcomeScreen:
state.showWelcomeScreen = true
case let .SetGlobalCallCount(globalCallCount):
state.globalCallCount = globalCallCount
case let .SetIssueCallCount(issueID, count):
Expand Down
3 changes: 3 additions & 0 deletions FiveCalls/FiveCalls/Welcome.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import SwiftUI

struct Welcome: View {
@AppStorage(UserDefaultsKey.hasShownWelcomeScreen.rawValue) var hasShownWelcomeScreen = false

@Environment(\.dismiss) var dismiss
@EnvironmentObject var store: Store

Expand Down Expand Up @@ -90,6 +92,7 @@ struct Welcome: View {
}
}
.onAppear() {
hasShownWelcomeScreen = true
if store.state.globalCallCount == 0 {
store.dispatch(action: .FetchStats(nil))
}
Expand Down