mirror of
				https://github.com/open-webui/open-webui
				synced 2025-06-26 18:26:48 +00:00 
			
		
		
		
	Update General.svelte
This commit is contained in:
		
							parent
							
								
									3814bbf7b3
								
							
						
					
					
						commit
						b9ea6130c7
					
				@ -1,318 +1,318 @@
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
    import { toast } from 'svelte-sonner';
 | 
			
		||||
    import { createEventDispatcher, onMount, getContext } from 'svelte';
 | 
			
		||||
    import { getLanguages, changeLanguage } from '$lib/i18n';
 | 
			
		||||
    const dispatch = createEventDispatcher();
 | 
			
		||||
	import { toast } from 'svelte-sonner';
 | 
			
		||||
	import { createEventDispatcher, onMount, getContext } from 'svelte';
 | 
			
		||||
	import { getLanguages, changeLanguage } from '$lib/i18n';
 | 
			
		||||
	const dispatch = createEventDispatcher();
 | 
			
		||||
 | 
			
		||||
    import { models, settings, theme, user } from '$lib/stores';
 | 
			
		||||
	import { models, settings, theme, user } from '$lib/stores';
 | 
			
		||||
 | 
			
		||||
    const i18n = getContext('i18n');
 | 
			
		||||
	const i18n = getContext('i18n');
 | 
			
		||||
 | 
			
		||||
    import AdvancedParams from './Advanced/AdvancedParams.svelte';
 | 
			
		||||
    import Textarea from '$lib/components/common/Textarea.svelte';
 | 
			
		||||
    export let saveSettings: Function;
 | 
			
		||||
    export let getModels: Function;
 | 
			
		||||
	import AdvancedParams from './Advanced/AdvancedParams.svelte';
 | 
			
		||||
	import Textarea from '$lib/components/common/Textarea.svelte';
 | 
			
		||||
	export let saveSettings: Function;
 | 
			
		||||
	export let getModels: Function;
 | 
			
		||||
 | 
			
		||||
    // General
 | 
			
		||||
    let themes = ['dark', 'light', 'oled-dark'];
 | 
			
		||||
    let selectedTheme = 'system';
 | 
			
		||||
	// General
 | 
			
		||||
	let themes = ['dark', 'light', 'oled-dark'];
 | 
			
		||||
	let selectedTheme = 'system';
 | 
			
		||||
 | 
			
		||||
    let languages: Awaited<ReturnType<typeof getLanguages>> = [];
 | 
			
		||||
    let lang = $i18n.language;
 | 
			
		||||
    let notificationEnabled = false;
 | 
			
		||||
    let system = '';
 | 
			
		||||
	let languages: Awaited<ReturnType<typeof getLanguages>> = [];
 | 
			
		||||
	let lang = $i18n.language;
 | 
			
		||||
	let notificationEnabled = false;
 | 
			
		||||
	let system = '';
 | 
			
		||||
 | 
			
		||||
    let showAdvanced = false;
 | 
			
		||||
	let showAdvanced = false;
 | 
			
		||||
 | 
			
		||||
    const toggleNotification = async () => {
 | 
			
		||||
        const permission = await Notification.requestPermission();
 | 
			
		||||
	const toggleNotification = async () => {
 | 
			
		||||
		const permission = await Notification.requestPermission();
 | 
			
		||||
 | 
			
		||||
        if (permission === 'granted') {
 | 
			
		||||
            notificationEnabled = !notificationEnabled;
 | 
			
		||||
            saveSettings({ notificationEnabled: notificationEnabled });
 | 
			
		||||
        } else {
 | 
			
		||||
            toast.error(
 | 
			
		||||
                $i18n.t(
 | 
			
		||||
                    'Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.'
 | 
			
		||||
                )
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
		if (permission === 'granted') {
 | 
			
		||||
			notificationEnabled = !notificationEnabled;
 | 
			
		||||
			saveSettings({ notificationEnabled: notificationEnabled });
 | 
			
		||||
		} else {
 | 
			
		||||
			toast.error(
 | 
			
		||||
				$i18n.t(
 | 
			
		||||
					'Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.'
 | 
			
		||||
				)
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
    let params = {
 | 
			
		||||
        // Advanced
 | 
			
		||||
        stream_response: null,
 | 
			
		||||
        function_calling: null,
 | 
			
		||||
        seed: null,
 | 
			
		||||
        temperature: null,
 | 
			
		||||
        reasoning_effort: null,
 | 
			
		||||
        logit_bias: null,
 | 
			
		||||
        frequency_penalty: null,
 | 
			
		||||
        presence_penalty: null,
 | 
			
		||||
        repeat_penalty: null,
 | 
			
		||||
        repeat_last_n: null,
 | 
			
		||||
        mirostat: null,
 | 
			
		||||
        mirostat_eta: null,
 | 
			
		||||
        mirostat_tau: null,
 | 
			
		||||
        top_k: null,
 | 
			
		||||
        top_p: null,
 | 
			
		||||
        min_p: null,
 | 
			
		||||
        stop: null,
 | 
			
		||||
        tfs_z: null,
 | 
			
		||||
        num_ctx: null,
 | 
			
		||||
        num_batch: null,
 | 
			
		||||
        num_keep: null,
 | 
			
		||||
        max_tokens: null,
 | 
			
		||||
        num_gpu: null
 | 
			
		||||
    };
 | 
			
		||||
	let params = {
 | 
			
		||||
		// Advanced
 | 
			
		||||
		stream_response: null,
 | 
			
		||||
		function_calling: null,
 | 
			
		||||
		seed: null,
 | 
			
		||||
		temperature: null,
 | 
			
		||||
		reasoning_effort: null,
 | 
			
		||||
		logit_bias: null,
 | 
			
		||||
		frequency_penalty: null,
 | 
			
		||||
		presence_penalty: null,
 | 
			
		||||
		repeat_penalty: null,
 | 
			
		||||
		repeat_last_n: null,
 | 
			
		||||
		mirostat: null,
 | 
			
		||||
		mirostat_eta: null,
 | 
			
		||||
		mirostat_tau: null,
 | 
			
		||||
		top_k: null,
 | 
			
		||||
		top_p: null,
 | 
			
		||||
		min_p: null,
 | 
			
		||||
		stop: null,
 | 
			
		||||
		tfs_z: null,
 | 
			
		||||
		num_ctx: null,
 | 
			
		||||
		num_batch: null,
 | 
			
		||||
		num_keep: null,
 | 
			
		||||
		max_tokens: null,
 | 
			
		||||
		num_gpu: null
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
    const saveHandler = async () => {
 | 
			
		||||
        saveSettings({
 | 
			
		||||
            system: system !== '' ? system : undefined,
 | 
			
		||||
            params: {
 | 
			
		||||
                stream_response: params.stream_response !== null ? params.stream_response : undefined,
 | 
			
		||||
                function_calling: params.function_calling !== null ? params.function_calling : undefined,
 | 
			
		||||
                seed: (params.seed !== null ? params.seed : undefined) ?? undefined,
 | 
			
		||||
                stop: params.stop ? params.stop.split(',').filter((e) => e) : undefined,
 | 
			
		||||
                temperature: params.temperature !== null ? params.temperature : undefined,
 | 
			
		||||
                reasoning_effort: params.reasoning_effort !== null ? params.reasoning_effort : undefined,
 | 
			
		||||
                logit_bias: params.logit_bias !== null ? params.logit_bias : undefined,
 | 
			
		||||
                frequency_penalty: params.frequency_penalty !== null ? params.frequency_penalty : undefined,
 | 
			
		||||
                presence_penalty: params.frequency_penalty !== null ? params.frequency_penalty : undefined,
 | 
			
		||||
                repeat_penalty: params.frequency_penalty !== null ? params.frequency_penalty : undefined,
 | 
			
		||||
                repeat_last_n: params.repeat_last_n !== null ? params.repeat_last_n : undefined,
 | 
			
		||||
                mirostat: params.mirostat !== null ? params.mirostat : undefined,
 | 
			
		||||
                mirostat_eta: params.mirostat_eta !== null ? params.mirostat_eta : undefined,
 | 
			
		||||
                mirostat_tau: params.mirostat_tau !== null ? params.mirostat_tau : undefined,
 | 
			
		||||
                top_k: params.top_k !== null ? params.top_k : undefined,
 | 
			
		||||
                top_p: params.top_p !== null ? params.top_p : undefined,
 | 
			
		||||
                min_p: params.min_p !== null ? params.min_p : undefined,
 | 
			
		||||
                tfs_z: params.tfs_z !== null ? params.tfs_z : undefined,
 | 
			
		||||
                num_ctx: params.num_ctx !== null ? params.num_ctx : undefined,
 | 
			
		||||
                num_batch: params.num_batch !== null ? params.num_batch : undefined,
 | 
			
		||||
                num_keep: params.num_keep !== null ? params.num_keep : undefined,
 | 
			
		||||
                max_tokens: params.max_tokens !== null ? params.max_tokens : undefined,
 | 
			
		||||
                use_mmap: params.use_mmap !== null ? params.use_mmap : undefined,
 | 
			
		||||
                use_mlock: params.use_mlock !== null ? params.use_mlock : undefined,
 | 
			
		||||
                num_thread: params.num_thread !== null ? params.num_thread : undefined,
 | 
			
		||||
                num_gpu: params.num_gpu !== null ? params.num_gpu : undefined,
 | 
			
		||||
                think: params.think !== null ? params.think : undefined,
 | 
			
		||||
                keep_alive: params.keep_alive !== null ? params.keep_alive : undefined,
 | 
			
		||||
                format: params.format !== null ? params.format : undefined
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        dispatch('save');
 | 
			
		||||
    };
 | 
			
		||||
	const saveHandler = async () => {
 | 
			
		||||
		saveSettings({
 | 
			
		||||
			system: system !== '' ? system : undefined,
 | 
			
		||||
			params: {
 | 
			
		||||
				stream_response: params.stream_response !== null ? params.stream_response : undefined,
 | 
			
		||||
				function_calling: params.function_calling !== null ? params.function_calling : undefined,
 | 
			
		||||
				seed: (params.seed !== null ? params.seed : undefined) ?? undefined,
 | 
			
		||||
				stop: params.stop ? params.stop.split(',').filter((e) => e) : undefined,
 | 
			
		||||
				temperature: params.temperature !== null ? params.temperature : undefined,
 | 
			
		||||
				reasoning_effort: params.reasoning_effort !== null ? params.reasoning_effort : undefined,
 | 
			
		||||
				logit_bias: params.logit_bias !== null ? params.logit_bias : undefined,
 | 
			
		||||
				frequency_penalty: params.frequency_penalty !== null ? params.frequency_penalty : undefined,
 | 
			
		||||
				presence_penalty: params.frequency_penalty !== null ? params.frequency_penalty : undefined,
 | 
			
		||||
				repeat_penalty: params.frequency_penalty !== null ? params.frequency_penalty : undefined,
 | 
			
		||||
				repeat_last_n: params.repeat_last_n !== null ? params.repeat_last_n : undefined,
 | 
			
		||||
				mirostat: params.mirostat !== null ? params.mirostat : undefined,
 | 
			
		||||
				mirostat_eta: params.mirostat_eta !== null ? params.mirostat_eta : undefined,
 | 
			
		||||
				mirostat_tau: params.mirostat_tau !== null ? params.mirostat_tau : undefined,
 | 
			
		||||
				top_k: params.top_k !== null ? params.top_k : undefined,
 | 
			
		||||
				top_p: params.top_p !== null ? params.top_p : undefined,
 | 
			
		||||
				min_p: params.min_p !== null ? params.min_p : undefined,
 | 
			
		||||
				tfs_z: params.tfs_z !== null ? params.tfs_z : undefined,
 | 
			
		||||
				num_ctx: params.num_ctx !== null ? params.num_ctx : undefined,
 | 
			
		||||
				num_batch: params.num_batch !== null ? params.num_batch : undefined,
 | 
			
		||||
				num_keep: params.num_keep !== null ? params.num_keep : undefined,
 | 
			
		||||
				max_tokens: params.max_tokens !== null ? params.max_tokens : undefined,
 | 
			
		||||
				use_mmap: params.use_mmap !== null ? params.use_mmap : undefined,
 | 
			
		||||
				use_mlock: params.use_mlock !== null ? params.use_mlock : undefined,
 | 
			
		||||
				num_thread: params.num_thread !== null ? params.num_thread : undefined,
 | 
			
		||||
				num_gpu: params.num_gpu !== null ? params.num_gpu : undefined,
 | 
			
		||||
				think: params.think !== null ? params.think : undefined,
 | 
			
		||||
				keep_alive: params.keep_alive !== null ? params.keep_alive : undefined,
 | 
			
		||||
				format: params.format !== null ? params.format : undefined
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
		dispatch('save');
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
    onMount(async () => {
 | 
			
		||||
        selectedTheme = localStorage.theme ?? 'system';
 | 
			
		||||
	onMount(async () => {
 | 
			
		||||
		selectedTheme = localStorage.theme ?? 'system';
 | 
			
		||||
 | 
			
		||||
        languages = await getLanguages();
 | 
			
		||||
		languages = await getLanguages();
 | 
			
		||||
 | 
			
		||||
        notificationEnabled = $settings.notificationEnabled ?? false;
 | 
			
		||||
        system = $settings.system ?? '';
 | 
			
		||||
		notificationEnabled = $settings.notificationEnabled ?? false;
 | 
			
		||||
		system = $settings.system ?? '';
 | 
			
		||||
 | 
			
		||||
        params = { ...params, ...$settings.params };
 | 
			
		||||
        params.stop = $settings?.params?.stop ? ($settings?.params?.stop ?? []).join(',') : null;
 | 
			
		||||
    });
 | 
			
		||||
		params = { ...params, ...$settings.params };
 | 
			
		||||
		params.stop = $settings?.params?.stop ? ($settings?.params?.stop ?? []).join(',') : null;
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
    const applyTheme = (_theme: string) => {
 | 
			
		||||
        let themeToApply = _theme === 'oled-dark' ? 'dark' : _theme;
 | 
			
		||||
	const applyTheme = (_theme: string) => {
 | 
			
		||||
		let themeToApply = _theme === 'oled-dark' ? 'dark' : _theme;
 | 
			
		||||
 | 
			
		||||
        if (_theme === 'system') {
 | 
			
		||||
            themeToApply = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
 | 
			
		||||
        }
 | 
			
		||||
		if (_theme === 'system') {
 | 
			
		||||
			themeToApply = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        if (themeToApply === 'dark' && !_theme.includes('oled')) {
 | 
			
		||||
            document.documentElement.style.setProperty('--color-gray-800', '#333');
 | 
			
		||||
            document.documentElement.style.setProperty('--color-gray-850', '#262626');
 | 
			
		||||
            document.documentElement.style.setProperty('--color-gray-900', '#171717');
 | 
			
		||||
            document.documentElement.style.setProperty('--color-gray-950', '#0d0d0d');
 | 
			
		||||
        }
 | 
			
		||||
		if (themeToApply === 'dark' && !_theme.includes('oled')) {
 | 
			
		||||
			document.documentElement.style.setProperty('--color-gray-800', '#333');
 | 
			
		||||
			document.documentElement.style.setProperty('--color-gray-850', '#262626');
 | 
			
		||||
			document.documentElement.style.setProperty('--color-gray-900', '#171717');
 | 
			
		||||
			document.documentElement.style.setProperty('--color-gray-950', '#0d0d0d');
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        themes
 | 
			
		||||
            .filter((e) => e !== themeToApply)
 | 
			
		||||
            .forEach((e) => {
 | 
			
		||||
                e.split(' ').forEach((e) => {
 | 
			
		||||
                    document.documentElement.classList.remove(e);
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
		themes
 | 
			
		||||
			.filter((e) => e !== themeToApply)
 | 
			
		||||
			.forEach((e) => {
 | 
			
		||||
				e.split(' ').forEach((e) => {
 | 
			
		||||
					document.documentElement.classList.remove(e);
 | 
			
		||||
				});
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
        themeToApply.split(' ').forEach((e) => {
 | 
			
		||||
            document.documentElement.classList.add(e);
 | 
			
		||||
        });
 | 
			
		||||
		themeToApply.split(' ').forEach((e) => {
 | 
			
		||||
			document.documentElement.classList.add(e);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
        const metaThemeColor = document.querySelector('meta[name="theme-color"]');
 | 
			
		||||
        if (metaThemeColor) {
 | 
			
		||||
            if (_theme.includes('system')) {
 | 
			
		||||
                const systemTheme = window.matchMedia('(prefers-color-scheme: dark)').matches
 | 
			
		||||
                    ? 'dark'
 | 
			
		||||
                    : 'light';
 | 
			
		||||
                console.log('Setting system meta theme color: ' + systemTheme);
 | 
			
		||||
                metaThemeColor.setAttribute('content', systemTheme === 'light' ? '#ffffff' : '#171717');
 | 
			
		||||
            } else {
 | 
			
		||||
                console.log('Setting meta theme color: ' + _theme);
 | 
			
		||||
                metaThemeColor.setAttribute(
 | 
			
		||||
                    'content',
 | 
			
		||||
                    _theme === 'dark'
 | 
			
		||||
                        ? '#171717'
 | 
			
		||||
                        : _theme === 'oled-dark'
 | 
			
		||||
                            ? '#000000'
 | 
			
		||||
                            : _theme === 'her'
 | 
			
		||||
                                ? '#983724'
 | 
			
		||||
                                : '#ffffff'
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
		const metaThemeColor = document.querySelector('meta[name="theme-color"]');
 | 
			
		||||
		if (metaThemeColor) {
 | 
			
		||||
			if (_theme.includes('system')) {
 | 
			
		||||
				const systemTheme = window.matchMedia('(prefers-color-scheme: dark)').matches
 | 
			
		||||
					? 'dark'
 | 
			
		||||
					: 'light';
 | 
			
		||||
				console.log('Setting system meta theme color: ' + systemTheme);
 | 
			
		||||
				metaThemeColor.setAttribute('content', systemTheme === 'light' ? '#ffffff' : '#171717');
 | 
			
		||||
			} else {
 | 
			
		||||
				console.log('Setting meta theme color: ' + _theme);
 | 
			
		||||
				metaThemeColor.setAttribute(
 | 
			
		||||
					'content',
 | 
			
		||||
					_theme === 'dark'
 | 
			
		||||
						? '#171717'
 | 
			
		||||
						: _theme === 'oled-dark'
 | 
			
		||||
							? '#000000'
 | 
			
		||||
							: _theme === 'her'
 | 
			
		||||
								? '#983724'
 | 
			
		||||
								: '#ffffff'
 | 
			
		||||
				);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        if (typeof window !== 'undefined' && window.applyTheme) {
 | 
			
		||||
            window.applyTheme();
 | 
			
		||||
        }
 | 
			
		||||
		if (typeof window !== 'undefined' && window.applyTheme) {
 | 
			
		||||
			window.applyTheme();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        if (_theme.includes('oled')) {
 | 
			
		||||
            document.documentElement.style.setProperty('--color-gray-800', '#101010');
 | 
			
		||||
            document.documentElement.style.setProperty('--color-gray-850', '#050505');
 | 
			
		||||
            document.documentElement.style.setProperty('--color-gray-900', '#000000');
 | 
			
		||||
            document.documentElement.style.setProperty('--color-gray-950', '#000000');
 | 
			
		||||
            document.documentElement.classList.add('dark');
 | 
			
		||||
        }
 | 
			
		||||
		if (_theme.includes('oled')) {
 | 
			
		||||
			document.documentElement.style.setProperty('--color-gray-800', '#101010');
 | 
			
		||||
			document.documentElement.style.setProperty('--color-gray-850', '#050505');
 | 
			
		||||
			document.documentElement.style.setProperty('--color-gray-900', '#000000');
 | 
			
		||||
			document.documentElement.style.setProperty('--color-gray-950', '#000000');
 | 
			
		||||
			document.documentElement.classList.add('dark');
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        console.log(_theme);
 | 
			
		||||
    };
 | 
			
		||||
		console.log(_theme);
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
    const themeChangeHandler = (_theme: string) => {
 | 
			
		||||
        theme.set(_theme);
 | 
			
		||||
        localStorage.setItem('theme', _theme);
 | 
			
		||||
        applyTheme(_theme);
 | 
			
		||||
    };
 | 
			
		||||
	const themeChangeHandler = (_theme: string) => {
 | 
			
		||||
		theme.set(_theme);
 | 
			
		||||
		localStorage.setItem('theme', _theme);
 | 
			
		||||
		applyTheme(_theme);
 | 
			
		||||
	};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<div class="flex flex-col h-full justify-between text-sm" id="tab-general">
 | 
			
		||||
    <div class="  overflow-y-scroll max-h-[28rem] lg:max-h-full">
 | 
			
		||||
        <div class="">
 | 
			
		||||
            <div class=" mb-1 text-sm font-medium">{$i18n.t('WebUI Settings')}</div>
 | 
			
		||||
	<div class="  overflow-y-scroll max-h-[28rem] lg:max-h-full">
 | 
			
		||||
		<div class="">
 | 
			
		||||
			<div class=" mb-1 text-sm font-medium">{$i18n.t('WebUI Settings')}</div>
 | 
			
		||||
 | 
			
		||||
            <div class="flex w-full justify-between">
 | 
			
		||||
                <div class=" self-center text-xs font-medium">{$i18n.t('Theme')}</div>
 | 
			
		||||
                <div class="flex items-center relative">
 | 
			
		||||
                    <select
 | 
			
		||||
                        class="dark:bg-gray-900 w-fit pr-8 rounded-sm py-2 px-2 text-xs bg-transparent text-right {$settings.highContrastMode
 | 
			
		||||
                            ? ''
 | 
			
		||||
                            : 'outline-hidden'}"
 | 
			
		||||
                        bind:value={selectedTheme}
 | 
			
		||||
                        placeholder="Select a theme"
 | 
			
		||||
                        on:change={() => themeChangeHandler(selectedTheme)}
 | 
			
		||||
                    >
 | 
			
		||||
                        <option value="system">⚙️ {$i18n.t('System')}</option>
 | 
			
		||||
                        <option value="dark">🌑 {$i18n.t('Dark')}</option>
 | 
			
		||||
                        <option value="oled-dark">🌃 {$i18n.t('OLED Dark')}</option>
 | 
			
		||||
                        <option value="light">☀️ {$i18n.t('Light')}</option>
 | 
			
		||||
                        <option value="her">🌷 Her</option>
 | 
			
		||||
                        <!-- <option value="rose-pine dark">🪻 {$i18n.t('Rosé Pine')}</option>
 | 
			
		||||
                        <option value="rose-pine-dawn light">🌷 {$i18n.t('Rosé Pine Dawn')}</option> -->
 | 
			
		||||
                    </select>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
			<div class="flex w-full justify-between">
 | 
			
		||||
				<div class=" self-center text-xs font-medium">{$i18n.t('Theme')}</div>
 | 
			
		||||
				<div class="flex items-center relative">
 | 
			
		||||
					<select
 | 
			
		||||
						class="dark:bg-gray-900 w-fit pr-8 rounded-sm py-2 px-2 text-xs bg-transparent text-right {$settings.highContrastMode
 | 
			
		||||
							? ''
 | 
			
		||||
							: 'outline-hidden'}"
 | 
			
		||||
						bind:value={selectedTheme}
 | 
			
		||||
						placeholder="Select a theme"
 | 
			
		||||
						on:change={() => themeChangeHandler(selectedTheme)}
 | 
			
		||||
					>
 | 
			
		||||
						<option value="system">⚙️ {$i18n.t('System')}</option>
 | 
			
		||||
						<option value="dark">🌑 {$i18n.t('Dark')}</option>
 | 
			
		||||
						<option value="oled-dark">🌃 {$i18n.t('OLED Dark')}</option>
 | 
			
		||||
						<option value="light">☀️ {$i18n.t('Light')}</option>
 | 
			
		||||
						<option value="her">🌷 Her</option>
 | 
			
		||||
						<!-- <option value="rose-pine dark">🪻 {$i18n.t('Rosé Pine')}</option>
 | 
			
		||||
						<option value="rose-pine-dawn light">🌷 {$i18n.t('Rosé Pine Dawn')}</option> -->
 | 
			
		||||
					</select>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
 | 
			
		||||
            <div class=" flex w-full justify-between">
 | 
			
		||||
                <div class=" self-center text-xs font-medium">{$i18n.t('Language')}</div>
 | 
			
		||||
                <div class="flex items-center relative">
 | 
			
		||||
                    <select
 | 
			
		||||
                        class="dark:bg-gray-900 w-fit pr-8 rounded-sm py-2 px-2 text-xs bg-transparent text-right {$settings.highContrastMode
 | 
			
		||||
                            ? ''
 | 
			
		||||
                            : 'outline-hidden'}"
 | 
			
		||||
                        bind:value={lang}
 | 
			
		||||
                        placeholder="Select a language"
 | 
			
		||||
                        on:change={(e) => {
 | 
			
		||||
                            changeLanguage(lang);
 | 
			
		||||
                        }}
 | 
			
		||||
                    >
 | 
			
		||||
                        {#each languages as language}
 | 
			
		||||
                            <option value={language['code']}>{language['title']}</option>
 | 
			
		||||
                        {/each}
 | 
			
		||||
                    </select>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            {#if $i18n.language === 'en-US'}
 | 
			
		||||
                <div class="mb-2 text-xs text-gray-400 dark:text-gray-500">
 | 
			
		||||
                    Couldn't find your language?
 | 
			
		||||
                    <a
 | 
			
		||||
                        class=" text-gray-300 font-medium underline"
 | 
			
		||||
                        href="https://github.com/open-webui/open-webui/blob/main/docs/CONTRIBUTING.md#-translations-and-internationalization"
 | 
			
		||||
                        target="_blank"
 | 
			
		||||
                    >
 | 
			
		||||
                        Help us translate Open WebUI!
 | 
			
		||||
                    </a>
 | 
			
		||||
                </div>
 | 
			
		||||
            {/if}
 | 
			
		||||
			<div class=" flex w-full justify-between">
 | 
			
		||||
				<div class=" self-center text-xs font-medium">{$i18n.t('Language')}</div>
 | 
			
		||||
				<div class="flex items-center relative">
 | 
			
		||||
					<select
 | 
			
		||||
						class="dark:bg-gray-900 w-fit pr-8 rounded-sm py-2 px-2 text-xs bg-transparent text-right {$settings.highContrastMode
 | 
			
		||||
							? ''
 | 
			
		||||
							: 'outline-hidden'}"
 | 
			
		||||
						bind:value={lang}
 | 
			
		||||
						placeholder="Select a language"
 | 
			
		||||
						on:change={(e) => {
 | 
			
		||||
							changeLanguage(lang);
 | 
			
		||||
						}}
 | 
			
		||||
					>
 | 
			
		||||
						{#each languages as language}
 | 
			
		||||
							<option value={language['code']}>{language['title']}</option>
 | 
			
		||||
						{/each}
 | 
			
		||||
					</select>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
			{#if $i18n.language === 'en-US'}
 | 
			
		||||
				<div class="mb-2 text-xs text-gray-400 dark:text-gray-500">
 | 
			
		||||
					Couldn't find your language?
 | 
			
		||||
					<a
 | 
			
		||||
						class=" text-gray-300 font-medium underline"
 | 
			
		||||
						href="https://github.com/open-webui/open-webui/blob/main/docs/CONTRIBUTING.md#-translations-and-internationalization"
 | 
			
		||||
						target="_blank"
 | 
			
		||||
					>
 | 
			
		||||
						Help us translate Open WebUI!
 | 
			
		||||
					</a>
 | 
			
		||||
				</div>
 | 
			
		||||
			{/if}
 | 
			
		||||
 | 
			
		||||
            <div>
 | 
			
		||||
                <div class=" py-0.5 flex w-full justify-between">
 | 
			
		||||
                    <div class=" self-center text-xs font-medium">{$i18n.t('Notifications')}</div>
 | 
			
		||||
			<div>
 | 
			
		||||
				<div class=" py-0.5 flex w-full justify-between">
 | 
			
		||||
					<div class=" self-center text-xs font-medium">{$i18n.t('Notifications')}</div>
 | 
			
		||||
 | 
			
		||||
                    <button
 | 
			
		||||
                        class="p-1 px-3 text-xs flex rounded-sm transition"
 | 
			
		||||
                        on:click={() => {
 | 
			
		||||
                            toggleNotification();
 | 
			
		||||
                        }}
 | 
			
		||||
                        type="button"
 | 
			
		||||
                    >
 | 
			
		||||
                        {#if notificationEnabled === true}
 | 
			
		||||
                            <span class="ml-2 self-center">{$i18n.t('On')}</span>
 | 
			
		||||
                        {:else}
 | 
			
		||||
                            <span class="ml-2 self-center">{$i18n.t('Off')}</span>
 | 
			
		||||
                        {/if}
 | 
			
		||||
                    </button>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
					<button
 | 
			
		||||
						class="p-1 px-3 text-xs flex rounded-sm transition"
 | 
			
		||||
						on:click={() => {
 | 
			
		||||
							toggleNotification();
 | 
			
		||||
						}}
 | 
			
		||||
						type="button"
 | 
			
		||||
					>
 | 
			
		||||
						{#if notificationEnabled === true}
 | 
			
		||||
							<span class="ml-2 self-center">{$i18n.t('On')}</span>
 | 
			
		||||
						{:else}
 | 
			
		||||
							<span class="ml-2 self-center">{$i18n.t('Off')}</span>
 | 
			
		||||
						{/if}
 | 
			
		||||
					</button>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
 | 
			
		||||
        {#if $user?.role === 'admin' || ($user?.permissions.chat?.system_prompt ?? true)}
 | 
			
		||||
            <hr class="border-gray-50 dark:border-gray-850 my-3" />
 | 
			
		||||
		{#if $user?.role === 'admin' || ($user?.permissions.chat?.system_prompt ?? true)}
 | 
			
		||||
			<hr class="border-gray-50 dark:border-gray-850 my-3" />
 | 
			
		||||
 | 
			
		||||
            <div>
 | 
			
		||||
                <div class=" my-2.5 text-sm font-medium">{$i18n.t('System Prompt')}</div>
 | 
			
		||||
                <Textarea
 | 
			
		||||
                    bind:value={system}
 | 
			
		||||
                    className={
 | 
			
		||||
                        "w-full text-sm outline-hidden resize-vertical" + ($settings.highContrastMode
 | 
			
		||||
                            ? " p-2.5 border-2 border-gray-300 dark:border-gray-700 rounded-lg bg-gray-50 dark:bg-gray-850 text-gray-900 dark:text-gray-100 focus:ring-1 focus:ring-blue-500 focus:border-blue-500 overflow-y-hidden"
 | 
			
		||||
                            : " bg-white dark:text-gray-300 dark:bg-gray-900")
 | 
			
		||||
                    }
 | 
			
		||||
                    rows="4"
 | 
			
		||||
                    placeholder={$i18n.t('Enter system prompt here')}
 | 
			
		||||
                />
 | 
			
		||||
            </div>
 | 
			
		||||
        {/if}
 | 
			
		||||
			<div>
 | 
			
		||||
				<div class=" my-2.5 text-sm font-medium">{$i18n.t('System Prompt')}</div>
 | 
			
		||||
				<Textarea
 | 
			
		||||
					bind:value={system}
 | 
			
		||||
					className={
 | 
			
		||||
						"w-full text-sm outline-hidden resize-vertical" + ($settings.highContrastMode
 | 
			
		||||
							? " p-2.5 border-2 border-gray-300 dark:border-gray-700 rounded-lg bg-gray-50 dark:bg-gray-850 text-gray-900 dark:text-gray-100 focus:ring-1 focus:ring-blue-500 focus:border-blue-500 overflow-y-hidden"
 | 
			
		||||
							: " bg-white dark:text-gray-300 dark:bg-gray-900")
 | 
			
		||||
					}
 | 
			
		||||
					rows="4"
 | 
			
		||||
					placeholder={$i18n.t('Enter system prompt here')}
 | 
			
		||||
				/>
 | 
			
		||||
			</div>
 | 
			
		||||
		{/if}
 | 
			
		||||
 | 
			
		||||
        {#if $user?.role === 'admin' || ($user?.permissions.chat?.controls ?? true)}
 | 
			
		||||
            <div class="mt-2 space-y-3 pr-1.5">
 | 
			
		||||
                <div class="flex justify-between items-center text-sm">
 | 
			
		||||
                    <div class="  font-medium">{$i18n.t('Advanced Parameters')}</div>
 | 
			
		||||
                    <button
 | 
			
		||||
                        class=" text-xs font-medium text-gray-500"
 | 
			
		||||
                        type="button"
 | 
			
		||||
                        on:click={() => {
 | 
			
		||||
                            showAdvanced = !showAdvanced;
 | 
			
		||||
                        }}>{showAdvanced ? $i18n.t('Hide') : $i18n.t('Show')}</button
 | 
			
		||||
                    >
 | 
			
		||||
                </div>
 | 
			
		||||
		{#if $user?.role === 'admin' || ($user?.permissions.chat?.controls ?? true)}
 | 
			
		||||
			<div class="mt-2 space-y-3 pr-1.5">
 | 
			
		||||
				<div class="flex justify-between items-center text-sm">
 | 
			
		||||
					<div class="  font-medium">{$i18n.t('Advanced Parameters')}</div>
 | 
			
		||||
					<button
 | 
			
		||||
						class=" text-xs font-medium text-gray-500"
 | 
			
		||||
						type="button"
 | 
			
		||||
						on:click={() => {
 | 
			
		||||
							showAdvanced = !showAdvanced;
 | 
			
		||||
						}}>{showAdvanced ? $i18n.t('Hide') : $i18n.t('Show')}</button
 | 
			
		||||
					>
 | 
			
		||||
				</div>
 | 
			
		||||
 | 
			
		||||
                {#if showAdvanced}
 | 
			
		||||
                    <AdvancedParams admin={$user?.role === 'admin'} bind:params />
 | 
			
		||||
                {/if}
 | 
			
		||||
            </div>
 | 
			
		||||
        {/if}
 | 
			
		||||
    </div>
 | 
			
		||||
				{#if showAdvanced}
 | 
			
		||||
					<AdvancedParams admin={$user?.role === 'admin'} bind:params />
 | 
			
		||||
				{/if}
 | 
			
		||||
			</div>
 | 
			
		||||
		{/if}
 | 
			
		||||
	</div>
 | 
			
		||||
 | 
			
		||||
    <div class="flex justify-end pt-3 text-sm font-medium">
 | 
			
		||||
        <button
 | 
			
		||||
            class="px-3.5 py-1.5 text-sm font-medium bg-black hover:bg-gray-900 text-white dark:bg-white dark:text-black dark:hover:bg-gray-100 transition rounded-full"
 | 
			
		||||
            on:click={() => {
 | 
			
		||||
                saveHandler();
 | 
			
		||||
            }}
 | 
			
		||||
        >
 | 
			
		||||
            {$i18n.t('Save')}
 | 
			
		||||
        </button>
 | 
			
		||||
    </div>
 | 
			
		||||
	<div class="flex justify-end pt-3 text-sm font-medium">
 | 
			
		||||
		<button
 | 
			
		||||
			class="px-3.5 py-1.5 text-sm font-medium bg-black hover:bg-gray-900 text-white dark:bg-white dark:text-black dark:hover:bg-gray-100 transition rounded-full"
 | 
			
		||||
			on:click={() => {
 | 
			
		||||
				saveHandler();
 | 
			
		||||
			}}
 | 
			
		||||
		>
 | 
			
		||||
			{$i18n.t('Save')}
 | 
			
		||||
		</button>
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user