commit: 4f96418143984e23db80e10b5db43779b72118a9
parent: 7206fee4372eba5bb05db9eb90100aee95003962
Author: lain <lain@soykaf.club>
Date: Wed, 8 Jul 2020 10:11:17 +0000
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
Diffstat:
10 files changed, 153 insertions(+), 76 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
@@ -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
- 'Bot' settings option and badge
- 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
- 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
diff --git a/src/components/settings_modal/tabs/profile_tab.js b/src/components/settings_modal/tabs/profile_tab.js
@@ -77,6 +77,33 @@ const ProfileTab = {
},
maxFields () {
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: {
@@ -150,11 +177,29 @@ const ProfileTab = {
}
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) {
const that = this
return new Promise((resolve, reject) => {
function updateAvatar (avatar) {
- that.$store.state.api.backendInteractor.updateAvatar({ avatar })
+ that.$store.state.api.backendInteractor.updateProfileImages({ avatar })
.then((user) => {
that.$store.commit('addNewUsers', [user])
that.$store.commit('setCurrentUser', user)
@@ -172,11 +217,11 @@ const ProfileTab = {
}
})
},
- submitBanner () {
- if (!this.bannerPreview) { return }
+ submitBanner (banner) {
+ if (!this.bannerPreview && banner !== '') { return }
this.bannerUploading = true
- this.$store.state.api.backendInteractor.updateBanner({ banner: this.banner })
+ this.$store.state.api.backendInteractor.updateProfileImages({ banner })
.then((user) => {
this.$store.commit('addNewUsers', [user])
this.$store.commit('setCurrentUser', user)
@@ -187,11 +232,11 @@ const ProfileTab = {
})
.then(() => { this.bannerUploading = false })
},
- submitBg () {
- if (!this.backgroundPreview) { return }
- let background = this.background
+ submitBackground (background) {
+ if (!this.backgroundPreview && background !== '') { return }
+
this.backgroundUploading = true
- this.$store.state.api.backendInteractor.updateBg({ background }).then((data) => {
+ this.$store.state.api.backendInteractor.updateProfileImages({ background }).then((data) => {
if (!data.error) {
this.$store.commit('addNewUsers', [data])
this.$store.commit('setCurrentUser', data)
diff --git a/src/components/settings_modal/tabs/profile_tab.scss b/src/components/settings_modal/tabs/profile_tab.scss
@@ -13,8 +13,14 @@
height: auto;
}
- .banner {
+ .banner-background-preview {
max-width: 100%;
+ width: 300px;
+ position: relative;
+
+ img {
+ width: 100%;
+ }
}
.uploading {
@@ -26,18 +32,40 @@
width: 100%;
}
- .bg {
- max-width: 100%;
+ .current-avatar-container {
+ position: relative;
+ width: 150px;
+ height: 150px;
}
.current-avatar {
display: block;
- width: 150px;
- height: 150px;
+ width: 100%;
+ height: 100%;
border-radius: $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 {
width: 100%;
@@ -86,6 +114,7 @@
&>.emoji-input {
flex: 1 1 auto;
margin: 0 .2em .5em;
+ min-width: 0;
}
&>.icon-container {
diff --git a/src/components/settings_modal/tabs/profile_tab.vue b/src/components/settings_modal/tabs/profile_tab.vue
@@ -161,11 +161,19 @@
<p class="visibility-notice">
{{ $t('settings.avatar_size_instruction') }}
</p>
- <p>{{ $t('settings.current_avatar') }}</p>
- <img
- :src="user.profile_image_url_original"
- class="current-avatar"
- >
+ <div class="current-avatar-container">
+ <img
+ :src="user.profile_image_url_original"
+ 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>
<button
v-show="pickAvatarBtnVisible"
@@ -184,15 +192,20 @@
</div>
<div class="setting-item">
<h2>{{ $t('settings.profile_banner') }}</h2>
- <p>{{ $t('settings.current_profile_banner') }}</p>
- <img
- :src="user.cover_photo"
- class="banner"
- >
+ <div class="banner-background-preview">
+ <img :src="user.cover_photo">
+ <i
+ 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>
<img
v-if="bannerPreview"
- class="banner"
+ class="banner-background-preview"
:src="bannerPreview"
>
<div>
@@ -208,7 +221,7 @@
<button
v-else-if="bannerPreview"
class="btn btn-default"
- @click="submitBanner"
+ @click="submitBanner(banner)"
>
{{ $t('general.submit') }}
</button>
@@ -225,10 +238,20 @@
</div>
<div class="setting-item">
<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>
<img
v-if="backgroundPreview"
- class="bg"
+ class="banner-background-preview"
:src="backgroundPreview"
>
<div>
@@ -244,7 +267,7 @@
<button
v-else-if="backgroundPreview"
class="btn btn-default"
- @click="submitBg"
+ @click="submitBackground(background)"
>
{{ $t('general.submit') }}
</button>
diff --git a/src/components/user_avatar/user_avatar.js b/src/components/user_avatar/user_avatar.js
@@ -8,26 +8,20 @@ const UserAvatar = {
],
data () {
return {
- showPlaceholder: false
+ showPlaceholder: false,
+ defaultAvatar: `${this.$store.state.instance.server + this.$store.state.instance.defaultAvatar}`
}
},
components: {
StillImage
},
- computed: {
- imgSrc () {
- return this.showPlaceholder ? '/images/avi.png' : this.user.profile_image_url_original
- }
- },
methods: {
+ imgSrc (src) {
+ return (!src || this.showPlaceholder) ? this.defaultAvatar : src
+ },
imageLoadError () {
this.showPlaceholder = true
}
- },
- watch: {
- src () {
- this.showPlaceholder = false
- }
}
}
diff --git a/src/components/user_avatar/user_avatar.vue b/src/components/user_avatar/user_avatar.vue
@@ -3,7 +3,7 @@
class="avatar"
:alt="user.screen_name"
:title="user.screen_name"
- :src="imgSrc"
+ :src="imgSrc(user.profile_image_url_original)"
:class="{ 'avatar-compact': compact, 'better-shadow': betterShadow }"
:image-load-error="imageLoadError"
/>
diff --git a/src/components/who_to_follow_panel/who_to_follow_panel.js b/src/components/who_to_follow_panel/who_to_follow_panel.js
@@ -7,7 +7,7 @@ function showWhoToFollow (panel, reply) {
panel.usersToFollow.forEach((toFollow, 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
toFollow.img = img
@@ -38,13 +38,7 @@ function getWhoToFollow (panel) {
const WhoToFollowPanel = {
data: () => ({
- usersToFollow: new Array(3).fill().map(x => (
- {
- img: '/images/avi.png',
- name: '',
- id: 0
- }
- ))
+ usersToFollow: []
}),
computed: {
user: function () {
@@ -68,6 +62,13 @@ const WhoToFollowPanel = {
},
mounted:
function () {
+ this.usersToFollow = new Array(3).fill().map(x => (
+ {
+ img: this.$store.state.instance.defaultAvatar,
+ name: '',
+ id: 0
+ }
+ ))
if (this.suggestionsEnabled) {
getWhoToFollow(this)
}
diff --git a/src/i18n/en.json b/src/i18n/en.json
@@ -290,9 +290,7 @@
"collapse_subject": "Collapse posts with subjects",
"composing": "Composing",
"confirm_new_password": "Confirm new password",
- "current_avatar": "Your current avatar",
"current_password": "Current password",
- "current_profile_banner": "Your current profile banner",
"mutes_and_blocks": "Mutes and Blocks",
"data_import_export_tab": "Data Import / Export",
"default_vis": "Default visibility scope",
@@ -399,6 +397,12 @@
"set_new_avatar": "Set new avatar",
"set_new_profile_background": "Set new profile background",
"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",
"subject_input_always_show": "Always show subject field",
"subject_line_behavior": "Copy subject when replying",
diff --git a/src/modules/instance.js b/src/modules/instance.js
@@ -15,6 +15,8 @@ const defaultState = {
// Stuff from static/config.json
alwaysShowSubjectInput: true,
+ defaultAvatar: '/images/avi.png',
+ defaultBanner: '/images/banner.png',
background: '/static/aurora_borealis.jpg',
collapseMessageWithSubject: false,
disableChat: false,
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
@@ -141,20 +141,11 @@ const updateNotificationSettings = ({ credentials, settings }) => {
}).then((data) => data.json())
}
-const updateAvatar = ({ credentials, avatar }) => {
+const updateProfileImages = ({ credentials, avatar = null, banner = null, background = null }) => {
const form = new FormData()
- form.append('avatar', avatar)
- return fetch(MASTODON_PROFILE_UPDATE_URL, {
- headers: authHeaders(credentials),
- 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)
+ if (avatar !== null) form.append('avatar', avatar)
+ if (banner !== null) form.append('header', banner)
+ if (background !== null) form.append('pleroma_background_image', background)
return fetch(MASTODON_PROFILE_UPDATE_URL, {
headers: authHeaders(credentials),
method: 'PATCH',
@@ -164,17 +155,6 @@ const updateBg = ({ credentials, background }) => {
.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 }) => {
return promisedRequest({
url: MASTODON_PROFILE_UPDATE_URL,
@@ -1206,10 +1186,8 @@ const apiService = {
deactivateUser,
register,
getCaptcha,
- updateAvatar,
- updateBg,
+ updateProfileImages,
updateProfile,
- updateBanner,
importBlocks,
importFollows,
deleteAccount,