Przeglądaj źródła

Polish Google auth button alignment and hover behavior.

Center icon/title content, increase icon size for readability, and add a subtle hover surface state to improve button feedback in dark and light modes.

Made-with: Cursor
huzaifahayat12 1 tydzień temu
rodzic
commit
139b2b0f4a
1 zmienionych plików z 30 dodań i 22 usunięć
  1. 30 22
      meetings_app/ViewController.swift

+ 30 - 22
meetings_app/ViewController.swift

@@ -86,6 +86,7 @@ final class ViewController: NSViewController {
86
     private weak var scheduleFilterDropdown: NSPopUpButton?
86
     private weak var scheduleFilterDropdown: NSPopUpButton?
87
     private weak var scheduleGoogleAuthButton: NSButton?
87
     private weak var scheduleGoogleAuthButton: NSButton?
88
     private var scheduleGoogleAuthButtonWidthConstraint: NSLayoutConstraint?
88
     private var scheduleGoogleAuthButtonWidthConstraint: NSLayoutConstraint?
89
+    private var scheduleGoogleAuthHovering = false
89
     private var scheduleCurrentProfile: GoogleProfileDisplay?
90
     private var scheduleCurrentProfile: GoogleProfileDisplay?
90
     private var scheduleProfileImageTask: Task<Void, Never>?
91
     private var scheduleProfileImageTask: Task<Void, Never>?
91
 
92
 
@@ -1895,7 +1896,7 @@ private extension ViewController {
1895
     }
1896
     }
1896
 
1897
 
