v3 init push
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
<script>
|
||||
import appIcon from '@components/AppIcon';
|
||||
|
||||
/**
|
||||
* Account settings, saved one field at a time.
|
||||
*
|
||||
* There is no Save button on purpose: each field commits on change, the same
|
||||
* way the book itself autosaves. A language change is the one setting that
|
||||
* needs the page back to pick up the new dictionary.
|
||||
*/
|
||||
export default {
|
||||
components: {
|
||||
appIcon
|
||||
},
|
||||
emits: ['close', 'signed-out'],
|
||||
inject: ['api', 'consts', 'lang', 'user'],
|
||||
data() {
|
||||
return {
|
||||
sName: this.user.name,
|
||||
sError: '',
|
||||
sSaved: '',
|
||||
bBusy: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
languages() {
|
||||
return this.consts.languages || ['en'];
|
||||
},
|
||||
//Intl knows the zone list; older engines only know the one in use.
|
||||
timezones() {
|
||||
try {
|
||||
return Intl.supportedValuesOf('timeZone');
|
||||
}
|
||||
catch{
|
||||
return [this.user.timezone].filter((sZone) => sZone !== '');
|
||||
}
|
||||
},
|
||||
languageNames() {
|
||||
const oNames = new Intl.DisplayNames([this.lang.locale], {type: 'language'});
|
||||
return this.languages.map((sCode) => ({
|
||||
code: sCode,
|
||||
label: oNames.of(sCode) || sCode
|
||||
}));
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async set(sField, sValue) {
|
||||
this.bBusy = true;
|
||||
this.sError = '';
|
||||
this.sSaved = '';
|
||||
|
||||
try {
|
||||
const asData = await this.api.post('account', {field: sField, value: sValue});
|
||||
Object.assign(this.user, asData.user);
|
||||
this.sSaved = sField;
|
||||
|
||||
//The dictionary is baked into the page, so a new language means
|
||||
//a new page - and nothing is lost, the book is already saved.
|
||||
if(sField === 'language') window.location.reload();
|
||||
}
|
||||
catch(oError) {
|
||||
this.sError = oError.desc_lang_text || oError.message || this.lang.get('error.unexpected');
|
||||
this.sName = this.user.name;
|
||||
}
|
||||
finally {
|
||||
this.bBusy = false;
|
||||
}
|
||||
},
|
||||
saveName() {
|
||||
const sName = this.sName.trim();
|
||||
if((sName !== '') && (sName !== this.user.name)) this.set('name', sName);
|
||||
},
|
||||
async signOut() {
|
||||
this.bBusy = true;
|
||||
try {
|
||||
await this.api.post('logout');
|
||||
this.$emit('signed-out');
|
||||
}
|
||||
catch(oError) {
|
||||
this.sError = oError.desc_lang_text || oError.message;
|
||||
}
|
||||
finally {
|
||||
this.bBusy = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="veil" @click.self="$emit('close')">
|
||||
<div class="leaf leaf--wide" role="dialog" aria-modal="true">
|
||||
<div class="leaf__head">
|
||||
<h2 class="leaf__title">{{ lang.get('account.settings') }}</h2>
|
||||
<p class="leaf__sub">{{ user.email }}</p>
|
||||
</div>
|
||||
|
||||
<p v-if="sError" class="leaf__error" role="alert">{{ sError }}</p>
|
||||
|
||||
<div class="leaf__row">
|
||||
<label class="paper-label" for="set-name">{{ lang.get('account.name') }}</label>
|
||||
<input
|
||||
id="set-name"
|
||||
v-model="sName"
|
||||
class="paper-field"
|
||||
type="text"
|
||||
maxlength="100"
|
||||
:disabled="bBusy"
|
||||
@change="saveName"
|
||||
@keyup.enter="saveName"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="leaf__row">
|
||||
<label class="paper-label" for="set-lang">{{ lang.get('account.language') }}</label>
|
||||
<select
|
||||
id="set-lang"
|
||||
class="paper-field"
|
||||
:value="user.language"
|
||||
:disabled="bBusy"
|
||||
@change="set('language', $event.target.value)"
|
||||
>
|
||||
<option v-for="oLanguage in languageNames" :key="oLanguage.code" :value="oLanguage.code">
|
||||
{{ oLanguage.label }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="leaf__row">
|
||||
<label class="paper-label" for="set-tz">{{ lang.get('account.timezone') }}</label>
|
||||
<select
|
||||
id="set-tz"
|
||||
class="paper-field"
|
||||
:value="user.timezone"
|
||||
:disabled="bBusy"
|
||||
@change="set('timezone', $event.target.value)"
|
||||
>
|
||||
<option v-for="sZone in timezones" :key="sZone" :value="sZone">{{ sZone }}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="leaf__actions">
|
||||
<button type="button" class="ink-button" @click="$emit('close')">
|
||||
<appIcon icon="check" />
|
||||
<span>{{ lang.get('action.close') }}</span>
|
||||
</button>
|
||||
<button type="button" class="text-button text-button--bad" :disabled="bBusy" @click="signOut">
|
||||
<span>{{ lang.get('account.sign_out') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user