app.tsx (3275B)
1 import { lazy, useEffect, Suspense, useState } from 'react'; 2 import { Home } from './pages/Home'; 3 import { Client } from './context'; 4 import { Header } from './components/header'; 5 import { MatrixClient } from './matrix/client'; 6 7 // eslint-disable-next-line @typescript-eslint/ban-ts-comment 8 // @ts-ignore 9 import olmWasmPath from "@matrix-org/olm/olm.wasm?url"; 10 import OlmLegacy from '@matrix-org/olm/olm_legacy.js?url'; 11 import Olm from '@matrix-org/olm'; 12 import { Route, Routes } from 'react-router-dom'; 13 import { useTranslation } from 'react-i18next'; 14 15 const Join = lazy(() => import("./pages/Join")); 16 const Post = lazy(() => import("./pages/Post")); 17 const Profile = lazy(() => import("./pages/Profile")); 18 19 20 const loadOlm = (): Promise<void> => { 21 /* Load Olm. We try the WebAssembly version first, and then the legacy */ 22 return Olm.init({ 23 locateFile: () => olmWasmPath, 24 }).then(() => { 25 console.log("Using WebAssembly Olm"); 26 }).catch((error) => { 27 console.log("Failed to load Olm: trying legacy version", error); 28 return new Promise((resolve, reject) => { 29 const s = document.createElement('script'); 30 s.src = OlmLegacy; // XXX: This should be cache-busted too 31 s.addEventListener('load', resolve); 32 s.addEventListener('error', reject); 33 document.body.append(s); 34 }).then(() => { 35 // Init window.Olm, ie. the one just loaded by the script tag, 36 // not 'Olm' which is still the failed wasm version. 37 return window.Olm.init(); 38 }).then(() => { 39 console.log("Using legacy Olm"); 40 }).catch((error) => { 41 console.log("Both WebAssembly and asm.js Olm failed!", error); 42 }); 43 }); 44 }; 45 46 47 export function App() { 48 // eslint-disable-next-line unicorn/no-useless-undefined 49 const [client, setClient] = useState<MatrixClient | undefined>(undefined); 50 51 const loadMatrixClient = async () => { 52 const client = await MatrixClient.new(); 53 setClient(client); 54 console.log("Client loaded"); 55 await client?.start(); 56 console.log("Client started"); 57 } 58 59 useEffect(() => { 60 async function loadMatrix() { 61 try { 62 await loadOlm(); 63 console.log("Olm loaded"); 64 } catch { 65 console.log("Olm not loaded"); 66 } 67 await loadMatrixClient(); 68 } 69 70 if (client == undefined) { 71 loadMatrix(); 72 } 73 }, []); 74 75 return ( 76 <Client.Provider value={ 77 client 78 }> 79 <Routes> 80 <Route path="/" element={<Home />} /> 81 <Route path="join" element={ 82 <Suspense fallback={<LoadingPage />}> 83 <Join /> 84 </Suspense> 85 } /> 86 <Route path="/post/:postId" element={ 87 <Suspense fallback={<LoadingPage />}> 88 <Post /> 89 </Suspense> 90 } /> 91 <Route path="/profile/:userId" element={ 92 <Suspense fallback={<LoadingPage />}> 93 <Profile /> 94 </Suspense> 95 } /> 96 </Routes> 97 </Client.Provider > 98 ); 99 } 100 101 function LoadingPage() { 102 const { t } = useTranslation(); 103 104 return ( 105 <div className="flex flex-col"> 106 <header> 107 <Header /> 108 </header> 109 <main className="m-12 mt-6 flex items-center justify-center"> 110 <p className="text-lg text-data font-bold">{t('Loading…')}</p> 111 </main> 112 </div> 113 ); 114 }