fix(access): reset router to home on re-lock so the reopened gate lands on idle

After a transaction with the gate enabled, the machine re-locks (cashOut/
cashIn → locked, not idle), so the view's isIdle watch never fires and the
router stays on /cash-out|/cash-in. When the next tap reopens the gate to
idle, the stale transaction view showed (e.g. a completed sell's collect
screen, stuck). Reset the route to / while locked (router-view hidden under
LockedView) so idle renders IdleView.
This commit is contained in:
Patrick Mulligan 2026-08-06 22:58:49 +02:00
commit 2c6c0f1a89

View file

@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, onUnmounted, ref, computed, watch } from 'vue' import { onMounted, onUnmounted, ref, computed, watch } from 'vue'
import { useRoute } from 'vue-router' import { useRoute, useRouter } from 'vue-router'
import { useAtmStore } from '@/stores/atm' import { useAtmStore } from '@/stores/atm'
import { useTheme } from '@/composables/useTheme' import { useTheme } from '@/composables/useTheme'
import { setBranding } from '@/composables/useBranding' import { setBranding } from '@/composables/useBranding'
@ -13,7 +13,21 @@ import ColorModeToggle from '@/components/ColorModeToggle.vue'
const atmStore = useAtmStore() const atmStore = useAtmStore()
const route = useRoute() const route = useRoute()
const router = useRouter()
const { current: currentTheme, themes, colorMode } = useTheme() const { current: currentTheme, themes, colorMode } = useTheme()
// When the machine re-locks after a transaction (access gate enabled), the
// router is still on /cash-in or /cash-out under the LockedView overlay. Reset
// it to home so that when the gate reopens to `idle`, IdleView shows — not the
// stale transaction view (e.g. a completed cash-out's collect screen). Runs
// while locked, so the router-view is hidden; no flicker. The disabled-gate path
// (never dwells in `locked`) still returns home via each view's isIdle watch.
watch(
() => atmStore.isLocked,
(locked) => {
if (locked && route.path !== '/') void router.push('/')
}
)
const debugExpanded = ref(false) const debugExpanded = ref(false)
const isSupport = computed(() => route.path === '/support') const isSupport = computed(() => route.path === '/support')
// Network detected dynamically from Lightning invoice prefix // Network detected dynamically from Lightning invoice prefix
@ -111,9 +125,7 @@ onMounted(async () => {
// Same env → pairing-seed precedence as lightning.ts: on a blank-.env // Same env → pairing-seed precedence as lightning.ts: on a blank-.env
// seed-driven machine the relay comes from the pairing transport, not env. // seed-driven machine the relay comes from the pairing transport, not env.
const relayUrl = const relayUrl =
config?.relayUrl || config?.relayUrl || import.meta.env.VITE_RELAY_URL || resolved?.transport?.relays?.[0]
import.meta.env.VITE_RELAY_URL ||
resolved?.transport?.relays?.[0]
if (signer && relayUrl) { if (signer && relayUrl) {
const client = new NostrClient({ relays: [{ url: relayUrl }], signer }) const client = new NostrClient({ relays: [{ url: relayUrl }], signer })
await client.connect() await client.connect()