Extend glass background and deepen 3D cards

This commit is contained in:
Rafal Kolarz 2026-10-23 01:28:42 +01:00
parent 79ce995af2
commit 6b19d78f53
7 changed files with 119 additions and 50 deletions

View File

@ -292,7 +292,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 12; CURRENT_PROJECT_VERSION = 13;
GENERATE_INFOPLIST_FILE = NO; GENERATE_INFOPLIST_FILE = NO;
INFOPLIST_FILE = Kasztelan/Info.plist; INFOPLIST_FILE = Kasztelan/Info.plist;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.food-and-drink"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.food-and-drink";
@ -316,7 +316,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 12; CURRENT_PROJECT_VERSION = 13;
GENERATE_INFOPLIST_FILE = NO; GENERATE_INFOPLIST_FILE = NO;
INFOPLIST_FILE = Kasztelan/Info.plist; INFOPLIST_FILE = Kasztelan/Info.plist;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.food-and-drink"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.food-and-drink";

View File

@ -89,7 +89,19 @@ struct CardView: View {
} }
private func loyaltyCard(compact: Bool) -> some View { private func loyaltyCard(compact: Bool) -> some View {
return VStack(spacing: compact ? 10 : 20) { GlassDepthDeck {
loyaltyCardFace(compact: compact)
}
.rotation3DEffect(
.degrees(-2.8),
axis: (x: 1, y: 0, z: 0),
anchor: .center,
perspective: 0.62
)
}
private func loyaltyCardFace(compact: Bool) -> some View {
VStack(spacing: compact ? 10 : 20) {
Image("Logo") Image("Logo")
.resizable() .resizable()
.scaledToFit() .scaledToFit()

View File

@ -4,18 +4,26 @@ struct MainTabView: View {
@EnvironmentObject private var model: AppModel @EnvironmentObject private var model: AppModel
var body: some View { var body: some View {
ZStack {
AmbientBackground()
TabView(selection: $model.selectedTab) { TabView(selection: $model.selectedTab) {
NavigationStack { WalletView() } NavigationStack { WalletView() }
.toolbarBackground(.hidden, for: .navigationBar)
.tabItem { Label(model.text("Karta", "Card"), systemImage: "creditcard.fill") } .tabItem { Label(model.text("Karta", "Card"), systemImage: "creditcard.fill") }
.tag(0) .tag(0)
NavigationStack { MessagesView() } NavigationStack { MessagesView() }
.toolbarBackground(.hidden, for: .navigationBar)
.tabItem { Label(model.text("Wiadomości", "Messages"), systemImage: "envelope.fill") } .tabItem { Label(model.text("Wiadomości", "Messages"), systemImage: "envelope.fill") }
.badge(model.messages.count) .badge(model.messages.count)
.tag(1) .tag(1)
NavigationStack { ProfileView() } NavigationStack { ProfileView() }
.toolbarBackground(.hidden, for: .navigationBar)
.tabItem { Label(model.text("Profil", "Profile"), systemImage: "person.crop.circle.fill") } .tabItem { Label(model.text("Profil", "Profile"), systemImage: "person.crop.circle.fill") }
.tag(2) .tag(2)
} }
.background(.clear)
}
.tint(KTheme.orange) .tint(KTheme.orange)
.toolbarBackground(.ultraThinMaterial, for: .tabBar) .toolbarBackground(.ultraThinMaterial, for: .tabBar)
.toolbarBackground(.visible, for: .tabBar) .toolbarBackground(.visible, for: .tabBar)

View File

@ -29,6 +29,7 @@ struct MessagesView: View {
} }
.background(AmbientBackground()) .background(AmbientBackground())
.toolbar { AppToolbar() } .toolbar { AppToolbar() }
.toolbarBackground(.hidden, for: .navigationBar)
.refreshable { await model.refresh() } .refreshable { await model.refresh() }
.task { await model.refresh() } .task { await model.refresh() }
} }

View File

@ -53,6 +53,7 @@ struct ProfileView: View {
} }
.background(AmbientBackground()) .background(AmbientBackground())
.toolbar { AppToolbar() } .toolbar { AppToolbar() }
.toolbarBackground(.hidden, for: .navigationBar)
.fullScreenCover(isPresented: $editingProfile) { EditProfileView() } .fullScreenCover(isPresented: $editingProfile) { EditProfileView() }
.sheet(isPresented: $changingPassword) { ChangePasswordView() } .sheet(isPresented: $changingPassword) { ChangePasswordView() }
.sheet(isPresented: $deletingAccount) { .sheet(isPresented: $deletingAccount) {

View File

@ -59,6 +59,46 @@ struct AmbientBackground: View {
} }
} }
struct GlassDepthDeck<Content: View>: View {
private let cornerRadius: CGFloat
private let content: Content
init(cornerRadius: CGFloat = 26, @ViewBuilder content: () -> Content) {
self.cornerRadius = cornerRadius
self.content = content()
}
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: cornerRadius, style: .continuous)
.fill(.ultraThinMaterial)
.overlay {
RoundedRectangle(cornerRadius: cornerRadius, style: .continuous)
.stroke(KTheme.purple.opacity(0.34), lineWidth: 1)
}
.scaleEffect(x: 0.88, y: 0.95)
.offset(y: 24)
.blur(radius: 1.2)
.opacity(0.62)
RoundedRectangle(cornerRadius: cornerRadius, style: .continuous)
.fill(.thinMaterial)
.overlay {
RoundedRectangle(cornerRadius: cornerRadius, style: .continuous)
.stroke(KTheme.pink.opacity(0.32), lineWidth: 1)
}
.scaleEffect(x: 0.95, y: 0.98)
.offset(y: 13)
.opacity(0.80)
content
.shadow(color: .black.opacity(0.48), radius: 34, y: 22)
.shadow(color: KTheme.pink.opacity(0.26), radius: 22, y: 8)
}
.padding(.bottom, 24)
}
}
struct PanelModifier: ViewModifier { struct PanelModifier: ViewModifier {
func body(content: Content) -> some View { func body(content: Content) -> some View {
content content

View File

@ -15,8 +15,9 @@ struct WalletView: View {
var body: some View { var body: some View {
walletCarousel walletCarousel
.background(KTheme.background) .background(.clear)
.toolbar { walletToolbar } .toolbar { walletToolbar }
.toolbarBackground(.hidden, for: .navigationBar)
.onAppear { selectedPage = 0 } .onAppear { selectedPage = 0 }
.task(id: model.user?.id) { await store.sync(using: model) } .task(id: model.user?.id) { await store.sync(using: model) }
.fullScreenCover(isPresented: $scannerPresented) { scannerView } .fullScreenCover(isPresented: $scannerPresented) { scannerView }
@ -166,7 +167,11 @@ struct WalletView: View {
} }
.padding(.horizontal, 12) .padding(.horizontal, 12)
.padding(.vertical, 8) .padding(.vertical, 8)
.background(.black.opacity(0.35), in: Capsule()) .background(.ultraThinMaterial, in: Capsule())
.overlay {
Capsule()
.stroke(.white.opacity(0.18), lineWidth: 1)
}
.padding(.bottom, 2) .padding(.bottom, 2)
.allowsHitTesting(false) .allowsHitTesting(false)
} }
@ -285,6 +290,7 @@ private struct DiscountCardView: View {
.accessibilityLabel(model.text("Usuń kartę", "Delete card")) .accessibilityLabel(model.text("Usuń kartę", "Delete card"))
} }
GlassDepthDeck {
VStack(spacing: 18) { VStack(spacing: 18) {
StoredBarcodeView(value: card.payload, symbology: card.symbology) StoredBarcodeView(value: card.payload, symbology: card.symbology)
.frame(maxWidth: .infinity) .frame(maxWidth: .infinity)
@ -320,7 +326,8 @@ private struct DiscountCardView: View {
RoundedRectangle(cornerRadius: 26, style: .continuous) RoundedRectangle(cornerRadius: 26, style: .continuous)
.stroke(.white.opacity(0.28), lineWidth: 1) .stroke(.white.opacity(0.28), lineWidth: 1)
} }
.shadow(color: KTheme.pink.opacity(0.24), radius: 28, y: 16) }
.rotation3DEffect(.degrees(-2.8), axis: (x: 1, y: 0, z: 0), perspective: 0.62)
Text(model.text("Dostępna offline • zaszyfrowana synchronizacja", "Available offline • encrypted sync")) Text(model.text("Dostępna offline • zaszyfrowana synchronizacja", "Available offline • encrypted sync"))
.font(.footnote) .font(.footnote)