mirror of
https://github.com/wukko/cobalt.git
synced 2024-11-15 12:50:01 +00:00
web/settings: convert LanguageDropdown
to universal SettingsDropdown
This commit is contained in:
parent
17c020fe22
commit
3a0b0fed8b
3 changed files with 69 additions and 39 deletions
|
@ -39,16 +39,14 @@
|
||||||
updateSetting({
|
updateSetting({
|
||||||
[settingContext]: {
|
[settingContext]: {
|
||||||
[settingId]: !isEnabled,
|
[settingId]: !isEnabled,
|
||||||
},
|
}
|
||||||
})}
|
})
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<h4 class="toggle-title">{title}</h4>
|
<h4 class="toggle-title">{title}</h4>
|
||||||
<Toggle enabled={isEnabled} />
|
<Toggle enabled={isEnabled} />
|
||||||
</button>
|
</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}
|
{#if description}
|
||||||
<div class="subtext toggle-description">{description}</div>
|
<div class="subtext toggle-description">{description}</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -1,57 +1,69 @@
|
||||||
<script lang="ts">
|
<script
|
||||||
import languages from "$i18n/languages.json";
|
lang="ts"
|
||||||
|
generics="
|
||||||
import { t, locales } from "$lib/i18n/translations";
|
Context extends Exclude<keyof CobaltSettings, 'schemaVersion'>,
|
||||||
import settings, { updateSetting } from "$lib/state/settings";
|
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";
|
import IconSelector from "@tabler/icons-svelte/IconSelector.svelte";
|
||||||
|
|
||||||
$: currentSetting = $settings.appearance.language;
|
export let title: string;
|
||||||
$: disabled = $settings.appearance.autoLanguage;
|
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;
|
const target = event.target as HTMLSelectElement;
|
||||||
|
|
||||||
updateSetting({
|
updateSetting({
|
||||||
appearance: {
|
[settingContext]: {
|
||||||
language: target.value as keyof typeof languages,
|
[settingId]: target.value,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="language-selector-parent" class:disabled aria-hidden={disabled}>
|
<div class="selector-parent" class:disabled aria-hidden={disabled}>
|
||||||
<div id="language-selector" class="selector button">
|
<div id="selector" class="selector button">
|
||||||
<div class="selector-info">
|
<div class="selector-info">
|
||||||
<h4 class="selector-title">
|
<h4 class="selector-title">
|
||||||
{$t("settings.language.preferred.title")}
|
{title}
|
||||||
</h4>
|
</h4>
|
||||||
<div class="right-side">
|
<div class="right-side">
|
||||||
<span class="selector-current" aria-hidden="true">
|
<span class="selector-current" aria-hidden="true">
|
||||||
{$t(`languages.${currentSetting}`)}
|
{selectedTitle}
|
||||||
</span>
|
</span>
|
||||||
<IconSelector />
|
<IconSelector />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<select
|
|
||||||
id="setting-dropdown-appearance-language"
|
<select on:change={e => onChange(e)} {disabled}>
|
||||||
on:change={updateLocale}
|
{#each Object.keys(items) as value}
|
||||||
{disabled}
|
<option {value} selected={selectedOption === value}>
|
||||||
>
|
{items[value]}
|
||||||
{#each $locales as value}
|
|
||||||
<option {value} selected={currentSetting === value}>
|
|
||||||
{$t(`languages.${value}`)}
|
|
||||||
</option>
|
</option>
|
||||||
{/each}
|
{/each}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="subtext toggle-description">
|
|
||||||
{$t("settings.language.preferred.description")}
|
{#if description}
|
||||||
|
<div class="subtext">
|
||||||
|
{description}
|
||||||
</div>
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.language-selector-parent {
|
.selector-parent {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
|
@ -59,11 +71,11 @@
|
||||||
transition: opacity 0.2s;
|
transition: opacity 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.language-selector-parent.disabled {
|
.selector-parent.disabled {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
#language-selector {
|
#selector {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -76,7 +88,7 @@
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
.disabled #language-selector {
|
.disabled #selector {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<script lang="ts">
|
<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";
|
import { themeOptions } from "$lib/types/settings";
|
||||||
|
|
||||||
|
@ -7,7 +8,16 @@
|
||||||
import SettingsButton from "$components/buttons/SettingsButton.svelte";
|
import SettingsButton from "$components/buttons/SettingsButton.svelte";
|
||||||
import SettingsToggle from "$components/buttons/SettingsToggle.svelte";
|
import SettingsToggle from "$components/buttons/SettingsToggle.svelte";
|
||||||
import SettingsCategory from "$components/settings/SettingsCategory.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>
|
</script>
|
||||||
|
|
||||||
<SettingsCategory sectionId="theme" title={$t("settings.theme")}>
|
<SettingsCategory sectionId="theme" title={$t("settings.theme")}>
|
||||||
|
@ -31,7 +41,17 @@
|
||||||
title={$t("settings.language.auto.title")}
|
title={$t("settings.language.auto.title")}
|
||||||
description={$t("settings.language.auto.description")}
|
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>
|
||||||
|
|
||||||
<SettingsCategory
|
<SettingsCategory
|
||||||
|
|
Loading…
Reference in a new issue