Files
pipu-music/apps/web/src/main.tsx
T
mrleo1nidandCursor efe78d7e07
ci / api / api (push) Successful in 43s
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 1m19s
ci / desktop / rust (desktop proxy) (push) Failing after 3m34s
ci / ts / ts (packages + web) (push) Failing after 2m49s
release / release (версия и заметки) (push) Successful in 5s
ci / db / db (push) Successful in 40s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m12s
ci / docker / docker (образы собираются — их сервер собирает сам при обновлении) (push) Successful in 1m28s
release / android (APK в релиз) (push) Failing after 2m0s
feat(desktop): wrap the web client in a Tauri app
EOF

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 23:45:03 +03:00

87 lines
2.5 KiB
TypeScript

import './styles.css';
import { AuthSession } from '@pipu/core';
import { createI18n, pickLocale } from '@pipu/i18n';
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { I18nextProvider } from 'react-i18next';
import { App } from './App';
import { createAppRouter } from './app/router';
import { applyTheme } from './app/session';
import { createDesktop, DesktopProvider } from './desktop';
const LOCALE_KEY = 'pipu.locale';
function storedLocale(): string[] {
try {
const v = localStorage.getItem(LOCALE_KEY);
return v ? [v] : [];
} catch {
return [];
}
}
/** «Chrome / Windows» — подпись сессии в списке устройств. */
function deviceName(): string {
const ua = navigator.userAgent;
const browser = /Edg\//.test(ua)
? 'Edge'
: /Firefox\//.test(ua)
? 'Firefox'
: /Chrome\//.test(ua)
? 'Chrome'
: /Safari\//.test(ua)
? 'Safari'
: 'Browser';
const os = /Windows/.test(ua)
? 'Windows'
: /Android/.test(ua)
? 'Android'
: /iPhone|iPad/.test(ua)
? 'iOS'
: /Mac OS X/.test(ua)
? 'macOS'
: /Linux/.test(ua)
? 'Linux'
: '';
return os ? `${browser} / ${os}` : browser;
}
applyTheme(undefined);
if (import.meta.env.VITE_E2E === '1') {
const { installE2EFetch } = await import('./test/e2eBridge');
installE2EFetch();
}
const i18n = await createI18n(pickLocale([...storedLocale(), ...navigator.languages]));
document.documentElement.lang = i18n.language;
i18n.on('languageChanged', (l) => {
document.documentElement.lang = l;
try {
localStorage.setItem(LOCALE_KEY, l);
} catch {
// недоступное хранилище не мешает работе
}
});
const desktop = await createDesktop();
const session = new AuthSession({
clientType: desktop ? 'desktop' : 'web',
deviceName: desktop ? 'Pipu / Desktop' : deviceName(),
baseUrl: desktop?.proxyBase,
refreshStore: desktop?.refreshStore,
});
// До первого рендера узнаём, есть ли сессия (refresh-cookie), — guards роутера решают сразу.
await session.restore();
const router = createAppRouter(session, { desktop });
createRoot(document.getElementById('root')!).render(
<StrictMode>
<I18nextProvider i18n={i18n}>
<DesktopProvider value={desktop}>
<App session={session} router={router} />
</DesktopProvider>
</I18nextProvider>
</StrictMode>,
);