|
|
@@ -1,11 +1,12 @@
|
|
|
import SwiftUI
|
|
|
+import AppKit
|
|
|
|
|
|
struct LauncherRootView: View {
|
|
|
@State private var query = ""
|
|
|
@State private var selectedApp: LauncherApp?
|
|
|
|
|
|
private let apps = LauncherApp.sampleApps
|
|
|
- private let columns = [GridItem(.adaptive(minimum: 122, maximum: 150), spacing: 24)]
|
|
|
+ private let columns = [GridItem(.adaptive(minimum: 120, maximum: 145), spacing: 22)]
|
|
|
|
|
|
private var filteredApps: [LauncherApp] {
|
|
|
let q = query.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
|
@@ -15,9 +16,12 @@ struct LauncherRootView: View {
|
|
|
|
|
|
var body: some View {
|
|
|
ZStack {
|
|
|
- Color(red: 0.05, green: 0.06, blue: 0.09)
|
|
|
+ VisualEffectBlur(material: .hudWindow, blendingMode: .behindWindow)
|
|
|
.ignoresSafeArea()
|
|
|
|
|
|
+ Color.black.opacity(0.22)
|
|
|
+ .ignoresSafeArea()
|
|
|
+
|
|
|
VStack(spacing: 16) {
|
|
|
SearchHeader(query: $query)
|
|
|
.padding(.top, 12)
|
|
|
@@ -46,7 +50,7 @@ struct LauncherRootView: View {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- .padding(.horizontal, 12)
|
|
|
+ .padding(.horizontal, 10)
|
|
|
.padding(.bottom, 8)
|
|
|
}
|
|
|
.sheet(item: $selectedApp) { app in
|
|
|
@@ -69,10 +73,14 @@ private struct SearchHeader: View {
|
|
|
.foregroundStyle(.white.opacity(0.94))
|
|
|
}
|
|
|
.padding(.horizontal, 12)
|
|
|
- .padding(.vertical, 9)
|
|
|
+ .padding(.vertical, 8)
|
|
|
.background(
|
|
|
- RoundedRectangle(cornerRadius: 16, style: .continuous)
|
|
|
- .fill(Color.white.opacity(0.08))
|
|
|
+ RoundedRectangle(cornerRadius: 15, style: .continuous)
|
|
|
+ .fill(Color.black.opacity(0.28))
|
|
|
+ )
|
|
|
+ .overlay(
|
|
|
+ RoundedRectangle(cornerRadius: 15, style: .continuous)
|
|
|
+ .stroke(Color.white.opacity(0.08), lineWidth: 1)
|
|
|
)
|
|
|
|
|
|
Spacer(minLength: 8)
|
|
|
@@ -112,11 +120,15 @@ private struct PromoBanner: View {
|
|
|
.fill(Color.blue.opacity(0.92))
|
|
|
)
|
|
|
}
|
|
|
- .padding(.horizontal, 12)
|
|
|
+ .padding(.horizontal, 11)
|
|
|
.padding(.vertical, 8)
|
|
|
.background(
|
|
|
RoundedRectangle(cornerRadius: 12, style: .continuous)
|
|
|
- .fill(Color.white.opacity(0.04))
|
|
|
+ .fill(Color.white.opacity(0.03))
|
|
|
+ )
|
|
|
+ .overlay(
|
|
|
+ RoundedRectangle(cornerRadius: 12, style: .continuous)
|
|
|
+ .stroke(Color.white.opacity(0.05), lineWidth: 1)
|
|
|
)
|
|
|
}
|
|
|
}
|
|
|
@@ -124,3 +136,21 @@ private struct PromoBanner: View {
|
|
|
#Preview {
|
|
|
LauncherRootView()
|
|
|
}
|
|
|
+
|
|
|
+private struct VisualEffectBlur: NSViewRepresentable {
|
|
|
+ let material: NSVisualEffectView.Material
|
|
|
+ let blendingMode: NSVisualEffectView.BlendingMode
|
|
|
+
|
|
|
+ func makeNSView(context: Context) -> NSVisualEffectView {
|
|
|
+ let view = NSVisualEffectView()
|
|
|
+ view.state = .active
|
|
|
+ view.material = material
|
|
|
+ view.blendingMode = blendingMode
|
|
|
+ return view
|
|
|
+ }
|
|
|
+
|
|
|
+ func updateNSView(_ nsView: NSVisualEffectView, context: Context) {
|
|
|
+ nsView.material = material
|
|
|
+ nsView.blendingMode = blendingMode
|
|
|
+ }
|
|
|
+}
|