More avatar providers (#200)
Reload the avatar after changing it Hide cropper after upload Fix aspect ratio Add loading variable Move avatar settings to seperate component Add avatar crop Fix avatar upload Add avatar file upload Add abstract methods for file upload Add saving avatar status Add avatar setting Co-authored-by: kolaente <k@knt.li> Reviewed-on: https://kolaente.dev/vikunja/frontend/pulls/200
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
import axios from 'axios'
|
||||
import {reduce, replace} from 'lodash'
|
||||
import { objectToSnakeCase } from '../helpers/case'
|
||||
import {objectToSnakeCase} from '../helpers/case'
|
||||
|
||||
export default class AbstractService {
|
||||
|
||||
@ -10,6 +10,7 @@ export default class AbstractService {
|
||||
|
||||
http = null
|
||||
loading = false
|
||||
uploadProgress = 0
|
||||
paths = {
|
||||
create: '',
|
||||
get: '',
|
||||
@ -134,10 +135,10 @@ export default class AbstractService {
|
||||
pattern = new RegExp(pattern instanceof RegExp ? pattern.source : pattern, 'g')
|
||||
|
||||
for (let parameter; (parameter = pattern.exec(route)) !== null;) {
|
||||
replace$$1[parameter[0]] = parameters[parameter[1]];
|
||||
replace$$1[parameter[0]] = parameters[parameter[1]]
|
||||
}
|
||||
|
||||
return replace$$1;
|
||||
return replace$$1
|
||||
}
|
||||
|
||||
/**
|
||||
@ -443,4 +444,62 @@ export default class AbstractService {
|
||||
cancel()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Uploads a file to a url.
|
||||
* @param url
|
||||
* @param file
|
||||
* @param fieldName The name of the field the file is uploaded to.
|
||||
* @returns {Q.Promise<unknown>}
|
||||
*/
|
||||
uploadFile(url, file, fieldName) {
|
||||
return this.uploadBlob(url, new Blob([file]), fieldName, file.name)
|
||||
}
|
||||
|
||||
/**
|
||||
* Uploads a blob to a url.
|
||||
* @param url
|
||||
* @param blob
|
||||
* @param fieldName
|
||||
* @param filename
|
||||
* @returns {Q.Promise<unknown>}
|
||||
*/
|
||||
uploadBlob(url, blob, fieldName, filename) {
|
||||
const data = new FormData()
|
||||
data.append(fieldName, blob, filename)
|
||||
return this.uploadFormData(url, data)
|
||||
}
|
||||
|
||||
/**
|
||||
* Uploads a form data object.
|
||||
* @param url
|
||||
* @param formData
|
||||
* @returns {Q.Promise<unknown>}
|
||||
*/
|
||||
uploadFormData(url, formData) {
|
||||
const cancel = this.setLoading()
|
||||
return this.http.put(
|
||||
url,
|
||||
formData,
|
||||
{
|
||||
headers: {
|
||||
'Content-Type':
|
||||
'multipart/form-data; boundary=' + formData._boundary,
|
||||
},
|
||||
onUploadProgress: progressEvent => {
|
||||
this.uploadProgress = Math.round((progressEvent.loaded * 100) / progressEvent.total)
|
||||
},
|
||||
},
|
||||
)
|
||||
.catch(error => {
|
||||
return this.errorHandler(error)
|
||||
})
|
||||
.then(response => {
|
||||
return Promise.resolve(this.modelCreateFactory(response.data))
|
||||
})
|
||||
.finally(() => {
|
||||
this.uploadProgress = 0
|
||||
cancel()
|
||||
})
|
||||
}
|
||||
}
|
@ -16,8 +16,6 @@ export default class AttachmentService extends AbstractService {
|
||||
return model
|
||||
}
|
||||
|
||||
uploadProgress = 0
|
||||
|
||||
useCreateInterceptor() {
|
||||
return false
|
||||
}
|
||||
@ -61,36 +59,15 @@ export default class AttachmentService extends AbstractService {
|
||||
* @returns {Promise<any|never>}
|
||||
*/
|
||||
create(model, files) {
|
||||
|
||||
let data = new FormData()
|
||||
const data = new FormData()
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
// TODO: Validation of file size
|
||||
data.append('files', new Blob([files[i]]), files[i].name);
|
||||
}
|
||||
|
||||
const cancel = this.setLoading()
|
||||
return this.http.put(
|
||||
return this.uploadFormData(
|
||||
this.getReplacedRoute(this.paths.create, model),
|
||||
data,
|
||||
{
|
||||
headers: {
|
||||
'Content-Type':
|
||||
'multipart/form-data; boundary=' + data._boundary,
|
||||
},
|
||||
onUploadProgress: progressEvent => {
|
||||
this.uploadProgress = Math.round( (progressEvent.loaded * 100) / progressEvent.total );
|
||||
}
|
||||
}
|
||||
data
|
||||
)
|
||||
.catch(error => {
|
||||
return this.errorHandler(error)
|
||||
})
|
||||
.then(response => {
|
||||
return Promise.resolve(this.modelCreateFactory(response.data))
|
||||
})
|
||||
.finally(() => {
|
||||
this.uploadProgress = 0
|
||||
cancel()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
29
src/services/avatar.js
Normal file
29
src/services/avatar.js
Normal file
@ -0,0 +1,29 @@
|
||||
import AbstractService from './abstractService'
|
||||
import AvatarModel from '../models/avatar'
|
||||
|
||||
export default class AvatarService extends AbstractService {
|
||||
constructor() {
|
||||
super({
|
||||
get: '/user/settings/avatar',
|
||||
update: '/user/settings/avatar',
|
||||
create: '/user/settings/avatar/upload',
|
||||
})
|
||||
}
|
||||
|
||||
modelFactory(data) {
|
||||
return new AvatarModel(data)
|
||||
}
|
||||
|
||||
useCreateInterceptor() {
|
||||
return false
|
||||
}
|
||||
|
||||
create(blob) {
|
||||
return this.uploadBlob(
|
||||
this.paths.create,
|
||||
blob,
|
||||
'avatar',
|
||||
'avatar.jpg', // This fails without a file name
|
||||
)
|
||||
}
|
||||
}
|
@ -8,8 +8,6 @@ export default class BackgroundUploadService extends AbstractService {
|
||||
})
|
||||
}
|
||||
|
||||
uploadProgress = 0
|
||||
|
||||
useCreateInterceptor() {
|
||||
return false
|
||||
}
|
||||
@ -25,33 +23,10 @@ export default class BackgroundUploadService extends AbstractService {
|
||||
* @returns {Promise<any|never>}
|
||||
*/
|
||||
create(listId, file) {
|
||||
|
||||
let data = new FormData()
|
||||
data.append('background', new Blob([file]), file.name);
|
||||
|
||||
const cancel = this.setLoading()
|
||||
return this.http.put(
|
||||
return this.uploadFile(
|
||||
this.getReplacedRoute(this.paths.create, {listId: listId}),
|
||||
data,
|
||||
{
|
||||
headers: {
|
||||
'Content-Type':
|
||||
'multipart/form-data; boundary=' + data._boundary,
|
||||
},
|
||||
onUploadProgress: progressEvent => {
|
||||
this.uploadProgress = Math.round((progressEvent.loaded * 100) / progressEvent.total);
|
||||
}
|
||||
}
|
||||
file,
|
||||
'background'
|
||||
)
|
||||
.catch(error => {
|
||||
return this.errorHandler(error)
|
||||
})
|
||||
.then(response => {
|
||||
return Promise.resolve(this.modelCreateFactory(response.data))
|
||||
})
|
||||
.finally(() => {
|
||||
this.uploadProgress = 0
|
||||
cancel()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user