/* eslint-disable import/first */ import React from 'react'; import { createRoot } from 'react-dom/client'; import { enableMapSet } from 'immer'; import '@fontsource/inter/variable.css'; import 'folds/dist/style.css'; import { configClass, varsClass } from 'folds'; enableMapSet(); import './index.css'; import { trimTrailingSlash } from './app/utils/common'; import App from './app/pages/App'; import { applySafeAreaInsets, isTauri } from './app/utils/tauri'; import { enableViewTransitionsForNavigation } from './app/utils/viewTransitions'; // import i18n (needs to be bundled ;)) import './app/i18n'; document.body.classList.add(configClass, varsClass); // Apply safe area insets for mobile devices applySafeAreaInsets(); // Enable View Transitions API for smooth navigation enableViewTransitionsForNavigation(); // Register Service Worker if ('serviceWorker' in navigator) { const swUrl = import.meta.env.MODE === 'production' ? `${trimTrailingSlash(import.meta.env.BASE_URL)}/sw.js` : `/dev-sw.js?dev-sw`; navigator.serviceWorker.register(swUrl); navigator.serviceWorker.addEventListener('message', (event) => { if (event.data?.type === 'token' && event.data?.responseKey) { // Use the centralized token utility to get the current access token // This ensures we always use the most up-to-date token from the MatrixClient const getCurrentAccessToken = async () => { const { getCurrentAccessToken: getToken } = await import('./app/utils/auth'); return getToken(); }; getCurrentAccessToken().then(token => { event.source!.postMessage({ responseKey: event.data.responseKey, token, }); }); } }); } /** * Check if we're running in Electron (not Tauri) * Electron exposes window.electron in preload.js */ const isElectron = (): boolean => 'electron' in window; /** * Check for app updates using Tauri updater * Prompts user if update is available and handles download/install * Note: Electron has its own auto-updater in main.js, so skip for Electron */ async function checkForUpdates() { // Skip if in Electron - Electron has its own auto-updater if (isElectron()) { console.log('Update check skipped - Electron handles updates natively'); return; } // Only run in Tauri context (not Electron) if (!isTauri() || isElectron()) { console.log('Update check skipped - not running in Tauri'); return; } console.log('Checking for updates...'); try { const { check } = await import('@tauri-apps/plugin-updater'); const { ask } = await import('@tauri-apps/plugin-dialog'); const { relaunch } = await import('@tauri-apps/plugin-process'); const update = await check(); console.log('Update check result:', update); if (update) { console.log(`Update available: ${update.version}`); const shouldUpdate = await ask( `A new version (${update.version}) is available. Would you like to update now?`, { title: 'Update Available', kind: 'info' } ); if (shouldUpdate) { console.log('User chose to update, downloading...'); await update.downloadAndInstall(); await relaunch(); } } else { console.log('App is up to date'); } } catch (error) { console.error('Failed to check for updates:', error); } } const mountApp = () => { const rootContainer = document.getElementById('root'); if (rootContainer === null) { console.error('Root container element not found!'); return; } const root = createRoot(rootContainer); root.render(); }; mountApp(); // Check for updates after app loads (with delay to not block startup) setTimeout(() => { checkForUpdates(); }, 3000);