mirror of
https://github.com/sudosylabs/vnidrop.git
synced 2026-08-05 10:29:58 +02:00
fix(apple): show receiver-approval modal on macOS release builds
The approval modal never appeared for a macOS sender: the receiver request reached the core and even fired its notification, but the modal stayed hidden. Root cause was observation, not presentation. `RootView` derived `approvals` and `messages` as `@ObservedObject` in `init` from a freshly built `AppGraph`. `init` runs on every view re-creation and each run makes a throwaway graph, so those observed objects were repointed to a dead `ApprovalCoordinator` that never receives core events — while the persisted `@StateObject graph` (and the models wired to it) kept the live one. Debug happened not to re-init the view, so it stayed on the live instance; release re-inits it, exposing the bug. Move the snackbar + approval modal into an `OverlayLayer` child view that takes the coordinator/messages as `@ObservedObject` and is constructed in `body` from the persisted `graph`, so the subscription is always against the live instances. While here: - Present the approval only after any open share/QR sheet has actually finished dismissing (macOS can't stack sheets), driven off the sheet's real `onDismiss` completion via a new `AdaptiveDrawer.onDismissed` hook and `SendModel.shareSheetsDismissed` — no wall-clock delay. - Move the list-level share-sheet state (`shareTargetId`) into `SendModel` so the approval flow can dismiss every share surface centrally. - Add a fallback: pending receiver rows in the Receivers panel now offer an Approve action (`SendModel.acceptReceiver`) alongside Refuse, for the case the modal didn't surface.
This commit is contained in:
@@ -7,11 +7,16 @@ struct AdaptiveDrawer<DrawerContent: View>: ViewModifier {
|
||||
@Binding var isPresented: Bool
|
||||
let windowClass: WindowClass
|
||||
let onDismiss: () -> Void
|
||||
/// Fired after the sheet's dismissal animation completes (as opposed to
|
||||
/// `onDismiss`, which requests the close). Lets callers serialize a follow-up
|
||||
/// sheet against this one's actual teardown instead of guessing a delay.
|
||||
let onDismissed: (() -> Void)?
|
||||
@ViewBuilder let drawerContent: () -> DrawerContent
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
content.sheet(
|
||||
isPresented: Binding(get: { isPresented }, set: { if !$0 { onDismiss() } })
|
||||
isPresented: Binding(get: { isPresented }, set: { if !$0 { onDismiss() } }),
|
||||
onDismiss: onDismissed
|
||||
) {
|
||||
SheetChrome(onClose: onDismiss) { drawerContent() }
|
||||
.modifier(PhoneDetents(enabled: windowClass == .phone))
|
||||
@@ -56,11 +61,12 @@ extension View {
|
||||
isPresented: Binding<Bool>,
|
||||
windowClass: WindowClass,
|
||||
onDismiss: @escaping () -> Void,
|
||||
onDismissed: (() -> Void)? = nil,
|
||||
@ViewBuilder content: @escaping () -> DrawerContent
|
||||
) -> some View {
|
||||
modifier(AdaptiveDrawer(
|
||||
isPresented: isPresented, windowClass: windowClass,
|
||||
onDismiss: onDismiss, drawerContent: content
|
||||
onDismiss: onDismiss, onDismissed: onDismissed, drawerContent: content
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user