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,14 +7,18 @@ struct SendScreen: View {
|
||||
@ObservedObject var model: SendModel
|
||||
let windowClass: WindowClass
|
||||
|
||||
/// Transfer whose share panel is presented inline from the list context menu.
|
||||
@State private var shareTarget: Transfer?
|
||||
/// Transfer pending an inline (list-level) delete confirmation.
|
||||
@State private var deleteTarget: Transfer?
|
||||
|
||||
private var outgoing: [Transfer] {
|
||||
model.coreState.transfers.filter { $0.direction == .send }
|
||||
}
|
||||
/// The transfer whose list-level share sheet is open, resolved from the model's
|
||||
/// `shareTargetId` (kept in the model so the approval flow can dismiss it).
|
||||
private var shareTarget: Transfer? {
|
||||
guard let id = model.state.shareTargetId else { return nil }
|
||||
return outgoing.first { $0.transferId == id }
|
||||
}
|
||||
private var selectedTransfer: Transfer? {
|
||||
guard let id = model.state.selectedTransferId else { return nil }
|
||||
return outgoing.first { $0.transferId == id }
|
||||
@@ -50,9 +54,10 @@ struct SendScreen: View {
|
||||
// composer drawer on the outer body, so the two don't clash). Opens the
|
||||
// share panel over the list without navigating into the transfer detail.
|
||||
.adaptiveDrawer(
|
||||
isPresented: Binding(get: { shareTarget != nil }, set: { if !$0 { shareTarget = nil } }),
|
||||
isPresented: Binding(get: { shareTarget != nil }, set: { if !$0 { model.closeShareTarget() } }),
|
||||
windowClass: windowClass,
|
||||
onDismiss: { shareTarget = nil }
|
||||
onDismiss: model.closeShareTarget,
|
||||
onDismissed: model.shareSheetDidDismiss
|
||||
) {
|
||||
if let shareTarget {
|
||||
TransferSharePanel(model: model, transfer: shareTarget)
|
||||
@@ -92,7 +97,8 @@ struct SendScreen: View {
|
||||
.adaptiveDrawer(
|
||||
isPresented: Binding(get: { model.state.detailPanel != nil }, set: { _ in }),
|
||||
windowClass: windowClass,
|
||||
onDismiss: model.closeDetailPanel
|
||||
onDismiss: model.closeDetailPanel,
|
||||
onDismissed: model.shareSheetDidDismiss
|
||||
) {
|
||||
if let panel = model.state.detailPanel {
|
||||
DetailPanelContent(model: model, transfer: transfer, panel: panel)
|
||||
@@ -127,7 +133,7 @@ struct SendScreen: View {
|
||||
.contextMenu {
|
||||
if transfer.ticket != nil {
|
||||
Button {
|
||||
shareTarget = transfer
|
||||
model.openShareTarget(transfer.transferId)
|
||||
} label: {
|
||||
Label(String(localized: L10n.Transfer.shareTitle), systemSymbol: .squareAndArrowUp)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user