WIP: toast

This commit is contained in:
Ryan Zhao 2023-08-28 17:09:41 +10:00
parent 012b3df646
commit 23f67763f4
3 changed files with 78 additions and 38 deletions

View File

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

View File

@ -1,11 +1,54 @@
// Copyright © 2023 Rangeproof Pty Ltd. All rights reserved.
import SwiftUI
import Combine
public struct Toast: View {
@State var dismiss: Bool = false
public struct ToastModifier: ViewModifier {
@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 height: CGFloat = 44
@ -15,40 +58,36 @@ public struct Toast: View {
}
public var body: some View {
VStack {
Spacer()
if !dismiss {
ZStack {
Capsule()
.foregroundColor(themeColor: .toast_background)
Text(message)
.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()
}
VStack(
spacing: 0
) {
ZStack {
Capsule()
.foregroundColor(themeColor: .toast_background)
Text(message)
.font(.system(size: Values.verySmallFontSize))
.foregroundColor(themeColor: .textPrimary)
.multilineTextAlignment(.center)
.frame(maxWidth: .infinity)
.padding(.horizontal, Values.mediumSpacing)
}
.frame(
width: Self.width,
height: Self.height
)
}
.frame(
maxWidth: .infinity,
maxHeight: .infinity,
alignment: .bottom
)
.padding(.bottom, Values.smallSpacing)
}
}
struct Toast_Previews: PreviewProvider {
static var previews: some View {
Toast("This QR code does not contain a Recovery Password.")
ToastView("Test message.")
}
}

View File

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