forked from AkkomaGang/akkoma-fe
Merge branch 'wyatt777/pleroma-fe-issue-353' into 'develop'
Allow remove of banner, avatar images issue #353 v2 See merge request pleroma/pleroma-fe!1156
This commit is contained in:
commit
4f96418143
10 changed files with 153 additions and 76 deletions
|
@ -19,6 +19,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Autocomplete domains from list of known instances
|
- Autocomplete domains from list of known instances
|
||||||
- 'Bot' settings option and badge
|
- 'Bot' settings option and badge
|
||||||
- Added profile meta data fields that can be set in profile settings
|
- Added profile meta data fields that can be set in profile settings
|
||||||
|
- Added option to reset avatar/banner in profile settings
|
||||||
- Descriptions can be set on uploaded files before posting
|
- Descriptions can be set on uploaded files before posting
|
||||||
- Added status preview option to preview your statuses before posting
|
- Added status preview option to preview your statuses before posting
|
||||||
- When a post is a reply to an unavailable post, the 'Reply to'-text has a strike-through style
|
- When a post is a reply to an unavailable post, the 'Reply to'-text has a strike-through style
|
||||||
|
|
|
@ -77,6 +77,33 @@ const ProfileTab = {
|
||||||
},
|
},
|
||||||
maxFields () {
|
maxFields () {
|
||||||
return this.fieldsLimits ? this.fieldsLimits.maxFields : 0
|
return this.fieldsLimits ? this.fieldsLimits.maxFields : 0
|
||||||
|
},
|
||||||
|
defaultAvatar () {
|
||||||
|
return this.$store.state.instance.server + this.$store.state.instance.defaultAvatar
|
||||||
|
},
|
||||||
|
defaultBanner () {
|
||||||
|
return this.$store.state.instance.server + this.$store.state.instance.defaultBanner
|
||||||
|
},
|
||||||
|
isDefaultAvatar () {
|
||||||
|
const baseAvatar = this.$store.state.instance.defaultAvatar
|
||||||
|
return !(this.$store.state.users.currentUser.profile_image_url) ||
|
||||||
|
this.$store.state.users.currentUser.profile_image_url.includes(baseAvatar)
|
||||||
|
},
|
||||||
|
isDefaultBanner () {
|
||||||
|
const baseBanner = this.$store.state.instance.defaultBanner
|
||||||
|
return !(this.$store.state.users.currentUser.cover_photo) ||
|
||||||
|
this.$store.state.users.currentUser.cover_photo.includes(baseBanner)
|
||||||
|
},
|
||||||
|
isDefaultBackground () {
|
||||||
|
return !(this.$store.state.users.currentUser.background_image)
|
||||||
|
},
|
||||||
|
avatarImgSrc () {
|
||||||
|
const src = this.$store.state.users.currentUser.profile_image_url_original
|
||||||
|
return (!src) ? this.defaultAvatar : src
|
||||||
|
},
|
||||||
|
bannerImgSrc () {
|
||||||
|
const src = this.$store.state.users.currentUser.cover_photo
|
||||||
|
return (!src) ? this.defaultBanner : src
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -150,11 +177,29 @@ const ProfileTab = {
|
||||||
}
|
}
|
||||||
reader.readAsDataURL(file)
|
reader.readAsDataURL(file)
|
||||||
},
|
},
|
||||||
|
resetAvatar () {
|
||||||
|
const confirmed = window.confirm(this.$t('settings.reset_avatar_confirm'))
|
||||||
|
if (confirmed) {
|
||||||
|
this.submitAvatar(undefined, '')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resetBanner () {
|
||||||
|
const confirmed = window.confirm(this.$t('settings.reset_banner_confirm'))
|
||||||
|
if (confirmed) {
|
||||||
|
this.submitBanner('')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resetBackground () {
|
||||||
|
const confirmed = window.confirm(this.$t('settings.reset_background_confirm'))
|
||||||
|
if (confirmed) {
|
||||||
|
this.submitBackground('')
|
||||||
|
}
|
||||||
|
},
|
||||||
submitAvatar (cropper, file) {
|
submitAvatar (cropper, file) {
|
||||||
const that = this
|
const that = this
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
function updateAvatar (avatar) {
|
function updateAvatar (avatar) {
|
||||||
that.$store.state.api.backendInteractor.updateAvatar({ avatar })
|
that.$store.state.api.backendInteractor.updateProfileImages({ avatar })
|
||||||
.then((user) => {
|
.then((user) => {
|
||||||
that.$store.commit('addNewUsers', [user])
|
that.$store.commit('addNewUsers', [user])
|
||||||
that.$store.commit('setCurrentUser', user)
|
that.$store.commit('setCurrentUser', user)
|
||||||
|
@ -172,11 +217,11 @@ const ProfileTab = {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
submitBanner () {
|
submitBanner (banner) {
|
||||||
if (!this.bannerPreview) { return }
|
if (!this.bannerPreview && banner !== '') { return }
|
||||||
|
|
||||||
this.bannerUploading = true
|
this.bannerUploading = true
|
||||||
this.$store.state.api.backendInteractor.updateBanner({ banner: this.banner })
|
this.$store.state.api.backendInteractor.updateProfileImages({ banner })
|
||||||
.then((user) => {
|
.then((user) => {
|
||||||
this.$store.commit('addNewUsers', [user])
|
this.$store.commit('addNewUsers', [user])
|
||||||
this.$store.commit('setCurrentUser', user)
|
this.$store.commit('setCurrentUser', user)
|
||||||
|
@ -187,11 +232,11 @@ const ProfileTab = {
|
||||||
})
|
})
|
||||||
.then(() => { this.bannerUploading = false })
|
.then(() => { this.bannerUploading = false })
|
||||||
},
|
},
|
||||||
submitBg () {
|
submitBackground (background) {
|
||||||
if (!this.backgroundPreview) { return }
|
if (!this.backgroundPreview && background !== '') { return }
|
||||||
let background = this.background
|
|
||||||
this.backgroundUploading = true
|
this.backgroundUploading = true
|
||||||
this.$store.state.api.backendInteractor.updateBg({ background }).then((data) => {
|
this.$store.state.api.backendInteractor.updateProfileImages({ background }).then((data) => {
|
||||||
if (!data.error) {
|
if (!data.error) {
|
||||||
this.$store.commit('addNewUsers', [data])
|
this.$store.commit('addNewUsers', [data])
|
||||||
this.$store.commit('setCurrentUser', data)
|
this.$store.commit('setCurrentUser', data)
|
||||||
|
|
|
@ -13,8 +13,14 @@
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.banner {
|
.banner-background-preview {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
width: 300px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.uploading {
|
.uploading {
|
||||||
|
@ -26,18 +32,40 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg {
|
.current-avatar-container {
|
||||||
max-width: 100%;
|
position: relative;
|
||||||
|
width: 150px;
|
||||||
|
height: 150px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.current-avatar {
|
.current-avatar {
|
||||||
display: block;
|
display: block;
|
||||||
width: 150px;
|
width: 100%;
|
||||||
height: 150px;
|
height: 100%;
|
||||||
border-radius: $fallback--avatarRadius;
|
border-radius: $fallback--avatarRadius;
|
||||||
border-radius: var(--avatarRadius, $fallback--avatarRadius);
|
border-radius: var(--avatarRadius, $fallback--avatarRadius);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.reset-button {
|
||||||
|
position: absolute;
|
||||||
|
top: 0.2em;
|
||||||
|
right: 0.2em;
|
||||||
|
border-radius: $fallback--tooltipRadius;
|
||||||
|
border-radius: var(--tooltipRadius, $fallback--tooltipRadius);
|
||||||
|
background-color: rgba(0, 0, 0, 0.6);
|
||||||
|
opacity: 0.7;
|
||||||
|
color: white;
|
||||||
|
width: 1.5em;
|
||||||
|
height: 1.5em;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 1.5em;
|
||||||
|
font-size: 1.5em;
|
||||||
|
cursor: pointer;
|
||||||
|
&:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.oauth-tokens {
|
.oauth-tokens {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
|
@ -86,6 +114,7 @@
|
||||||
&>.emoji-input {
|
&>.emoji-input {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
margin: 0 .2em .5em;
|
margin: 0 .2em .5em;
|
||||||
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
&>.icon-container {
|
&>.icon-container {
|
||||||
|
|
|
@ -161,11 +161,19 @@
|
||||||
<p class="visibility-notice">
|
<p class="visibility-notice">
|
||||||
{{ $t('settings.avatar_size_instruction') }}
|
{{ $t('settings.avatar_size_instruction') }}
|
||||||
</p>
|
</p>
|
||||||
<p>{{ $t('settings.current_avatar') }}</p>
|
<div class="current-avatar-container">
|
||||||
<img
|
<img
|
||||||
:src="user.profile_image_url_original"
|
:src="user.profile_image_url_original"
|
||||||
class="current-avatar"
|
class="current-avatar"
|
||||||
>
|
>
|
||||||
|
<i
|
||||||
|
v-if="!isDefaultAvatar && pickAvatarBtnVisible"
|
||||||
|
:title="$t('settings.reset_avatar')"
|
||||||
|
class="reset-button icon-cancel"
|
||||||
|
type="button"
|
||||||
|
@click="resetAvatar"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<p>{{ $t('settings.set_new_avatar') }}</p>
|
<p>{{ $t('settings.set_new_avatar') }}</p>
|
||||||
<button
|
<button
|
||||||
v-show="pickAvatarBtnVisible"
|
v-show="pickAvatarBtnVisible"
|
||||||
|
@ -184,15 +192,20 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="setting-item">
|
<div class="setting-item">
|
||||||
<h2>{{ $t('settings.profile_banner') }}</h2>
|
<h2>{{ $t('settings.profile_banner') }}</h2>
|
||||||
<p>{{ $t('settings.current_profile_banner') }}</p>
|
<div class="banner-background-preview">
|
||||||
<img
|
<img :src="user.cover_photo">
|
||||||
:src="user.cover_photo"
|
<i
|
||||||
class="banner"
|
v-if="!isDefaultBanner"
|
||||||
>
|
:title="$t('settings.reset_profile_banner')"
|
||||||
|
class="reset-button icon-cancel"
|
||||||
|
type="button"
|
||||||
|
@click="resetBanner"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<p>{{ $t('settings.set_new_profile_banner') }}</p>
|
<p>{{ $t('settings.set_new_profile_banner') }}</p>
|
||||||
<img
|
<img
|
||||||
v-if="bannerPreview"
|
v-if="bannerPreview"
|
||||||
class="banner"
|
class="banner-background-preview"
|
||||||
:src="bannerPreview"
|
:src="bannerPreview"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
|
@ -208,7 +221,7 @@
|
||||||
<button
|
<button
|
||||||
v-else-if="bannerPreview"
|
v-else-if="bannerPreview"
|
||||||
class="btn btn-default"
|
class="btn btn-default"
|
||||||
@click="submitBanner"
|
@click="submitBanner(banner)"
|
||||||
>
|
>
|
||||||
{{ $t('general.submit') }}
|
{{ $t('general.submit') }}
|
||||||
</button>
|
</button>
|
||||||
|
@ -225,10 +238,20 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="setting-item">
|
<div class="setting-item">
|
||||||
<h2>{{ $t('settings.profile_background') }}</h2>
|
<h2>{{ $t('settings.profile_background') }}</h2>
|
||||||
|
<div class="banner-background-preview">
|
||||||
|
<img :src="user.background_image">
|
||||||
|
<i
|
||||||
|
v-if="!isDefaultBackground"
|
||||||
|
:title="$t('settings.reset_profile_background')"
|
||||||
|
class="reset-button icon-cancel"
|
||||||
|
type="button"
|
||||||
|
@click="resetBackground"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<p>{{ $t('settings.set_new_profile_background') }}</p>
|
<p>{{ $t('settings.set_new_profile_background') }}</p>
|
||||||
<img
|
<img
|
||||||
v-if="backgroundPreview"
|
v-if="backgroundPreview"
|
||||||
class="bg"
|
class="banner-background-preview"
|
||||||
:src="backgroundPreview"
|
:src="backgroundPreview"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
|
@ -244,7 +267,7 @@
|
||||||
<button
|
<button
|
||||||
v-else-if="backgroundPreview"
|
v-else-if="backgroundPreview"
|
||||||
class="btn btn-default"
|
class="btn btn-default"
|
||||||
@click="submitBg"
|
@click="submitBackground(background)"
|
||||||
>
|
>
|
||||||
{{ $t('general.submit') }}
|
{{ $t('general.submit') }}
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -8,26 +8,20 @@ const UserAvatar = {
|
||||||
],
|
],
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
showPlaceholder: false
|
showPlaceholder: false,
|
||||||
|
defaultAvatar: `${this.$store.state.instance.server + this.$store.state.instance.defaultAvatar}`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
StillImage
|
StillImage
|
||||||
},
|
},
|
||||||
computed: {
|
|
||||||
imgSrc () {
|
|
||||||
return this.showPlaceholder ? '/images/avi.png' : this.user.profile_image_url_original
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
imgSrc (src) {
|
||||||
|
return (!src || this.showPlaceholder) ? this.defaultAvatar : src
|
||||||
|
},
|
||||||
imageLoadError () {
|
imageLoadError () {
|
||||||
this.showPlaceholder = true
|
this.showPlaceholder = true
|
||||||
}
|
}
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
src () {
|
|
||||||
this.showPlaceholder = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
class="avatar"
|
class="avatar"
|
||||||
:alt="user.screen_name"
|
:alt="user.screen_name"
|
||||||
:title="user.screen_name"
|
:title="user.screen_name"
|
||||||
:src="imgSrc"
|
:src="imgSrc(user.profile_image_url_original)"
|
||||||
:class="{ 'avatar-compact': compact, 'better-shadow': betterShadow }"
|
:class="{ 'avatar-compact': compact, 'better-shadow': betterShadow }"
|
||||||
:image-load-error="imageLoadError"
|
:image-load-error="imageLoadError"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -7,7 +7,7 @@ function showWhoToFollow (panel, reply) {
|
||||||
|
|
||||||
panel.usersToFollow.forEach((toFollow, index) => {
|
panel.usersToFollow.forEach((toFollow, index) => {
|
||||||
let user = shuffled[index]
|
let user = shuffled[index]
|
||||||
let img = user.avatar || '/images/avi.png'
|
let img = user.avatar || this.$store.state.instance.defaultAvatar
|
||||||
let name = user.acct
|
let name = user.acct
|
||||||
|
|
||||||
toFollow.img = img
|
toFollow.img = img
|
||||||
|
@ -38,13 +38,7 @@ function getWhoToFollow (panel) {
|
||||||
|
|
||||||
const WhoToFollowPanel = {
|
const WhoToFollowPanel = {
|
||||||
data: () => ({
|
data: () => ({
|
||||||
usersToFollow: new Array(3).fill().map(x => (
|
usersToFollow: []
|
||||||
{
|
|
||||||
img: '/images/avi.png',
|
|
||||||
name: '',
|
|
||||||
id: 0
|
|
||||||
}
|
|
||||||
))
|
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
user: function () {
|
user: function () {
|
||||||
|
@ -68,6 +62,13 @@ const WhoToFollowPanel = {
|
||||||
},
|
},
|
||||||
mounted:
|
mounted:
|
||||||
function () {
|
function () {
|
||||||
|
this.usersToFollow = new Array(3).fill().map(x => (
|
||||||
|
{
|
||||||
|
img: this.$store.state.instance.defaultAvatar,
|
||||||
|
name: '',
|
||||||
|
id: 0
|
||||||
|
}
|
||||||
|
))
|
||||||
if (this.suggestionsEnabled) {
|
if (this.suggestionsEnabled) {
|
||||||
getWhoToFollow(this)
|
getWhoToFollow(this)
|
||||||
}
|
}
|
||||||
|
|
|
@ -290,9 +290,7 @@
|
||||||
"collapse_subject": "Collapse posts with subjects",
|
"collapse_subject": "Collapse posts with subjects",
|
||||||
"composing": "Composing",
|
"composing": "Composing",
|
||||||
"confirm_new_password": "Confirm new password",
|
"confirm_new_password": "Confirm new password",
|
||||||
"current_avatar": "Your current avatar",
|
|
||||||
"current_password": "Current password",
|
"current_password": "Current password",
|
||||||
"current_profile_banner": "Your current profile banner",
|
|
||||||
"mutes_and_blocks": "Mutes and Blocks",
|
"mutes_and_blocks": "Mutes and Blocks",
|
||||||
"data_import_export_tab": "Data Import / Export",
|
"data_import_export_tab": "Data Import / Export",
|
||||||
"default_vis": "Default visibility scope",
|
"default_vis": "Default visibility scope",
|
||||||
|
@ -399,6 +397,12 @@
|
||||||
"set_new_avatar": "Set new avatar",
|
"set_new_avatar": "Set new avatar",
|
||||||
"set_new_profile_background": "Set new profile background",
|
"set_new_profile_background": "Set new profile background",
|
||||||
"set_new_profile_banner": "Set new profile banner",
|
"set_new_profile_banner": "Set new profile banner",
|
||||||
|
"reset_avatar": "Reset avatar",
|
||||||
|
"reset_profile_background": "Reset profile background",
|
||||||
|
"reset_profile_banner": "Reset profile banner",
|
||||||
|
"reset_avatar_confirm": "Do you really want to reset the avatar?",
|
||||||
|
"reset_banner_confirm": "Do you really want to reset the banner?",
|
||||||
|
"reset_background_confirm": "Do you really want to reset the background?",
|
||||||
"settings": "Settings",
|
"settings": "Settings",
|
||||||
"subject_input_always_show": "Always show subject field",
|
"subject_input_always_show": "Always show subject field",
|
||||||
"subject_line_behavior": "Copy subject when replying",
|
"subject_line_behavior": "Copy subject when replying",
|
||||||
|
|
|
@ -15,6 +15,8 @@ const defaultState = {
|
||||||
|
|
||||||
// Stuff from static/config.json
|
// Stuff from static/config.json
|
||||||
alwaysShowSubjectInput: true,
|
alwaysShowSubjectInput: true,
|
||||||
|
defaultAvatar: '/images/avi.png',
|
||||||
|
defaultBanner: '/images/banner.png',
|
||||||
background: '/static/aurora_borealis.jpg',
|
background: '/static/aurora_borealis.jpg',
|
||||||
collapseMessageWithSubject: false,
|
collapseMessageWithSubject: false,
|
||||||
disableChat: false,
|
disableChat: false,
|
||||||
|
|
|
@ -141,20 +141,11 @@ const updateNotificationSettings = ({ credentials, settings }) => {
|
||||||
}).then((data) => data.json())
|
}).then((data) => data.json())
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateAvatar = ({ credentials, avatar }) => {
|
const updateProfileImages = ({ credentials, avatar = null, banner = null, background = null }) => {
|
||||||
const form = new FormData()
|
const form = new FormData()
|
||||||
form.append('avatar', avatar)
|
if (avatar !== null) form.append('avatar', avatar)
|
||||||
return fetch(MASTODON_PROFILE_UPDATE_URL, {
|
if (banner !== null) form.append('header', banner)
|
||||||
headers: authHeaders(credentials),
|
if (background !== null) form.append('pleroma_background_image', background)
|
||||||
method: 'PATCH',
|
|
||||||
body: form
|
|
||||||
}).then((data) => data.json())
|
|
||||||
.then((data) => parseUser(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
const updateBg = ({ credentials, background }) => {
|
|
||||||
const form = new FormData()
|
|
||||||
form.append('pleroma_background_image', background)
|
|
||||||
return fetch(MASTODON_PROFILE_UPDATE_URL, {
|
return fetch(MASTODON_PROFILE_UPDATE_URL, {
|
||||||
headers: authHeaders(credentials),
|
headers: authHeaders(credentials),
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
|
@ -164,17 +155,6 @@ const updateBg = ({ credentials, background }) => {
|
||||||
.then((data) => parseUser(data))
|
.then((data) => parseUser(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateBanner = ({ credentials, banner }) => {
|
|
||||||
const form = new FormData()
|
|
||||||
form.append('header', banner)
|
|
||||||
return fetch(MASTODON_PROFILE_UPDATE_URL, {
|
|
||||||
headers: authHeaders(credentials),
|
|
||||||
method: 'PATCH',
|
|
||||||
body: form
|
|
||||||
}).then((data) => data.json())
|
|
||||||
.then((data) => parseUser(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
const updateProfile = ({ credentials, params }) => {
|
const updateProfile = ({ credentials, params }) => {
|
||||||
return promisedRequest({
|
return promisedRequest({
|
||||||
url: MASTODON_PROFILE_UPDATE_URL,
|
url: MASTODON_PROFILE_UPDATE_URL,
|
||||||
|
@ -1206,10 +1186,8 @@ const apiService = {
|
||||||
deactivateUser,
|
deactivateUser,
|
||||||
register,
|
register,
|
||||||
getCaptcha,
|
getCaptcha,
|
||||||
updateAvatar,
|
updateProfileImages,
|
||||||
updateBg,
|
|
||||||
updateProfile,
|
updateProfile,
|
||||||
updateBanner,
|
|
||||||
importBlocks,
|
importBlocks,
|
||||||
importFollows,
|
importFollows,
|
||||||
deleteAccount,
|
deleteAccount,
|
||||||
|
|
Loading…
Reference in a new issue