Merge branch '437-user-profile-settings' into 'develop'
Transition to MastoAPI: user profile settings Closes #437 See merge request pleroma/pleroma-fe!682
This commit is contained in:
commit
0f7f685c5e
5 changed files with 66 additions and 136 deletions
|
@ -70,22 +70,10 @@ const ImageCropper = {
|
||||||
this.dataUrl = undefined
|
this.dataUrl = undefined
|
||||||
this.$emit('close')
|
this.$emit('close')
|
||||||
},
|
},
|
||||||
submit () {
|
submit (cropping = true) {
|
||||||
this.submitting = true
|
this.submitting = true
|
||||||
this.avatarUploadError = null
|
this.avatarUploadError = null
|
||||||
this.submitHandler(this.cropper, this.file)
|
this.submitHandler(cropping && this.cropper, this.file)
|
||||||
.then(() => this.destroy())
|
|
||||||
.catch((err) => {
|
|
||||||
this.submitError = err
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
this.submitting = false
|
|
||||||
})
|
|
||||||
},
|
|
||||||
submitWithoutCropping () {
|
|
||||||
this.submitting = true
|
|
||||||
this.avatarUploadError = null
|
|
||||||
this.submitHandler(false, this.dataUrl)
|
|
||||||
.then(() => this.destroy())
|
.then(() => this.destroy())
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
this.submitError = err
|
this.submitError = err
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
<img ref="img" :src="dataUrl" alt="" @load.stop="createCropper" />
|
<img ref="img" :src="dataUrl" alt="" @load.stop="createCropper" />
|
||||||
</div>
|
</div>
|
||||||
<div class="image-cropper-buttons-wrapper">
|
<div class="image-cropper-buttons-wrapper">
|
||||||
<button class="btn" type="button" :disabled="submitting" @click="submit" v-text="saveText"></button>
|
<button class="btn" type="button" :disabled="submitting" @click="submit()" v-text="saveText"></button>
|
||||||
<button class="btn" type="button" :disabled="submitting" @click="destroy" v-text="cancelText"></button>
|
<button class="btn" type="button" :disabled="submitting" @click="destroy" v-text="cancelText"></button>
|
||||||
<button class="btn" type="button" :disabled="submitting" @click="submitWithoutCropping" v-text="saveWithoutCroppingText"></button>
|
<button class="btn" type="button" :disabled="submitting" @click="submit(false)" v-text="saveWithoutCroppingText"></button>
|
||||||
<i class="icon-spin4 animate-spin" v-if="submitting"></i>
|
<i class="icon-spin4 animate-spin" v-if="submitting"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="alert error" v-if="submitError">
|
<div class="alert error" v-if="submitError">
|
||||||
|
|
|
@ -109,37 +109,23 @@ const UserSettings = {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
updateProfile () {
|
updateProfile () {
|
||||||
const name = this.newName
|
|
||||||
const description = this.newBio
|
|
||||||
const locked = this.newLocked
|
|
||||||
// Backend notation.
|
|
||||||
/* eslint-disable camelcase */
|
|
||||||
const default_scope = this.newDefaultScope
|
|
||||||
const no_rich_text = this.newNoRichText
|
|
||||||
const hide_follows = this.hideFollows
|
|
||||||
const hide_followers = this.hideFollowers
|
|
||||||
const show_role = this.showRole
|
|
||||||
|
|
||||||
/* eslint-enable camelcase */
|
|
||||||
this.$store.state.api.backendInteractor
|
this.$store.state.api.backendInteractor
|
||||||
.updateProfile({
|
.updateProfile({
|
||||||
params: {
|
params: {
|
||||||
name,
|
note: this.newBio,
|
||||||
description,
|
locked: this.newLocked,
|
||||||
locked,
|
|
||||||
// Backend notation.
|
// Backend notation.
|
||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
default_scope,
|
display_name: this.newName,
|
||||||
no_rich_text,
|
default_scope: this.newDefaultScope,
|
||||||
hide_follows,
|
no_rich_text: this.newNoRichText,
|
||||||
hide_followers,
|
hide_follows: this.hideFollows,
|
||||||
show_role
|
hide_followers: this.hideFollowers,
|
||||||
|
show_role: this.showRole
|
||||||
/* eslint-enable camelcase */
|
/* eslint-enable camelcase */
|
||||||
}}).then((user) => {
|
}}).then((user) => {
|
||||||
if (!user.error) {
|
this.$store.commit('addNewUsers', [user])
|
||||||
this.$store.commit('addNewUsers', [user])
|
this.$store.commit('setCurrentUser', user)
|
||||||
this.$store.commit('setCurrentUser', user)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
changeVis (visibility) {
|
changeVis (visibility) {
|
||||||
|
@ -159,23 +145,29 @@ const UserSettings = {
|
||||||
reader.onload = ({target}) => {
|
reader.onload = ({target}) => {
|
||||||
const img = target.result
|
const img = target.result
|
||||||
this[slot + 'Preview'] = img
|
this[slot + 'Preview'] = img
|
||||||
|
this[slot] = file
|
||||||
}
|
}
|
||||||
reader.readAsDataURL(file)
|
reader.readAsDataURL(file)
|
||||||
},
|
},
|
||||||
submitAvatar (cropper, file) {
|
submitAvatar (cropper, file) {
|
||||||
let img
|
const that = this
|
||||||
if (cropper) {
|
return new Promise((resolve, reject) => {
|
||||||
img = cropper.getCroppedCanvas().toDataURL(file.type)
|
function updateAvatar (avatar) {
|
||||||
} else {
|
that.$store.state.api.backendInteractor.updateAvatar({ avatar })
|
||||||
img = file
|
.then((user) => {
|
||||||
}
|
that.$store.commit('addNewUsers', [user])
|
||||||
|
that.$store.commit('setCurrentUser', user)
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
reject(new Error(that.$t('upload.error.base') + ' ' + err.message))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return this.$store.state.api.backendInteractor.updateAvatar({ params: { img } }).then((user) => {
|
if (cropper) {
|
||||||
if (!user.error) {
|
cropper.getCroppedCanvas().toBlob(updateAvatar, file.type)
|
||||||
this.$store.commit('addNewUsers', [user])
|
|
||||||
this.$store.commit('setCurrentUser', user)
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error(this.$t('upload.error.base') + user.error)
|
updateAvatar(file)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
@ -185,30 +177,17 @@ const UserSettings = {
|
||||||
submitBanner () {
|
submitBanner () {
|
||||||
if (!this.bannerPreview) { return }
|
if (!this.bannerPreview) { return }
|
||||||
|
|
||||||
let banner = this.bannerPreview
|
|
||||||
// eslint-disable-next-line no-undef
|
|
||||||
let imginfo = new Image()
|
|
||||||
/* eslint-disable camelcase */
|
|
||||||
let offset_top, offset_left, width, height
|
|
||||||
imginfo.src = banner
|
|
||||||
width = imginfo.width
|
|
||||||
height = imginfo.height
|
|
||||||
offset_top = 0
|
|
||||||
offset_left = 0
|
|
||||||
this.bannerUploading = true
|
this.bannerUploading = true
|
||||||
this.$store.state.api.backendInteractor.updateBanner({params: {banner, offset_top, offset_left, width, height}}).then((data) => {
|
this.$store.state.api.backendInteractor.updateBanner({banner: this.banner})
|
||||||
if (!data.error) {
|
.then((user) => {
|
||||||
let clone = JSON.parse(JSON.stringify(this.$store.state.users.currentUser))
|
this.$store.commit('addNewUsers', [user])
|
||||||
clone.cover_photo = data.url
|
this.$store.commit('setCurrentUser', user)
|
||||||
this.$store.commit('addNewUsers', [clone])
|
|
||||||
this.$store.commit('setCurrentUser', clone)
|
|
||||||
this.bannerPreview = null
|
this.bannerPreview = null
|
||||||
} else {
|
})
|
||||||
this.bannerUploadError = this.$t('upload.error.base') + data.error
|
.catch((err) => {
|
||||||
}
|
this.bannerUploadError = this.$t('upload.error.base') + ' ' + err.message
|
||||||
this.bannerUploading = false
|
})
|
||||||
})
|
.then(() => { this.bannerUploading = false })
|
||||||
/* eslint-enable camelcase */
|
|
||||||
},
|
},
|
||||||
submitBg () {
|
submitBg () {
|
||||||
if (!this.backgroundPreview) { return }
|
if (!this.backgroundPreview) { return }
|
||||||
|
|
|
@ -3,10 +3,7 @@ const LOGIN_URL = '/api/account/verify_credentials.json'
|
||||||
const ALL_FOLLOWING_URL = '/api/qvitter/allfollowing'
|
const ALL_FOLLOWING_URL = '/api/qvitter/allfollowing'
|
||||||
const MENTIONS_URL = '/api/statuses/mentions.json'
|
const MENTIONS_URL = '/api/statuses/mentions.json'
|
||||||
const REGISTRATION_URL = '/api/account/register.json'
|
const REGISTRATION_URL = '/api/account/register.json'
|
||||||
const AVATAR_UPDATE_URL = '/api/qvitter/update_avatar.json'
|
|
||||||
const BG_UPDATE_URL = '/api/qvitter/update_background_image.json'
|
const BG_UPDATE_URL = '/api/qvitter/update_background_image.json'
|
||||||
const BANNER_UPDATE_URL = '/api/account/update_profile_banner.json'
|
|
||||||
const PROFILE_UPDATE_URL = '/api/account/update_profile.json'
|
|
||||||
const EXTERNAL_PROFILE_URL = '/api/externalprofile/show.json'
|
const EXTERNAL_PROFILE_URL = '/api/externalprofile/show.json'
|
||||||
const QVITTER_USER_NOTIFICATIONS_READ_URL = '/api/qvitter/statuses/notifications/read.json'
|
const QVITTER_USER_NOTIFICATIONS_READ_URL = '/api/qvitter/statuses/notifications/read.json'
|
||||||
const BLOCKS_IMPORT_URL = '/api/pleroma/blocks_import'
|
const BLOCKS_IMPORT_URL = '/api/pleroma/blocks_import'
|
||||||
|
@ -50,6 +47,7 @@ const MASTODON_MUTE_USER_URL = id => `/api/v1/accounts/${id}/mute`
|
||||||
const MASTODON_UNMUTE_USER_URL = id => `/api/v1/accounts/${id}/unmute`
|
const MASTODON_UNMUTE_USER_URL = id => `/api/v1/accounts/${id}/unmute`
|
||||||
const MASTODON_POST_STATUS_URL = '/api/v1/statuses'
|
const MASTODON_POST_STATUS_URL = '/api/v1/statuses'
|
||||||
const MASTODON_MEDIA_UPLOAD_URL = '/api/v1/media'
|
const MASTODON_MEDIA_UPLOAD_URL = '/api/v1/media'
|
||||||
|
const MASTODON_PROFILE_UPDATE_URL = '/api/v1/accounts/update_credentials'
|
||||||
|
|
||||||
import { each, map, concat, last } from 'lodash'
|
import { each, map, concat, last } from 'lodash'
|
||||||
import { parseStatus, parseUser, parseNotification, parseAttachment } from '../entity_normalizer/entity_normalizer.service.js'
|
import { parseStatus, parseUser, parseNotification, parseAttachment } from '../entity_normalizer/entity_normalizer.service.js'
|
||||||
|
@ -79,28 +77,16 @@ const promisedRequest = (url, options) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Params
|
const updateAvatar = ({credentials, avatar}) => {
|
||||||
// cropH
|
|
||||||
// cropW
|
|
||||||
// cropX
|
|
||||||
// cropY
|
|
||||||
// img (base 64 encodend data url)
|
|
||||||
const updateAvatar = ({credentials, params}) => {
|
|
||||||
let url = AVATAR_UPDATE_URL
|
|
||||||
|
|
||||||
const form = new FormData()
|
const form = new FormData()
|
||||||
|
form.append('avatar', avatar)
|
||||||
each(params, (value, key) => {
|
return fetch(MASTODON_PROFILE_UPDATE_URL, {
|
||||||
if (value) {
|
|
||||||
form.append(key, value)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return fetch(url, {
|
|
||||||
headers: authHeaders(credentials),
|
headers: authHeaders(credentials),
|
||||||
method: 'POST',
|
method: 'PATCH',
|
||||||
body: form
|
body: form
|
||||||
}).then((data) => data.json())
|
})
|
||||||
|
.then((data) => data.json())
|
||||||
|
.then((data) => parseUser(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateBg = ({credentials, params}) => {
|
const updateBg = ({credentials, params}) => {
|
||||||
|
@ -121,52 +107,29 @@ const updateBg = ({credentials, params}) => {
|
||||||
}).then((data) => data.json())
|
}).then((data) => data.json())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Params
|
const updateBanner = ({credentials, banner}) => {
|
||||||
// height
|
|
||||||
// width
|
|
||||||
// offset_left
|
|
||||||
// offset_top
|
|
||||||
// banner (base 64 encodend data url)
|
|
||||||
const updateBanner = ({credentials, params}) => {
|
|
||||||
let url = BANNER_UPDATE_URL
|
|
||||||
|
|
||||||
const form = new FormData()
|
const form = new FormData()
|
||||||
|
form.append('header', banner)
|
||||||
each(params, (value, key) => {
|
return fetch(MASTODON_PROFILE_UPDATE_URL, {
|
||||||
if (value) {
|
|
||||||
form.append(key, value)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return fetch(url, {
|
|
||||||
headers: authHeaders(credentials),
|
headers: authHeaders(credentials),
|
||||||
method: 'POST',
|
method: 'PATCH',
|
||||||
body: form
|
body: form
|
||||||
}).then((data) => data.json())
|
})
|
||||||
|
.then((data) => data.json())
|
||||||
|
.then((data) => parseUser(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Params
|
|
||||||
// name
|
|
||||||
// url
|
|
||||||
// location
|
|
||||||
// description
|
|
||||||
const updateProfile = ({credentials, params}) => {
|
const updateProfile = ({credentials, params}) => {
|
||||||
// Always include these fields, because they might be empty or false
|
return promisedRequest(MASTODON_PROFILE_UPDATE_URL, {
|
||||||
const fields = ['description', 'locked', 'no_rich_text', 'hide_follows', 'hide_followers', 'show_role']
|
headers: {
|
||||||
let url = PROFILE_UPDATE_URL
|
'Accept': 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
const form = new FormData()
|
...authHeaders(credentials)
|
||||||
|
},
|
||||||
each(params, (value, key) => {
|
method: 'PATCH',
|
||||||
if (fields.includes(key) || value) {
|
body: JSON.stringify(params)
|
||||||
form.append(key, value)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
return fetch(url, {
|
.then((data) => parseUser(data))
|
||||||
headers: authHeaders(credentials),
|
|
||||||
method: 'POST',
|
|
||||||
body: form
|
|
||||||
}).then((data) => data.json())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Params needed:
|
// Params needed:
|
||||||
|
|
|
@ -101,9 +101,9 @@ const backendInteractorService = (credentials) => {
|
||||||
|
|
||||||
const getCaptcha = () => apiService.getCaptcha()
|
const getCaptcha = () => apiService.getCaptcha()
|
||||||
const register = (params) => apiService.register(params)
|
const register = (params) => apiService.register(params)
|
||||||
const updateAvatar = ({params}) => apiService.updateAvatar({credentials, params})
|
const updateAvatar = ({avatar}) => apiService.updateAvatar({credentials, avatar})
|
||||||
const updateBg = ({params}) => apiService.updateBg({credentials, params})
|
const updateBg = ({params}) => apiService.updateBg({credentials, params})
|
||||||
const updateBanner = ({params}) => apiService.updateBanner({credentials, params})
|
const updateBanner = ({banner}) => apiService.updateBanner({credentials, banner})
|
||||||
const updateProfile = ({params}) => apiService.updateProfile({credentials, params})
|
const updateProfile = ({params}) => apiService.updateProfile({credentials, params})
|
||||||
|
|
||||||
const externalProfile = (profileUrl) => apiService.externalProfile({profileUrl, credentials})
|
const externalProfile = (profileUrl) => apiService.externalProfile({profileUrl, credentials})
|
||||||
|
|
Loading…
Reference in a new issue