editable meta and bdey
This commit is contained in:
parent
51eb61180d
commit
2df895ab02
9 changed files with 343 additions and 137 deletions
|
|
@ -115,6 +115,7 @@
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
display: flex;
|
||||
|
||||
.emoji-picker-icon {
|
||||
position: absolute;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
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'
|
||||
import fileSizeFormatService from 'src/components/../services/file_size_format/file_size_format.js'
|
||||
import ProgressButton from 'src/components/progress_button/progress_button.vue'
|
||||
import EmojiInput from 'src/components/emoji_input/emoji_input.vue'
|
||||
import suggestor from 'src/components/emoji_input/suggestor.js'
|
||||
import Autosuggest from 'src/components/autosuggest/autosuggest.vue'
|
||||
import Checkbox from 'src/components/checkbox/checkbox.vue'
|
||||
import InterfaceLanguageSwitcher from 'src/components/interface_language_switcher/interface_language_switcher.vue'
|
||||
import Select from 'src/components/select/select.vue'
|
||||
|
|
@ -53,10 +53,10 @@ const ProfileTab = {
|
|||
}
|
||||
},
|
||||
components: {
|
||||
UserCard,
|
||||
ScopeSelector,
|
||||
ImageCropper,
|
||||
EmojiInput,
|
||||
Autosuggest,
|
||||
ProgressButton,
|
||||
Checkbox,
|
||||
BooleanSetting,
|
||||
|
|
@ -88,12 +88,6 @@ const ProfileTab = {
|
|||
userSuggestor () {
|
||||
return suggestor({ store: this.$store })
|
||||
},
|
||||
fieldsLimits () {
|
||||
return this.$store.state.instance.fieldsLimits
|
||||
},
|
||||
maxFields () {
|
||||
return this.fieldsLimits ? this.fieldsLimits.maxFields : 0
|
||||
},
|
||||
defaultAvatar () {
|
||||
return this.$store.state.instance.server + this.$store.state.instance.defaultAvatar
|
||||
},
|
||||
|
|
|
|||
|
|
@ -125,9 +125,4 @@
|
|||
padding: 0 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.birthday-input {
|
||||
display: block;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,12 @@
|
|||
<div class="profile-tab">
|
||||
<div class="setting-item">
|
||||
<h2>{{ $t('settings.name_bio') }}</h2>
|
||||
<UserCard
|
||||
:user-id="user.id"
|
||||
:editable="true"
|
||||
:switcher="false"
|
||||
rounded="top"
|
||||
/>
|
||||
<p>{{ $t('settings.name') }}</p>
|
||||
<EmojiInput
|
||||
v-model="newName"
|
||||
|
|
@ -41,75 +47,6 @@
|
|||
</template>
|
||||
</Checkbox>
|
||||
</p>
|
||||
<div>
|
||||
<p>{{ $t('settings.birthday.label') }}</p>
|
||||
<input
|
||||
id="birthday"
|
||||
v-model="newBirthday"
|
||||
type="date"
|
||||
class="input birthday-input"
|
||||
>
|
||||
<Checkbox v-model="showBirthday">
|
||||
{{ $t('settings.birthday.show_birthday') }}
|
||||
</Checkbox>
|
||||
</div>
|
||||
<div v-if="maxFields > 0">
|
||||
<p>{{ $t('settings.profile_fields.label') }}</p>
|
||||
<div
|
||||
v-for="(_, i) in newFields"
|
||||
:key="i"
|
||||
class="profile-fields"
|
||||
>
|
||||
<EmojiInput
|
||||
v-model="newFields[i].name"
|
||||
enable-emoji-picker
|
||||
hide-emoji-button
|
||||
:suggest="userSuggestor"
|
||||
>
|
||||
<template #default="inputProps">
|
||||
<input
|
||||
v-model="newFields[i].name"
|
||||
:placeholder="$t('settings.profile_fields.name')"
|
||||
v-bind="propsToNative(inputProps)"
|
||||
class="input"
|
||||
>
|
||||
</template>
|
||||
</EmojiInput>
|
||||
<EmojiInput
|
||||
v-model="newFields[i].value"
|
||||
enable-emoji-picker
|
||||
hide-emoji-button
|
||||
:suggest="userSuggestor"
|
||||
>
|
||||
<template #default="inputProps">
|
||||
<input
|
||||
v-model="newFields[i].value"
|
||||
:placeholder="$t('settings.profile_fields.value')"
|
||||
v-bind="propsToNative(inputProps)"
|
||||
class="input"
|
||||
>
|
||||
</template>
|
||||
</EmojiInput>
|
||||
<button
|
||||
class="delete-field button-unstyled -hover-highlight"
|
||||
@click="deleteField(i)"
|
||||
>
|
||||
<!-- TODO something is wrong with v-show here -->
|
||||
<FAIcon
|
||||
v-if="newFields.length > 1"
|
||||
icon="times"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
v-if="newFields.length < maxFields"
|
||||
class="add-field faint button-unstyled -hover-highlight"
|
||||
@click="addField"
|
||||
>
|
||||
<FAIcon icon="plus" />
|
||||
{{ $t("settings.profile_fields.add_field") }}
|
||||
</button>
|
||||
</div>
|
||||
<p>
|
||||
<label>
|
||||
{{ $t('settings.actor_type') }}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
import merge from 'lodash/merge'
|
||||
import unescape from 'lodash/unescape'
|
||||
|
||||
import ColorInput from 'src/components/color_input/color_input.vue'
|
||||
import UserAvatar from '../user_avatar/user_avatar.vue'
|
||||
import RemoteFollow from '../remote_follow/remote_follow.vue'
|
||||
|
|
@ -10,11 +13,17 @@ import Select from '../select/select.vue'
|
|||
import UserLink from '../user_link/user_link.vue'
|
||||
import RichContent from 'src/components/rich_content/rich_content.jsx'
|
||||
import UserTimedFilterModal from 'src/components/user_timed_filter_modal/user_timed_filter_modal.vue'
|
||||
import Checkbox from 'src/components/checkbox/checkbox.vue'
|
||||
import EmojiInput from 'src/components/emoji_input/emoji_input.vue'
|
||||
|
||||
import localeService from 'src/services/locale/locale.service.js'
|
||||
import suggestor from 'src/components/emoji_input/suggestor.js'
|
||||
|
||||
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
|
||||
import { mapGetters } from 'vuex'
|
||||
import { usePostStatusStore } from 'src/stores/post_status'
|
||||
import { propsToNative } from 'src/services/attributes_helper/attributes_helper.service.js'
|
||||
|
||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||
import {
|
||||
faBell,
|
||||
|
|
@ -24,13 +33,15 @@ import {
|
|||
faEdit,
|
||||
faTimes,
|
||||
faExpandAlt,
|
||||
faBirthdayCake
|
||||
faBirthdayCake,
|
||||
faSave
|
||||
} from '@fortawesome/free-solid-svg-icons'
|
||||
|
||||
import { useMediaViewerStore } from '../../stores/media_viewer'
|
||||
import { useInterfaceStore } from '../../stores/interface'
|
||||
|
||||
library.add(
|
||||
faSave,
|
||||
faRss,
|
||||
faBell,
|
||||
faSearchPlus,
|
||||
|
|
@ -43,6 +54,7 @@ library.add(
|
|||
|
||||
export default {
|
||||
props: [
|
||||
'editable',
|
||||
'userId',
|
||||
'switcher',
|
||||
'selected',
|
||||
|
|
@ -55,6 +67,7 @@ export default {
|
|||
],
|
||||
components: {
|
||||
UserAvatar,
|
||||
Checkbox,
|
||||
RemoteFollow,
|
||||
ModerationTools,
|
||||
AccountActions,
|
||||
|
|
@ -65,13 +78,27 @@ export default {
|
|||
UserLink,
|
||||
UserNote,
|
||||
UserTimedFilterModal,
|
||||
ColorInput
|
||||
ColorInput,
|
||||
EmojiInput
|
||||
},
|
||||
data () {
|
||||
const user = this.$store.state.users.currentUser
|
||||
|
||||
return {
|
||||
followRequestInProgress: false,
|
||||
muteExpiryAmount: 0,
|
||||
muteExpiryUnit: 'minutes'
|
||||
muteExpiryUnit: 'minutes',
|
||||
|
||||
// Editable stuff
|
||||
newName: user.name_unescaped,
|
||||
newActorType: user.actor_type,
|
||||
newBio: unescape(user.description),
|
||||
newBirthday: user.birthday,
|
||||
newShowBirthday: user.show_birthday,
|
||||
newFields: user.fields.map(field => ({ name: field.name, value: field.value })),
|
||||
editingFields: false,
|
||||
newLocked: user.locked,
|
||||
newShowRole: user.show_role,
|
||||
}
|
||||
},
|
||||
created () {
|
||||
|
|
@ -114,6 +141,13 @@ export default {
|
|||
const days = Math.ceil((new Date() - new Date(this.user.created_at)) / (60 * 60 * 24 * 1000))
|
||||
return Math.round(this.user.statuses_count / days)
|
||||
},
|
||||
emoji () {
|
||||
return this.$store.state.instance.customEmoji.map(e => ({
|
||||
shortcode: e.displayText,
|
||||
static_url: e.imageUrl,
|
||||
url: e.imageUrl
|
||||
}))
|
||||
},
|
||||
userHighlightType: {
|
||||
get () {
|
||||
const data = this.$store.getters.mergedConfig.highlight[this.user.screen_name]
|
||||
|
|
@ -184,6 +218,31 @@ export default {
|
|||
const browserLocale = localeService.internalToBrowserLocale(this.$i18n.locale)
|
||||
return this.user.birthday && new Date(Date.parse(this.user.birthday)).toLocaleDateString(browserLocale, { timeZone: 'UTC', day: 'numeric', month: 'long', year: 'numeric' })
|
||||
},
|
||||
|
||||
// Editable stuff
|
||||
fieldsLimits () {
|
||||
return this.$store.state.instance.fieldsLimits
|
||||
},
|
||||
maxFields () {
|
||||
return this.fieldsLimits ? this.fieldsLimits.maxFields : 0
|
||||
},
|
||||
emojiUserSuggestor () {
|
||||
return suggestor({
|
||||
emoji: [
|
||||
...this.$store.getters.standardEmojiList,
|
||||
...this.$store.state.instance.customEmoji
|
||||
],
|
||||
store: this.$store
|
||||
})
|
||||
},
|
||||
emojiSuggestor () {
|
||||
return suggestor({
|
||||
emoji: [
|
||||
...this.$store.getters.standardEmojiList,
|
||||
...this.$store.state.instance.customEmoji
|
||||
]
|
||||
})
|
||||
},
|
||||
...mapGetters(['mergedConfig'])
|
||||
},
|
||||
methods: {
|
||||
|
|
@ -238,6 +297,48 @@ export default {
|
|||
e.preventDefault()
|
||||
this.onAvatarClick()
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Editable stuff
|
||||
addField () {
|
||||
if (this.newFields.length < this.maxFields) {
|
||||
this.newFields.push({ name: '', value: '' })
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
deleteField (index) {
|
||||
this.newFields.splice(index, 1)
|
||||
},
|
||||
propsToNative (props) {
|
||||
return propsToNative(props)
|
||||
},
|
||||
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)
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,17 @@
|
|||
position: relative;
|
||||
z-index: 1;
|
||||
|
||||
// editing headers
|
||||
h4 {
|
||||
line-height: 2;
|
||||
display: flex;
|
||||
padding: 0 1.0em;
|
||||
|
||||
span {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.user-card-inner {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
|
@ -179,6 +190,10 @@
|
|||
padding: 0.6em;
|
||||
margin: -0.6em;
|
||||
|
||||
&.save-profile-button {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
&:hover .icon {
|
||||
color: var(--textFaint);
|
||||
}
|
||||
|
|
@ -400,37 +415,64 @@
|
|||
.user-profile-fields {
|
||||
margin: 0 0.5em;
|
||||
|
||||
--emoji-size: 1.8em;
|
||||
|
||||
img {
|
||||
object-fit: contain;
|
||||
vertical-align: middle;
|
||||
max-width: 100%;
|
||||
max-height: 400px;
|
||||
|
||||
&.emoji {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.user-profile-field-add,
|
||||
.user-profile-field {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
margin: 0.25em;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--roundness);
|
||||
line-height: 2em;
|
||||
}
|
||||
|
||||
.user-profile-field-add {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.user-profile-field {
|
||||
.input {
|
||||
text-align: inherit;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.delete-field {
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
width: 2em;
|
||||
}
|
||||
|
||||
.user-profile-field-name,
|
||||
.user-profile-field-value {
|
||||
.user-profile-field-value,
|
||||
.user-profile-field-add {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
line-height: 2em;
|
||||
display: inline-flex;
|
||||
|
||||
&.-edit {
|
||||
padding: 0;
|
||||
|
||||
input {
|
||||
font-weight: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.user-profile-field-name {
|
||||
flex: 0 1 50%;
|
||||
font-weight: 600;
|
||||
text-align: right;
|
||||
justify-content: end;
|
||||
color: var(--lightText);
|
||||
min-width: 9em;
|
||||
border-right: 1px solid var(--border);
|
||||
|
|
|
|||
|
|
@ -27,6 +27,19 @@
|
|||
/>
|
||||
</div>
|
||||
</a>
|
||||
<button
|
||||
v-else-if="editable"
|
||||
class="user-info-avatar button-unstyled -link"
|
||||
@click="editAvatar"
|
||||
>
|
||||
<UserAvatar :user="user" />
|
||||
<div class="user-info-avatar -link -overlay">
|
||||
<FAIcon
|
||||
class="fa-scale-110 fa-old-padding"
|
||||
icon="pencil"
|
||||
/>
|
||||
</div>
|
||||
</button>
|
||||
<UserAvatar
|
||||
v-else-if="typeof avatarAction === 'function'"
|
||||
class="user-info-avatar"
|
||||
|
|
@ -42,9 +55,25 @@
|
|||
</router-link>
|
||||
<div class="user-summary">
|
||||
<div class="top-line">
|
||||
<div class="other-actions">
|
||||
<div
|
||||
class="other-actions"
|
||||
>
|
||||
<button
|
||||
v-if="!isOtherUser && user.is_local"
|
||||
v-if="editable"
|
||||
:disabled="newName && newName.length === 0"
|
||||
class="btn button-unstyled save-profile-button"
|
||||
@click="updateProfile"
|
||||
>
|
||||
{{ $t('settings.save') }}
|
||||
<FAIcon
|
||||
fixed-width
|
||||
class="icon"
|
||||
icon="save"
|
||||
:title="$t('user_card.edit_profile')"
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
v-else-if="!editable && !isOtherUser && user.is_local"
|
||||
class="button-unstyled edit-profile-button"
|
||||
@click.stop="openProfileTab"
|
||||
>
|
||||
|
|
@ -100,7 +129,7 @@
|
|||
<RichContent
|
||||
:title="user.name"
|
||||
:html="user.name"
|
||||
:emoji="user.emoji"
|
||||
:emoji="editable ? emoji : user.emoji"
|
||||
/>
|
||||
</router-link>
|
||||
</div>
|
||||
|
|
@ -166,7 +195,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="loggedIn && isOtherUser"
|
||||
v-if="!editable && loggedIn && isOtherUser"
|
||||
class="user-interactions"
|
||||
>
|
||||
<div class="btn-group">
|
||||
|
|
@ -242,7 +271,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="loggedIn && isOtherUser && (hasNote || !hideBio) && !mergedConfig.userCardHidePersonalMarks"
|
||||
v-if="!editable && loggedIn && isOtherUser && (hasNote || !hideBio) && !mergedConfig.userCardHidePersonalMarks"
|
||||
class="personal-marks"
|
||||
>
|
||||
<UserNote
|
||||
|
|
@ -291,44 +320,127 @@
|
|||
class="user-card-bio"
|
||||
:class="{ '-justify-left': mergedConfig.userCardLeftJustify }"
|
||||
:html="user.description_html"
|
||||
:emoji="user.emoji"
|
||||
:emoji="editable ? emoji : user.emoji"
|
||||
:handle-links="true"
|
||||
/>
|
||||
<div
|
||||
v-if="!hideBio && user.fields_html && user.fields_html.length > 0"
|
||||
class="user-profile-fields"
|
||||
>
|
||||
<dl
|
||||
v-for="(field, index) in user.fields_html"
|
||||
:key="index"
|
||||
class="user-profile-field"
|
||||
<h4 v-if="editable">
|
||||
<span>
|
||||
{{ $t('settings.profile_fields.label') }}
|
||||
</span>
|
||||
<button
|
||||
class="button-default"
|
||||
@click="editingFields = !editingFields"
|
||||
>
|
||||
<dt
|
||||
:title="user.fields_text[index].name"
|
||||
class="user-profile-field-name"
|
||||
{{ $t('settings.toggle_edit') }}
|
||||
</button>
|
||||
</h4>
|
||||
<template v-if="!editable || !editingFields">
|
||||
<div
|
||||
v-if="!hideBio && user.fields_html && user.fields_html.length > 0"
|
||||
class="user-profile-fields"
|
||||
>
|
||||
<dl
|
||||
v-for="(field, index) in newFields"
|
||||
:key="index"
|
||||
class="user-profile-field"
|
||||
>
|
||||
<RichContent
|
||||
:html="field.name"
|
||||
:emoji="user.emoji"
|
||||
/>
|
||||
</dt>
|
||||
<dd
|
||||
:title="user.fields_text[index].value"
|
||||
class="user-profile-field-value"
|
||||
<dt
|
||||
:title="field.name"
|
||||
class="user-profile-field-name"
|
||||
>
|
||||
<RichContent
|
||||
:html="field.name"
|
||||
:emoji="editable ? emoji : user.emoji"
|
||||
/>
|
||||
</dt>
|
||||
<dd
|
||||
:title="field.value"
|
||||
class="user-profile-field-value"
|
||||
>
|
||||
<RichContent
|
||||
:html="field.value"
|
||||
:emoji="editable ? emoji : user.emoji"
|
||||
/>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="editingFields">
|
||||
<div
|
||||
v-if="maxFields > 0"
|
||||
class="user-profile-fields"
|
||||
>
|
||||
<dl
|
||||
v-for="(_, i) in newFields"
|
||||
:key="i"
|
||||
class="user-profile-field"
|
||||
>
|
||||
<RichContent
|
||||
:html="field.value"
|
||||
:emoji="user.emoji"
|
||||
/>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<dt
|
||||
class="user-profile-field-name -edit"
|
||||
>
|
||||
<EmojiInput
|
||||
v-model="newFields[i].name"
|
||||
enable-emoji-picker
|
||||
:suggest="emojiSuggestor"
|
||||
>
|
||||
<template #default="inputProps">
|
||||
<input
|
||||
v-model="newFields[i].name"
|
||||
:placeholder="$t('settings.profile_fields.name')"
|
||||
v-bind="propsToNative(inputProps)"
|
||||
class="input"
|
||||
>
|
||||
</template>
|
||||
</EmojiInput>
|
||||
</dt>
|
||||
<dd
|
||||
class="user-profile-field-value -edit"
|
||||
>
|
||||
<EmojiInput
|
||||
v-model="newFields[i].value"
|
||||
enable-emoji-picker
|
||||
:suggest="emojiSuggestor"
|
||||
>
|
||||
<template #default="inputProps">
|
||||
<input
|
||||
v-model="newFields[i].value"
|
||||
:placeholder="$t('settings.profile_fields.value')"
|
||||
v-bind="propsToNative(inputProps)"
|
||||
class="input input"
|
||||
>
|
||||
</template>
|
||||
</EmojiInput>
|
||||
<button
|
||||
class="delete-field button-unstyled -hover-highlight"
|
||||
@click="deleteField(i)"
|
||||
>
|
||||
<!-- TODO something is wrong with v-show here -->
|
||||
<FAIcon
|
||||
v-if="newFields.length > 1"
|
||||
icon="times"
|
||||
/>
|
||||
</button>
|
||||
</dd>
|
||||
</dl>
|
||||
<p class="user-profile-field-add">
|
||||
<button
|
||||
v-if="newFields.length < maxFields"
|
||||
class="add-field faint button-unstyled -hover-highlight"
|
||||
@click="addField"
|
||||
>
|
||||
<FAIcon icon="plus" />
|
||||
{{ ' ' }}
|
||||
{{ $t("settings.profile_fields.add_field") }}
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
<div
|
||||
v-if="!hideBio"
|
||||
class="user-extras"
|
||||
v-if="!hideBio"
|
||||
>
|
||||
<span
|
||||
v-if="!mergedConfig.hideUserStats"
|
||||
v-if="!editable && !mergedConfig.hideUserStats"
|
||||
class="user-stats"
|
||||
>
|
||||
<dl
|
||||
|
|
@ -365,16 +477,38 @@
|
|||
<dt>{{ $t('user_card.followers') }}</dt>
|
||||
</dl>
|
||||
</span>
|
||||
<div
|
||||
v-if="!hideBio && !!user.birthday"
|
||||
class="birthday"
|
||||
>
|
||||
<FAIcon
|
||||
class="fa-old-padding"
|
||||
icon="birthday-cake"
|
||||
/>
|
||||
{{ $t('user_card.birthday', { birthday: formattedBirthday }) }}
|
||||
</div>
|
||||
<template v-if="!hideBio">
|
||||
<div
|
||||
v-if="user.birthday && !editable"
|
||||
class="birthday"
|
||||
>
|
||||
<FAIcon
|
||||
class="fa-old-padding"
|
||||
icon="birthday-cake"
|
||||
/>
|
||||
{{ $t('user_card.birthday', { birthday: formattedBirthday }) }}
|
||||
</div>
|
||||
<div
|
||||
v-else-if="editable"
|
||||
class="birthday"
|
||||
>
|
||||
<FAIcon
|
||||
class="fa-old-padding"
|
||||
icon="birthday-cake"
|
||||
/>
|
||||
<input
|
||||
id="birthday"
|
||||
v-model="newBirthday"
|
||||
type="date"
|
||||
class="input birthday-input"
|
||||
>
|
||||
<div>
|
||||
<Checkbox v-model="showBirthday">
|
||||
{{ $t('settings.birthday.show_birthday') }}
|
||||
</Checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<teleport to="#modal">
|
||||
<UserTimedFilterModal
|
||||
|
|
|
|||
|
|
@ -394,6 +394,7 @@
|
|||
"expert_mode": "Show advanced",
|
||||
"save": "Save changes",
|
||||
"security": "Security",
|
||||
"toggle_edit": "Toggle edit",
|
||||
"setting_changed": "Setting is different from default",
|
||||
"setting_server_side": "This setting is tied to your profile and affects all sessions and clients",
|
||||
"enter_current_password_to_confirm": "Enter your current password to confirm your identity",
|
||||
|
|
|
|||
|
|
@ -139,6 +139,7 @@ const defaultState = {
|
|||
|
||||
// Nasty stuff
|
||||
customEmoji: [],
|
||||
rawCustomEmoji: [],
|
||||
customEmojiFetched: false,
|
||||
emoji: {},
|
||||
emojiFetched: false,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue