diff --git a/scripts/copy-res.js b/scripts/copy-res.js index dc55cb1a..ff8ee458 100755 --- a/scripts/copy-res.js +++ b/scripts/copy-res.js @@ -61,6 +61,7 @@ const COPY_LIST = [ // in the bundle dir with the js to avoid caching issues giving us wasm that // doesn't match our js, but I cannot find any way to get webpack to do this. ["node_modules/olm/olm.wasm", "webapp", { directwatch: 1 }], + ["node_modules/olm/olm_legacy.js", "webapp", { directwatch: 1 }], ["./config.json", "webapp", { directwatch: 1 }], ]; diff --git a/src/vector/index.js b/src/vector/index.js index 8fde38f5..57d1f87a 100644 --- a/src/vector/index.js +++ b/src/vector/index.js @@ -229,19 +229,7 @@ async function loadApp() { window.addEventListener('hashchange', onHashChange); - /* Start loading Olm. Note that we *don't* wait for this to load: the - * js-sdk will also call this and actually wait on the promise before it - * tries to use the library. It can be loading its wasm while the rest of - * the app loads though. - * - * We also need to tell the Olm js to look for its wasm file at the same - * level as index.html. It really should be in the same place as the js, - * ie. in the bundle directory, to avoid caching issues, but as far as I - * can tell this is completely impossible with webpack. - */ - Olm.init({ - locateFile: () => 'olm.wasm', - }); + await loadOlm(); await loadLanguage(); @@ -365,6 +353,42 @@ async function loadApp() { } } +function loadOlm() { + /* Load Olm. We try the WebAssembly version first, and then the legacy, + * asm.js version if that fails. For this reason we need to wait for this + * to finish before continuing to load the rest of the app. In future + * we could somehow pass a promise down to react-sdk and have it wait on + * that so olm can be loading in parallel with the rest of the app. + * + * We also need to tell the Olm js to look for its wasm file at the same + * level as index.html. It really should be in the same place as the js, + * ie. in the bundle directory, to avoid caching issues, but as far as I + * can tell this is completely impossible with webpack. + */ + return Olm.init({ + locateFile: () => 'olm.wasm', + }).then(() => { + console.log("Using WebAssembly Olm"); + }).catch((e) => { + console.log("Failed to load Olm: trying legacy version"); + return new Promise((resolve, reject) => { + const s = document.createElement('script'); + s.src = 'olm_legacy.js'; + s.onload = resolve; + s.onerror = reject; + document.body.appendChild(s); + }).then(() => { + // Init window.Olm, ie. the one just loaded by the script tag, + // not 'Olm' which is still the failed wasm version. + return window.Olm.init(); + }).then(() => { + console.log("Using legacy Olm"); + }).catch((e) => { + console.log("Both WebAssembly and asm.js Olm failed!", e); + }); + }); +} + async function loadLanguage() { const prefLang = SettingsStore.getValue("language", null, /*excludeDefault=*/true); let langs = [];