1897
     private func makeGoogleAuthButton() -> NSButton {
1898
     private func makeGoogleAuthButton() -> NSButton {
1898
-        let button = NSButton(title: "", target: self, action: #selector(scheduleConnectButtonPressed(_:)))
1899
+        let button = HoverButton(title: "", target: self, action: #selector(scheduleConnectButtonPressed(_:)))
1899
         button.translatesAutoresizingMaskIntoConstraints = false
1900
         button.translatesAutoresizingMaskIntoConstraints = false
1900
         button.isBordered = false
1901
         button.isBordered = false
1901
         button.bezelStyle = .regularSquare
1902
         button.bezelStyle = .regularSquare
@@ -1904,8 +1905,8 @@ private extension ViewController {
1904
         button.layer?.borderWidth = 1
1905
         button.layer?.borderWidth = 1
1905
         button.font = NSFont.systemFont(ofSize: 14, weight: .semibold)
1906
         button.font = NSFont.systemFont(ofSize: 14, weight: .semibold)
1906
         button.imagePosition = .imageLeading
1907
         button.imagePosition = .imageLeading
1907
-        button.alignment = .left
1908
-        button.imageHugsTitle = false
1908
+        button.alignment = .center
1909
+        button.imageHugsTitle = true
1909
         button.lineBreakMode = .byTruncatingTail
1910
         button.lineBreakMode = .byTruncatingTail
1910
         button.contentTintColor = palette.textPrimary
1911
         button.contentTintColor = palette.textPrimary
1911
         button.imageScaling = .scaleNone
1912
         button.imageScaling = .scaleNone
@@ -1913,6 +1914,11 @@ private extension ViewController {
1913
         let widthConstraint = button.widthAnchor.constraint(equalToConstant: 248)
1914
         let widthConstraint = button.widthAnchor.constraint(equalToConstant: 248)
1914
         widthConstraint.isActive = true
1915
         widthConstraint.isActive = true
1915
         scheduleGoogleAuthButtonWidthConstraint = widthConstraint
1916
         scheduleGoogleAuthButtonWidthConstraint = widthConstraint
1917
+        button.onHoverChanged = { [weak self] hovering in
1918
+            self?.scheduleGoogleAuthHovering = hovering
1919
+            self?.applyGoogleAuthButtonSurface()
1920
+        }
1921
+        button.onHoverChanged?(false)
1916
         return button
1922
         return button
1917
     }
1923
     }
1918
 
1924
 
@@ -2951,7 +2957,6 @@ private extension ViewController {
2951
     private func updateGoogleAuthButtonTitle() {
2957
     private func updateGoogleAuthButtonTitle() {
2952
         let signedIn = (googleOAuth.loadTokens() != nil)
2958
         let signedIn = (googleOAuth.loadTokens() != nil)
2953
         guard let button = scheduleGoogleAuthButton else { return }
2959
         guard let button = scheduleGoogleAuthButton else { return }
2954
-        let iconLeftInset: CGFloat = 12
2955
 
2960
 
2956
         let profileName = scheduleCurrentProfile?.name ?? "Google account"
2961
         let profileName = scheduleCurrentProfile?.name ?? "Google account"
2957
         let profileEmail = scheduleCurrentProfile?.email ?? "Sign in with Google"
2962
         let profileEmail = scheduleCurrentProfile?.email ?? "Sign in with Google"
@@ -2968,12 +2973,12 @@ private extension ViewController {
2968
 
2973
 
2969
         if signedIn {
2974
         if signedIn {
2970
             let symbol = NSImage(systemSymbolName: "person.crop.circle.fill", accessibilityDescription: "Profile")
2975
             let symbol = NSImage(systemSymbolName: "person.crop.circle.fill", accessibilityDescription: "Profile")
2971
-            button.image = symbol.flatMap { paddedImage($0, iconSize: NSSize(width: 16, height: 16), leftInset: iconLeftInset) }
2972
-            button.symbolConfiguration = NSImage.SymbolConfiguration(pointSize: 16, weight: .regular)
2976
+            button.image = symbol.flatMap { resizedImage($0, to: NSSize(width: 20, height: 20)) }
2977
+            button.symbolConfiguration = NSImage.SymbolConfiguration(pointSize: 20, weight: .regular)
2973
             button.contentTintColor = palette.textPrimary
2978
             button.contentTintColor = palette.textPrimary
2974
         } else {
2979
         } else {
2975
             if let g = NSImage(named: "GoogleGLogo") {
2980
             if let g = NSImage(named: "GoogleGLogo") {
2976
-                button.image = paddedImage(g, iconSize: NSSize(width: 16, height: 16), leftInset: iconLeftInset)
2981
+                button.image = resizedImage(g, to: NSSize(width: 20, height: 20))
2977
             } else {
2982
             } else {
2978
                 button.image = nil
2983
                 button.image = nil
2979
             }
2984
             }
@@ -2981,9 +2986,7 @@ private extension ViewController {
2981
         }
2986
         }
2982
         button.contentTintColor = signedIn ? palette.textPrimary : nil
2987
         button.contentTintColor = signedIn ? palette.textPrimary : nil
2983
 
2988
 
2984
-        let isDark = darkModeEnabled
2985
-        button.layer?.backgroundColor = isDark ? NSColor(calibratedRed: 8.0 / 255.0, green: 14.0 / 255.0, blue: 24.0 / 255.0, alpha: 1).cgColor : NSColor.white.cgColor
2986
-        button.layer?.borderColor = (isDark ? NSColor(calibratedWhite: 0.50, alpha: 1) : NSColor(calibratedWhite: 0.72, alpha: 1)).cgColor
2989
+        applyGoogleAuthButtonSurface()
2987
     }
2990
     }
2988
 
2991
 
2989
     private func makeGoogleProfileDisplay(from profile: GoogleUserProfile) -> GoogleProfileDisplay {
2992
     private func makeGoogleProfileDisplay(from profile: GoogleUserProfile) -> GoogleProfileDisplay {
@@ -3010,7 +3013,7 @@ private extension ViewController {
3010
                 if Task.isCancelled { return }
3013
                 if Task.isCancelled { return }
3011
                 guard let image = NSImage(data: data) else { return }
3014
                 guard let image = NSImage(data: data) else { return }
3012
                 await MainActor.run {
3015
                 await MainActor.run {
3013
-                    self?.scheduleGoogleAuthButton?.image = self?.paddedImage(image, iconSize: NSSize(width: 16, height: 16), leftInset: 12)
3016
+                    self?.scheduleGoogleAuthButton?.image = self?.resizedImage(image, to: NSSize(width: 20, height: 20))
3014
                     self?.scheduleGoogleAuthButton?.contentTintColor = nil
3017
                     self?.scheduleGoogleAuthButton?.contentTintColor = nil
3015
                 }
3018
                 }
3016
             } catch {
3019
             } catch {
@@ -3031,17 +3034,22 @@ private extension ViewController {
3031
         return result
3034
         return result
3032
     }
3035
     }
3033
 
3036
 
3034
-    private func paddedImage(_ image: NSImage, iconSize: NSSize, leftInset: CGFloat) -> NSImage {
3035
-        let canvasSize = NSSize(width: iconSize.width + leftInset, height: iconSize.height)
3036
-        let result = NSImage(size: canvasSize)
3037
-        result.lockFocus()
3038
-        image.draw(in: NSRect(x: leftInset, y: 0, width: iconSize.width, height: iconSize.height),
3039
-                   from: NSRect(origin: .zero, size: image.size),
3040
-                   operation: .copy,
3041
-                   fraction: 1.0)
3042
-        result.unlockFocus()
3043
-        result.isTemplate = false
3044
-        return result
3037
+    private func applyGoogleAuthButtonSurface() {
3038
+        guard let button = scheduleGoogleAuthButton else { return }
3039
+        let isDark = darkModeEnabled
3040
+        let baseBackground = isDark
3041
+            ? NSColor(calibratedRed: 8.0 / 255.0, green: 14.0 / 255.0, blue: 24.0 / 255.0, alpha: 1)
3042
+            : NSColor.white
3043
+        let hoverBlend = isDark ? NSColor.white : NSColor.black
3044
+        let hoverBackground = baseBackground.blended(withFraction: 0.07, of: hoverBlend) ?? baseBackground
3045
+        let baseBorder = isDark
3046
+            ? NSColor(calibratedWhite: 0.50, alpha: 1)
3047
+            : NSColor(calibratedWhite: 0.72, alpha: 1)
3048
+        let hoverBorder = isDark
3049
+            ? NSColor(calibratedWhite: 0.62, alpha: 1)
3050
+            : NSColor(calibratedWhite: 0.56, alpha: 1)
3051
+        button.layer?.backgroundColor = (scheduleGoogleAuthHovering ? hoverBackground : baseBackground).cgColor
3052
+        button.layer?.borderColor = (scheduleGoogleAuthHovering ? hoverBorder : baseBorder).cgColor
3045
     }
3053
     }
3046
 
3054
 
3047
     @MainActor
3055
     @MainActor