diff --git a/Session/Onboarding/LoadAccountView.swift b/Session/Onboarding/LoadAccountView.swift
index fbf9bff22..51baa0919 100644
--- a/Session/Onboarding/LoadAccountView.swift
+++ b/Session/Onboarding/LoadAccountView.swift
@@ -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() {
diff --git a/SessionUIKit/Components/Toast.swift b/SessionUIKit/Components/Toast.swift
index f5b9cb433..b0ba526f2 100644
--- a/SessionUIKit/Components/Toast.swift
+++ b/SessionUIKit/Components/Toast.swift
@@ -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.")
     }
 }
diff --git a/SessionUIKit/Utilities/SwiftUI+Utilities.swift b/SessionUIKit/Utilities/SwiftUI+Utilities.swift
index 0e81f3807..550504629 100644
--- a/SessionUIKit/Utilities/SwiftUI+Utilities.swift
+++ b/SessionUIKit/Utilities/SwiftUI+Utilities.swift
@@ -84,6 +84,10 @@ extension View {
                 .foregroundColor(themeColor: color)
         )
     }
+    
+    public func toastView(message: Binding<String?>) -> some View {
+        self.modifier(ToastModifier(message: message))
+    }
 }
 
 extension Binding {