WIP: toast

pull/891/head
Ryan Zhao 2 years ago
parent 012b3df646
commit 23f67763f4

@ -48,7 +48,9 @@ struct LoadAccountView: View {
private func continueWithSeed(seed: Data, onError: (() -> ())?) { private func continueWithSeed(seed: Data, onError: (() -> ())?) {
if (seed.count != 16) { if (seed.count != 16) {
errorString = "recovery_password_error_generic".localized() errorString = "recovery_password_error_generic".localized()
onError?() DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
onError?()
}
return return
} }
let (ed25519KeyPair, x25519KeyPair) = try! Identity.generate(from: seed) let (ed25519KeyPair, x25519KeyPair) = try! Identity.generate(from: seed)
@ -272,12 +274,6 @@ struct ScanQRCodeView: View {
maxWidth: .infinity, maxWidth: .infinity,
maxHeight: .infinity maxHeight: .infinity
) )
if let error: String = error, !error.isEmpty {
withAnimation(.easeIn(duration: 0.5)) {
Toast(error)
}
}
} else { } else {
VStack( VStack(
alignment: .center, alignment: .center,
@ -305,6 +301,7 @@ struct ScanQRCodeView: View {
.padding(.bottom, Values.massiveSpacing) .padding(.bottom, Values.massiveSpacing)
} }
} }
.toastView(message: $error)
} }
private func requestCameraAccess() { private func requestCameraAccess() {

@ -1,11 +1,54 @@
// Copyright © 2023 Rangeproof Pty Ltd. All rights reserved. // Copyright © 2023 Rangeproof Pty Ltd. All rights reserved.
import SwiftUI import SwiftUI
import Combine
public struct Toast: View { public struct ToastModifier: ViewModifier {
@State var dismiss: Bool = false @Binding var message: String?
@State private var workItem: DispatchWorkItem?
let message: String public func body(content: Content) -> some View {
content
.frame(maxWidth: .infinity, maxHeight: .infinity)
.overlay(
ZStack {
mainToastView()
}.animation(.spring(), value: message)
)
.onReceive(Just(message)) { value in
showToast()
}
}
@ViewBuilder func mainToastView() -> some View {
if let message: String = message {
ToastView(message)
}
}
private func showToast() {
workItem?.cancel()
let task = DispatchWorkItem {
dismissToast()
}
workItem = task
DispatchQueue.main.asyncAfter(deadline: .now() + 5, execute: task)
}
private func dismissToast() {
withAnimation {
message = nil
}
workItem?.cancel()
workItem = nil
}
}
public struct ToastView: View {
var message: String
static let width: CGFloat = 320 static let width: CGFloat = 320
static let height: CGFloat = 44 static let height: CGFloat = 44
@ -15,40 +58,36 @@ public struct Toast: View {
} }
public var body: some View { public var body: some View {
VStack { VStack(
Spacer() spacing: 0
) {
ZStack {
Capsule()
.foregroundColor(themeColor: .toast_background)
if !dismiss { Text(message)
ZStack { .font(.system(size: Values.verySmallFontSize))
Capsule() .foregroundColor(themeColor: .textPrimary)
.foregroundColor(themeColor: .toast_background) .multilineTextAlignment(.center)
.frame(maxWidth: .infinity)
Text(message) .padding(.horizontal, Values.mediumSpacing)
.font(.system(size: Values.verySmallFontSize))
.foregroundColor(themeColor: .textPrimary)
.multilineTextAlignment(.center)
.frame(maxWidth: .infinity)
.padding(.horizontal, Values.mediumSpacing)
}
.frame(
width: Self.width,
height: Self.height
)
.padding(.bottom, Values.smallSpacing)
}
}
.onAppear {
Timer.scheduledTimerOnMainThread(withTimeInterval: 5) { _ in
withAnimation(.easeOut(duration: 0.5)) {
dismiss.toggle()
}
} }
.frame(
width: Self.width,
height: Self.height
)
} }
.frame(
maxWidth: .infinity,
maxHeight: .infinity,
alignment: .bottom
)
.padding(.bottom, Values.smallSpacing)
} }
} }
struct Toast_Previews: PreviewProvider { struct Toast_Previews: PreviewProvider {
static var previews: some View { static var previews: some View {
Toast("This QR code does not contain a Recovery Password.") ToastView("Test message.")
} }
} }

@ -84,6 +84,10 @@ extension View {
.foregroundColor(themeColor: color) .foregroundColor(themeColor: color)
) )
} }
public func toastView(message: Binding<String?>) -> some View {
self.modifier(ToastModifier(message: message))
}
} }
extension Binding { extension Binding {

Loading…
Cancel
Save