fix(startup): Firefox no longer hangs on "Heating up" after login (#303)
CI / Build & Quality Checks (pull_request) Successful in 1m50s
CI / Trigger Desktop Build (pull_request) Skipped
CI / Docker image build & smoke test (pull_request) Skipped
CI / Secret scan (gitleaks) (pull_request) Successful in 14s
CI / Playwright smoke (e2e) (pull_request) Successful in 12m48s
CI / Build & Quality Checks (pull_request) Successful in 1m50s
CI / Trigger Desktop Build (pull_request) Skipped
CI / Docker image build & smoke test (pull_request) Skipped
CI / Secret scan (gitleaks) (pull_request) Successful in 14s
CI / Playwright smoke (e2e) (pull_request) Successful in 12m48s
initClient awaited navigator.storage.persist() before creating the client. Chromium and WebKit answer at once, but Firefox shows a permission prompt and leaves the promise pending until it's answered, so the app sat on "Heating up" (no sync, no crypto, no IndexedDB) for every Firefox user who didn't notice the prompt. The request is still made (KE-1 only needs that), but startup waits at most 1.5 s for the answer. The comment claiming persist() never prompts is corrected. Verified in Playwright Firefox with the prompt left unanswered (persist() still pending): before, still "Heating up" after 20 s; now the room list after 12 s. Fixes #303 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
400ee76b63
commit
02950499ea
@@ -20,9 +20,12 @@ export const IDB_VERSION_CONFLICT = 'IDB_VERSION_CONFLICT';
|
||||
* session. When that happens the device "resurrects" with a blank key store and the
|
||||
* client re-uploads a one-time key at an id Synapse already holds → a permanent
|
||||
* `400 M_UNKNOWN: … already exists` upload-conflict storm (and, downstream,
|
||||
* undecryptable to-device/media keys). `persist()` grants based on engagement / PWA
|
||||
* install and shows no prompt; denial/absence is non-fatal.
|
||||
* undecryptable to-device/media keys). Chromium/WebKit answer `persist()` at once
|
||||
* (engagement / PWA install); Firefox shows a permission prompt and the promise
|
||||
* stays pending until it's answered. Denial/absence is non-fatal.
|
||||
*/
|
||||
const PERSIST_WAIT_MS = 1500;
|
||||
|
||||
export const requestPersistentStorage = async (): Promise<boolean> => {
|
||||
try {
|
||||
if (!navigator.storage?.persist) return false;
|
||||
@@ -39,7 +42,15 @@ export const requestPersistentStorage = async (): Promise<boolean> => {
|
||||
|
||||
export const initClient = async (session: Session): Promise<MatrixClient> => {
|
||||
// Protect the crypto store from eviction before we create and write to it.
|
||||
await requestPersistentStorage();
|
||||
// [Gitea #303] Never block startup on the answer: Firefox prompts and leaves
|
||||
// the promise pending until the user responds, which froze the app on
|
||||
// "Heating up". KE-1 only needs the request made; give it 1.5 s at most.
|
||||
await Promise.race([
|
||||
requestPersistentStorage(),
|
||||
new Promise<boolean>((resolve) => {
|
||||
setTimeout(() => resolve(false), PERSIST_WAIT_MS);
|
||||
}),
|
||||
]);
|
||||
|
||||
const indexedDBStore = new IndexedDBStore({
|
||||
indexedDB: globalThis.indexedDB,
|
||||
|
||||
Reference in New Issue
Block a user