Merge branch 'profile-edit' into shigusegubu-themes3

This commit is contained in:
Henry Jameson 2025-08-08 10:18:02 +03:00
commit 651ce2080e
8 changed files with 159 additions and 107 deletions

View file

@ -45,10 +45,10 @@
inset: 0;
justify-content: center;
place-items: center center;
overflow: auto;
}
.dialog-modal.panel {
max-height: 80vh;
max-width: 90vw;
z-index: 2001;
cursor: default;

View file

@ -13,7 +13,7 @@
v-if="!$store.state.users.currentUser.locked && newStatus.visibility == 'private' && !disableLockWarning"
keypath="post_status.account_not_locked_warning"
tag="p"
class="alert neutral"
class="visibility-notice"
scope="global"
>
<button
@ -25,52 +25,52 @@
</i18n-t>
<p
v-if="!hideScopeNotice && newStatus.visibility === 'public'"
class="alert neutral notice-dismissible"
class="visibility-notice notice-dismissible"
>
<span>{{ $t('post_status.scope_notice.public') }}</span>
<button
class="fa-scale-110 button-unstyled fa-old-padding dismiss"
<a
class="fa-scale-110 fa-old-padding dismiss"
:title="$t('post_status.scope_notice_dismiss')"
role="button"
tabindex="0"
@click.prevent="dismissScopeNotice()"
>
<FAIcon icon="times" />
</button>
</a>
</p>
<p
v-else-if="!hideScopeNotice && newStatus.visibility === 'unlisted'"
class="alert neutral notice-dismissible"
class="visibility-notice notice-dismissible"
>
<span>{{ $t('post_status.scope_notice.unlisted') }}</span>
<button
class="fa-scale-110 button-unstyled fa-old-padding dismiss"
<a
class="fa-scale-110 fa-old-padding dismiss"
:title="$t('post_status.scope_notice_dismiss')"
role="button"
tabindex="0"
@click.prevent="dismissScopeNotice()"
>
<FAIcon icon="times" />
</button>
</a>
</p>
<p
v-else-if="!hideScopeNotice && newStatus.visibility === 'private' && $store.state.users.currentUser.locked"
class="alert neutral notice-dismissible"
class="visibility-notice notice-dismissible"
>
<span>{{ $t('post_status.scope_notice.private') }}</span>
<button
class="fa-scale-110 button-unstyled fa-old-padding dismiss"
<a
class="fa-scale-110 fa-old-padding dismiss"
:title="$t('post_status.scope_notice_dismiss')"
role="button"
tabindex="0"
@click.prevent="dismissScopeNotice()"
>
<FAIcon icon="times" />
</button>
</a>
</p>
<p
v-else-if="newStatus.visibility === 'direct'"
class="alert neutral"
class="visibility-notice"
>
<span v-if="safeDMEnabled">{{ $t('post_status.direct_warning_to_first_only') }}</span>
<span v-else>{{ $t('post_status.direct_warning_to_all') }}</span>

View file

@ -412,6 +412,10 @@
display: flex;
padding: 0;
margin: 0;
.user-info {
margin: 1em;
}
}
.side-drawer ul {

View file

@ -186,14 +186,6 @@ export default {
relationship () {
return this.$store.getters.relationship(this.userId)
},
style () {
return {
backgroundImage: [
'linear-gradient(to bottom, var(--profileTint), var(--profileTint))',
`url(${this.bannerImgSrc})`
].join(', ')
}
},
isOtherUser () {
return this.user.id !== this.$store.state.users.currentUser.id
},
@ -290,12 +282,14 @@ export default {
// Editable stuff
avatarImgSrc () {
const currentUrl = this.user.profile_image_url_original || this.defaultAvatar
const newUrl = this.newAvatar === '' ? this.defaultAvatar : this.newAvatar
if (!this.editable) return currentUrl
const newUrl = this.newAvatar === null ? this.defaultAvatar : this.newAvatar
return (this.newAvatar === null) ? currentUrl : newUrl
},
bannerImgSrc () {
const currentUrl = this.user.cover_photo || this.defaultBanner
const newUrl = this.newBanner === '' ? this.defaultBanner : this.newBanner
if (!this.editable) return currentUrl
const newUrl = this.newBanner === null ? this.defaultBanner : this.newBanner
return (this.newBanner === null) ? currentUrl : newUrl
},
defaultAvatar () {
@ -419,11 +413,11 @@ export default {
},
resetImage () {
if (this.editImage === 'avatar') {
this.newAvatar = ''
this.newAvatarFile = ''
this.newAvatar = null
this.newAvatarFile = null
} else {
this.newBanner = ''
this.newBannerFile = ''
this.newBanner = null
this.newBannerFile = null
}
this.editImage = false
},
@ -438,6 +432,9 @@ export default {
propsToNative (props) {
return propsToNative(props)
},
cancelImageText () {
return
},
resetState () {
const user = this.$store.state.users.currentUser

View file

@ -111,7 +111,8 @@
}
}
.background-image {
.banner-overlay,
.banner-image {
position: absolute;
inset: 0;
right: -1.2em;
@ -119,11 +120,24 @@
top: -1.4em;
padding: 0;
mask: linear-gradient(to top, transparent 0, white 5em) bottom no-repeat;
background-size: cover;
background-color: var(--profileBg);
border-top-left-radius: calc(var(--roundness) - 1px);
border-top-right-radius: calc(var(--roundness) - 1px);
}
.banner-image {
z-index: -2;
img {
object-fit: cover;
height: 100%;
width: 100%;
}
}
.banner-overlay {
background-color: var(--profileTint);
pointer-events: none; // let user copy bg url
z-index: -1;
}
.bottom-buttons {
@ -491,6 +505,8 @@
.edit-image {
.panel-body {
text-align: center;
display: flex;
flex-direction: column;
}
.current-avatar {
@ -499,9 +515,19 @@
.image-container {
display: flex;
margin: 0 1em 0.5em;
align-self: center;
margin: 0 0 1em;
max-height: 30em;
max-width: 100%;
flex: 1 0 20em;
aspect-ratio: 1;
gap: 0.5em;
&.-banner {
aspect-ratio: 3;
max-width: 100%;
}
.new-image {
display: flex;
flex-direction: column;
@ -509,6 +535,7 @@
.cropper {
flex: 1;
overflow-x: auto;
}
> * {
@ -546,4 +573,16 @@
aspect-ratio: unset;
}
}
#modal.-mobile & {
#pick-image {
height: 3em;
}
.image-container {
&.-banner {
max-height: 10em;
}
}
}
}

View file

@ -3,10 +3,15 @@
<div class="user-card-inner">
<div class="user-info">
<div class="user-identity">
<div class="banner-image">
<img
:src="bannerImgSrc"
:class="{ 'hide-bio': hideBio }"
>
</div>
<div
class="banner-overlay"
:class="{ 'hide-bio': hideBio }"
:style="style"
class="background-image"
/>
<a
v-if="avatarAction === 'zoom'"
@ -222,74 +227,72 @@
</div>
</div>
<div
v-if="loggedIn"
v-if="loggedIn && isOtherUser"
class="user-interactions"
>
<template v-if="isOtherUser">
<div class="btn-group">
<FollowButton
:relationship="relationship"
:user="user"
/>
<template v-if="relationship.following">
<ProgressButton
v-if="!relationship.notifying"
class="btn button-default"
:click="subscribeUser"
:title="$t('user_card.subscribe')"
>
<FAIcon icon="bell" />
</ProgressButton>
<ProgressButton
v-else
class="btn button-default toggled"
:click="unsubscribeUser"
:title="$t('user_card.unsubscribe')"
>
<FALayers>
<FAIcon
icon="rss"
transform="left-5 shrink-6 up-3 rotate-20"
flip="horizontal"
/>
<FAIcon
icon="rss"
transform="right-5 shrink-6 up-3 rotate-20"
/>
<FAIcon icon="bell" />
</FALayers>
</ProgressButton>
</template>
</div>
<button
v-if="relationship.muting"
class="btn button-default btn-mute toggled"
:disabled="user.deactivated"
@click="unmuteUser"
>
{{ $t('user_card.muted') }}
</button>
<button
v-else
class="btn button-default btn-mute"
:disabled="user.deactivated"
@click="muteUser"
>
{{ $t('user_card.mute') }}
</button>
<button
class="btn button-default btn-mention"
:disabled="user.deactivated"
@click="mentionUser"
>
{{ $t('user_card.mention') }}
</button>
<ModerationTools
v-if="showModerationMenu"
class="moderation-menu"
<div class="btn-group">
<FollowButton
:relationship="relationship"
:user="user"
/>
</template>
<template v-if="relationship.following">
<ProgressButton
v-if="!relationship.notifying"
class="btn button-default"
:click="subscribeUser"
:title="$t('user_card.subscribe')"
>
<FAIcon icon="bell" />
</ProgressButton>
<ProgressButton
v-else
class="btn button-default toggled"
:click="unsubscribeUser"
:title="$t('user_card.unsubscribe')"
>
<FALayers>
<FAIcon
icon="rss"
transform="left-5 shrink-6 up-3 rotate-20"
flip="horizontal"
/>
<FAIcon
icon="rss"
transform="right-5 shrink-6 up-3 rotate-20"
/>
<FAIcon icon="bell" />
</FALayers>
</ProgressButton>
</template>
</div>
<button
v-if="relationship.muting"
class="btn button-default btn-mute toggled"
:disabled="user.deactivated"
@click="unmuteUser"
>
{{ $t('user_card.muted') }}
</button>
<button
v-else
class="btn button-default btn-mute"
:disabled="user.deactivated"
@click="muteUser"
>
{{ $t('user_card.mute') }}
</button>
<button
class="btn button-default btn-mention"
:disabled="user.deactivated"
@click="mentionUser"
>
{{ $t('user_card.mention') }}
</button>
<ModerationTools
v-if="showModerationMenu"
class="moderation-menu"
:user="user"
/>
</div>
<div
v-if="!loggedIn && user.is_local"
@ -455,8 +458,7 @@
>
<template #default="inputProps">
<input
v-model="newFields[i].name"
:placeholder="$t('settings.profile_fields.name')"
v-model="newFields[i].name" :placeholder="$t('settings.profile_fields.name')"
v-bind="propsToNative(inputProps)"
class="input"
>
@ -653,7 +655,13 @@
<template #header>
{{ editImage === 'avatar' ? $t('settings.change_avatar') : $t('settings.change_banner') }}
</template>
<div class="image-container">
<p>
{{ editImage === 'avatar' ? $t('settings.avatar_size_instruction') : $t('settings.banner_size_instruction' ) }}
</p>
<div
class="image-container"
:class="{ '-banner': editImage === 'banner' }"
>
<image-cropper
ref="cropper"
class="cropper"
@ -667,11 +675,8 @@
type="button"
@click="() => $refs.cropper.pickImage()"
>
{{ $t('settings.upload_picture') }}
{{ $t('settings.select_picture') }}
</button>
<p class="visibility-notice">
{{ editImage === 'avatar' ? $t('settings.avatar_size_instruction') : $t('settings.banner_size_instruction' ) }}
</p>
<template #footer>
<button
class="button-default btn"

View file

@ -28,7 +28,7 @@
}
.user-info {
margin: 0.6em;
margin: 0.6em 0.6em 0;
.Avatar {
width: 5em;
@ -38,6 +38,12 @@
}
}
.post-status-form {
form {
margin-top: 0;
}
}
.signed-in {
z-index: 10;
}

View file

@ -787,6 +787,7 @@
"type_domains_to_mute": "Search domains to mute",
"upload_a_photo": "Upload a photo",
"upload_picture": "Upload picture",
"select_picture": "Select picture",
"user_settings": "User Settings",
"values": {
"false": "no",