More things
This commit is contained in:
@@ -1,14 +1,16 @@
|
||||
<script setup lang="ts">
|
||||
/* Centered profile popup, opened by the account row in the sidebar (and closed
|
||||
with esc, a backdrop click, or navigation — the same shape as the settings
|
||||
popup). It holds the account itself: the profile picture, the username and
|
||||
the password, and the way out. */
|
||||
popup). It holds the account itself: the profile picture, the username, the
|
||||
password, the interface language the account reads the wiki in, and the
|
||||
way out. */
|
||||
const { open, hide } = useProfileMenu()
|
||||
const { hide: hideSearch } = useSearch()
|
||||
const { hide: hideSettings } = useSettings()
|
||||
const { hide: hideSignIn, show: openSignIn } = useSignInPopup()
|
||||
const { user, signOut, updateUsername, changePassword, setAvatar } = useAuth()
|
||||
const { t } = useI18n()
|
||||
const { user, signOut, updateUsername, changePassword, setAvatar, updateLocale } = useAuth()
|
||||
const { t, locale } = useI18n()
|
||||
const { choose } = useAppLocale()
|
||||
const route = useRoute()
|
||||
|
||||
const panelEl = ref<HTMLElement | null>(null)
|
||||
@@ -166,6 +168,24 @@ function leave() {
|
||||
hide()
|
||||
}
|
||||
|
||||
/* --- the interface language ---
|
||||
Turn the language Mathew speaks in. The device's own choice (the cookie
|
||||
setLocale keeps) lands at once, and the account saves it too, so the next
|
||||
device says the same hello. An account that won't take it — a session gone
|
||||
quiet — doesn't undo the switch made here. */
|
||||
const language = ref('en')
|
||||
|
||||
async function setLanguage(code: string) {
|
||||
if (language.value === code) return
|
||||
language.value = code
|
||||
await choose(code)
|
||||
try {
|
||||
await updateLocale(code)
|
||||
} catch {
|
||||
/* the device-level switch stands on its own */
|
||||
}
|
||||
}
|
||||
|
||||
/* sync the form from the account whenever the popup opens */
|
||||
watch(
|
||||
open,
|
||||
@@ -178,6 +198,7 @@ watch(
|
||||
username.value = user.value?.username ?? ''
|
||||
currentPassword.value = ''
|
||||
newPassword.value = ''
|
||||
language.value = locale.value
|
||||
avatarBusy.value = false
|
||||
avatarError.value = ''
|
||||
nameError.value = ''
|
||||
@@ -340,6 +361,30 @@ watch(
|
||||
<p v-else-if="passwordSaved" class="profile-saved">{{ t('profile.passwordChanged') }}</p>
|
||||
</section>
|
||||
|
||||
<!-- the interface language -->
|
||||
<section class="profile-group" aria-labelledby="profile-language">
|
||||
<div class="profile-group-head">
|
||||
<span id="profile-language" class="profile-group-title">{{ t('profile.language') }}</span>
|
||||
<span class="profile-group-hint">{{ t('profile.languageHint') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="theme-switch" role="radiogroup" :aria-label="t('profile.languageAria')">
|
||||
<button
|
||||
v-for="l in APP_LANGUAGES"
|
||||
:key="l.code"
|
||||
type="button"
|
||||
role="radio"
|
||||
class="theme-option"
|
||||
:class="{ active: language === l.code }"
|
||||
:aria-checked="language === l.code"
|
||||
:lang="l.code"
|
||||
@click="setLanguage(l.code)"
|
||||
>
|
||||
<span>{{ l.name }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="profile-group">
|
||||
<button type="button" class="btn btn-danger btn-sm profile-signout" @click="leave()">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
|
||||
Reference in New Issue
Block a user