Extend glass background and deepen 3D cards
This commit is contained in:
parent
79ce995af2
commit
6b19d78f53
|
|
@ -292,7 +292,7 @@
|
|||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 12;
|
||||
CURRENT_PROJECT_VERSION = 13;
|
||||
GENERATE_INFOPLIST_FILE = NO;
|
||||
INFOPLIST_FILE = Kasztelan/Info.plist;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.food-and-drink";
|
||||
|
|
@ -316,7 +316,7 @@
|
|||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 12;
|
||||
CURRENT_PROJECT_VERSION = 13;
|
||||
GENERATE_INFOPLIST_FILE = NO;
|
||||
INFOPLIST_FILE = Kasztelan/Info.plist;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.food-and-drink";
|
||||
|
|
|
|||
|
|
@ -89,7 +89,19 @@ struct CardView: 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")
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
|
|
|
|||
|
|
@ -4,17 +4,25 @@ struct MainTabView: View {
|
|||
@EnvironmentObject private var model: AppModel
|
||||
|
||||
var body: some View {
|
||||
TabView(selection: $model.selectedTab) {
|
||||
NavigationStack { WalletView() }
|
||||
.tabItem { Label(model.text("Karta", "Card"), systemImage: "creditcard.fill") }
|
||||
.tag(0)
|
||||
NavigationStack { MessagesView() }
|
||||
.tabItem { Label(model.text("Wiadomości", "Messages"), systemImage: "envelope.fill") }
|
||||
.badge(model.messages.count)
|
||||
.tag(1)
|
||||
NavigationStack { ProfileView() }
|
||||
.tabItem { Label(model.text("Profil", "Profile"), systemImage: "person.crop.circle.fill") }
|
||||
.tag(2)
|
||||
ZStack {
|
||||
AmbientBackground()
|
||||
|
||||
TabView(selection: $model.selectedTab) {
|
||||
NavigationStack { WalletView() }
|
||||
.toolbarBackground(.hidden, for: .navigationBar)
|
||||
.tabItem { Label(model.text("Karta", "Card"), systemImage: "creditcard.fill") }
|
||||
.tag(0)
|
||||
NavigationStack { MessagesView() }
|
||||
.toolbarBackground(.hidden, for: .navigationBar)
|
||||
.tabItem { Label(model.text("Wiadomości", "Messages"), systemImage: "envelope.fill") }
|
||||
.badge(model.messages.count)
|
||||
.tag(1)
|
||||
NavigationStack { ProfileView() }
|
||||
.toolbarBackground(.hidden, for: .navigationBar)
|
||||
.tabItem { Label(model.text("Profil", "Profile"), systemImage: "person.crop.circle.fill") }
|
||||
.tag(2)
|
||||
}
|
||||
.background(.clear)
|
||||
}
|
||||
.tint(KTheme.orange)
|
||||
.toolbarBackground(.ultraThinMaterial, for: .tabBar)
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ struct MessagesView: View {
|
|||
}
|
||||
.background(AmbientBackground())
|
||||
.toolbar { AppToolbar() }
|
||||
.toolbarBackground(.hidden, for: .navigationBar)
|
||||
.refreshable { await model.refresh() }
|
||||
.task { await model.refresh() }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ struct ProfileView: View {
|
|||
}
|
||||
.background(AmbientBackground())
|
||||
.toolbar { AppToolbar() }
|
||||
.toolbarBackground(.hidden, for: .navigationBar)
|
||||
.fullScreenCover(isPresented: $editingProfile) { EditProfileView() }
|
||||
.sheet(isPresented: $changingPassword) { ChangePasswordView() }
|
||||
.sheet(isPresented: $deletingAccount) {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
func body(content: Content) -> some View {
|
||||
content
|
||||
|
|
|
|||
|
|
@ -15,8 +15,9 @@ struct WalletView: View {
|
|||
|
||||
var body: some View {
|
||||
walletCarousel
|
||||
.background(KTheme.background)
|
||||
.background(.clear)
|
||||
.toolbar { walletToolbar }
|
||||
.toolbarBackground(.hidden, for: .navigationBar)
|
||||
.onAppear { selectedPage = 0 }
|
||||
.task(id: model.user?.id) { await store.sync(using: model) }
|
||||
.fullScreenCover(isPresented: $scannerPresented) { scannerView }
|
||||
|
|
@ -166,7 +167,11 @@ struct WalletView: View {
|
|||
}
|
||||
.padding(.horizontal, 12)
|
||||
.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)
|
||||
.allowsHitTesting(false)
|
||||
}
|
||||
|
|
@ -285,42 +290,44 @@ private struct DiscountCardView: View {
|
|||
.accessibilityLabel(model.text("Usuń kartę", "Delete card"))
|
||||
}
|
||||
|
||||
VStack(spacing: 18) {
|
||||
StoredBarcodeView(value: card.payload, symbology: card.symbology)
|
||||
.frame(maxWidth: .infinity)
|
||||
.frame(height: card.isTwoDimensional ? 220 : 132)
|
||||
.padding(14)
|
||||
.background(.white)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 14, style: .continuous))
|
||||
Text(card.payload)
|
||||
.font(.system(.headline, design: .monospaced).weight(.bold))
|
||||
.multilineTextAlignment(.center)
|
||||
.textSelection(.enabled)
|
||||
.lineLimit(3)
|
||||
.minimumScaleFactor(0.65)
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(22)
|
||||
.background(
|
||||
ZStack {
|
||||
LinearGradient(
|
||||
colors: [KTheme.purple.opacity(0.92), KTheme.pink.opacity(0.88), KTheme.orange.opacity(0.86)],
|
||||
startPoint: .topLeading,
|
||||
endPoint: .bottomTrailing
|
||||
)
|
||||
Circle()
|
||||
.fill(.white.opacity(0.15))
|
||||
.frame(width: 170, height: 170)
|
||||
.blur(radius: 8)
|
||||
.offset(x: 145, y: -100)
|
||||
GlassDepthDeck {
|
||||
VStack(spacing: 18) {
|
||||
StoredBarcodeView(value: card.payload, symbology: card.symbology)
|
||||
.frame(maxWidth: .infinity)
|
||||
.frame(height: card.isTwoDimensional ? 220 : 132)
|
||||
.padding(14)
|
||||
.background(.white)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 14, style: .continuous))
|
||||
Text(card.payload)
|
||||
.font(.system(.headline, design: .monospaced).weight(.bold))
|
||||
.multilineTextAlignment(.center)
|
||||
.textSelection(.enabled)
|
||||
.lineLimit(3)
|
||||
.minimumScaleFactor(0.65)
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(22)
|
||||
.background(
|
||||
ZStack {
|
||||
LinearGradient(
|
||||
colors: [KTheme.purple.opacity(0.92), KTheme.pink.opacity(0.88), KTheme.orange.opacity(0.86)],
|
||||
startPoint: .topLeading,
|
||||
endPoint: .bottomTrailing
|
||||
)
|
||||
Circle()
|
||||
.fill(.white.opacity(0.15))
|
||||
.frame(width: 170, height: 170)
|
||||
.blur(radius: 8)
|
||||
.offset(x: 145, y: -100)
|
||||
}
|
||||
)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 26, style: .continuous))
|
||||
.overlay {
|
||||
RoundedRectangle(cornerRadius: 26, style: .continuous)
|
||||
.stroke(.white.opacity(0.28), lineWidth: 1)
|
||||
}
|
||||
)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 26, style: .continuous))
|
||||
.overlay {
|
||||
RoundedRectangle(cornerRadius: 26, style: .continuous)
|
||||
.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"))
|
||||
.font(.footnote)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user