fix: recover mobile workspace loading in place (Closes #1124)
This commit is contained in:
1 parent
db85bfa5f9
commit
9252807364
4 files changed
+187
-75
No files matched your search
@@ -314,6 +314,7 @@
|
||||
<div class="small" id="notification-page-status" aria-live="polite"></div>
|
||||
<button class="load-more-notifications" id="load-more-notifications" type="button" hidden>Load older updates</button>
|
||||
<div class="small" id="my-work-action-status" aria-live="assertive"></div>
|
||||
<button class="retry-work-route" id="retry-workspace" type="button" hidden>Retry workspace</button>
|
||||
<button class="release-receipt-launcher" id="release-receipt-launcher" type="button" hidden>Merged · tracking release</button>
|
||||
<button class="retry-work-route" id="retry-unfiled-draft-sync" type="button" hidden>Retry Draft sync</button>
|
||||
<div class="small" id="today-sync-status" aria-live="polite">Today is saved on this device.</div>
|
||||
|
||||
@@ -1,41 +1,75 @@
|
||||
async function loadWorkspace({ document, window = null, createLoader = createFeatureLoader }) {
|
||||
async function loadWorkspace({
|
||||
document,
|
||||
window = null,
|
||||
createLoader = createFeatureLoader,
|
||||
schedule = callback => setTimeout(callback,750),
|
||||
}) {
|
||||
let cameOnline = false;
|
||||
let replayed = false;
|
||||
let retryInFlight = null;
|
||||
const captureOnline = () => { cameOnline = true; };
|
||||
window?.addEventListener('online', captureOnline);
|
||||
const status = document.querySelector('#my-work-action-status');
|
||||
const retryButton = document.querySelector('#retry-workspace');
|
||||
const url = document.querySelector(
|
||||
'meta[name="stackchain-feature-today-timer"]'
|
||||
)?.content || '';
|
||||
const loader = createLoader({
|
||||
document,
|
||||
urls: { 'today-timer': url },
|
||||
});
|
||||
if (status) status.textContent = 'Starting workspace…';
|
||||
try {
|
||||
await loader.load('today-timer');
|
||||
if (status) status.textContent = '';
|
||||
return {
|
||||
replayOnline(callback) {
|
||||
if (replayed) return;
|
||||
replayed = true;
|
||||
window?.removeEventListener('online', captureOnline);
|
||||
if (cameOnline) callback();
|
||||
},
|
||||
const urls = {'today-timer':url};
|
||||
const loader = createLoader({document, urls});
|
||||
|
||||
let attempts = 0;
|
||||
const load = () => {
|
||||
if (attempts++) urls['today-timer'] = url + '?retry=' + attempts;
|
||||
return loader.load('today-timer');
|
||||
};
|
||||
const waitForRecovery = () => new Promise(resolve => {
|
||||
if (status) status.textContent = 'Workspace unavailable. Reconnect or retry.';
|
||||
if (retryButton) {
|
||||
retryButton.hidden = retryButton.disabled = false;
|
||||
}
|
||||
|
||||
const recover = () => {
|
||||
if (retryInFlight) return retryInFlight;
|
||||
if (retryButton) retryButton.disabled = true;
|
||||
retryInFlight = load().then(() => {
|
||||
window?.removeEventListener('online', recover);
|
||||
resolve();
|
||||
}).catch(() => {
|
||||
if (status) status.textContent = 'Workspace unavailable. Reconnect or retry.';
|
||||
if (retryButton) retryButton.disabled = false;
|
||||
}).finally(() => {
|
||||
retryInFlight = null;
|
||||
});
|
||||
return retryInFlight;
|
||||
};
|
||||
} catch (error) {
|
||||
|
||||
window?.removeEventListener('online', captureOnline);
|
||||
if (window?.location?.reload) {
|
||||
if (cameOnline) window.location.reload();
|
||||
else window.addEventListener('online', () => window.location.reload(), { once: true });
|
||||
window?.addEventListener('online', recover);
|
||||
retryButton?.addEventListener('click', recover);
|
||||
});
|
||||
|
||||
try {
|
||||
await load();
|
||||
} catch {
|
||||
await new Promise(resolve => schedule(resolve));
|
||||
try {
|
||||
await load();
|
||||
} catch {
|
||||
await waitForRecovery();
|
||||
}
|
||||
if (status) {
|
||||
status.textContent = window
|
||||
? 'Workspace could not load. Reconnect to retry automatically, or reload now.'
|
||||
: 'Workspace could not load. Check your connection, then reload to retry.';
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
|
||||
window?.removeEventListener('online', captureOnline);
|
||||
if (retryButton) retryButton.hidden = true;
|
||||
if (status) status.textContent = '';
|
||||
return {
|
||||
replayOnline(callback) {
|
||||
if (replayed) return;
|
||||
replayed = true;
|
||||
window?.removeEventListener('online', captureOnline);
|
||||
if (cameOnline) callback();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof module !== 'undefined' && module.exports) module.exports = loadWorkspace;
|
||||
if (typeof module !== 'undefined' && module.exports) module.exports = loadWorkspace;
|
||||
Reference in new issue
Block a user