Explorar o código

Google-style launcher tiles

Made-with: Cursor
huzaifahayat12 hai 4 meses
pai
achega
e881eca9fc
Modificáronse 1 ficheiros con 47 adicións e 44 borrados
  1. 47 44
      google_apps/AppTileView.swift

+ 47 - 44
google_apps/AppTileView.swift

@@ -86,16 +86,21 @@ struct AppTileView: View {
     }
 
     private var tileContent: some View {
-        VStack(spacing: 11) {
-            AppIconView(app: app, size: 64)
-                .shadow(
-                    color: .black.opacity(isHovering ? 0.34 : 0.2),
-                    radius: isHovering ? 14 : 8,
-                    x: 0,
-                    y: isHovering ? 10 : 5
-                )
-                .scaleEffect(isPressing ? 0.96 : 1.0)
-                .offset(y: isHovering ? -1 : 0)
+        VStack(spacing: 9) {
+            AppIconView(
+                app: app,
+                size: 48,
+                showAppBackground: false,
+                iconPaddingFactor: 0.07
+            )
+            .shadow(
+                color: .black.opacity(isHovering ? 0.24 : 0.06),
+                radius: isHovering ? 12 : 5,
+                x: 0,
+                y: isHovering ? 8 : 2
+            )
+            .scaleEffect(isPressing ? 0.97 : (isHovering ? 1.02 : 1.0))
+            .offset(y: isHovering ? -0.5 : 0)
 
             Text(app.name)
                 .font(.system(size: 13, weight: .medium))
@@ -103,61 +108,53 @@ struct AppTileView: View {
                 .lineLimit(1)
                 .truncationMode(.tail)
                 .frame(maxWidth: .infinity)
-                .offset(y: isHovering ? -0.5 : 0)
+                .offset(y: isHovering ? -0.25 : 0)
         }
-        .padding(.horizontal, 7)
-        .padding(.vertical, 10)
+        .padding(.horizontal, 10)
+        .padding(.vertical, 12)
         .background(
             RoundedRectangle(cornerRadius: tileCornerRadius, style: .continuous)
-                .fill(
-                    LinearGradient(
-                        colors: isHovering
-                            ? [Color.white.opacity(0.16), Color.white.opacity(0.06)]
-                            : [Color.white.opacity(0.03), Color.white.opacity(0.015)],
-                        startPoint: .topLeading,
-                        endPoint: .bottomTrailing
-                    )
-                )
+                .fill(Color.white.opacity(isHovering ? 0.07 : 0.02))
         )
         .overlay(
-            // Soft spotlight makes hover feel richer without harsh contrast.
             RoundedRectangle(cornerRadius: tileCornerRadius, style: .continuous)
-                .fill(
-                    RadialGradient(
-                        colors: isHovering
-                            ? [Color.white.opacity(0.16), Color.clear]
-                            : [Color.clear, Color.clear],
-                        center: .top,
-                        startRadius: 0,
-                        endRadius: 80
-                    )
-                )
+                .fill(RadialGradient(
+                    colors: [
+                        Color.white.opacity(isHovering ? 0.16 : 0.06),
+                        .clear
+                    ],
+                    center: .top,
+                    startRadius: 12,
+                    endRadius: 100
+                ))
                 .allowsHitTesting(false)
         )
         .overlay(
             RoundedRectangle(cornerRadius: tileCornerRadius, style: .continuous)
                 .stroke(
-                    isHovering ? Color.white.opacity(0.3) : Color.white.opacity(0.06),
-                    lineWidth: isHovering ? 1.3 : 1
+                    isHovering ? Color.white.opacity(0.28) : Color.white.opacity(0.10),
+                    lineWidth: isHovering ? 1.2 : 1
                 )
         )
         .overlay(
             RoundedRectangle(cornerRadius: tileCornerRadius, style: .continuous)
                 .inset(by: 1)
                 .stroke(
-                    isHovering ? Color.white.opacity(0.12) : Color.clear,
+                    isHovering ? Color.white.opacity(0.16) : Color.white.opacity(0.04),
                     lineWidth: 1
                 )
                 .allowsHitTesting(false)
         )
-        .scaleEffect(isPressing ? 0.985 : (isHovering ? 1.02 : 1.0))
-        .offset(y: isPressing ? 0 : (isHovering ? -2 : 0))
+        .scaleEffect(isPressing ? 0.99 : (isHovering ? 1.02 : 1.0))
+        .offset(y: isPressing ? 0 : (isHovering ? -1 : 0))
         .shadow(
             color: .black.opacity(isHovering ? 0.22 : 0),
             radius: isHovering ? 18 : 0,
             x: 0,
             y: isHovering ? 12 : 0
         )
+        // Ensure tiles look consistent across the adaptive grid.
+        .frame(maxWidth: .infinity, minHeight: 94)
         .contentShape(RoundedRectangle(cornerRadius: tileCornerRadius, style: .continuous))
         .animation(.spring(response: 0.24, dampingFraction: 0.88), value: isHovering)
         .animation(.easeOut(duration: 0.12), value: isPressing)
@@ -269,6 +266,8 @@ private struct HideMenuIndicatorIfAvailable: ViewModifier {
 private struct AppIconView: View {
     let app: LauncherApp
     let size: CGFloat
+    var showAppBackground: Bool = true
+    var iconPaddingFactor: CGFloat = 0.12
 
     var body: some View {
         ZStack {
@@ -283,27 +282,31 @@ private struct AppIconView: View {
                     .font(.system(size: size * 0.34, weight: .regular))
                     .foregroundStyle(.white.opacity(0.9))
             } else {
-                RoundedRectangle(cornerRadius: 18, style: .continuous)
-                    .fill(LinearGradient(colors: gradientColors, startPoint: .topLeading, endPoint: .bottomTrailing))
-                RoundedRectangle(cornerRadius: 18, style: .continuous)
-                    .stroke(Color.white.opacity(0.08), lineWidth: 1)
+                if showAppBackground {
+                    RoundedRectangle(cornerRadius: 18, style: .continuous)
+                        .fill(LinearGradient(colors: gradientColors, startPoint: .topLeading, endPoint: .bottomTrailing))
+                    RoundedRectangle(cornerRadius: 18, style: .continuous)
+                        .stroke(Color.white.opacity(0.08), lineWidth: 1)
+                }
 
                 if let webURL = app.webURL {
                     WebSiteFaviconView(
                         webURL: webURL,
                         size: size,
                         assetIconName: app.assetIconName,
-                        fallbackSymbolName: app.fallbackSymbolName
+                        fallbackSymbolName: app.fallbackSymbolName,
+                        iconPaddingFactor: iconPaddingFactor
                     )
                 } else if let iconImage = NSImage(named: app.assetIconName) {
                     Image(nsImage: iconImage)
                         .resizable()
                         .scaledToFit()
-                        .padding(size * 0.12)
+                        .padding(size * iconPaddingFactor)
                 } else {
                     Image(systemName: app.fallbackSymbolName)
                         .font(.system(size: size * 0.32, weight: .semibold))
                         .foregroundStyle(.white)
+                        .padding(size * iconPaddingFactor)
                 }
             }
         }