From 7f20a5f328153065e82a09e751ae9a7be15bfb55 Mon Sep 17 00:00:00 2001 From: krugerk <4656811+krugerk@users.noreply.github.com> Date: Fri, 6 Dec 2024 13:09:02 +0100 Subject: [PATCH 1/7] SignIn screen, now in SwiftUI took the opportunity to modernize the screen a bit background color of yellow, loading indicator and twaek the version shown in dark mode --- BeeSwift.xcodeproj/project.pbxproj | 4 + BeeSwift/Gallery/GalleryViewController.swift | 41 ++++-- BeeSwift/SignInView.swift | 131 +++++++++++++++++++ 3 files changed, 168 insertions(+), 8 deletions(-) create mode 100644 BeeSwift/SignInView.swift diff --git a/BeeSwift.xcodeproj/project.pbxproj b/BeeSwift.xcodeproj/project.pbxproj index 37044a771..d27ceed33 100644 --- a/BeeSwift.xcodeproj/project.pbxproj +++ b/BeeSwift.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 9B65F2322CFA6427009674A7 /* DeeplinkGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B65F2312CFA6418009674A7 /* DeeplinkGenerator.swift */; }; + 9B2488422D030E5100E610E0 /* SignInView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B2488412D030E5100E610E0 /* SignInView.swift */; }; 9B8CA57D24B120CA009C86C2 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9B8CA57C24B120CA009C86C2 /* LaunchScreen.storyboard */; }; A10D4E931B07948500A72D29 /* DatapointsTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A10D4E921B07948500A72D29 /* DatapointsTableView.swift */; }; A10DC2DF207BFCBA00FB7B3A /* RemoveHKMetricViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A10DC2DE207BFCBA00FB7B3A /* RemoveHKMetricViewController.swift */; }; @@ -219,6 +220,7 @@ /* Begin PBXFileReference section */ 9B65F2312CFA6418009674A7 /* DeeplinkGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeeplinkGenerator.swift; sourceTree = ""; }; + 9B2488412D030E5100E610E0 /* SignInView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignInView.swift; sourceTree = ""; }; 9B8CA57C24B120CA009C86C2 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; A10D4E921B07948500A72D29 /* DatapointsTableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DatapointsTableView.swift; sourceTree = ""; }; A10DC2DE207BFCBA00FB7B3A /* RemoveHKMetricViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoveHKMetricViewController.swift; sourceTree = ""; }; @@ -495,6 +497,7 @@ E43BEA832A036A9C00FC3A38 /* LogReader.swift */, A1453B3E1AEDFCC8006F48DA /* SignInViewController.swift */, E4015D9E2D10DC4D00F58D94 /* SceneDelegate.swift */, + 9B2488412D030E5100E610E0 /* SignInView.swift */, ); path = BeeSwift; sourceTree = ""; @@ -1028,6 +1031,7 @@ A10DC2DF207BFCBA00FB7B3A /* RemoveHKMetricViewController.swift in Sources */, E412DAE12B86A8F70099E483 /* GoalImageView.swift in Sources */, A1619EA41BEECC1500E14B3A /* EditDefaultNotificationsViewController.swift in Sources */, + 9B2488422D030E5100E610E0 /* SignInView.swift in Sources */, A149B3701AEF528C00F19A09 /* SettingsViewController.swift in Sources */, E46DC80F2AA58DF20059FDFE /* PullToRefreshHint.swift in Sources */, A1E618E21E78158700D8ED93 /* HealthKitConfigViewController.swift in Sources */, diff --git a/BeeSwift/Gallery/GalleryViewController.swift b/BeeSwift/Gallery/GalleryViewController.swift index e80328033..5851625a4 100644 --- a/BeeSwift/Gallery/GalleryViewController.swift +++ b/BeeSwift/Gallery/GalleryViewController.swift @@ -216,13 +216,17 @@ class GalleryViewController: UIViewController, UICollectionViewDelegateFlowLayou make.right.equalTo(self.view.safeAreaLayoutGuide.snp.rightMargin) make.bottom.equalTo(self.collectionView!.keyboardLayoutGuide.snp.top) } + + if !ServiceLocator.currentUserManager.signedIn(context: ServiceLocator.persistentContainer.viewContext) { + presentSignInScreen() + } } override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + if !ServiceLocator.currentUserManager.signedIn(context: ServiceLocator.persistentContainer.viewContext) { - let signInVC = SignInViewController() - signInVC.modalPresentationStyle = .fullScreen - self.present(signInVC, animated: true, completion: nil) + presentSignInScreen() } else { self.updateGoals() self.fetchGoals() @@ -280,15 +284,34 @@ class GalleryViewController: UIViewController, UICollectionViewDelegateFlowLayou } @objc func handleSignOut() { + logger.debug("\(#function)") + self.goals = [] self.filteredGoals = [] self.collectionView?.reloadData() - if self.presentedViewController != nil { - if type(of: self.presentedViewController!) == SignInViewController.self { return } + + presentSignInScreen() + } + + + private var isSignInViewBeingPresented: Bool { + guard let presentedViewController else { return false } + + return type(of: presentedViewController) == UIHostingController.self + } + + + private func presentSignInScreen() { + let shallPresentSignIn = presentedViewController == nil || !isSignInViewBeingPresented + + guard shallPresentSignIn else { + logger.debug("\(#function) - already presenting sign in; not presenting it yet again") + return } - let signInVC = SignInViewController() - signInVC.modalPresentationStyle = .fullScreen - self.present(signInVC, animated: true, completion: nil) + + let hostingVC = UIHostingController(rootView: SignInView()) + hostingVC.modalPresentationStyle = .fullScreen + self.present(hostingVC, animated: true) } func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { @@ -512,3 +535,5 @@ class GalleryViewController: UIViewController, UICollectionViewDelegateFlowLayou } } + +import SwiftUI diff --git a/BeeSwift/SignInView.swift b/BeeSwift/SignInView.swift new file mode 100644 index 000000000..08d72c805 --- /dev/null +++ b/BeeSwift/SignInView.swift @@ -0,0 +1,131 @@ +// Part of BeeSwift. Copyright Beeminder + +import SwiftUI +import BeeKit + +struct SignInView: View { + @StateObject private var viewModel = SignInViewModel() + @State private var showingFailedSignInAlert = false + @State private var showingMissingDataAlert = false + @Environment(\.dismiss) private var dismiss + + var body: some View { + ZStack { + Color.yellow + .opacity(0.8) + .ignoresSafeArea() + + HStack(alignment: .center) { + + VStack(alignment: .center, spacing: 15) { + Spacer() + + Image("website_logo_mid") + .resizable() + .scaledToFit() + .frame(maxWidth: 200) + .padding(.bottom) + + VStack(spacing: 15) { + TextField("Email or username", text: $viewModel.email) + .textFieldStyle(RoundedBorderTextFieldStyle()) + .textInputAutocapitalization(.never) + .autocorrectionDisabled() + .keyboardType(.emailAddress) + .textContentType(.emailAddress) + .submitLabel(.next) + + SecureField("Password", text: $viewModel.password) + .textFieldStyle(RoundedBorderTextFieldStyle()) + .textInputAutocapitalization(.never) + .submitLabel(.done) + + Button(action: signIn) { + Text("Sign In") + .font(.system(size: 20)) + .foregroundColor(.white) + .frame(maxWidth: .infinity) + .frame(height: 44) + } + .background(Color("BeeminderGray")) + .cornerRadius(8) + .disabled(viewModel.isLoading) + } + .frame(maxWidth: .infinity) + .padding(.horizontal, 40) + + Spacer() + Spacer() + Spacer() + } + .padding() + + } + .alert("Could not sign in", isPresented: $showingFailedSignInAlert) { + Button("OK", role: .cancel) { } + } message: { + Text("Invalid credentials") + } + .alert("Incomplete Account Details", isPresented: $showingMissingDataAlert) { + Button("OK", role: .cancel) { } + } message: { + Text("Username and Password are required") + } + .onReceive(NotificationCenter.default.publisher(for: Notification.Name(CurrentUserManager.failedSignInNotificationName))) { _ in + viewModel.isLoading = false + showingFailedSignInAlert = true + } + .onReceive(NotificationCenter.default.publisher(for: Notification.Name(CurrentUserManager.signedInNotificationName))) { _ in + viewModel.isLoading = false + dismiss() + } + } + .overlay { + if viewModel.isLoading { + ProgressView() + .scaleEffect(1.5) + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(Color.black.opacity(0.2)) + } + } + } + + private func signIn() { + guard !viewModel.email.trimmingCharacters(in: .whitespaces).isEmpty, + !viewModel.password.isEmpty else { + showingMissingDataAlert = true + return + } + + Task { + await viewModel.signIn() + } + } +} + +@MainActor +class SignInViewModel: ObservableObject { + @Published var email = "" + @Published var password = "" + @Published var isLoading = false + + func signIn() async { + isLoading = true + + // Delay the task by 3 seconds: + do { + try await Task.sleep(nanoseconds: 3_000_000_000) + } catch { + print("canceled early") + } + + await ServiceLocator.currentUserManager.signInWithEmail( + email.trimmingCharacters(in: .whitespaces), + password: password + ) + } +} + +#Preview { + SignInView() +} From 8c5bbb90b313f03bfa4c44938660993df8360c0d Mon Sep 17 00:00:00 2001 From: krugerk <4656811+krugerk@users.noreply.github.com> Date: Fri, 6 Dec 2024 14:06:58 +0100 Subject: [PATCH 2/7] remove cruft --- BeeSwift.xcodeproj/project.pbxproj | 4 - BeeSwift/SignInView.swift | 2 +- BeeSwift/SignInViewController.swift | 154 ---------------------------- 3 files changed, 1 insertion(+), 159 deletions(-) delete mode 100644 BeeSwift/SignInViewController.swift diff --git a/BeeSwift.xcodeproj/project.pbxproj b/BeeSwift.xcodeproj/project.pbxproj index d27ceed33..bd3591ca8 100644 --- a/BeeSwift.xcodeproj/project.pbxproj +++ b/BeeSwift.xcodeproj/project.pbxproj @@ -15,7 +15,6 @@ A11A87C61FEBFF7200A43E47 /* ChooseGoalSortViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A11A87C51FEBFF7200A43E47 /* ChooseGoalSortViewController.swift */; }; A11BC2D91FFAD5BC00E56064 /* TimerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A11BC2D81FFAD5BC00E56064 /* TimerViewController.swift */; }; A12BA94E1AFF202200AFEF32 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A12BA94D1AFF202200AFEF32 /* SystemConfiguration.framework */; }; - A1453B3F1AEDFCC8006F48DA /* SignInViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1453B3E1AEDFCC8006F48DA /* SignInViewController.swift */; }; A149147B1BE79FD50060600A /* EditNotificationsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A149147A1BE79FD40060600A /* EditNotificationsViewController.swift */; }; A149147F1BE7A5670060600A /* SettingsTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A149147E1BE7A5670060600A /* SettingsTableViewCell.swift */; }; A149B3701AEF528C00F19A09 /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A149B36F1AEF528C00F19A09 /* SettingsViewController.swift */; }; @@ -235,7 +234,6 @@ A1453B341AED9184006F48DA /* UIColorExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIColorExtension.swift; sourceTree = ""; }; A1453B381AEDA71D006F48DA /* BSLabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BSLabel.swift; sourceTree = ""; }; A1453B3C1AEDFA52006F48DA /* CurrentUserManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CurrentUserManager.swift; sourceTree = ""; }; - A1453B3E1AEDFCC8006F48DA /* SignInViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignInViewController.swift; sourceTree = ""; }; A149147A1BE79FD40060600A /* EditNotificationsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EditNotificationsViewController.swift; sourceTree = ""; }; A149147E1BE7A5670060600A /* SettingsTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsTableViewCell.swift; sourceTree = ""; }; A149B36F1AEF528C00F19A09 /* SettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = ""; }; @@ -495,7 +493,6 @@ A196CB231AE4142F00B90A3E /* Images.xcassets */, 9B8CA57C24B120CA009C86C2 /* LaunchScreen.storyboard */, E43BEA832A036A9C00FC3A38 /* LogReader.swift */, - A1453B3E1AEDFCC8006F48DA /* SignInViewController.swift */, E4015D9E2D10DC4D00F58D94 /* SceneDelegate.swift */, 9B2488412D030E5100E610E0 /* SignInView.swift */, ); @@ -1015,7 +1012,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - A1453B3F1AEDFCC8006F48DA /* SignInViewController.swift in Sources */, A1E618E41E7934C700D8ED93 /* HealthKitConfigTableViewCell.swift in Sources */, E4B083392932F90400A71564 /* ConfigureHKMetricViewController.swift in Sources */, E43BEA842A036A9C00FC3A38 /* LogReader.swift in Sources */, diff --git a/BeeSwift/SignInView.swift b/BeeSwift/SignInView.swift index 08d72c805..6257c78b4 100644 --- a/BeeSwift/SignInView.swift +++ b/BeeSwift/SignInView.swift @@ -47,7 +47,7 @@ struct SignInView: View { .frame(maxWidth: .infinity) .frame(height: 44) } - .background(Color("BeeminderGray")) + .background(Color.gray) .cornerRadius(8) .disabled(viewModel.isLoading) } diff --git a/BeeSwift/SignInViewController.swift b/BeeSwift/SignInViewController.swift deleted file mode 100644 index 8b53e8947..000000000 --- a/BeeSwift/SignInViewController.swift +++ /dev/null @@ -1,154 +0,0 @@ -// -// SignInViewController.swift -// BeeSwift -// -// Created by Andy Brett on 4/26/15. -// Copyright (c) 2015 APB. All rights reserved. -// - -import Foundation -import MBProgressHUD -import SafariServices - -import BeeKit - -class SignInViewController : UIViewController, UITextFieldDelegate { - - var headerLabel = BSLabel() - var emailTextField = BSTextField() - var passwordTextField = BSTextField() - var beeImageView = UIImageView() - var signInButton = BSButton() - var divider = UIView() - - override func viewDidLoad() { - super.viewDidLoad() - - let scrollView = UIScrollView() - self.view.addSubview(scrollView) - scrollView.snp.makeConstraints { (make) -> Void in - make.edges.equalTo(self.view) - } - - NotificationCenter.default.addObserver(self, selector: #selector(self.handleFailedSignIn(_:)), name: NSNotification.Name(rawValue: CurrentUserManager.failedSignInNotificationName), object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(self.handleSignedIn(_:)), name: NSNotification.Name(rawValue: CurrentUserManager.signedInNotificationName), object: nil) - self.view.backgroundColor = UIColor.systemBackground - - - self.beeImageView.image = UIImage(named: "website_logo_mid") - scrollView.addSubview(self.beeImageView) - self.beeImageView.snp.makeConstraints { (make) in - make.centerX.equalTo(scrollView) - make.centerY.equalToSuperview().multipliedBy(0.55) - } - - scrollView.addSubview(self.headerLabel) - self.headerLabel.textAlignment = NSTextAlignment.center - self.headerLabel.snp.makeConstraints { (make) -> Void in - make.top.equalTo(beeImageView.snp.bottom) - make.centerX.equalToSuperview() - } - - scrollView.addSubview(self.emailTextField) - self.emailTextField.isHidden = true - self.emailTextField.placeholder = "Email or username" - self.emailTextField.autocapitalizationType = .none - self.emailTextField.autocorrectionType = .no - self.emailTextField.keyboardType = UIKeyboardType.emailAddress - self.emailTextField.returnKeyType = .next - self.emailTextField.delegate = self - self.emailTextField.snp.makeConstraints { (make) -> Void in - make.top.equalTo(self.headerLabel.snp.bottom).offset(15) - make.centerX.equalTo(scrollView) - make.width.equalTo(scrollView).multipliedBy(0.75) - make.height.equalTo(Constants.defaultTextFieldHeight) - } - - scrollView.addSubview(self.passwordTextField) - self.passwordTextField.isHidden = true - self.passwordTextField.placeholder = "Password" - self.passwordTextField.isSecureTextEntry = true - self.passwordTextField.returnKeyType = .done - self.passwordTextField.autocapitalizationType = .none - self.passwordTextField.delegate = self - self.passwordTextField.snp.makeConstraints { (make) -> Void in - make.top.equalTo(self.emailTextField.snp.bottom).offset(15) - make.centerX.equalTo(self.emailTextField) - make.width.equalTo(self.emailTextField) - make.height.equalTo(Constants.defaultTextFieldHeight) - } - - scrollView.addSubview(self.signInButton) - self.signInButton.isHidden = true - self.signInButton.setTitle("Sign In", for: UIControl.State()) - self.signInButton.titleLabel?.font = UIFont.beeminder.defaultFontPlain.withSize(20) - self.signInButton.titleLabel?.textColor = UIColor.white - self.signInButton.addTarget(self, action: #selector(SignInViewController.signInButtonPressed), for: UIControl.Event.touchUpInside) - self.signInButton.snp.makeConstraints { (make) -> Void in - make.left.equalTo(self.passwordTextField) - make.right.equalTo(self.passwordTextField) - make.top.equalTo(self.passwordTextField.snp.bottom).offset(15) - make.height.equalTo(Constants.defaultTextFieldHeight) - } - - scrollView.addSubview(self.divider) - self.divider.isHidden = true - self.divider.backgroundColor = UIColor.Beeminder.gray - - self.chooseSignInButtonPressed() - } - - @objc func chooseSignInButtonPressed() { - self.emailTextField.isHidden = false - self.passwordTextField.isHidden = false - self.headerLabel.text = "Sign in to Beeminder" - self.headerLabel.isHidden = false - self.signInButton.isHidden = false - self.divider.snp.remakeConstraints { (make) -> Void in - make.left.equalTo(self.signInButton) - make.right.equalTo(self.signInButton) - make.height.equalTo(1) - make.top.equalTo(self.signInButton.snp.bottom).offset(15) - } - } - - var missingDataOnSignIn: UIAlertController { - let lackOfCredentials = UIAlertController(title: "Incomplete Account Details", message: "Username and Password are required", preferredStyle: .alert) - lackOfCredentials.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil)) - - return lackOfCredentials - } - - @objc func handleFailedSignIn(_ notification : Notification) { - let failureAC = UIAlertController(title: "Could not sign in", message: "Invalid credentials", preferredStyle: .alert) - failureAC.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil)) - self.present(failureAC, animated: true, completion: nil) - MBProgressHUD.hide(for: self.view, animated: true) - } - - @objc func handleSignedIn(_ notification : Notification) { - MBProgressHUD.hide(for: self.view, animated: true) - } - - @objc func signInButtonPressed() { - Task { @MainActor in - guard let email = self.emailTextField.text?.trimmingCharacters(in: .whitespaces), let password = self.passwordTextField.text, !email.isEmpty, !password.isEmpty else { - self.present(self.missingDataOnSignIn, animated: true, completion: nil) - return - } - - MBProgressHUD.showAdded(to: self.view, animated: true) - await ServiceLocator.currentUserManager.signInWithEmail(email, password: password) - } - } - - func textFieldShouldReturn(_ textField: UITextField) -> Bool { - if textField.isEqual(self.emailTextField) { - self.passwordTextField.becomeFirstResponder() - } - else if textField.isEqual(self.passwordTextField) { - self.signInButtonPressed() - } - return true - } -} From 0d22dfd54354cc6022a10d882e1c3c2c2e1d96b0 Mon Sep 17 00:00:00 2001 From: krugerk <4656811+krugerk@users.noreply.github.com> Date: Fri, 6 Dec 2024 14:16:39 +0100 Subject: [PATCH 3/7] clean code --- BeeSwift/Gallery/GalleryViewController.swift | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/BeeSwift/Gallery/GalleryViewController.swift b/BeeSwift/Gallery/GalleryViewController.swift index 5851625a4..652779553 100644 --- a/BeeSwift/Gallery/GalleryViewController.swift +++ b/BeeSwift/Gallery/GalleryViewController.swift @@ -13,7 +13,7 @@ import SwiftyJSON import HealthKit import SafariServices import OSLog - +import SwiftUI import BeeKit @@ -534,6 +534,3 @@ class GalleryViewController: UIViewController, UICollectionViewDelegateFlowLayou self.fetchGoals() } } - - -import SwiftUI From 7e410f95e9ba4939e9a625f951c2eee15ddcb39a Mon Sep 17 00:00:00 2001 From: krugerk <4656811+krugerk@users.noreply.github.com> Date: Fri, 6 Dec 2024 14:27:28 +0100 Subject: [PATCH 4/7] clean code --- BeeSwift/SignInView.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/BeeSwift/SignInView.swift b/BeeSwift/SignInView.swift index 6257c78b4..e6dacbbe7 100644 --- a/BeeSwift/SignInView.swift +++ b/BeeSwift/SignInView.swift @@ -112,7 +112,6 @@ class SignInViewModel: ObservableObject { func signIn() async { isLoading = true - // Delay the task by 3 seconds: do { try await Task.sleep(nanoseconds: 3_000_000_000) } catch { From 4d60e50dacaacd01c72c1a5b6caed12c022745e0 Mon Sep 17 00:00:00 2001 From: krugerk <4656811+krugerk@users.noreply.github.com> Date: Fri, 6 Dec 2024 17:11:31 +0100 Subject: [PATCH 5/7] make my logo bigger --- BeeSwift/SignInButton.swift | 32 ++++++++++++++++++++++++++++++++ BeeSwift/SignInView.swift | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 BeeSwift/SignInButton.swift diff --git a/BeeSwift/SignInButton.swift b/BeeSwift/SignInButton.swift new file mode 100644 index 000000000..195aa83c7 --- /dev/null +++ b/BeeSwift/SignInButton.swift @@ -0,0 +1,32 @@ +struct SignInButton: View { + @Environment(\.colorScheme) private var colorScheme + let action: () -> Void + let isDisabled: Bool + + init(action: @escaping () -> Void, isDisabled: Bool = false) { + self.action = action + self.isDisabled = isDisabled + } + + var body: some View { + Button(action: action) { + Label("Sign In", systemImage: "iphone.and.arrow.forward.inward") + .font(.system(size: 20)) + .frame(maxWidth: .infinity) + .frame(height: 44) + } + .buttonStyle(.bordered) + .foregroundStyle(colorScheme == .dark ? Color.yellow : Color.black) + .overlay { + if colorScheme == .dark { + RoundedRectangle(cornerRadius: 4) + .stroke(Color.yellow, lineWidth: 4) + } else { + RoundedRectangle(cornerRadius: 4) + .stroke(.clear) + } + } +// .cornerRadius(4) + .disabled(isDisabled) + } +} diff --git a/BeeSwift/SignInView.swift b/BeeSwift/SignInView.swift index e6dacbbe7..422badf81 100644 --- a/BeeSwift/SignInView.swift +++ b/BeeSwift/SignInView.swift @@ -23,7 +23,7 @@ struct SignInView: View { Image("website_logo_mid") .resizable() .scaledToFit() - .frame(maxWidth: 200) + .frame(maxWidth: 400) .padding(.bottom) VStack(spacing: 15) { From de9c2a4572a341b47e325edffae20efe1c23055a Mon Sep 17 00:00:00 2001 From: krugerk <4656811+krugerk@users.noreply.github.com> Date: Sat, 28 Dec 2024 12:09:09 +0100 Subject: [PATCH 6/7] also include the sign in button --- BeeSwift.xcodeproj/project.pbxproj | 8 ++++++-- BeeSwift/SignInButton.swift | 2 ++ BeeSwift/SignInView.swift | 12 ++---------- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/BeeSwift.xcodeproj/project.pbxproj b/BeeSwift.xcodeproj/project.pbxproj index bd3591ca8..5448af84f 100644 --- a/BeeSwift.xcodeproj/project.pbxproj +++ b/BeeSwift.xcodeproj/project.pbxproj @@ -7,8 +7,9 @@ objects = { /* Begin PBXBuildFile section */ - 9B65F2322CFA6427009674A7 /* DeeplinkGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B65F2312CFA6418009674A7 /* DeeplinkGenerator.swift */; }; 9B2488422D030E5100E610E0 /* SignInView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B2488412D030E5100E610E0 /* SignInView.swift */; }; + 9B65F2322CFA6427009674A7 /* DeeplinkGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B65F2312CFA6418009674A7 /* DeeplinkGenerator.swift */; }; + 9B6F0CE82D2011F00077D37D /* SignInButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B6F0CE72D2011F00077D37D /* SignInButton.swift */; }; 9B8CA57D24B120CA009C86C2 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9B8CA57C24B120CA009C86C2 /* LaunchScreen.storyboard */; }; A10D4E931B07948500A72D29 /* DatapointsTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A10D4E921B07948500A72D29 /* DatapointsTableView.swift */; }; A10DC2DF207BFCBA00FB7B3A /* RemoveHKMetricViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A10DC2DE207BFCBA00FB7B3A /* RemoveHKMetricViewController.swift */; }; @@ -218,8 +219,9 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 9B65F2312CFA6418009674A7 /* DeeplinkGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeeplinkGenerator.swift; sourceTree = ""; }; 9B2488412D030E5100E610E0 /* SignInView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignInView.swift; sourceTree = ""; }; + 9B65F2312CFA6418009674A7 /* DeeplinkGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeeplinkGenerator.swift; sourceTree = ""; }; + 9B6F0CE72D2011F00077D37D /* SignInButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignInButton.swift; sourceTree = ""; }; 9B8CA57C24B120CA009C86C2 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; A10D4E921B07948500A72D29 /* DatapointsTableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DatapointsTableView.swift; sourceTree = ""; }; A10DC2DE207BFCBA00FB7B3A /* RemoveHKMetricViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoveHKMetricViewController.swift; sourceTree = ""; }; @@ -478,6 +480,7 @@ A196CB161AE4142E00B90A3E /* BeeSwift */ = { isa = PBXGroup; children = ( + 9B6F0CE72D2011F00077D37D /* SignInButton.swift */, 9B65F2312CFA6418009674A7 /* DeeplinkGenerator.swift */, A1E618E51E79E01900D8ED93 /* Cells */, E46071002B43DA7100305DB4 /* Gallery */, @@ -1017,6 +1020,7 @@ E43BEA842A036A9C00FC3A38 /* LogReader.swift in Sources */, 9B65F2322CFA6427009674A7 /* DeeplinkGenerator.swift in Sources */, A196CB1F1AE4142F00B90A3E /* GalleryViewController.swift in Sources */, + 9B6F0CE82D2011F00077D37D /* SignInButton.swift in Sources */, A1BE73AA1E8B45BF00DEC4DB /* ChooseHKMetricViewController.swift in Sources */, A149147B1BE79FD50060600A /* EditNotificationsViewController.swift in Sources */, E4015D9F2D10DC4D00F58D94 /* SceneDelegate.swift in Sources */, diff --git a/BeeSwift/SignInButton.swift b/BeeSwift/SignInButton.swift index 195aa83c7..532dc1b40 100644 --- a/BeeSwift/SignInButton.swift +++ b/BeeSwift/SignInButton.swift @@ -1,3 +1,5 @@ +import SwiftUI + struct SignInButton: View { @Environment(\.colorScheme) private var colorScheme let action: () -> Void diff --git a/BeeSwift/SignInView.swift b/BeeSwift/SignInView.swift index 422badf81..34a065c7f 100644 --- a/BeeSwift/SignInView.swift +++ b/BeeSwift/SignInView.swift @@ -40,16 +40,8 @@ struct SignInView: View { .textInputAutocapitalization(.never) .submitLabel(.done) - Button(action: signIn) { - Text("Sign In") - .font(.system(size: 20)) - .foregroundColor(.white) - .frame(maxWidth: .infinity) - .frame(height: 44) - } - .background(Color.gray) - .cornerRadius(8) - .disabled(viewModel.isLoading) + SignInButton(action: signIn, + isDisabled: viewModel.isLoading) } .frame(maxWidth: .infinity) .padding(.horizontal, 40) From 561b9cd36a344019e1bce479e6489d6ed4e26634 Mon Sep 17 00:00:00 2001 From: krugerk <4656811+krugerk@users.noreply.github.com> Date: Sat, 28 Dec 2024 12:14:03 +0100 Subject: [PATCH 7/7] Update BeeSwift/SignInButton.swift --- BeeSwift/SignInButton.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/BeeSwift/SignInButton.swift b/BeeSwift/SignInButton.swift index 532dc1b40..f37165a54 100644 --- a/BeeSwift/SignInButton.swift +++ b/BeeSwift/SignInButton.swift @@ -28,7 +28,6 @@ struct SignInButton: View { .stroke(.clear) } } -// .cornerRadius(4) .disabled(isDisabled) } }