| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- import SwiftUI
- import AppKit
- struct AppIconView: View {
- let app: LauncherApp
- let size: CGFloat
- var showAppBackground: Bool = true
- var iconPaddingFactor: CGFloat = 0.12
- @Environment(\.colorScheme) private var colorScheme
- var body: some View {
- ZStack {
- if app.isCreateNew {
- RoundedRectangle(cornerRadius: 18, style: .continuous)
- .stroke(createTileStrokeColor, lineWidth: 2)
- .background(
- RoundedRectangle(cornerRadius: 18, style: .continuous)
- .fill(createTileFillColor)
- )
- Image(systemName: "plus")
- .font(.system(size: size * 0.34, weight: .regular))
- .foregroundStyle(createTileIconColor)
- } else {
- 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,
- iconPaddingFactor: iconPaddingFactor
- )
- } else if let iconImage = NSImage(named: app.assetIconName) {
- Image(nsImage: iconImage)
- .resizable()
- .scaledToFit()
- .padding(size * iconPaddingFactor)
- } else {
- Image(systemName: app.fallbackSymbolName)
- .font(.system(size: size * 0.32, weight: .semibold))
- .foregroundStyle(.white)
- .padding(size * iconPaddingFactor)
- }
- }
- }
- .frame(width: size, height: size)
- }
- private var gradientColors: [Color] {
- switch app.name {
- case let name where name.contains("Gmail"):
- return [Color.red.opacity(0.85), Color.orange.opacity(0.8)]
- case let name where name.contains("Docs"):
- return [Color.blue.opacity(0.9), Color.indigo.opacity(0.85)]
- case let name where name.contains("Drive"):
- return [Color.green.opacity(0.9), Color.blue.opacity(0.75)]
- case let name where name.contains("YouTube"):
- return [Color.red.opacity(0.95), Color.pink.opacity(0.75)]
- case let name where name.contains("Maps"):
- return [Color.green.opacity(0.85), Color.teal.opacity(0.75)]
- default:
- return [Color.blue.opacity(0.85), Color.cyan.opacity(0.7)]
- }
- }
- private var createTileStrokeColor: Color {
- colorScheme == .dark ? Color.white.opacity(0.35) : Color.black.opacity(0.22)
- }
- private var createTileFillColor: Color {
- colorScheme == .dark ? Color.white.opacity(0.03) : Color.white.opacity(0.85)
- }
- private var createTileIconColor: Color {
- colorScheme == .dark ? Color.white.opacity(0.9) : Color.primary.opacity(0.88)
- }
- }
|