-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #40 from gertrude-app/bug-fixes-macapp
- Loading branch information
Showing
19 changed files
with
650 additions
and
173 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
166 changes: 166 additions & 0 deletions
166
macapp/App/Sources/App/Onboarding/OnboardingFeature.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
import ComposableArchitecture | ||
import Foundation | ||
|
||
struct OnboardingFeature: Feature { | ||
struct State: Equatable, Encodable { | ||
struct MacUser: Equatable, Encodable { | ||
var id: uid_t | ||
var name: String | ||
var isAdmin: Bool | ||
|
||
enum RemediationStep: String, Equatable, Encodable { | ||
case create | ||
case `switch` | ||
case demote | ||
case choose | ||
} | ||
} | ||
|
||
var windowOpen = false | ||
var step: Step = .welcome | ||
var userRemediationStep: MacUser.RemediationStep? | ||
var currentUser: MacUser? | ||
var users: [MacUser] = [] | ||
} | ||
|
||
enum Action: Equatable, Sendable { | ||
enum Webview: Equatable, Sendable { | ||
case primaryBtnClicked | ||
case secondaryBtnClicked | ||
case chooseSwitchToNonAdminUserClicked | ||
case chooseCreateNonAdminClicked | ||
case chooseDemoteAdminClicked | ||
} | ||
|
||
enum Delegate: Equatable, Sendable { | ||
case saveCurrentStep(State.Step?) | ||
} | ||
|
||
case webview(Webview) | ||
case delegate(Delegate) | ||
case receivedUserData(uid_t, [MacOSUser]) | ||
} | ||
|
||
struct Reducer: FeatureReducer { | ||
@Dependency(\.app) var app | ||
@Dependency(\.device) var device | ||
@Dependency(\.storage) var storage | ||
|
||
func reduce(into state: inout State, action: Action) -> Effect<Action> { | ||
let step = state.step | ||
let userIsAdmin = state.currentUser?.isAdmin != false | ||
switch action { | ||
|
||
case .receivedUserData(let currentUserId, let users): | ||
state.users = users.map(State.MacUser.init) | ||
state.currentUser = state.users.first(where: { $0.id == currentUserId }) | ||
return .none | ||
|
||
case .webview(.primaryBtnClicked) where step == .welcome: | ||
state.step = .confirmGertrudeAccount | ||
return .exec { send in | ||
await send(.receivedUserData(device.currentUserId(), try await device.listMacOSUsers())) | ||
} | ||
|
||
case .webview(.primaryBtnClicked) where step == .confirmGertrudeAccount: | ||
state.step = .macosUserAccountType | ||
return .none | ||
|
||
case .webview(.secondaryBtnClicked) where step == .confirmGertrudeAccount: | ||
state.step = .noGertrudeAccount | ||
return .none | ||
|
||
case .webview(.secondaryBtnClicked) where step == .noGertrudeAccount: | ||
return .exec { _ in | ||
await storage.deleteAll() | ||
await app.quit() | ||
} | ||
|
||
case .webview(.primaryBtnClicked) where step == .macosUserAccountType && !userIsAdmin: | ||
state.step = .getChildConnectionCode | ||
return .none | ||
|
||
// they choose to ignore the warning about user type and proceed | ||
case .webview(.secondaryBtnClicked) where step == .macosUserAccountType && userIsAdmin: | ||
state.step = .getChildConnectionCode | ||
return .none | ||
|
||
// they click "show me how to fix" on the BAD mac os user landing page | ||
case .webview(.primaryBtnClicked) where step == .macosUserAccountType && userIsAdmin: | ||
state.userRemediationStep = state.users.count == 1 ? .create : .choose | ||
return .send(.delegate(.saveCurrentStep(.macosUserAccountType))) | ||
|
||
case .webview(.chooseDemoteAdminClicked): | ||
state.userRemediationStep = .demote | ||
return .none | ||
|
||
case .webview(.chooseCreateNonAdminClicked): | ||
state.userRemediationStep = .create | ||
return .none | ||
|
||
case .webview(.chooseSwitchToNonAdminUserClicked): | ||
state.userRemediationStep = .switch | ||
return .none | ||
|
||
case .webview(.primaryBtnClicked): | ||
return .none | ||
|
||
case .webview(.secondaryBtnClicked): | ||
return .none | ||
|
||
case .delegate: | ||
return .none | ||
} | ||
} | ||
} | ||
|
||
struct RootReducer: RootReducing { | ||
// todo | ||
} | ||
} | ||
|
||
extension OnboardingFeature.RootReducer { | ||
func reduce(into state: inout State, action: Action) -> Effect<Self.Action> { | ||
.none | ||
} | ||
} | ||
|
||
extension OnboardingFeature.State { | ||
enum Step: Equatable, Codable { | ||
case welcome | ||
case confirmGertrudeAccount | ||
case noGertrudeAccount | ||
case macosUserAccountType | ||
case getChildConnectionCode | ||
case connectChild | ||
case allowNotifications_start | ||
case allowNotifications_grant | ||
case allowScreenshots_required | ||
case allowScreenshots_openSysSettings | ||
case allowScreenshots_grantAndRestart | ||
case allowScreenshots_success | ||
case allowKeylogging_required | ||
case allowKeylogging_openSysSettings | ||
case allowKeylogging_grant | ||
case allowKeylogging_failed | ||
case allowKeylogging_success | ||
case installSysExt_explain | ||
case installSysExt_start | ||
case installSysExt_allowInstall | ||
case installSysExt_allowFiltering | ||
case installSysExt_failed | ||
case installSysExt_success | ||
case locateMenuBarIcon | ||
case viewHealthCheck | ||
case howToUseGertrude | ||
case finish | ||
} | ||
} | ||
|
||
extension OnboardingFeature.State.MacUser { | ||
init(_ user: MacOSUser) { | ||
id = user.id | ||
name = user.name | ||
isAdmin = user.type == .admin | ||
} | ||
} |
Oops, something went wrong.