From f65fb5890c06fefd7d72780595fca1003f16be66 Mon Sep 17 00:00:00 2001 From: Benjamin Faershtein <119711889+RCGV1@users.noreply.github.com> Date: Tue, 1 Apr 2025 22:36:37 -0700 Subject: [PATCH] Add animation to demo disconnect --- Meshtastic/Views/Bluetooth/Connect.swift | 43 ++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/Meshtastic/Views/Bluetooth/Connect.swift b/Meshtastic/Views/Bluetooth/Connect.swift index 880faf8d..ce12f5d6 100644 --- a/Meshtastic/Views/Bluetooth/Connect.swift +++ b/Meshtastic/Views/Bluetooth/Connect.swift @@ -26,6 +26,10 @@ struct Connect: View { @State var liveActivityStarted = false @State var presentingSwitchPreferredPeripheral = false @State var selectedPeripherialId = "" + @State private var showSwipeDemo = false + @State private var swipeDemoOffset: CGFloat = 0 + @State private var showDeleteButton: Bool = false + @AppStorage("hasSeenSwipeDemo") private var hasSeenSwipeDemo = false init () { let notificationCenter = UNUserNotificationCenter.current() @@ -89,6 +93,28 @@ struct Connect: View { .font(.caption) .foregroundColor(Color.gray) .padding([.top]) + .offset(x: swipeDemoOffset) + .overlay( + GeometryReader { geometry in + ZStack { + Rectangle() + .foregroundColor(.red) + .frame(width: 80) + .offset(x: geometry.size.width - 80) + VStack { + Image(systemName: "antenna.radiowaves.left.and.right.slash") + .foregroundColor(.white) + .font(.title3) + Text("Disconnect") + .foregroundColor(.white) + .font(.caption) + } + } + .offset(x: geometry.size.width - 50) + + .opacity(showDeleteButton ? 1 : 0) + } + ) .swipeActions { Button(role: .destructive) { if let connectedPeripheral = bleManager.connectedPeripheral, @@ -323,6 +349,23 @@ struct Connect: View { } else { isUnsetRegion = false } + // Show swipe demo if user hasn't seen it before and we're connected + if !hasSeenSwipeDemo && bleManager.isSubscribed && node != nil { + DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { + withAnimation(.easeInOut(duration: 0.6)) { + swipeDemoOffset = -80 + showDeleteButton = true + } + DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { + withAnimation(.easeInOut(duration: 0.6)) { + swipeDemoOffset = 0 + showDeleteButton = false + } + // Mark as seen so it doesn't appear again + hasSeenSwipeDemo = true + } + } + } } catch { Logger.data.error("💥 Error fetching node info: \(error.localizedDescription, privacy: .public)") }