taler-ios

iOS apps for GNU Taler (wallet)
Log | Files | Refs | README | LICENSE

commit fdc73097f1a556c9d22d68ec85a23df3e69ad18f
parent d30fe6eae6bd19ffbe710c5f676fb76dcc1c71ff
Author: Marc Stibane <marc@taler.net>
Date:   Sat, 17 Jun 2023 19:21:45 +0200

Launch animation, SideBarView

Diffstat:
MTalerWallet.xcodeproj/project.pbxproj | 2+-
MTalerWallet1/Controllers/PublicConstants.swift | 3+++
MTalerWallet1/Views/Main/MainView.swift | 72++++++++++++++++++++++++++++++++++++++++--------------------------------
MTalerWallet1/Views/Main/SideBarView.swift | 28++++++++++++++++++++++++----
4 files changed, 68 insertions(+), 37 deletions(-)

diff --git a/TalerWallet.xcodeproj/project.pbxproj b/TalerWallet.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ diff --git a/TalerWallet1/Controllers/PublicConstants.swift b/TalerWallet1/Controllers/PublicConstants.swift @@ -4,6 +4,9 @@ */ import Foundation +public let LAUNCHDURATION: Double = 1.60 +public let SLIDEDURATION: Double = 0.45 + public let HTTPS = "https://" public let DEMOBANK = HTTPS + "bAnK.dEmO.tAlEr.nEt" // should be weird to read, but still work public let DEMOSHOP = HTTPS + "shop.demo.taler.net" diff --git a/TalerWallet1/Views/Main/MainView.swift b/TalerWallet1/Views/Main/MainView.swift @@ -28,33 +28,34 @@ struct MainView: View { let _ = Self._printChanges() let _ = symLog.vlog() // just to get the # to compare it with .onAppear & onDisappear #endif - NavigationView { // the one and only for all non-sheet views - if controller.backendState == .ready { - Content(symLog: symLog) - // any change to rootViewId triggers popToRootView behaviour - .id(viewState.rootViewId) - .onOpenURL { url in - symLog.log(".onOpenURL: \(url)") - // will be called on a taler:// scheme either - // by user tapping such link in a browser (bank website) - // or when launching the app from iOS Camera.app scanning a QR code - urlToOpen = url // raise sheet - } - } else if controller.backendState == .error { - ErrorView(errortext: nil) // TODO: show Error View - } else { - LaunchAnimationView() - } - }.navigationViewStyle(.stack) - .overlay(alignment: .top) { - // Show the viewID on top of the app's NavigationView - DebugViewV() - .id("ViewID") - } - .sheet(item: $urlToOpen, onDismiss: sheetDismissed) { url in - let sheet = AnyView(URLSheet(urlToOpen: url)) - Sheet(sheetView: sheet) + Group { + if controller.backendState == .ready { + Content(symLog: symLog) + // any change to rootViewId triggers popToRootView behaviour + .id(viewState.rootViewId) + } else if controller.backendState == .error { + ErrorView(errortext: nil) // TODO: show Error View + } else { + LaunchAnimationView() } + } + .animation(.easeOut(duration: LAUNCHDURATION), value: controller.backendState) + .overlay(alignment: .top) { + // Show the viewID on top of the app's NavigationView + DebugViewV() + .id("ViewID") + } + .onOpenURL { url in + symLog.log(".onOpenURL: \(url)") + // will be called on a taler:// scheme either + // by user tapping such link in a browser (bank website) + // or when launching the app from iOS Camera.app scanning a QR code + urlToOpen = url // raise sheet + } + .sheet(item: $urlToOpen, onDismiss: sheetDismissed) { url in + let sheet = AnyView(URLSheet(urlToOpen: url)) + Sheet(sheetView: sheet) + } } // body } // MARK: - Content @@ -97,12 +98,19 @@ extension MainView { let _ = symLog?.vlog() // just to get the # to compare it with .onAppear & onDisappear #endif ZStack(alignment: .leading) { - views[currentView].view - .id(views[currentView].name) - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) - .transition(.backslide) - SideBarView(views: views, currentView: $currentView, sidebarVisible: $sidebarVisible) + NavigationView { // the one and only for all non-sheet views + VStack(alignment: .leading) { // only needed for backslide transition + views[currentView].view + .id(views[currentView].name) + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) + .transition(.backslide) + } + }.navigationViewStyle(.stack) + // The side view is on top of the current view + SideBarView(views: views, + currentView: $currentView, + sidebarVisible: $sidebarVisible) } } - } + } // Content } diff --git a/TalerWallet1/Views/Main/SideBarView.swift b/TalerWallet1/Views/Main/SideBarView.swift @@ -15,21 +15,39 @@ struct SidebarItem { struct SideBarView: View { private let symLog = SymLogV(0) - var views: [SidebarItem] + let views: [SidebarItem] @Binding var currentView: Int @Binding var sidebarVisible: Bool + @State private var rotationEnabled = false + @State private var rotationDirection = false + + private let animationTimer = Timer + .publish(every: 1.6, on: .current, in: .common) + .autoconnect() var body: some View { HStack { // sideView left, clear dismiss target right EqualIconWidthDomain { VStack(spacing: 10) { - Text("GNU Taler") - .font(.largeTitle).bold() + Link("GNU Taler", destination: URL(string:"https://taler.net")!) + .font(.largeTitle) //.bold() iOS 16 + .padding(.top, 30) Image("taler-logo-2023-red") .resizable() .scaledToFit() .frame(width: 100, height: 100) + .rotationEffect(rotationDirection ? Angle(degrees: 0) : Angle(degrees: 900)) .accessibilityHidden(true) // decorative logo + .onTapGesture { + rotationEnabled.toggle() + } + .onReceive(animationTimer) { timerValue in + if rotationEnabled { + withAnimation(.easeInOut(duration: 1.9)) { + rotationDirection.toggle() + } + } + } ForEach(0..<views.count, id: \.self) { i in Button { symLog.log("sidebar item \"\(views[i].name)\" selected") @@ -68,7 +86,8 @@ struct SideBarView: View { sidebarVisible = false } } - .animation(sidebarVisible ? .easeOut : .easeIn, value: sidebarVisible) + .animation(.linear //(duration: SLIDEDURATION) + , value: sidebarVisible) } } // MARK: - @@ -81,6 +100,7 @@ fileprivate struct BindingViewContainer : View { var body: some View { ZStack(alignment: .leading) { views[currentView].view + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) SideBarView(views: views, currentView: $currentView, sidebarVisible: $sidebarVisible) } }