#258 update names, flags, links, age for all languages

This commit is contained in:
Andrea 2021-12-14 18:38:53 +01:00
parent a936b00f4b
commit 961de266e5
18 changed files with 199 additions and 66 deletions

View File

@ -12,7 +12,7 @@
<div class="row flex-row-reverse">
<div class="col-12 col-md-4">
<div class="btn-group-vertical w-100 mb-3">
<SocialLogin v-for="(providerOptions, provider) in socialProviders"
<SocialLogin v-for="(providerOptions, provider) in socialProviders" :key="provider"
:provider="provider" :options="providerOptions"/>
</div>
</div>

View File

@ -0,0 +1,37 @@
<template>
<div v-if="hasChanges" class="form-check form-switch my-2">
<label>
<input class="form-check-input" type="checkbox" v-model="propagate">
<T>profile.editor.propagate</T>
</label>
</div>
</template>
<script>
export default {
props: {
field: { required: true },
before: { required: true },
after: { required: true },
},
data() {
return {
propagate: false,
}
},
computed: {
hasChanges() {
return JSON.stringify(this.before) !== JSON.stringify(this.after);
}
},
methods: {
emit() {
this.$emit('change', this.field, this.hasChanges && this.propagate);
},
},
watch: {
hasChanges() { this.emit(); },
propagate() { this.emit(); },
}
}
</script>

View File

@ -551,6 +551,7 @@ profile:
header: 'Card editor'
save: 'Save your card'
defaults: 'Restore defaults'
propagate: 'Propagate this change to your cards in all languages'
opinion:
yes: 'Yes'
jokingly: 'Jokingly'

View File

@ -443,6 +443,7 @@ profile:
header: 'Visitenkarte-Editor'
save: 'Visitenkarte speichern'
defaults: 'Standardwerte wiederherstellen'
propagate: 'Propagate this change to your cards in all languages' # TODO
opinion:
yes: 'Ja'
jokingly: 'Scherzhaft'

View File

@ -552,6 +552,7 @@ profile:
header: 'Card editor'
save: 'Save your card'
defaults: 'Restore defaults'
propagate: 'Propagate this change to your cards in all languages'
opinion:
yes: 'Yes'
jokingly: 'Jokingly'

View File

@ -456,6 +456,7 @@ profile:
header: 'Editor de tarjetas'
save: 'Guarda tu tarjeta'
defaults: 'Restaurar valores predeterminados'
propagate: 'Propagate this change to your cards in all languages' # TODO
opinion:
yes: 'Sí'
jokingly: 'En broma'

View File

@ -449,6 +449,7 @@ profile:
header: 'Éditeur de carte'
save: 'Sauvegarder votre carte'
defaults: 'Restaurer les valeurs par défaut'
propagate: 'Propagate this change to your cards in all languages' # TODO
opinion:
yes: 'Oui'
jokingly: 'Pour plaisanter'

View File

@ -455,6 +455,7 @@ profile:
header: 'Editor de cartões'
save: 'Salve o cartão'
defaults: 'Restaurar valores padrão'
propagate: 'Propagate this change to your cards in all languages' # TODO
opinion:
yes: 'Sim'
jokingly: 'É brincadeira'

View File

@ -457,6 +457,7 @@ profile:
header: 'カード編集'
save: 'カード保存'
defaults: '既定に復元'
propagate: 'Propagate this change to your cards in all languages' # TODO
opinion:
yes: '好き'
jokingly: '冗談っぽく'

View File

@ -449,6 +449,7 @@ profile:
header: 'Kaart editor'
save: 'Sla jouw kaart op'
defaults: 'Zet terug naar standaardwaarden'
propagate: 'Propagate this change to your cards in all languages' # TODO
opinion:
yes: 'Ja'
jokingly: 'Voor de grap'

View File

@ -453,6 +453,7 @@ profile:
header: 'Kort redigerer'
save: 'Lagre kort'
defaults: 'Restaurer originale'
propagate: 'Propagate this change to your cards in all languages' # TODO
opinion:
yes: 'Ja'
jokingly: 'På tull'

View File

