diff --git a/App/Sources/UI/Views/Icons/PrivacyIconView.swift b/App/Sources/UI/Views/Icons/PrivacyIconView.swift new file mode 100644 index 00000000..449af574 --- /dev/null +++ b/App/Sources/UI/Views/Icons/PrivacyIconView.swift @@ -0,0 +1,79 @@ +import SwiftUI + +struct PrivacyIconView: View { + let size: CGFloat + var body: some View { + ZStack { + InternalPrivayIconView( + size: size, + primaryColor: .systemGray, + secondaryColor: .systemGreen, + primaryTintColor: .white, + secondaryTintColor: .yellow + ) + + InternalPrivayIconView( + size: size, + primaryColor: .systemGreen, + secondaryColor: .white, + primaryTintColor: .systemYellow, + secondaryTintColor: .white + ) + .mask(alignment: .trailing) { + Rectangle() + .frame(width: size * 0.5) + } + } + } +} + +private struct InternalPrivayIconView: View { + let size: CGFloat + let primaryColor: NSColor + let secondaryColor: NSColor + let primaryTintColor: NSColor + let secondaryTintColor: NSColor + + var body: some View { + Rectangle() + .fill( + LinearGradient(stops: [ + .init(color: Color(primaryColor.blended(withFraction: 0.2, of: primaryTintColor)!), location: 0.0), + .init(color: Color(primaryColor.withSystemEffect(.disabled)), location: 1.0), + ], startPoint: .top, endPoint: .bottom) + ) + .overlay { iconOverlay().opacity(0.65) } + .overlay { iconBorder(size) } + .overlay { + LinearGradient(stops: [ + .init(color: Color(nsColor: secondaryColor.blended(withFraction: 0.5, of: secondaryTintColor)!), location: 0.2), + .init(color: Color(nsColor: secondaryColor.blended(withFraction: 0.3, of: .black)!), location: 1.0), + ], startPoint: .top, endPoint: .bottom) + .mask { + Image(systemName: "shield.lefthalf.filled") + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: size * 0.5) + } + .shadow(radius: 4) + } + .frame(width: size, height: size) + .fixedSize() + .iconShape(size) + } +} + +#Preview { + HStack(alignment: .top, spacing: 8) { + PrivacyIconView(size: 192) + VStack(alignment: .leading, spacing: 8) { + PrivacyIconView(size: 128) + HStack(alignment: .top, spacing: 8) { + PrivacyIconView(size: 64) + PrivacyIconView(size: 32) + PrivacyIconView(size: 16) + } + } + } + .padding() +} diff --git a/App/Sources/UI/Views/PromoView.swift b/App/Sources/UI/Views/PromoView.swift index 09126b12..cff40738 100644 --- a/App/Sources/UI/Views/PromoView.swift +++ b/App/Sources/UI/Views/PromoView.swift @@ -130,7 +130,8 @@ private struct AutomationView: View { var body: some View { VStack(spacing: 16) { TriggersIconView(size: 64) - Text("Automation") + Text("Automation\nTriggers") + .multilineTextAlignment(.center) } } } @@ -212,10 +213,7 @@ private struct UniqueModifierView: View { private struct PrivacyFirstView: View { var body: some View { VStack(spacing: 16) { - Image(systemName: "shield.lefthalf.filled") - .resizable() - .aspectRatio(contentMode: .fit) - .frame(width: 64, height: 64) + PrivacyIconView(size: 64) Text("Privacy First") } } @@ -257,19 +255,19 @@ private struct WindowManagementView: View { .init(color: Color(nsColor: .white.withSystemEffect(.disabled)), location: 1.0), ], startPoint: .topLeading, endPoint: .bottom) ) - .overlay { iconOverlay().opacity(0.5) } + .overlay { iconOverlay().opacity(0.25) } .overlay(alignment: .topLeading) { HStack(alignment: .top, spacing: 0) { MinimizeAllWindowTrafficLightsView(size) Rectangle() .fill(.white) .frame(maxWidth: .infinity) - .overlay { iconOverlay().opacity(0.5) } + .overlay { iconOverlay().opacity(0.25) } } } .iconShape(size.width * 0.7) .frame(width: size.width, height: size.height) - .shadow(color: .black.opacity(0.1), radius: 4, y: 2) + .shadow(color: .black.opacity(0.3), radius: 4, y: 2) Text("Window Mangement") .font(.system(size: 18, design: .rounded))