From 2355cbb12e24d8e32c644f069065404d3dda31fb Mon Sep 17 00:00:00 2001 From: kchro3 Date: Mon, 13 Nov 2023 23:22:41 -0800 Subject: [PATCH] wip --- TypeaheadAI/Actors/SpecialCopyActor.swift | 1 - TypeaheadAI/AppDelegate.swift | 6 ++- TypeaheadAI/AppState.swift | 3 +- TypeaheadAI/Supabase/SupabaseManager.swift | 54 ++++++++----------- TypeaheadAI/TypeaheadAIApp.swift | 6 ++- TypeaheadAI/Views/Menu/MenuView.swift | 14 ++--- .../Onboarding/LoggedOutOnboardingView.swift | 2 +- .../Views/Onboarding/OnboardingView.swift | 12 ++++- TypeaheadAI/Views/Settings/AccountView.swift | 8 +-- .../Views/Settings/LoggedOutAccountView.swift | 9 +--- 10 files changed, 54 insertions(+), 61 deletions(-) diff --git a/TypeaheadAI/Actors/SpecialCopyActor.swift b/TypeaheadAI/Actors/SpecialCopyActor.swift index 15e91c1..1ae3185 100644 --- a/TypeaheadAI/Actors/SpecialCopyActor.swift +++ b/TypeaheadAI/Actors/SpecialCopyActor.swift @@ -90,7 +90,6 @@ actor SpecialCopyActor: CanSimulateCopy { } } -// Define the notification name extension somewhere in your codebase extension Notification.Name { static let smartCopyPerformed = Notification.Name("smartCopyPerformed") } diff --git a/TypeaheadAI/AppDelegate.swift b/TypeaheadAI/AppDelegate.swift index f6a8e6e..faaaeab 100644 --- a/TypeaheadAI/AppDelegate.swift +++ b/TypeaheadAI/AppDelegate.swift @@ -16,7 +16,11 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele // Handle the URL if url.host == "login-callback" { let urlDict: [String: URL] = ["url": url] - NotificationCenter.default.post(name: Notification.Name("OAuthCallBack"), object: nil, userInfo: urlDict) + NotificationCenter.default.post(name: .oAuthCallback, object: nil, userInfo: urlDict) + } + if url.host == "onboarding-callback" { + let urlDict: [String: URL] = ["url": url] + NotificationCenter.default.post(name: .oAuthOnboardingCallback, object: nil, userInfo: urlDict) } } } diff --git a/TypeaheadAI/AppState.swift b/TypeaheadAI/AppState.swift index a7eae0e..c2c051d 100644 --- a/TypeaheadAI/AppState.swift +++ b/TypeaheadAI/AppState.swift @@ -30,8 +30,7 @@ final class AppState: ObservableObject { @Published var settingsManager: SettingsManager @Published var clientManager: ClientManager @Published var intentManager: IntentManager - - var supabaseManager = SupabaseManager() + @Published var supabaseManager = SupabaseManager() private let historyManager: HistoryManager private let appContextManager: AppContextManager diff --git a/TypeaheadAI/Supabase/SupabaseManager.swift b/TypeaheadAI/Supabase/SupabaseManager.swift index 26f35f3..ddf1a0c 100644 --- a/TypeaheadAI/Supabase/SupabaseManager.swift +++ b/TypeaheadAI/Supabase/SupabaseManager.swift @@ -10,36 +10,34 @@ import Supabase import SwiftUI import Foundation -class SupabaseManager { +extension Notification.Name { + static let oAuthCallback = Notification.Name("oauthCallback") + static let oAuthOnboardingCallback = Notification.Name("oauthOnboardingCallback") +} + +class SupabaseManager: ObservableObject { let client = SupabaseClient( supabaseURL: URL(string: "https://hwkkvezmbrlrhvipbsum.supabase.co")!, supabaseKey: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Imh3a2t2ZXptYnJscmh2aXBic3VtIiwicm9sZSI6ImFub24iLCJpYXQiOjE2OTgzNjY4NTEsImV4cCI6MjAxMzk0Mjg1MX0.aDzWW0p2uI7wsVGsu1mtfvEh4my8s9zhgVTr4r008YU") private let callbackURL: URL = URL(string: "app.typeahead://login-callback")! + private let onboardingCallbackURL: URL = URL(string: "app.typeahead://onboarding-callback")! - // Use this as a flag for checking if the user is signed in. - @AppStorage("token3") var token: String? - @AppStorage("uuid") var uuid: String? - - init() { - // Register OAuth notifications - NotificationCenter.default.addObserver( - self, - selector: #selector(self.oAuthCallback(_:)), - name: NSNotification.Name(rawValue: "OAuthCallBack"), - object: nil) - } - + @MainActor func registerWithEmail(email: String, password: String) async throws { try await client.auth.signUp(email: email, password: password) let session = try await client.auth.session - let user = session.user - uuid = user.id.uuidString - token = "placeholder" } - func signinWithApple() async throws { - let url = try client.auth.getOAuthSignInURL(provider: Provider.apple, redirectTo: callbackURL) + @MainActor + func signinWithEmail(email: String, password: String) async throws { + let authResponse = try await client.auth.signIn(email: email, password: password) + let user = authResponse.user + } + + func signinWithApple(onboarding: Bool = false) async throws { + let callback = onboarding ? onboardingCallbackURL : callbackURL + let url = try client.auth.getOAuthSignInURL(provider: Provider.apple, redirectTo: callback) NSWorkspace.shared.open(url) } @@ -48,23 +46,13 @@ class SupabaseManager { NSWorkspace.shared.open(url) } + @MainActor func signout() async throws { - uuid = nil - token = nil try await client.auth.signOut() } - @objc func oAuthCallback(_ notification: NSNotification){ - guard let url = notification.userInfo?["url"] as? URL else { return } - Task { - do { - let session = try await client.auth.session(from: url) - let user = session.user - uuid = user.id.uuidString - token = "placeholder" - } catch { - print("### oAuthCallback error: \(error)") - } - } + func signinFromUrl(from: URL) async throws { + let session = try await client.auth.session(from: from) + let user = session.user } } diff --git a/TypeaheadAI/TypeaheadAIApp.swift b/TypeaheadAI/TypeaheadAIApp.swift index 5a78207..48df1c8 100644 --- a/TypeaheadAI/TypeaheadAIApp.swift +++ b/TypeaheadAI/TypeaheadAIApp.swift @@ -13,7 +13,7 @@ struct TypeaheadAIApp { static let onboardingKey = "hasOnboardedV4" static func main() { -// UserDefaults.standard.setValue(false, forKey: onboardingKey) + UserDefaults.standard.setValue(false, forKey: onboardingKey) if UserDefaults.standard.bool(forKey: onboardingKey) { MacOS13AndLaterApp.main() @@ -62,6 +62,7 @@ struct MacOS13AndLaterApp: App { promptManager: appState.promptManager, modalManager: appState.modalManager, settingsManager: appState.settingsManager, + supabaseManager: appState.supabaseManager, isMenuVisible: $appState.isMenuVisible ) } label: { @@ -101,6 +102,7 @@ struct MacOS13AndLaterAppWithOnboardingV2: App { promptManager: appState.promptManager, modalManager: appState.modalManager, settingsManager: appState.settingsManager, + supabaseManager: appState.supabaseManager, isMenuVisible: $appState.isMenuVisible ) } label: { @@ -117,6 +119,7 @@ struct CommonMenuView: View { @ObservedObject var promptManager: PromptManager @ObservedObject var modalManager: ModalManager @ObservedObject var settingsManager: SettingsManager + @ObservedObject var supabaseManager: SupabaseManager @Binding var isMenuVisible: Bool var body: some View { @@ -124,6 +127,7 @@ struct CommonMenuView: View { promptManager: promptManager, modalManager: modalManager, settingsManager: settingsManager, + supabaseManager: supabaseManager, isMenuVisible: $isMenuVisible ) .environment(\.managedObjectContext, persistenceController.container.viewContext) diff --git a/TypeaheadAI/Views/Menu/MenuView.swift b/TypeaheadAI/Views/Menu/MenuView.swift index 26b03a9..3a7dc53 100644 --- a/TypeaheadAI/Views/Menu/MenuView.swift +++ b/TypeaheadAI/Views/Menu/MenuView.swift @@ -14,17 +14,16 @@ struct MenuView: View { @ObservedObject var promptManager: PromptManager @ObservedObject var modalManager: ModalManager @ObservedObject var settingsManager: SettingsManager - - private let supabaseManager = SupabaseManager() + @ObservedObject var supabaseManager: SupabaseManager @Binding var isMenuVisible: Bool @Environment(\.managedObjectContext) private var viewContext @Environment(\.colorScheme) private var colorScheme - @AppStorage("token3") var token: String? @AppStorage("settingsTab") var settingsTab: String? @AppStorage("selectedModel") private var selectedModelURL: URL? + @State private var isLoggedIn: Bool = false @State private var currentPreset: String = "" @State private var isEditingID: UUID? @FocusState private var isTextFieldFocused: Bool @@ -103,10 +102,12 @@ struct MenuView: View { isMenuVisible = false } - if token != nil { + if isLoggedIn { MenuButtonView(title: "Sign out") { - token = nil - isMenuVisible = false + Task { + try await supabaseManager.signout() + isMenuVisible = false + } } } else { MenuButtonView(title: "Sign in") { @@ -156,6 +157,7 @@ struct MenuView_Previews: PreviewProvider { promptManager: promptManager, modalManager: modalManager, settingsManager: SettingsManager(context: context), + supabaseManager: SupabaseManager(), isMenuVisible: $isMenuVisible ) .environment(\.managedObjectContext, context) diff --git a/TypeaheadAI/Views/Onboarding/LoggedOutOnboardingView.swift b/TypeaheadAI/Views/Onboarding/LoggedOutOnboardingView.swift index ad5bf37..e118cdb 100644 --- a/TypeaheadAI/Views/Onboarding/LoggedOutOnboardingView.swift +++ b/TypeaheadAI/Views/Onboarding/LoggedOutOnboardingView.swift @@ -46,7 +46,7 @@ struct LoggedOutOnboardingView: View { AccountOptionButton(label: "Sign-in with Apple", width: 250) { Task { do { - try await supabaseManager.signinWithApple() + try await supabaseManager.signinWithApple(onboarding: true) } catch { failedToRegisterReason = error.localizedDescription failedToSignIn = true diff --git a/TypeaheadAI/Views/Onboarding/OnboardingView.swift b/TypeaheadAI/Views/Onboarding/OnboardingView.swift index a4d6495..ee54bb9 100644 --- a/TypeaheadAI/Views/Onboarding/OnboardingView.swift +++ b/TypeaheadAI/Views/Onboarding/OnboardingView.swift @@ -16,6 +16,7 @@ struct OnboardingView: View { var modalManager: ModalManager var intentManager: IntentManager + @State private var isLoggedIn: Bool = false @State private var step: Int = 1 private let totalSteps: Int = 7 @@ -30,8 +31,8 @@ struct OnboardingView: View { } var body: some View { - VStack { - if let _ = supabaseManager.uuid { + Group { + if isLoggedIn { VStack { panel @@ -44,6 +45,13 @@ struct OnboardingView: View { LoggedOutOnboardingView( supabaseManager: supabaseManager ) + .onReceive(NotificationCenter.default.publisher(for: .oAuthOnboardingCallback), perform: { notification in + guard let url = notification.userInfo?["url"] as? URL else { return } + Task { + try await supabaseManager.signinFromUrl(from: url) + isLoggedIn = true + } + }) } } .frame(width: 500, height: 550) diff --git a/TypeaheadAI/Views/Settings/AccountView.swift b/TypeaheadAI/Views/Settings/AccountView.swift index ce422f9..799df8c 100644 --- a/TypeaheadAI/Views/Settings/AccountView.swift +++ b/TypeaheadAI/Views/Settings/AccountView.swift @@ -10,12 +10,8 @@ import Supabase import AuthenticationServices struct AccountView: View { - // Use this as a flag for checking if the user is signed in. - @AppStorage("token3") var token: String? - @AppStorage("uuid") var uuid: String? - @Environment(\.colorScheme) var colorScheme - var supabaseManager: SupabaseManager + @ObservedObject var supabaseManager: SupabaseManager var body: some View { VStack(alignment: .leading) { @@ -56,7 +52,7 @@ struct AccountView: View { .frame(maxWidth: .infinity) HStack { - Text("User ID: \(uuid ?? "")") + Text("User ID: \(supabaseManager.uuid ?? "")") .font(.footnote) .foregroundStyle(.secondary) .padding(10) diff --git a/TypeaheadAI/Views/Settings/LoggedOutAccountView.swift b/TypeaheadAI/Views/Settings/LoggedOutAccountView.swift index e008cd7..85b4463 100644 --- a/TypeaheadAI/Views/Settings/LoggedOutAccountView.swift +++ b/TypeaheadAI/Views/Settings/LoggedOutAccountView.swift @@ -9,9 +9,6 @@ import SwiftUI struct LoggedOutAccountView: View { // Use this as a flag for checking if the user is signed in. - @AppStorage("token3") var token: String? - @AppStorage("uuid") var uuid: String? - @Environment(\.colorScheme) var colorScheme @State private var email: String = "" @@ -93,11 +90,7 @@ struct LoggedOutAccountView: View { Button { Task { do { - let authResponse = try await supabaseManager.client.auth.signIn(email: email, password: password) - let user = authResponse.user - uuid = user.id.uuidString - token = "placeholder" - let _ = try await supabaseManager.client.auth.session + _ = try await supabaseManager.signinWithEmail(email: email, password: password) email = "" password = "" } catch {