reorganization of some settings

This commit is contained in:
Henry Jameson 2025-08-04 13:48:09 +03:00
commit 800ab90cf9
9 changed files with 113 additions and 121 deletions

View file

@ -2,6 +2,7 @@
<div class="interface-language-switcher">
<label>
{{ promptText }}
<ProfileSettingIndicator :is-profile="profile" />
</label>
<ul class="setting-list">
<li
@ -46,12 +47,15 @@
<script>
import localeService from '../../services/locale/locale.service.js'
import Select from '../select/select.vue'
import ProfileSettingIndicator from 'src/components/settings_modal/helpers/profile_setting_indicator.vue'
export default {
components: {
// eslint-disable-next-line vue/no-reserved-component-names
Select
Select,
ProfileSettingIndicator
},
props: {
promptText: {
@ -62,11 +66,12 @@ export default {
type: [Array, String],
required: true
},
setLanguage: {
type: Function,
required: true
profile: {
type: Boolean,
default: false
}
},
emits: ['update'],
computed: {
languages () {
return localeService.languages
@ -77,7 +82,7 @@ export default {
return Array.isArray(this.language) ? this.language : [this.language]
},
set: function (val) {
this.setLanguage(val)
this.$emit('update', val)
}
}
},

View file

@ -10,8 +10,8 @@ import InterfaceLanguageSwitcher from 'src/components/interface_language_switche
import Select from 'src/components/select/select.vue'
import SharedComputedObject from '../helpers/shared_computed_object.js'
import ProfileSettingIndicator from '../helpers/profile_setting_indicator.vue'
import localeService from 'src/services/locale/locale.service.js'
import { clearCache, cacheKey, emojiCacheKey } from 'src/services/sw/sw.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
@ -77,7 +77,6 @@ const GeneralTab = {
UnitSetting,
InterfaceLanguageSwitcher,
ScopeSelector,
ProfileSettingIndicator,
Select
},
computed: {
@ -122,7 +121,19 @@ const GeneralTab = {
},
clearEmojiCache () {
this.clearCache(emojiCacheKey)
}
},
updateProfile () {
const params = {
language: localeService.internalToBackendLocaleMulti(this.emailLanguage)
}
this.$store.state.api.backendInteractor
.updateProfile({ params })
.then((user) => {
this.$store.commit('addNewUsers', [user])
this.$store.commit('setCurrentUser', user)
})
},
}
}

View file

@ -7,7 +7,15 @@
<interface-language-switcher
:prompt-text="$t('settings.interfaceLanguage')"
:language="language"
:set-language="val => language = val"
@update="val => language = val"
/>
</li>
<li>
<interface-language-switcher
:prompt-text="$t('settings.email_language')"
:language="emailLanguage"
:profile="true"
@update="val => { emailLanguage = val; updateProfile() }"
/>
</li>
<li v-if="instanceSpecificPanelPresent">

View file

@ -1,5 +1,3 @@
import unescape from 'lodash/unescape'
import merge from 'lodash/merge'
import UserCard from 'src/components/user_card/user_card.vue'
import ImageCropper from 'src/components/image_cropper/image_cropper.vue'
import ScopeSelector from 'src/components/scope_selector/scope_selector.vue'
@ -12,7 +10,8 @@ import InterfaceLanguageSwitcher from 'src/components/interface_language_switche
import Select from 'src/components/select/select.vue'
import BooleanSetting from '../helpers/boolean_setting.vue'
import SharedComputedObject from '../helpers/shared_computed_object.js'
import localeService from 'src/services/locale/locale.service.js'
import ProfileSettingIndicator from '../helpers/profile_setting_indicator.vue'
import { propsToNative } from 'src/services/attributes_helper/attributes_helper.service.js'
import { library } from '@fortawesome/fontawesome-svg-core'
@ -32,20 +31,8 @@ library.add(
const ProfileTab = {
data () {
return {
newName: this.$store.state.users.currentUser.name_unescaped,
newBio: unescape(this.$store.state.users.currentUser.description),
newLocked: this.$store.state.users.currentUser.locked,
newBirthday: this.$store.state.users.currentUser.birthday,
showBirthday: this.$store.state.users.currentUser.show_birthday,
newFields: this.$store.state.users.currentUser.fields.map(field => ({ name: field.name, value: field.value })),
showRole: this.$store.state.users.currentUser.show_role,
role: this.$store.state.users.currentUser.role,
bot: this.$store.state.users.currentUser.bot,
actorType: this.$store.state.users.currentUser.actor_type,
bannerUploading: false,
locked: this.$store.state.users.currentUser.locked,
backgroundUploading: false,
banner: null,
bannerPreview: null,
background: null,
backgroundPreview: null,
emailLanguage: this.$store.state.users.currentUser.language || ['']
@ -60,6 +47,7 @@ const ProfileTab = {
Checkbox,
BooleanSetting,
InterfaceLanguageSwitcher,
ProfileSettingIndicator,
Select
},
computed: {
@ -91,41 +79,8 @@ const ProfileTab = {
const src = this.$store.state.users.currentUser.cover_photo
return (!src) ? this.defaultBanner : src
},
groupActorAvailable () {
return this.$store.state.instance.groupActorAvailable
},
availableActorTypes () {
return this.groupActorAvailable ? ['Person', 'Service', 'Group'] : ['Person', 'Service']
}
},
methods: {
updateProfile () {
const params = {
note: this.newBio,
locked: this.newLocked,
// Backend notation.
display_name: this.newName,
fields_attributes: this.newFields.filter(el => el != null),
actor_type: this.actorType,
show_role: this.showRole,
birthday: this.newBirthday || '',
show_birthday: this.showBirthday
}
if (this.emailLanguage) {
params.language = localeService.internalToBackendLocaleMulti(this.emailLanguage)
}
this.$store.state.api.backendInteractor
.updateProfile({ params })
.then((user) => {
this.newFields.splice(user.fields.length)
merge(this.newFields, user.fields)
this.$store.commit('addNewUsers', [user])
this.$store.commit('setCurrentUser', user)
})
},
changeVis (visibility) {
this.newDefaultScope = visibility
},
@ -177,9 +132,29 @@ const ProfileTab = {
.catch(this.displayUploadError)
.finally(() => { this.backgroundUploading = false })
},
updateProfile () {
const params = {
locked: this.locked
}
this.$store.state.api.backendInteractor
.updateProfile({ params })
.then((user) => {
this.$store.commit('addNewUsers', [user])
this.$store.commit('setCurrentUser', user)
})
.catch((error) => {
this.displayUploadError(error)
})
},
propsToNative (props) {
return propsToNative(props)
}
},
watch: {
locked () {
this.updateProfile()
}
}
}

View file

@ -5,57 +5,8 @@
:editable="true"
:switcher="false"
rounded="top"
>
<template v-if="role === 'admin' || role === 'moderator'">
<h4>{{ $t('settings.show_labels') }}</h4>
<p class="user-card-setting">
<Checkbox v-model="showRole">
<template v-if="role === 'admin'">
{{ $t('settings.show_admin_badge') }}
</template>
<template v-if="role === 'moderator'">
{{ $t('settings.show_moderator_badge') }}
</template>
</Checkbox>
</p>
</template>
<h4>{{ $t('settings.user_type') }}</h4>
<p class="user-card-setting">
<label>
{{ $t('settings.actor_type') }}
<Select v-model="actorType">
<option
v-for="option in availableActorTypes"
:key="option"
:value="option"
>
{{ $t('settings.actor_type_' + option) }}
</option>
</Select>
<div v-if="groupActorAvailable">
<small>
{{ $t('settings.actor_type_description') }}
</small>
</div>
</label>
</p>
</UserCard>
<div class="setting-item">
<p>
<interface-language-switcher
:prompt-text="$t('settings.email_language')"
:language="emailLanguage"
:set-language="val => emailLanguage = val"
/>
</p>
<button
:disabled="newName && newName.length === 0"
class="btn button-default"
@click="updateProfile"
>
{{ $t('settings.save') }}
</button>
</div>
</UserCard>
<div class="setting-item">
<h2>{{ $t('settings.profile_background') }}</h2>
<div class="banner-background-preview">
@ -103,12 +54,10 @@
<h2>{{ $t('settings.account_privacy') }}</h2>
<ul class="setting-list">
<li>
<BooleanSetting
source="profile"
path="locked"
>
<Checkbox v-model="locked">
{{ $t('settings.lock_account_description') }}
</BooleanSetting>
</Checkbox>
<ProfileSettingIndicator :is-profile="true" />
</li>
<li>
<BooleanSetting

View file

@ -115,7 +115,6 @@ export default {
newCoverPhoto: user.cover_photo,
newFields: user.fields.map(field => ({ name: field.name, value: field.value })),
editingFields: false,
newLocked: user.locked,
newShowRole: user.show_role,
}
},
@ -123,9 +122,18 @@ export default {
this.$store.dispatch('fetchUserRelationship', this.user.id)
},
computed: {
groupActorAvailable () {
return this.$store.state.instance.groupActorAvailable
},
availableActorTypes () {
return this.groupActorAvailable ? ['Person', 'Service', 'Group'] : ['Person', 'Service']
},
user () {
return this.$store.getters.findUser(this.userId)
},
role () {
return this.user.role
},
relationship () {
return this.$store.getters.relationship(this.userId)
},
@ -428,13 +436,11 @@ export default {
this.newShowBirthday = user.show_birthday
this.newCoverPhoto = user.cover_photo
this.newFields = user.fields.map(field => ({ name: field.name, value: field.value }))
this.newLocked = user.locked
this.newShowRole = user.show_role
},
updateProfile () {
const params = {
note: this.newBio,
locked: this.newLocked,
// Backend notation.
display_name: this.newName,

View file

@ -27,7 +27,6 @@
display: block;
line-height: 1.3;
padding: 0 0.6em;
margin: 0 0.6em;
img {
object-fit: contain;
@ -37,8 +36,14 @@
}
}
.user-card-setting {
margin-left: 0.6em;
margin-right: 0.6em;
}
.user-card-bio {
text-align: center;
margin: 0 0.6em;
&.input {
margin: 0 1em;

View file

@ -331,7 +331,41 @@
</div>
</div>
</div>
<slot />
<template v-if="editable">
<h4>{{ $t('settings.user_preferences') }}</h4>
<p
v-if="role === 'admin' || role === 'moderator'"
class="user-card-setting"
>
<Checkbox v-model="newShowRole">
<template v-if="role === 'admin'">
{{ $t('settings.show_admin_badge') }}
</template>
<template v-if="role === 'moderator'">
{{ $t('settings.show_moderator_badge') }}
</template>
</Checkbox>
</p>
<p class="user-card-setting">
<label>
{{ $t('settings.actor_type') }}
<Select v-model="newActorType">
<option
v-for="option in availableActorTypes"
:key="option"
:value="option"
>
{{ $t('settings.actor_type_' + option) }}
</option>
</Select>
<div v-if="groupActorAvailable">
<small>
{{ $t('settings.actor_type_description') }}
</small>
</div>
</label>
</p>
</template>
<div
v-if="!editable && loggedIn && isOtherUser && (hasNote || !hideBio) && !mergedConfig.userCardHidePersonalMarks"
class="personal-marks"
@ -671,7 +705,7 @@
<button
class="button-default btn"
type="button"
@click="destroy"
@click="editImage = false"
>
{{ this.$t('image_cropper.cancel') }}
</button>

View file

@ -492,8 +492,7 @@
"avatarRadius": "Avatars",
"background": "Background",
"bio": "Bio",
"user_type": "User type",
"show_labels": "User labels",
"user_preferences": "User preferences",
"email_language": "Language for receiving emails from the server",
"block_export": "Block export",
"block_export_button": "Export your blocks to a csv file",