@ -1245,6 +1245,7 @@ profile:
header: 'Edytor wizytówki'
save: 'Zapisz wizytówkę'
defaults: 'Przywróć domyślne'
propagate: 'Zapisz tę zmianę we wszystkich swoich wizytówkach, w każdym języku'
opinion:
yes: 'Tak'
jokingly: 'Żartobliwie'

View File

@ -451,6 +451,7 @@ profile:
header: 'Editor de cartões'
save: 'Salve o cartão'
defaults: 'Restaurar valores padrão'
propagate: 'Propagate this change to your cards in all languages' # TODO
opinion:
yes: 'Sim'
jokingly: 'É brincadeira'
@ -626,7 +627,7 @@ terms:
Oi! Lhe escrevemos para informar que atualizámos nossos termos de serviço.
changes:
- >
Em janeiro vamos começar a vamos deletar em breve as contas não usadas para previr a acumulação dos nomes
Em janeiro vamos começar a vamos deletar em breve as contas não usadas para previr a acumulação dos nomes
(quando não há nem carta nem entrada por um mês).
- >
Gostávamos de oferecer um espaço seguro para toda a gente queer independentemente de sua idade
@ -640,7 +641,7 @@ terms:
Todas estas traduções são auxiliares, a versão inglesa continua sendo a única juricamente vinculativa.
- >
Apesar de queerfobia, transfobia, exclusionismo queer e trolling
sempre terem sido compreendidos como infrangimentos de Termos de Serviço como «infringir as regras sociais»,
sempre terem sido compreendidos como infrangimentos de Termos de Serviço como «infringir as regras sociais»,
daqui por diante enlistamos todas elas como proibidas.
admin:

View File

@ -482,6 +482,7 @@ profile:
header: 'Редактор карточек'
save: 'Сохранить Вашу карточку'
defaults: 'Вернуть слова по умолчанию'
propagate: 'Propagate this change to your cards in all languages' # TODO
opinion:
yes: 'Да'
jokingly: 'В шутку'

View File

@ -456,6 +456,7 @@ profile:
header: 'רעדאַקציע פון די װיזיט־⁠קאַרטל'
save: 'Save your card'
defaults: 'Restore defaults' # TODO
propagate: 'Propagate this change to your cards in all languages' # TODO
opinion:
yes: 'יאָ'
jokingly: 'אין אַ שפּאַס'

View File

@ -435,6 +435,7 @@ profile:
header: '卡編輯'
save: '保存卡'
defaults: 'Restore defaults' # TODO
propagate: 'Propagate this change to your cards in all languages' # TODO
opinion:
yes: '至愛'
jokingly: '諧謔'

View File

