123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- <script>
- import { io } from 'socket.io-client';
- import { spring } from 'svelte/motion';
- let loadingProgress = spring(0, {
- stiffness: 0.05
- });
- import { onMount, tick, setContext } from 'svelte';
- import {
- config,
- user,
- theme,
- WEBUI_NAME,
- mobile,
- socket,
- activeUserCount,
- USAGE_POOL
- } from '$lib/stores';
- import { goto } from '$app/navigation';
- import { page } from '$app/stores';
- import { Toaster, toast } from 'svelte-sonner';
- import { getBackendConfig } from '$lib/apis';
- import { getSessionUser } from '$lib/apis/auths';
- import '../tailwind.css';
- import '../app.css';
- import 'tippy.js/dist/tippy.css';
- import { WEBUI_BASE_URL, WEBUI_HOSTNAME } from '$lib/constants';
- import i18n, { initI18n, getLanguages } from '$lib/i18n';
- setContext('i18n', i18n);
- let loaded = false;
- const BREAKPOINT = 768;
- let wakeLock = null;
- onMount(async () => {
- theme.set(localStorage.theme);
- mobile.set(window.innerWidth < BREAKPOINT);
- const onResize = () => {
- if (window.innerWidth < BREAKPOINT) {
- mobile.set(true);
- } else {
- mobile.set(false);
- }
- };
- window.addEventListener('resize', onResize);
- const setWakeLock = async () => {
- try {
- wakeLock = await navigator.wakeLock.request('screen');
- } catch (err) {
- // The Wake Lock request has failed - usually system related, such as battery.
- console.log(err);
- }
- if (wakeLock) {
- // Add a listener to release the wake lock when the page is unloaded
- wakeLock.addEventListener('release', () => {
- // the wake lock has been released
- console.log('Wake Lock released');
- });
- }
- };
- if ('wakeLock' in navigator) {
- await setWakeLock();
- document.addEventListener('visibilitychange', async () => {
- // Re-request the wake lock if the document becomes visible
- if (wakeLock !== null && document.visibilityState === 'visible') {
- await setWakeLock();
- }
- });
- }
- let backendConfig = null;
- try {
- backendConfig = await getBackendConfig();
- console.log('Backend config:', backendConfig);
- } catch (error) {
- console.error('Error loading backend config:', error);
- }
- // Initialize i18n even if we didn't get a backend config,
- // so `/error` can show something that's not `undefined`.
- const languages = await getLanguages();
- const browserLanguage = navigator.languages
- ? navigator.languages[0]
- : navigator.language || navigator.userLanguage;
- initI18n(languages.includes(browserLanguage) ? browserLanguage : backendConfig?.default_locale);
- if (backendConfig) {
- // Save Backend Status to Store
- await config.set(backendConfig);
- await WEBUI_NAME.set(backendConfig.name);
- if ($config) {
- const _socket = io(`${WEBUI_BASE_URL}`, {
- path: '/ws/socket.io',
- auth: { token: localStorage.token }
- });
- _socket.on('connect', () => {
- console.log('connected');
- });
- await socket.set(_socket);
- _socket.on('user-count', (data) => {
- console.log('user-count', data);
- activeUserCount.set(data.count);
- });
- _socket.on('usage', (data) => {
- console.log('usage', data);
- USAGE_POOL.set(data['models']);
- });
- if (localStorage.token) {
- // Get Session User Info
- const sessionUser = await getSessionUser(localStorage.token).catch((error) => {
- toast.error(error);
- return null;
- });
- if (sessionUser) {
- // Save Session User to Store
- await user.set(sessionUser);
- } else {
- // Redirect Invalid Session User to /auth Page
- localStorage.removeItem('token');
- await goto('/auth');
- }
- } else {
- // Don't redirect if we're already on the auth page
- // Needed because we pass in tokens from OAuth logins via URL fragments
- if ($page.url.pathname !== '/auth') {
- await goto('/auth');
- }
- }
- }
- } else {
- // Redirect to /error when Backend Not Detected
- await goto(`/error`);
- }
- await tick();
- if (
- document.documentElement.classList.contains('her') &&
- document.getElementById('progress-bar')
- ) {
- loadingProgress.subscribe((value) => {
- const progressBar = document.getElementById('progress-bar');
- if (progressBar) {
- progressBar.style.width = `${value}%`;
- }
- });
- await loadingProgress.set(100);
- document.getElementById('splash-screen')?.remove();
- const audio = new Audio(`/audio/greeting.mp3`);
- const playAudio = () => {
- audio.play();
- document.removeEventListener('click', playAudio);
- };
- document.addEventListener('click', playAudio);
- loaded = true;
- } else {
- document.getElementById('splash-screen')?.remove();
- loaded = true;
- }
- return () => {
- window.removeEventListener('resize', onResize);
- };
- });
- </script>
- <svelte:head>
- <title>{$WEBUI_NAME}</title>
- <link crossorigin="anonymous" rel="icon" href="{WEBUI_BASE_URL}/static/favicon.png" />
- <!-- rosepine themes have been disabled as it's not up to date with our latest version. -->
- <!-- feel free to make a PR to fix if anyone wants to see it return -->
- <!-- <link rel="stylesheet" type="text/css" href="/themes/rosepine.css" />
- <link rel="stylesheet" type="text/css" href="/themes/rosepine-dawn.css" /> -->
- </svelte:head>
- {#if loaded}
- <slot />
- {/if}
- <Toaster richColors position="top-center" />
|