2024-02-05 09:58:54 +00:00
|
|
|
<script lang="ts">
|
2024-03-26 07:59:57 +00:00
|
|
|
import { config, models, settings, user } from '$lib/stores';
|
2024-03-01 04:40:36 +00:00
|
|
|
import { createEventDispatcher, onMount, getContext } from 'svelte';
|
2024-03-01 09:18:07 +00:00
|
|
|
import { toast } from 'svelte-sonner';
|
2024-05-12 09:47:23 +00:00
|
|
|
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
2024-06-16 22:32:26 +00:00
|
|
|
import { updateUserInfo } from '$lib/apis/users';
|
|
|
|
|
import { getUserPosition } from '$lib/utils';
|
2025-08-06 22:11:16 +00:00
|
|
|
import Minus from '$lib/components/icons/Minus.svelte';
|
|
|
|
|
import Plus from '$lib/components/icons/Plus.svelte';
|
|
|
|
|
import Switch from '$lib/components/common/Switch.svelte';
|
|
|
|
|
import ManageFloatingActionButtonsModal from './Interface/ManageFloatingActionButtonsModal.svelte';
|
2024-02-05 09:58:54 +00:00
|
|
|
const dispatch = createEventDispatcher();
|
|
|
|
|
|
2024-03-01 04:40:36 +00:00
|
|
|
const i18n = getContext('i18n');
|
|
|
|
|
|
2024-02-06 05:05:38 +00:00
|
|
|
export let saveSettings: Function;
|
|
|
|
|
|
2024-06-17 08:31:22 +00:00
|
|
|
let backgroundImageUrl = null;
|
|
|
|
|
let inputFiles = null;
|
|
|
|
|
let filesInputElement;
|
|
|
|
|
|
2024-02-06 05:05:38 +00:00
|
|
|
// Addons
|
|
|
|
|
let titleAutoGenerate = true;
|
2025-06-03 14:47:49 +00:00
|
|
|
let autoFollowUps = true;
|
2024-10-20 03:34:17 +00:00
|
|
|
let autoTags = true;
|
|
|
|
|
|
2024-02-06 05:05:38 +00:00
|
|
|
let responseAutoCopy = false;
|
2024-06-04 18:48:46 +00:00
|
|
|
let widescreenMode = false;
|
2024-04-21 09:45:07 +00:00
|
|
|
let splitLargeChunks = false;
|
2024-08-04 01:56:04 +00:00
|
|
|
let scrollOnBranchChange = true;
|
2024-06-16 22:32:26 +00:00
|
|
|
let userLocation = false;
|
2024-02-06 05:05:38 +00:00
|
|
|
|
2024-02-05 09:58:54 +00:00
|
|
|
// Interface
|
2024-06-05 16:14:15 +00:00
|
|
|
let defaultModelId = '';
|
2024-02-06 10:22:34 +00:00
|
|
|
let showUsername = false;
|
2025-04-20 06:13:19 +00:00
|
|
|
|
2025-03-31 04:19:09 +00:00
|
|
|
let notificationSound = true;
|
2025-04-20 06:13:19 +00:00
|
|
|
let notificationSoundAlways = false;
|
2025-03-31 04:19:09 +00:00
|
|
|
|
2025-05-16 13:06:21 +00:00
|
|
|
let highContrastMode = false;
|
|
|
|
|
|
2025-04-10 17:36:57 +00:00
|
|
|
let detectArtifacts = true;
|
2025-08-06 18:47:34 +00:00
|
|
|
let displayMultiModelResponsesInTabs = false;
|
2025-04-10 17:36:57 +00:00
|
|
|
|
2024-10-26 04:31:18 +00:00
|
|
|
let richTextInput = true;
|
2025-08-06 08:21:18 +00:00
|
|
|
let showFormattingToolbar = false;
|
2025-07-07 17:43:28 +00:00
|
|
|
let insertPromptAsRichText = false;
|
2025-03-31 04:19:09 +00:00
|
|
|
let promptAutocomplete = false;
|
|
|
|
|
|
2024-11-19 04:58:18 +00:00
|
|
|
let largeTextAsFile = false;
|
2024-06-13 04:18:53 +00:00
|
|
|
|
2025-09-07 15:24:32 +00:00
|
|
|
let insertSuggestionPrompt = false;
|
2025-07-18 13:49:24 +00:00
|
|
|
let keepFollowUpPrompts = false;
|
|
|
|
|
let insertFollowUpPrompt = false;
|
|
|
|
|
|
2025-08-10 20:43:41 +00:00
|
|
|
let regenerateMenu = true;
|
|
|
|
|
|
2024-10-06 18:45:13 +00:00
|
|
|
let landingPageMode = '';
|
2024-05-15 22:39:41 +00:00
|
|
|
let chatBubble = true;
|
2025-04-07 00:02:39 +00:00
|
|
|
let chatDirection: 'LTR' | 'RTL' | 'auto' = 'auto';
|
2025-03-04 04:53:14 +00:00
|
|
|
let ctrlEnterToSend = false;
|
2025-04-14 08:56:15 +00:00
|
|
|
let copyFormatted = false;
|
2024-10-27 02:44:46 +00:00
|
|
|
|
2025-08-20 18:49:05 +00:00
|
|
|
let temporaryChatByDefault = false;
|
2025-07-18 12:45:56 +00:00
|
|
|
let chatFadeStreamingText = true;
|
2025-03-15 02:01:59 +00:00
|
|
|
let collapseCodeBlocks = false;
|
2025-03-15 01:56:04 +00:00
|
|
|
let expandDetails = false;
|
|
|
|
|
|
2025-08-06 19:28:05 +00:00
|
|
|
let showFloatingActionButtons = true;
|
|
|
|
|
let floatingActionButtons = null;
|
|
|
|
|
|
2024-12-25 06:28:14 +00:00
|
|
|
let imageCompression = false;
|
|
|
|
|
let imageCompressionSize = {
|
|
|
|
|
width: '',
|
|
|
|
|
height: ''
|
|
|
|
|
};
|
2025-08-06 11:11:43 +00:00
|
|
|
let imageCompressionInChannels = true;
|
2024-12-25 06:28:14 +00:00
|
|
|
|
2025-05-10 14:59:04 +00:00
|
|
|
// chat export
|
|
|
|
|
let stylizedPdfExport = true;
|
|
|
|
|
|
2024-10-27 02:44:46 +00:00
|
|
|
// Admin - Show Update Available Toast
|
2024-10-21 07:30:29 +00:00
|
|
|
let showUpdateToast = true;
|
2024-10-27 02:44:46 +00:00
|
|
|
let showChangelog = true;
|
2024-02-06 10:22:34 +00:00
|
|
|
|
2024-06-13 04:18:53 +00:00
|
|
|
let showEmojiInCall = false;
|
2024-06-22 20:21:36 +00:00
|
|
|
let voiceInterruption = false;
|
2024-08-14 15:05:43 +00:00
|
|
|
let hapticFeedback = false;
|
2024-06-13 04:18:53 +00:00
|
|
|
|
2025-02-05 08:37:47 +00:00
|
|
|
let webSearch = null;
|
2025-01-28 17:01:46 +00:00
|
|
|
|
2025-04-13 00:09:39 +00:00
|
|
|
let iframeSandboxAllowSameOrigin = false;
|
|
|
|
|
let iframeSandboxAllowForms = false;
|
|
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
let showManageFloatingActionButtonsModal = false;
|
2024-05-15 22:39:41 +00:00
|
|
|
|
2024-10-06 18:45:13 +00:00
|
|
|
const toggleLandingPageMode = async () => {
|
|
|
|
|
landingPageMode = landingPageMode === '' ? 'chat' : '';
|
|
|
|
|
saveSettings({ landingPageMode: landingPageMode });
|
|
|
|
|
};
|
|
|
|
|
|
2024-06-16 22:32:26 +00:00
|
|
|
const toggleUserLocation = async () => {
|
|
|
|
|
if (userLocation) {
|
|
|
|
|
const position = await getUserPosition().catch((error) => {
|
|
|
|
|
toast.error(error.message);
|
|
|
|
|
return null;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (position) {
|
|
|
|
|
await updateUserInfo(localStorage.token, { location: position });
|
2024-06-24 16:09:45 +00:00
|
|
|
toast.success($i18n.t('User location successfully retrieved.'));
|
2024-06-16 22:32:26 +00:00
|
|
|
} else {
|
|
|
|
|
userLocation = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
saveSettings({ userLocation });
|
|
|
|
|
};
|
|
|
|
|
|
2024-02-06 05:05:38 +00:00
|
|
|
const toggleTitleAutoGenerate = async () => {
|
2024-03-26 07:59:57 +00:00
|
|
|
saveSettings({
|
|
|
|
|
title: {
|
|
|
|
|
...$settings.title,
|
|
|
|
|
auto: titleAutoGenerate
|
|
|
|
|
}
|
|
|
|
|
});
|
2024-02-06 05:05:38 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const toggleResponseAutoCopy = async () => {
|
|
|
|
|
const permission = await navigator.clipboard
|
|
|
|
|
.readText()
|
|
|
|
|
.then(() => {
|
|
|
|
|
return 'granted';
|
|
|
|
|
})
|
|
|
|
|
.catch(() => {
|
|
|
|
|
return '';
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (permission === 'granted') {
|
|
|
|
|
saveSettings({ responseAutoCopy: responseAutoCopy });
|
|
|
|
|
} else {
|
2025-08-06 22:11:16 +00:00
|
|
|
responseAutoCopy = false;
|
2024-02-06 05:05:38 +00:00
|
|
|
toast.error(
|
2024-06-24 16:12:39 +00:00
|
|
|
$i18n.t(
|
2024-06-24 16:21:29 +00:00
|
|
|
'Clipboard write permission denied. Please check your browser settings to grant the necessary access.'
|
|
|
|
|
)
|
2024-02-06 05:05:38 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2024-05-16 20:22:30 +00:00
|
|
|
const toggleChangeChatDirection = async () => {
|
2025-04-06 23:57:36 +00:00
|
|
|
if (chatDirection === 'auto') {
|
|
|
|
|
chatDirection = 'LTR';
|
|
|
|
|
} else if (chatDirection === 'LTR') {
|
|
|
|
|
chatDirection = 'RTL';
|
|
|
|
|
} else if (chatDirection === 'RTL') {
|
|
|
|
|
chatDirection = 'auto';
|
|
|
|
|
}
|
2024-05-18 22:02:47 +00:00
|
|
|
saveSettings({ chatDirection });
|
2024-05-16 20:22:30 +00:00
|
|
|
};
|
|
|
|
|
|
2025-03-04 04:53:14 +00:00
|
|
|
const togglectrlEnterToSend = async () => {
|
|
|
|
|
ctrlEnterToSend = !ctrlEnterToSend;
|
|
|
|
|
saveSettings({ ctrlEnterToSend });
|
2025-02-05 12:43:35 +00:00
|
|
|
};
|
|
|
|
|
|
2024-02-05 09:58:54 +00:00
|
|
|
const updateInterfaceHandler = async () => {
|
2024-02-21 20:51:52 +00:00
|
|
|
saveSettings({
|
2024-12-25 06:28:14 +00:00
|
|
|
models: [defaultModelId],
|
|
|
|
|
imageCompressionSize: imageCompressionSize
|
2024-02-21 20:51:52 +00:00
|
|
|
});
|
2024-02-05 09:58:54 +00:00
|
|
|
};
|
|
|
|
|
|
2025-02-05 08:37:47 +00:00
|
|
|
const toggleWebSearch = async () => {
|
|
|
|
|
webSearch = webSearch === null ? 'always' : null;
|
|
|
|
|
saveSettings({ webSearch: webSearch });
|
2025-01-28 17:01:46 +00:00
|
|
|
};
|
|
|
|
|
|
2024-02-05 09:58:54 +00:00
|
|
|
onMount(async () => {
|
2024-05-27 05:47:42 +00:00
|
|
|
titleAutoGenerate = $settings?.title?.auto ?? true;
|
2025-06-10 09:39:41 +00:00
|
|
|
autoTags = $settings?.autoTags ?? true;
|
|
|
|
|
autoFollowUps = $settings?.autoFollowUps ?? true;
|
2024-06-13 04:18:53 +00:00
|
|
|
|
2025-06-10 09:39:41 +00:00
|
|
|
highContrastMode = $settings?.highContrastMode ?? false;
|
2025-05-16 13:07:52 +00:00
|
|
|
|
2025-06-10 09:39:41 +00:00
|
|
|
detectArtifacts = $settings?.detectArtifacts ?? true;
|
|
|
|
|
responseAutoCopy = $settings?.responseAutoCopy ?? false;
|
2024-10-21 07:30:29 +00:00
|
|
|
|
2025-06-10 09:39:41 +00:00
|
|
|
showUsername = $settings?.showUsername ?? false;
|
|
|
|
|
showUpdateToast = $settings?.showUpdateToast ?? true;
|
|
|
|
|
showChangelog = $settings?.showChangelog ?? true;
|
2024-06-13 04:18:53 +00:00
|
|
|
|
2025-06-10 09:39:41 +00:00
|
|
|
showEmojiInCall = $settings?.showEmojiInCall ?? false;
|
|
|
|
|
voiceInterruption = $settings?.voiceInterruption ?? false;
|
2024-06-13 04:18:53 +00:00
|
|
|
|
2025-08-06 18:47:34 +00:00
|
|
|
displayMultiModelResponsesInTabs = $settings?.displayMultiModelResponsesInTabs ?? false;
|
2025-07-18 12:45:56 +00:00
|
|
|
chatFadeStreamingText = $settings?.chatFadeStreamingText ?? true;
|
|
|
|
|
|
2025-06-10 09:39:41 +00:00
|
|
|
richTextInput = $settings?.richTextInput ?? true;
|
2025-08-06 08:21:18 +00:00
|
|
|
showFormattingToolbar = $settings?.showFormattingToolbar ?? false;
|
2025-07-07 17:43:28 +00:00
|
|
|
insertPromptAsRichText = $settings?.insertPromptAsRichText ?? false;
|
2025-06-10 09:39:41 +00:00
|
|
|
promptAutocomplete = $settings?.promptAutocomplete ?? false;
|
2025-07-07 17:43:28 +00:00
|
|
|
|
2025-09-07 15:24:32 +00:00
|
|
|
insertSuggestionPrompt = $settings?.insertSuggestionPrompt ?? false;
|
2025-07-18 13:49:24 +00:00
|
|
|
keepFollowUpPrompts = $settings?.keepFollowUpPrompts ?? false;
|
|
|
|
|
insertFollowUpPrompt = $settings?.insertFollowUpPrompt ?? false;
|
|
|
|
|
|
2025-08-10 20:43:41 +00:00
|
|
|
regenerateMenu = $settings?.regenerateMenu ?? true;
|
|
|
|
|
|
2025-06-10 09:39:41 +00:00
|
|
|
largeTextAsFile = $settings?.largeTextAsFile ?? false;
|
|
|
|
|
copyFormatted = $settings?.copyFormatted ?? false;
|
2024-11-19 04:58:18 +00:00
|
|
|
|
2025-06-10 09:39:41 +00:00
|
|
|
collapseCodeBlocks = $settings?.collapseCodeBlocks ?? false;
|
|
|
|
|
expandDetails = $settings?.expandDetails ?? false;
|
2025-03-15 02:01:59 +00:00
|
|
|
|
2025-06-10 09:39:41 +00:00
|
|
|
landingPageMode = $settings?.landingPageMode ?? '';
|
|
|
|
|
chatBubble = $settings?.chatBubble ?? true;
|
|
|
|
|
widescreenMode = $settings?.widescreenMode ?? false;
|
|
|
|
|
splitLargeChunks = $settings?.splitLargeChunks ?? false;
|
|
|
|
|
scrollOnBranchChange = $settings?.scrollOnBranchChange ?? true;
|
2025-08-20 18:49:05 +00:00
|
|
|
|
|
|
|
|
temporaryChatByDefault = $settings?.temporaryChatByDefault ?? false;
|
2025-06-10 09:39:41 +00:00
|
|
|
chatDirection = $settings?.chatDirection ?? 'auto';
|
|
|
|
|
userLocation = $settings?.userLocation ?? false;
|
2024-06-05 16:14:15 +00:00
|
|
|
|
2025-04-20 06:13:19 +00:00
|
|
|
notificationSound = $settings?.notificationSound ?? true;
|
|
|
|
|
notificationSoundAlways = $settings?.notificationSoundAlways ?? false;
|
2024-12-25 20:49:24 +00:00
|
|
|
|
2025-05-10 14:59:04 +00:00
|
|
|
iframeSandboxAllowSameOrigin = $settings?.iframeSandboxAllowSameOrigin ?? false;
|
|
|
|
|
iframeSandboxAllowForms = $settings?.iframeSandboxAllowForms ?? false;
|
|
|
|
|
|
|
|
|
|
stylizedPdfExport = $settings?.stylizedPdfExport ?? true;
|
|
|
|
|
|
2025-06-10 09:39:41 +00:00
|
|
|
hapticFeedback = $settings?.hapticFeedback ?? false;
|
|
|
|
|
ctrlEnterToSend = $settings?.ctrlEnterToSend ?? false;
|
2024-08-14 15:05:43 +00:00
|
|
|
|
2025-08-06 19:28:05 +00:00
|
|
|
showFloatingActionButtons = $settings?.showFloatingActionButtons ?? true;
|
|
|
|
|
floatingActionButtons = $settings?.floatingActionButtons ?? null;
|
|
|
|
|
|
2025-06-10 09:39:41 +00:00
|
|
|
imageCompression = $settings?.imageCompression ?? false;
|
|
|
|
|
imageCompressionSize = $settings?.imageCompressionSize ?? { width: '', height: '' };
|
2025-08-06 11:11:43 +00:00
|
|
|
imageCompressionInChannels = $settings?.imageCompressionInChannels ?? true;
|
2024-12-25 06:28:14 +00:00
|
|
|
|
2024-07-10 06:43:28 +00:00
|
|
|
defaultModelId = $settings?.models?.at(0) ?? '';
|
|
|
|
|
if ($config?.default_models) {
|
|
|
|
|
defaultModelId = $config.default_models.split(',')[0];
|
|
|
|
|
}
|
2024-06-17 08:31:22 +00:00
|
|
|
|
2025-06-10 09:39:41 +00:00
|
|
|
backgroundImageUrl = $settings?.backgroundImageUrl ?? null;
|
|
|
|
|
webSearch = $settings?.webSearch ?? null;
|
2024-02-05 09:58:54 +00:00
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<ManageFloatingActionButtonsModal
|
|
|
|
|
bind:show={showManageFloatingActionButtonsModal}
|
|
|
|
|
{floatingActionButtons}
|
|
|
|
|
onSave={(buttons) => {
|
|
|
|
|
floatingActionButtons = buttons;
|
|
|
|
|
saveSettings({ floatingActionButtons });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
|
2024-02-05 09:58:54 +00:00
|
|
|
<form
|
2025-06-11 11:45:47 +00:00
|
|
|
id="tab-interface"
|
2024-02-05 09:58:54 +00:00
|
|
|
class="flex flex-col h-full justify-between space-y-3 text-sm"
|
|
|
|
|
on:submit|preventDefault={() => {
|
|
|
|
|
updateInterfaceHandler();
|
|
|
|
|
dispatch('save');
|
|
|
|
|
}}
|
|
|
|
|
>
|
2024-06-17 08:31:22 +00:00
|
|
|
<input
|
|
|
|
|
bind:this={filesInputElement}
|
|
|
|
|
bind:files={inputFiles}
|
|
|
|
|
type="file"
|
|
|
|
|
hidden
|
|
|
|
|
accept="image/*"
|
|
|
|
|
on:change={() => {
|
|
|
|
|
let reader = new FileReader();
|
|
|
|
|
reader.onload = (event) => {
|
|
|
|
|
let originalImageUrl = `${event.target.result}`;
|
|
|
|
|
|
|
|
|
|
backgroundImageUrl = originalImageUrl;
|
|
|
|
|
saveSettings({ backgroundImageUrl });
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
inputFiles &&
|
|
|
|
|
inputFiles.length > 0 &&
|
|
|
|
|
['image/gif', 'image/webp', 'image/jpeg', 'image/png'].includes(inputFiles[0]['type'])
|
|
|
|
|
) {
|
|
|
|
|
reader.readAsDataURL(inputFiles[0]);
|
|
|
|
|
} else {
|
|
|
|
|
console.log(`Unsupported File Type '${inputFiles[0]['type']}'.`);
|
|
|
|
|
inputFiles = null;
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
|
2024-11-13 06:43:18 +00:00
|
|
|
<div class=" space-y-3 overflow-y-scroll max-h-[28rem] lg:max-h-full">
|
2024-02-06 05:05:38 +00:00
|
|
|
<div>
|
2025-08-06 22:25:52 +00:00
|
|
|
<h1 class=" mb-2 text-sm font-medium">{$i18n.t('UI')}</h1>
|
2024-02-06 05:05:38 +00:00
|
|
|
|
2025-05-16 13:06:21 +00:00
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-06-16 08:51:12 +00:00
|
|
|
<div id="high-contrast-mode-label" class=" self-center text-xs">
|
2025-05-16 13:06:21 +00:00
|
|
|
{$i18n.t('High Contrast Mode')} ({$i18n.t('Beta')})
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="high-contrast-mode-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={highContrastMode}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ highContrastMode });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
<div class="py-0.5 flex w-full justify-between">
|
|
|
|
|
<div id="notification-sound-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Notification Sound')}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="notification-sound-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={notificationSound}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ notificationSound });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{#if notificationSound}
|
|
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
|
|
|
|
<div id="play-notification-sound-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Always Play Notification Sound')}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="play-notification-sound-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={notificationSoundAlways}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ notificationSoundAlways });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
{/if}
|
|
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
<div id="allow-user-location-label" class=" py-0.5 flex w-full justify-between">
|
|
|
|
|
<div class=" self-center text-xs">{$i18n.t('Allow User Location')}</div>
|
|
|
|
|
|
|
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="allow-user-location-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={userLocation}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
toggleUserLocation();
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2025-05-16 13:06:21 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2024-10-06 18:45:13 +00:00
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-08-06 22:11:16 +00:00
|
|
|
<div id="haptic-feedback-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Haptic Feedback')} ({$i18n.t('Android')})
|
2025-06-16 11:05:35 +00:00
|
|
|
</div>
|
2024-10-06 18:45:13 +00:00
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="haptic-feedback-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={hapticFeedback}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ hapticFeedback });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2024-10-06 18:45:13 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2024-05-15 22:39:41 +00:00
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-08-06 22:11:16 +00:00
|
|
|
<div id="copy-formatted-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Copy Formatted Text')}
|
2025-06-16 11:05:35 +00:00
|
|
|
</div>
|
2024-05-15 22:39:41 +00:00
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="copy-formatted-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={copyFormatted}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ copyFormatted });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2024-05-15 22:39:41 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
{#if $user?.role === 'admin'}
|
2024-06-17 08:31:22 +00:00
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-08-06 22:11:16 +00:00
|
|
|
<div id="toast-notifications-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Toast notifications for new updates')}
|
2024-06-17 08:31:22 +00:00
|
|
|
</div>
|
|
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="toast-notifications-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={showUpdateToast}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ showUpdateToast });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
|
|
|
|
<div id="whats-new-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t(`Show "What's New" modal on login`)}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="whats-new-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={showChangelog}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ showChangelog });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2024-06-17 08:31:22 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
{/if}
|
|
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class=" my-2 text-sm font-medium">{$i18n.t('Chat')}</div>
|
|
|
|
|
|
2024-06-16 22:32:26 +00:00
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-08-06 18:55:47 +00:00
|
|
|
<div id="chat-direction-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Chat direction')}
|
2025-06-16 11:05:35 +00:00
|
|
|
</div>
|
2024-06-16 22:32:26 +00:00
|
|
|
|
|
|
|
|
<button
|
2025-08-07 10:19:27 +00:00
|
|
|
aria-labelledby="chat-direction-label chat-direction-mode"
|
2025-08-06 18:55:47 +00:00
|
|
|
class="p-1 px-3 text-xs flex rounded-sm transition"
|
|
|
|
|
on:click={toggleChangeChatDirection}
|
|
|
|
|
type="button"
|
|
|
|
|
>
|
2025-08-07 10:19:27 +00:00
|
|
|
<span class="ml-2 self-center" id="chat-direction-mode">
|
|
|
|
|
{chatDirection === 'LTR'
|
|
|
|
|
? $i18n.t('LTR')
|
|
|
|
|
: chatDirection === 'RTL'
|
|
|
|
|
? $i18n.t('RTL')
|
|
|
|
|
: $i18n.t('Auto')}
|
|
|
|
|
</span>
|
2025-08-06 18:55:47 +00:00
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-08-06 22:11:16 +00:00
|
|
|
<div id="landing-page-mode-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Landing Page Mode')}
|
2025-08-06 18:55:47 +00:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<button
|
2025-08-07 10:19:27 +00:00
|
|
|
aria-labelledby="landing-page-mode-label notification-sound-state"
|
2025-02-16 03:27:25 +00:00
|
|
|
class="p-1 px-3 text-xs flex rounded-sm transition"
|
2024-06-16 22:32:26 +00:00
|
|
|
on:click={() => {
|
2025-08-06 22:11:16 +00:00
|
|
|
toggleLandingPageMode();
|
2024-06-16 22:32:26 +00:00
|
|
|
}}
|
|
|
|
|
type="button"
|
|
|
|
|
>
|
2025-08-07 10:19:27 +00:00
|
|
|
<span class="ml-2 self-center" id="notification-sound-state"
|
2025-08-11 09:59:01 +00:00
|
|
|
>{landingPageMode === '' ? $i18n.t('Default') : $i18n.t('Chat')}</span
|
2025-08-07 10:19:27 +00:00
|
|
|
>
|
2024-06-16 22:32:26 +00:00
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2024-02-06 05:05:38 +00:00
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-08-06 22:11:16 +00:00
|
|
|
<div id="chat-background-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Chat Background Image')}
|
2025-06-16 11:05:35 +00:00
|
|
|
</div>
|
2024-06-17 08:31:22 +00:00
|
|
|
|
|
|
|
|
<button
|
2025-08-07 10:19:27 +00:00
|
|
|
aria-labelledby="chat-background-label background-image-url-state"
|
2025-02-16 03:27:25 +00:00
|
|
|
class="p-1 px-3 text-xs flex rounded-sm transition"
|
2025-08-06 18:55:47 +00:00
|
|
|
on:click={() => {
|
2025-08-06 22:11:16 +00:00
|
|
|
if (backgroundImageUrl !== null) {
|
|
|
|
|
backgroundImageUrl = null;
|
|
|
|
|
saveSettings({ backgroundImageUrl });
|
|
|
|
|
} else {
|
|
|
|
|
filesInputElement.click();
|
|
|
|
|
}
|
2025-08-06 18:55:47 +00:00
|
|
|
}}
|
2024-06-17 08:31:22 +00:00
|
|
|
type="button"
|
|
|
|
|
>
|
2025-08-07 10:19:27 +00:00
|
|
|
<span class="ml-2 self-center" id="background-image-url-state"
|
|
|
|
|
>{backgroundImageUrl !== null ? $i18n.t('Reset') : $i18n.t('Upload')}</span
|
|
|
|
|
>
|
2024-06-17 08:31:22 +00:00
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2024-12-25 20:49:24 +00:00
|
|
|
<div>
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
|
|
|
|
<div id="chat-bubble-ui-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Chat Bubble UI')}
|
2024-12-25 20:49:24 +00:00
|
|
|
</div>
|
|
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
|
|
|
|
tooltip={true}
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="chat-bubble-ui-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
bind:state={chatBubble}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ chatBubble });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2024-12-25 20:49:24 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
{#if !$settings.chatBubble}
|
2025-04-20 06:13:19 +00:00
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-08-06 22:11:16 +00:00
|
|
|
<div id="chat-bubble-username-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Display the username instead of You in the Chat')}
|
2025-04-20 06:13:19 +00:00
|
|
|
</div>
|
|
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="chat-bubble-username-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={showUsername}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ showUsername });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2025-04-20 06:13:19 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
{/if}
|
|
|
|
|
|
2024-10-27 02:44:46 +00:00
|
|
|
<div>
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
|
|
|
|
<div id="widescreen-mode-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Widescreen Mode')}
|
|
|
|
|
</div>
|
2025-06-03 14:47:49 +00:00
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="widescreen-mode-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={widescreenMode}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ widescreenMode });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2025-06-03 14:47:49 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-08-20 18:49:05 +00:00
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
|
|
|
|
<div id="temp-chat-default-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Temporary Chat by Default')}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
|
|
|
|
ariaLabelledbyId="temp-chat-default-label"
|
|
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={temporaryChatByDefault}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ temporaryChatByDefault });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-06-03 14:47:49 +00:00
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-08-06 22:11:16 +00:00
|
|
|
<div id="fade-streaming-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Fade Effect for Streaming Text')}
|
2025-06-16 11:05:35 +00:00
|
|
|
</div>
|
2024-10-27 02:44:46 +00:00
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="fade-streaming-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={chatFadeStreamingText}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ chatFadeStreamingText });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2025-04-10 17:36:57 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-08-06 22:11:16 +00:00
|
|
|
<div id="auto-generation-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Title Auto-Generation')}
|
2025-04-10 17:36:57 +00:00
|
|
|
</div>
|
|
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="auto-generation-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={titleAutoGenerate}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
toggleTitleAutoGenerate();
|
2025-08-06 18:55:47 +00:00
|
|
|
}}
|
2025-08-06 22:11:16 +00:00
|
|
|
/>
|
2025-07-18 12:45:56 +00:00
|
|
|
</div>
|
2025-07-18 13:49:24 +00:00
|
|
|
</div>
|
2025-08-06 22:11:16 +00:00
|
|
|
</div>
|
2025-07-18 13:49:24 +00:00
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-08-07 10:19:27 +00:00
|
|
|
<div class=" self-center text-xs" id="follow-up-auto-generation-label">
|
|
|
|
|
{$i18n.t('Follow-Up Auto-Generation')}
|
|
|
|
|
</div>
|
2025-07-18 13:49:24 +00:00
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="follow-up-auto-generation-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={autoFollowUps}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ autoFollowUps });
|
2025-08-06 18:55:47 +00:00
|
|
|
}}
|
2025-08-06 22:11:16 +00:00
|
|
|
/>
|
2025-07-18 13:49:24 +00:00
|
|
|
</div>
|
2024-08-04 01:56:04 +00:00
|
|
|
</div>
|
2025-08-06 22:11:16 +00:00
|
|
|
</div>
|
2024-08-04 01:56:04 +00:00
|
|
|
|
2025-08-06 18:47:34 +00:00
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-08-06 22:11:16 +00:00
|
|
|
<div id="chat-tags-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Chat Tags Auto-Generation')}
|
2025-08-06 18:47:34 +00:00
|
|
|
</div>
|
|
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="chat-tags-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={autoTags}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ autoTags });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2025-08-06 18:47:34 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2024-10-26 04:31:18 +00:00
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-08-06 22:11:16 +00:00
|
|
|
<div id="auto-copy-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Auto-Copy Response to Clipboard')}
|
2025-08-06 08:21:18 +00:00
|
|
|
</div>
|
|
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="auto-copy-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={responseAutoCopy}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
toggleResponseAutoCopy();
|
2025-03-31 04:19:09 +00:00
|
|
|
}}
|
2025-08-06 22:11:16 +00:00
|
|
|
/>
|
2025-03-31 04:19:09 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2025-08-06 22:11:16 +00:00
|
|
|
</div>
|
2025-03-31 04:19:09 +00:00
|
|
|
|
2025-09-07 15:24:32 +00:00
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
|
|
|
|
<div id="insert-suggestion-prompt-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Insert Suggestion Prompt to Input')}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
|
|
|
|
ariaLabelledbyId="insert-suggestion-prompt-label"
|
|
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={insertSuggestionPrompt}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ insertSuggestionPrompt });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2024-11-19 04:58:18 +00:00
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-08-07 10:19:27 +00:00
|
|
|
<div id="keep-follow-up-prompts-label" class=" self-center text-xs">
|
2025-08-06 22:11:16 +00:00
|
|
|
{$i18n.t('Keep Follow-Up Prompts in Chat')}
|
2024-11-19 04:58:18 +00:00
|
|
|
</div>
|
|
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="keep-follow-up-prompts-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={keepFollowUpPrompts}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ keepFollowUpPrompts });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2024-11-19 04:58:18 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-04-14 08:56:15 +00:00
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-08-07 10:19:27 +00:00
|
|
|
<div id="insert-follow-up-prompt-label" class=" self-center text-xs">
|
2025-08-06 22:11:16 +00:00
|
|
|
{$i18n.t('Insert Follow-Up Prompt to Input')}
|
2025-04-14 08:56:15 +00:00
|
|
|
</div>
|
|
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="insert-follow-up-prompt-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={insertFollowUpPrompt}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ insertFollowUpPrompt });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2025-04-14 08:56:15 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-08-10 20:43:41 +00:00
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
|
|
|
|
<div id="regenerate-menu-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Regenerate Menu')}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
|
|
|
|
ariaLabelledbyId="regenerate-menu-label"
|
|
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={regenerateMenu}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ regenerateMenu });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-03-15 02:01:59 +00:00
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-08-06 22:11:16 +00:00
|
|
|
<div id="always-collapse-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Always Collapse Code Blocks')}
|
|
|
|
|
</div>
|
2025-08-06 18:55:47 +00:00
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="always-collapse-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={collapseCodeBlocks}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ collapseCodeBlocks });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2025-08-06 18:55:47 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-08-06 22:11:16 +00:00
|
|
|
<div id="always-expand-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Always Expand Details')}
|
2025-06-16 11:05:35 +00:00
|
|
|
</div>
|
2025-03-15 02:01:59 +00:00
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="always-expand-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={expandDetails}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ expandDetails });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2025-03-15 02:01:59 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-03-15 01:56:04 +00:00
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-08-06 22:11:16 +00:00
|
|
|
<div id="keep-followup-prompts-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Display Multi-model Responses in Tabs')}
|
2025-06-16 11:05:35 +00:00
|
|
|
</div>
|
2025-03-15 01:56:04 +00:00
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="keep-followup-prompts-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={displayMultiModelResponsesInTabs}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ displayMultiModelResponsesInTabs });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2025-08-06 18:55:47 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-08-06 22:11:16 +00:00
|
|
|
<div id="scroll-on-branch-change-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Scroll On Branch Change')}
|
2025-08-06 18:55:47 +00:00
|
|
|
</div>
|
|
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="scroll-on-branch-change-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={scrollOnBranchChange}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ scrollOnBranchChange });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2025-03-15 01:56:04 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2024-02-06 05:05:38 +00:00
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-08-06 22:11:16 +00:00
|
|
|
<div id="stylized-pdf-export-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Stylized PDF Export')}
|
2024-03-02 21:53:41 +00:00
|
|
|
</div>
|
2024-02-06 05:05:38 +00:00
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="stylized-pdf-export-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={stylizedPdfExport}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ stylizedPdfExport });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2024-02-06 05:05:38 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2024-02-10 00:00:39 +00:00
|
|
|
|
2024-02-15 08:34:55 +00:00
|
|
|
<div>
|
2025-08-06 18:55:47 +00:00
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-08-07 10:19:27 +00:00
|
|
|
<label id="floating-action-buttons-label" class=" self-center text-xs">
|
2025-08-08 08:17:50 +00:00
|
|
|
{$i18n.t('Floating Quick Actions')}
|
2025-08-07 10:19:27 +00:00
|
|
|
</label>
|
2024-02-15 08:34:55 +00:00
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="flex items-center gap-3 p-1">
|
|
|
|
|
{#if showFloatingActionButtons}
|
|
|
|
|
<button
|
2025-08-06 22:20:32 +00:00
|
|
|
class="text-xs text-gray-700 dark:text-gray-400 underline"
|
2025-08-06 22:11:16 +00:00
|
|
|
type="button"
|
2025-08-08 08:17:50 +00:00
|
|
|
aria-label={$i18n.t('Open Modal To Manage Floating Quick Actions')}
|
2025-08-06 22:11:16 +00:00
|
|
|
on:click={() => {
|
|
|
|
|
showManageFloatingActionButtonsModal = true;
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{$i18n.t('Manage')}
|
|
|
|
|
</button>
|
2024-10-20 03:34:17 +00:00
|
|
|
{/if}
|
|
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="floating-action-buttons-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={showFloatingActionButtons}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ showFloatingActionButtons });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
2025-04-13 00:09:39 +00:00
|
|
|
</div>
|
2024-02-15 08:34:55 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-08-06 18:55:47 +00:00
|
|
|
<div>
|
2024-06-13 04:18:53 +00:00
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-08-06 22:11:16 +00:00
|
|
|
<div id="web-search-in-chat-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Web Search in Chat')}
|
2024-06-17 08:31:22 +00:00
|
|
|
</div>
|
2024-06-13 04:18:53 +00:00
|
|
|
|
|
|
|
|
<button
|
2025-08-07 10:19:27 +00:00
|
|
|
aria-labelledby="web-search-in-chat-label web-search-state"
|
2025-02-16 03:27:25 +00:00
|
|
|
class="p-1 px-3 text-xs flex rounded-sm transition"
|
2024-06-13 04:18:53 +00:00
|
|
|
on:click={() => {
|
2025-08-06 22:11:16 +00:00
|
|
|
toggleWebSearch();
|
2024-04-21 09:45:07 +00:00
|
|
|
}}
|
|
|
|
|
type="button"
|
|
|
|
|
>
|
2025-08-07 10:19:27 +00:00
|
|
|
<span class="ml-2 self-center" id="web-search-state"
|
|
|
|
|
>{webSearch === 'always' ? $i18n.t('Always') : $i18n.t('Default')}</span
|
|
|
|
|
>
|
2024-04-21 09:45:07 +00:00
|
|
|
</button>
|
|
|
|
|
</div>
|
2025-08-06 18:55:47 +00:00
|
|
|
</div>
|
2024-02-05 09:58:54 +00:00
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class=" my-2 text-sm font-medium">{$i18n.t('Input')}</div>
|
|
|
|
|
|
2025-02-05 12:43:35 +00:00
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-08-07 10:19:27 +00:00
|
|
|
<div id="enter-key-behavior-label ctrl-enter-to-send-state" class=" self-center text-xs">
|
2025-08-06 22:11:16 +00:00
|
|
|
{$i18n.t('Enter Key Behavior')}
|
2025-02-05 12:43:35 +00:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<button
|
2025-08-06 22:11:16 +00:00
|
|
|
aria-labelledby="enter-key-behavior-label"
|
|
|
|
|
class="p-1 px-3 text-xs flex rounded transition"
|
2025-02-05 12:43:35 +00:00
|
|
|
on:click={() => {
|
2025-08-06 22:11:16 +00:00
|
|
|
togglectrlEnterToSend();
|
2025-02-05 12:43:35 +00:00
|
|
|
}}
|
|
|
|
|
type="button"
|
|
|
|
|
>
|
2025-08-07 10:19:27 +00:00
|
|
|
<span class="ml-2 self-center" id="ctrl-enter-to-send-state"
|
|
|
|
|
>{ctrlEnterToSend === true
|
|
|
|
|
? $i18n.t('Ctrl+Enter to Send')
|
|
|
|
|
: $i18n.t('Enter to Send')}</span
|
|
|
|
|
>
|
2025-02-05 12:43:35 +00:00
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2024-08-14 15:05:43 +00:00
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-08-06 22:11:16 +00:00
|
|
|
<div id="rich-input-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Rich Text Input for Chat')}
|
2024-10-27 02:44:46 +00:00
|
|
|
</div>
|
2024-08-14 15:05:43 +00:00
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
|
|
|
|
tooltip={true}
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="rich-input-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
bind:state={richTextInput}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ richTextInput });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2024-08-14 15:05:43 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
{#if richTextInput}
|
|
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-08-07 10:19:27 +00:00
|
|
|
<div id="show-formatting-toolbar-label" class=" self-center text-xs">
|
2025-08-06 22:11:16 +00:00
|
|
|
{$i18n.t('Show Formatting Toolbar')}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="show-formatting-toolbar-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={showFormattingToolbar}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ showFormattingToolbar });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2025-06-16 11:05:35 +00:00
|
|
|
</div>
|
2025-08-06 22:11:16 +00:00
|
|
|
</div>
|
2025-01-28 17:01:46 +00:00
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-08-07 10:19:27 +00:00
|
|
|
<div id="insert-prompt-as-rich-text-label" class=" self-center text-xs">
|
2025-08-06 22:11:16 +00:00
|
|
|
{$i18n.t('Insert Prompt as Rich Text')}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="insert-prompt-as-rich-text-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={insertPromptAsRichText}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ insertPromptAsRichText });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2025-08-06 18:55:47 +00:00
|
|
|
</div>
|
2025-08-06 22:11:16 +00:00
|
|
|
|
|
|
|
|
{#if $config?.features?.enable_autocomplete_generation}
|
|
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
|
|
|
|
<div id="prompt-autocompletion-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Prompt Autocompletion')}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="prompt-autocompletion-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={promptAutocomplete}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ promptAutocomplete });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
{/if}
|
|
|
|
|
{/if}
|
2025-08-06 18:55:47 +00:00
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-08-06 22:11:16 +00:00
|
|
|
<div id="paste-large-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Paste Large Text as File')}
|
2025-08-06 18:55:47 +00:00
|
|
|
</div>
|
|
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
|
|
|
|
tooltip={true}
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="paste-large-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
bind:state={largeTextAsFile}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ largeTextAsFile });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2025-01-28 17:01:46 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class=" my-2 text-sm font-medium">{$i18n.t('Artifacts')}</div>
|
|
|
|
|
|
2025-08-06 19:28:05 +00:00
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-08-06 22:11:16 +00:00
|
|
|
<div id="detect-artifacts-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Detect Artifacts Automatically')}
|
2025-08-06 19:28:05 +00:00
|
|
|
</div>
|
|
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="detect-artifacts-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={detectArtifacts}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ detectArtifacts });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2025-08-06 19:28:05 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-04-13 00:09:39 +00:00
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-06-16 11:05:35 +00:00
|
|
|
<div id="iframe-sandbox-allow-same-origin-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('iframe Sandbox Allow Same Origin')}
|
|
|
|
|
</div>
|
2025-04-13 00:09:39 +00:00
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="iframe-sandbox-allow-same-origin-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={iframeSandboxAllowSameOrigin}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ iframeSandboxAllowSameOrigin });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2025-04-13 00:09:39 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-06-16 11:05:35 +00:00
|
|
|
<div id="iframe-sandbox-allow-forms-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('iframe Sandbox Allow Forms')}
|
|
|
|
|
</div>
|
2025-04-13 00:09:39 +00:00
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="iframe-sandbox-allow-forms-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={iframeSandboxAllowForms}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ iframeSandboxAllowForms });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
2025-05-10 14:59:04 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class=" my-2 text-sm font-medium">{$i18n.t('Voice')}</div>
|
2024-05-16 20:22:30 +00:00
|
|
|
|
2024-06-22 20:21:36 +00:00
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-08-07 10:19:27 +00:00
|
|
|
<div class=" self-center text-xs" id="allow-voice-interruption-in-call-label">
|
|
|
|
|
{$i18n.t('Allow Voice Interruption in Call')}
|
|
|
|
|
</div>
|
2024-06-22 20:21:36 +00:00
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="allow-voice-interruption-in-call-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={voiceInterruption}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ voiceInterruption });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2024-06-22 20:21:36 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2024-06-17 08:31:22 +00:00
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-06-16 11:05:35 +00:00
|
|
|
<div id="display-emoji-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Display Emoji in Call')}
|
|
|
|
|
</div>
|
2024-06-05 16:14:15 +00:00
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="display-emoji-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={showEmojiInCall}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ showEmojiInCall });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2024-06-05 16:14:15 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2024-12-25 06:28:14 +00:00
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class=" my-2 text-sm font-medium">{$i18n.t('File')}</div>
|
2024-12-25 06:28:14 +00:00
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-06-16 11:05:35 +00:00
|
|
|
<div id="image-compression-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Image Compression')}
|
|
|
|
|
</div>
|
2024-12-25 06:28:14 +00:00
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="image-compression-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={imageCompression}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ imageCompression });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2024-12-25 06:28:14 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{#if imageCompression}
|
|
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between text-xs">
|
2025-06-16 11:05:35 +00:00
|
|
|
<div id="image-compression-size-label" class=" self-center text-xs">
|
|
|
|
|
{$i18n.t('Image Max Compression Size')}
|
|
|
|
|
</div>
|
2024-12-25 06:28:14 +00:00
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="p-1">
|
2025-06-16 11:05:35 +00:00
|
|
|
<label class="sr-only" for="image-comp-width"
|
|
|
|
|
>{$i18n.t('Image Max Compression Size width')}</label
|
|
|
|
|
>
|
2024-12-25 06:28:14 +00:00
|
|
|
<input
|
|
|
|
|
bind:value={imageCompressionSize.width}
|
|
|
|
|
type="number"
|
2025-08-07 10:19:27 +00:00
|
|
|
aria-labelledby="image-comp-width"
|
2025-02-16 03:27:25 +00:00
|
|
|
class="w-20 bg-transparent outline-hidden text-center"
|
2024-12-25 06:28:14 +00:00
|
|
|
min="0"
|
2025-08-14 00:15:16 +00:00
|
|
|
placeholder={$i18n.t('Width')}
|
2024-12-25 06:28:14 +00:00
|
|
|
/>x
|
2025-06-16 11:05:35 +00:00
|
|
|
<label class="sr-only" for="image-comp-height"
|
|
|
|
|
>{$i18n.t('Image Max Compression Size height')}</label
|
|
|
|
|
>
|
2024-12-25 06:28:14 +00:00
|
|
|
<input
|
|
|
|
|
bind:value={imageCompressionSize.height}
|
|
|
|
|
type="number"
|
2025-08-07 10:19:27 +00:00
|
|
|
aria-labelledby="image-comp-height"
|
2025-02-16 03:27:25 +00:00
|
|
|
class="w-20 bg-transparent outline-hidden text-center"
|
2024-12-25 06:28:14 +00:00
|
|
|
min="0"
|
2025-08-14 00:15:16 +00:00
|
|
|
placeholder={$i18n.t('Height')}
|
2024-12-25 06:28:14 +00:00
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2025-08-06 11:11:43 +00:00
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
<div class=" py-0.5 flex w-full justify-between">
|
2025-08-07 10:19:27 +00:00
|
|
|
<div id="image-compression-in-channels-label" class=" self-center text-xs">
|
2025-08-06 11:11:43 +00:00
|
|
|
{$i18n.t('Compress Images in Channels')}
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-08-06 22:11:16 +00:00
|
|
|
<div class="flex items-center gap-2 p-1">
|
|
|
|
|
<Switch
|
2025-08-07 10:19:27 +00:00
|
|
|
ariaLabelledbyId="image-compression-in-channels-label"
|
2025-08-06 22:11:16 +00:00
|
|
|
tooltip={true}
|
|
|
|
|
bind:state={imageCompressionInChannels}
|
|
|
|
|
on:change={() => {
|
|
|
|
|
saveSettings({ imageCompressionInChannels });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2025-08-06 11:11:43 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2024-12-25 06:28:14 +00:00
|
|
|
{/if}
|
2024-06-05 16:14:15 +00:00
|
|
|
</div>
|
2024-02-05 09:58:54 +00:00
|
|
|
</div>
|
|
|
|
|
|
2024-03-16 09:24:32 +00:00
|
|
|
<div class="flex justify-end text-sm font-medium">
|
2024-02-05 09:58:54 +00:00
|
|
|
<button
|
2024-10-21 07:05:27 +00:00
|
|
|
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"
|
2024-02-05 09:58:54 +00:00
|
|
|
type="submit"
|
|
|
|
|
>
|
2024-03-04 08:53:56 +00:00
|
|
|
{$i18n.t('Save')}
|
2024-02-05 09:58:54 +00:00
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</form>
|