@ -30,6 +30,7 @@
<div class="form-group">
<label for="teamName">Team page display name:</label>
<input class="form-control" name="teamName" maxlength="36" v-model="teamName"/>
<PropagateCheckbox field="teamName" :before="beforeChanges.teamName" :after="teamName" v-if="otherProfiles > 0" @change="propagateChanged"/>
</div>
<hr/>
@ -44,6 +45,7 @@
<div class="form-group">
<label for="footerName">Footer display name:</label>
<input class="form-control" name="footerName" maxlength="36" v-model="footerName"/>
<PropagateCheckbox field="footerName" :before="beforeChanges.footerName" :after="footerName" v-if="otherProfiles > 0" @change="propagateChanged"/>
</div>
<div class="form-group">
@ -96,6 +98,7 @@
<T>profile.names</T>
</h3>
<OpinionListInput v-model="names"/>
<PropagateCheckbox field="names" :before="beforeChanges.names" :after="names" v-if="otherProfiles > 0" @change="propagateChanged"/>
</section>
<section class="form-group">
@ -131,6 +134,7 @@
<ButtonList v-model="flags" :options="allFlags" v-slot="s">
<Flag :name="s.desc.split('|')[0]" :alt="s.desc.split('|')[1]" :img="`/flags/${s.v}.png`"/>
</ButtonList>
<PropagateCheckbox field="flags" :before="beforeChanges.flags" :after="flags" v-if="otherProfiles > 0" @change="propagateChanged"/>
<details class="form-group border rounded" :open="Object.keys(customFlags).length > 0">
<summary class="px-3 py-2">
@ -140,7 +144,7 @@
<ImageWidgetRich v-model="customFlags" sizes="flag"/>
</div>
</details>
<PropagateCheckbox field="customFlags" :before="beforeChanges.customFlags" :after="customFlags" v-if="otherProfiles > 0" @change="propagateChanged"/>
<Answer question="flags" small/>
</section>
@ -152,6 +156,7 @@
<ListInput v-model="links" v-slot="s">
<input v-model="s.val" type="url" class="form-control" @keyup="s.update(s.val)" @paste="s.update(s.val)" @change="s.update(s.val)" required/>
</ListInput>
<PropagateCheckbox field="links" :before="beforeChanges.links" :after="links" v-if="otherProfiles > 0" @change="propagateChanged"/>
<p class="small text-muted mb-0">
<Icon v="ad"/>
<T>profile.linksRecommended</T>
@ -179,6 +184,7 @@
<div class="input-group mb-3">
<datepicker v-model="birthday" inline :disabled-dates="disabledDates" initial-view="year"/>
</div>
<PropagateCheckbox field="birthday" :before="beforeChanges.birthday" :after="birthday" v-if="otherProfiles > 0" @change="propagateChanged"/>
</section>
<section class="form-group">
@ -223,6 +229,73 @@
}
}))
const buildProfile = (profiles, currentLocale) => {
for (let locale in profiles) {
if (!profiles.hasOwnProperty(locale)) {
continue;
}
if (locale === currentLocale) {
const profile = profiles[locale];
return {
names: dictToList(profile.names),
pronouns: dictToList(profile.pronouns),
description: profile.description,
birthday: profile.birthday,
links: Object.keys(profile.links).length ? profile.links : [],
flags: profile.flags,
customFlags: profile.customFlags,
words: profile.words.map(x => dictToList(x)),
teamName: profile.teamName,
footerName: profile.footerName,
footerAreas: profile.footerAreas,
credentials: profile.credentials,
credentialsLevel: profile.credentialsLevel,
credentialsName: profile.credentialsName,
};
}
}
for (let locale in profiles) {
if (!profiles.hasOwnProperty(locale)) {
continue;
}
const profile = profiles[locale];
return {
names: dictToList(profile.names),
pronouns: [],
description: '',
birthday: profile.birthday,
links: Object.keys(profile.links).length ? profile.links : [],
flags: profile.flags.filter(f => !f.startsWith('-')),
customFlags: profile.customFlags,
words: [...defaultWords],
teamName: profile.teamName,
footerName: profile.footerName,
footerAreas: [],
credentials: [],
credentialsLevel: null,
credentialsName: null,
};
}
return {
names: [],
pronouns: [],
description: '',
birthday: null,
links: [],
flags: [],
customFlags: {},
words: [...defaultWords],
teamName: '',
footerName: '',
footerAreas: [],
credentials: [],
credentialsLevel: null,
credentialsName: null,
};
};
export default {
mixins: [link],
data() {
@ -232,6 +305,7 @@
to: minBirthdate,
from: maxBirthdate,
},
propagate: [],
};
},
async asyncData({ app, store }) {
@ -243,69 +317,12 @@
authorization: 'Bearer ' + store.state.token,
} })).profiles;
for (let locale in profiles) {
if (!profiles.hasOwnProperty(locale)) {
continue;
}
if (locale === app.context.env.LOCALE) {
const profile = profiles[locale];
return {
names: dictToList(profile.names),
pronouns: dictToList(profile.pronouns),
description: profile.description,
birthday: profile.birthday,
links: Object.keys(profile.links).length ? profile.links : [],
flags: profile.flags,
customFlags: profile.customFlags,
words: profile.words.map(x => dictToList(x)),
teamName: profile.teamName,
footerName: profile.footerName,
footerAreas: profile.footerAreas,
credentials: profile.credentials,
credentialsLevel: profile.credentialsLevel,
credentialsName: profile.credentialsName,
};
}
}
for (let locale in profiles) {
if (!profiles.hasOwnProperty(locale)) {
continue;
}
const profile = profiles[locale];
return {
names: dictToList(profile.names),
pronouns: [],
description: '',
birthday: profile.birthday,
links: Object.keys(profile.links).length ? profile.links : [],
flags: profile.flags.filter(f => !f.startsWith('-')),
customFlags: profile.customFlags,
words: [...defaultWords],
teamName: profile.teamName,
footerName: profile.footerName,
footerAreas: [],
credentials: [],
credentialsLevel: null,
credentialsName: null,
};
}
const profile = buildProfile(profiles, app.context.env.LOCALE);
return {
names: [],
pronouns: [],
description: '',
birthday: null,
links: [],
flags: [],
customFlags: {},
words: [...defaultWords],
teamName: '',
footerName: '',
footerAreas: [],
credentials: [],
credentialsLevel: null,
credentialsName: null,
...profile,
beforeChanges: JSON.parse(JSON.stringify(profile)),
otherProfiles: Object.keys(profiles).filter(l => l !== app.context.env.LOCALE).length,
};
},
mounted() {
@ -327,12 +344,15 @@
flags: [...this.flags],
customFlags: {...this.customFlags},
words: this.words.map(x => listToDict(x)),
teamName: this.teamName,
footerName: this.footerName,
footerAreas: this.footerAreas,
credentials: this.credentials,
credentialsLevel: this.credentialsLevel,
credentialsName: this.credentialsName,
propagate: this.propagate,
});
this.$router.push(`/@${this.$user().username}`);
} finally {
@ -365,7 +385,13 @@
await this.$confirm();
this.words = [...defaultWords];
}
},
propagateChanged(field, checked) {
this.propagate = this.propagate.filter(f => f !== field);
if (checked) {
this.propagate.push(field);
}
},
},
computed: {
mainPronoun() {

View File

@ -200,6 +200,62 @@ router.post('/profile/save', handleErrorAsync(async (req, res) => {
)`);
}
if ((req.body.propagate || []).includes('teamName')) {
await req.db.get(SQL`UPDATE profiles
SET teamName = ${req.isGranted() ? req.body.teamName || null : ''}
WHERE userId = ${req.user.id} AND teamName != '' AND teamName IS NOT NULL;
`);
}
if ((req.body.propagate || []).includes('footerName')) {
await req.db.get(SQL`UPDATE profiles
SET footerName = ${req.isGranted() ? req.body.footerName || null : ''}
WHERE userId = ${req.user.id} AND footerName != '' AND footerName IS NOT NULL;
`);
}
if ((req.body.propagate || []).includes('names')) {
await req.db.get(SQL`UPDATE profiles
SET names = ${JSON.stringify(req.body.names)}
WHERE userId = ${req.user.id};
`);
}
if ((req.body.propagate || []).includes('flags')) {
await req.db.get(SQL`UPDATE profiles
SET flags = ${JSON.stringify(req.body.flags)}
WHERE userId = ${req.user.id};
`);
}
if ((req.body.propagate || []).includes('customFlags')) {
await req.db.get(SQL`UPDATE profiles
customFlags = ${JSON.stringify(req.body.customFlags)}
WHERE userId = ${req.user.id};
`);
}
if ((req.body.propagate || []).includes('links')) {
await req.db.get(SQL`UPDATE profiles
SET links = ${JSON.stringify(req.body.links.filter(x => !!x))}
WHERE userId = ${req.user.id};
`);
}
if ((req.body.propagate || []).includes('links')) {
await req.db.get(SQL`UPDATE profiles
SET links = ${JSON.stringify(req.body.links.filter(x => !!x))}
WHERE userId = ${req.user.id};
`);
}
if ((req.body.propagate || []).includes('birthday')) {
await req.db.get(SQL`UPDATE profiles
SET birthday = ${sanitiseBirthday(req.body.birthday || null)}
WHERE userId = ${req.user.id};
`);
}
const sus = [...isSuspicious(req.body)];
if (sus.length && !await hasAutomatedReports(req.db, req.user.id)) {
await req.db.get(SQL`