web/settings: convert LanguageDropdown to universal SettingsDropdown

This commit is contained in:
wukko 2024-10-28 21:42:07 +06:00
parent 17c020fe22
commit 3a0b0fed8b
No known key found for this signature in database
GPG key ID: 3E30B3F26C7B4AA2
3 changed files with 69 additions and 39 deletions

View file

@ -39,16 +39,14 @@
updateSetting({
[settingContext]: {
[settingId]: !isEnabled,
},
})}
}
})
}
>
<h4 class="toggle-title">{title}</h4>
<Toggle enabled={isEnabled} />
</button>
<!--
description is repeated here because there may be several toggles per settings category,
and each of them needs its own description. this is intended. don't "clean it up".
-->
{#if description}
<div class="subtext toggle-description">{description}</div>
{/if}

View file

@ -1,57 +1,69 @@
<script lang="ts">
import languages from "$i18n/languages.json";
import { t, locales } from "$lib/i18n/translations";
import settings, { updateSetting } from "$lib/state/settings";
<script
lang="ts"
generics="
Context extends Exclude<keyof CobaltSettings, 'schemaVersion'>,
Id extends keyof CobaltSettings[Context]
"
>
import { updateSetting } from "$lib/state/settings";
import type { CobaltSettings } from "$lib/types/settings";
import IconSelector from "@tabler/icons-svelte/IconSelector.svelte";
$: currentSetting = $settings.appearance.language;
$: disabled = $settings.appearance.autoLanguage;
export let title: string;
export let description: string = "";
export let items: Record<string, string>;
const updateLocale = (event: Event) => {
export let settingId: Id;
export let settingContext: Context;
export let selectedOption: string;
export let selectedTitle: string;
export let disabled = false;
const onChange = (event: Event) => {
const target = event.target as HTMLSelectElement;
updateSetting({
appearance: {
language: target.value as keyof typeof languages,
[settingContext]: {
[settingId]: target.value,
},
});
};
</script>
<div class="language-selector-parent" class:disabled aria-hidden={disabled}>
<div id="language-selector" class="selector button">
<div class="selector-parent" class:disabled aria-hidden={disabled}>
<div id="selector" class="selector button">
<div class="selector-info">
<h4 class="selector-title">
{$t("settings.language.preferred.title")}
{title}
</h4>
<div class="right-side">
<span class="selector-current" aria-hidden="true">
{$t(`languages.${currentSetting}`)}
{selectedTitle}
</span>
<IconSelector />
</div>
</div>
<select
id="setting-dropdown-appearance-language"
on:change={updateLocale}
{disabled}
>
{#each $locales as value}
<option {value} selected={currentSetting === value}>
{$t(`languages.${value}`)}
<select on:change={e => onChange(e)} {disabled}>
{#each Object.keys(items) as value}
<option {value} selected={selectedOption === value}>
{items[value]}
</option>
{/each}
</select>
</div>
<div class="subtext toggle-description">
{$t("settings.language.preferred.description")}
{#if description}
<div class="subtext">
{description}
</div>
{/if}
</div>
<style>
.language-selector-parent {
.selector-parent {
display: flex;
flex-direction: column;
gap: 10px;
@ -59,11 +71,11 @@
transition: opacity 0.2s;
}
.language-selector-parent.disabled {
.selector-parent.disabled {
opacity: 0.5;
}
#language-selector {
#selector {
display: flex;
flex-direction: row;
align-items: center;
@ -76,7 +88,7 @@
overflow: scroll;
}
.disabled #language-selector {
.disabled #selector {
pointer-events: none;
}

View file

@ -1,5 +1,6 @@
<script lang="ts">
import { t } from "$lib/i18n/translations";
import { t, locales } from "$lib/i18n/translations";
import settings from "$lib/state/settings";
import { themeOptions } from "$lib/types/settings";
@ -7,7 +8,16 @@
import SettingsButton from "$components/buttons/SettingsButton.svelte";
import SettingsToggle from "$components/buttons/SettingsToggle.svelte";
import SettingsCategory from "$components/settings/SettingsCategory.svelte";
import LanguageDropdown from "$components/settings/LanguageDropdown.svelte";
import SettingsDropdown from "$components/settings/SettingsDropdown.svelte";
const dropdownItems = () => {
return $locales.reduce((obj, lang) => {
return {
...obj,
[lang]: $t(`languages.${lang}`),
};
}, {});
};
</script>
<SettingsCategory sectionId="theme" title={$t("settings.theme")}>
@ -31,7 +41,17 @@
title={$t("settings.language.auto.title")}
description={$t("settings.language.auto.description")}
/>
<LanguageDropdown />
<SettingsDropdown
title={$t("settings.language.preferred.title")}
description={$t("settings.language.preferred.description")}
items={dropdownItems()}
settingContext="appearance"
settingId="language"
selectedOption={$settings.appearance.language}
selectedTitle={$t(`languages.${$settings.appearance.language}`)}
disabled={$settings.appearance.autoLanguage}
/>
</SettingsCategory>
<SettingsCategory