| 1 | // app-offer.js: the web's "Join in the app" page (native.html, Waiting). |
| 2 | // |
| 3 | // Opens the Calls app once, with the offer in the link, and then asks |
| 4 | // the server every two seconds whether the app has taken it up. When it |
| 5 | // has, the answer names the confirmation page for the app's request and |
| 6 | // this tab goes there — this browser, where the person is signed in, so |
| 7 | // the confirmation needs no sign-in. An expired offer says so. With no |
| 8 | // script none of this runs: the button opens the app and the page |
| 9 | // refreshes itself (a <noscript> refresh), arriving at the same place. |
| 10 | (() => { |
| 11 | 'use strict'; |
| 12 | const box = document.getElementById('app-offer'); |
| 13 | if (!box) return; |
| 14 | const status = document.getElementById('app-offer-status'); |
| 15 | const app = box.dataset.app; |
| 16 | const poll = box.dataset.poll; |
| 17 | const key = 'calls.appOffer:' + poll; |
| 18 | let opened = false; |
| 19 | try { opened = sessionStorage.getItem(key) === '1'; } catch { /* private mode */ } |
| 20 | if (!opened && app) { |
| 21 | try { sessionStorage.setItem(key, '1'); } catch { /* this page only */ } |
| 22 | // A browser that wants a click first ignores this; the button is there. |
| 23 | location.href = app; |
| 24 | } |
| 25 | let stopped = false; |
| 26 | async function ask() { |
| 27 | if (stopped) return; |
| 28 | try { |
| 29 | const res = await fetch(poll, { headers: { Accept: 'application/json' }, credentials: 'same-origin', cache: 'no-store' }); |
| 30 | const body = await res.json().catch(() => ({})); |
| 31 | if (body.next) { |
| 32 | stopped = true; |
| 33 | location.href = body.next; |
| 34 | return; |
| 35 | } |
| 36 | if (res.status === 404 || body.expired) { |
| 37 | stopped = true; |
| 38 | if (status) status.textContent = 'This link to the app has expired. Go back to the meeting and choose Join in the app again.'; |
| 39 | return; |
| 40 | } |
| 41 | } catch { /* offline for a moment: ask again */ } |
| 42 | setTimeout(ask, 2000); |
| 43 | } |
| 44 | setTimeout(ask, 1500); |
| 45 | })(); |
| 46 | |