Keep slow app sessions alive and defer automatic companion prompts
This commit is contained in:
@@ -61,6 +61,15 @@
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-if="slowLoad && !iframeBlocked && !uiReadyBlocked" role="status"
|
||||
class="absolute top-3 left-3 right-3 z-10 flex items-center gap-2 rounded-lg border border-white/10 bg-black/80 px-3 py-2 text-xs text-white/75 backdrop-blur-md">
|
||||
<span class="min-w-0 flex-1">{{ appTitle }} is taking longer to load. You can keep waiting.</span>
|
||||
<button type="button" class="shrink-0 rounded px-2 py-1 text-white hover:bg-white/10" @click="$emit('refresh')">Retry</button>
|
||||
<button type="button" class="shrink-0 rounded p-1 text-white/60 hover:bg-white/10" aria-label="Dismiss loading notice" @click="$emit('dismissSlowLoad')">
|
||||
<svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-width="2" d="m6 6 12 12M18 6 6 18" /></svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Iframe blocked fallback. Suppressed while the ElectrumX sync screen
|
||||
(the "pre UI") is showing: a still-syncing Electrum server isn't
|
||||
reachable yet, so the "App not reachable / retry" overlay would just
|
||||
@@ -136,6 +145,7 @@ const props = defineProps<{
|
||||
autoRetryCount: number
|
||||
refreshKey: number
|
||||
uiReadyBlocked?: boolean
|
||||
slowLoad?: boolean
|
||||
blockedReason?: string
|
||||
blockedTitle?: string
|
||||
// True while the container is up but its probe hasn't answered yet and the
|
||||
@@ -151,6 +161,7 @@ const emit = defineEmits<{
|
||||
iframeError: []
|
||||
refresh: []
|
||||
openNewTabAndBack: []
|
||||
dismissSlowLoad: []
|
||||
}>()
|
||||
|
||||
const iframeRef = ref<HTMLIFrameElement | null>(null)
|
||||
|
||||
@@ -68,6 +68,19 @@ describe('AppSessionFrame warm-up state', () => {
|
||||
})
|
||||
|
||||
describe('HTTP readiness gate', () => {
|
||||
it('keeps the same iframe while reporting a slow load and lets the user dismiss the notice', async () => {
|
||||
const frame = mountFrame({ iframeBlocked: false, slowLoad: false });
|
||||
const original = frame.get('iframe').element;
|
||||
await frame.setProps({ slowLoad: true });
|
||||
expect(frame.get('iframe').element).toBe(original);
|
||||
expect(frame.get('[role="status"]').text()).toContain('Bitcoin is taking longer to load');
|
||||
await frame.get('[aria-label="Dismiss loading notice"]').trigger('click');
|
||||
expect(frame.emitted('dismissSlowLoad')).toHaveLength(1);
|
||||
await frame.setProps({ slowLoad: false });
|
||||
expect(frame.get('iframe').element).toBe(original);
|
||||
expect(frame.find('[role="status"]').exists()).toBe(false);
|
||||
frame.unmount();
|
||||
})
|
||||
it('does not show a missing-configuration error during initial installation', () => {
|
||||
const frame = mountFrame({ appUrl: '', uiReadyBlocked: true, blockedReason: 'Waiting for the app to be ready…' })
|
||||
expect(frame.text()).not.toContain('App not configured')
|
||||
|
||||
Reference in New Issue
Block a user