Skip to content

Instantly share code, notes, and snippets.

@dimensi
Last active April 4, 2018 10:11
Show Gist options
  • Save dimensi/0b7d8ee3776736f533c8739ffdd2d417 to your computer and use it in GitHub Desktop.
Save dimensi/0b7d8ee3776736f533c8739ffdd2d417 to your computer and use it in GitHub Desktop.
AvatarUploader
<template>
<Avatar
editMode
:image="avatar"
@changeFile="onFileChange"
@edit="editPhoto"
:size="size"
:color="color"
@remove="removePhoto"/>
</template>
<script>
import { mapperApi } from 'src/utils/api';
const imageApi = mapperApi(require('src/api/images').default);
class UploaderError extends Error {
constructor(status) {
super(status);
Error.captureStackTrace(this, UploaderError);
this.name = 'UploaderError';
this.status = status;
this.message = `Image was ${status}`;
}
}
export default {
name: 'AvatarUploader',
model: {
prop: 'uploaderStarter',
event: 'change',
},
props: ['image', 'options', 'size', 'color'],
data() {
return {
file: null,
avatar: null,
imageToSend: {},
imageWasDeleted: false,
imageWasEdited: false,
};
},
created() {
if (this.image) {
this.file = this.image;
this.avatar = this.image.thumbnail;
}
},
methods: {
removePhoto() {
this.file = null;
this.avatar = null;
this.imageToSend = {};
this.imageWasDeleted = true;
this.$emit('change', this.getImage);
},
editPhoto() {
let file;
let status;
if (this.file instanceof File) {
file = this.file;
status = 'new';
} else if (this.file instanceof Object) {
file = this.file.image;
status = 'edited';
}
this.openCropper(file, status);
},
onFileChange(e) {
const files = e.target.files || e.dataTransfer.files;
if (!files.length) return;
this.openCropper(files[0], 'new');
},
doneCrop({ file, croppedImage, options }, status) {
this.imageToSend = {};
this.file = file;
this.avatar = croppedImage;
if (status === 'new') {
this.imageWasDeleted = false;
this.imageWasEdited = false;
this.imageToSend.image = file;
}
if (status === 'edited') {
this.imageWasDeleted = false;
this.imageWasEdited = true;
this.imageToSend.id = this.image.id;
}
this.imageToSend.options = options;
this.$emit('change', this.getImage);
},
openCropper(file, status) {
this.$store.dispatch('CropperModal', {
file,
options: this.options,
done: cropObject => {
this.doneCrop(cropObject, status);
},
});
},
async getImage() {
const imageToSend = this.imageToSend;
let dataForImage;
let response;
if (this.imageWasDeleted) {
throw new UploaderError('deleted');
}
if (this.imageWasEdited) {
dataForImage = { ...imageToSend.options };
response = await imageApi.updateImage(imageToSend.id, dataForImage);
if (response) {
throw new UploaderError('edited');
}
}
if (imageToSend.image) {
dataForImage = new FormData();
dataForImage.append('image', this.imageToSend.image);
Object.keys(imageToSend.options).forEach(key => {
dataForImage.append(key, imageToSend.options[key]);
});
response = await imageApi.setImage(dataForImage);
}
return response.image;
},
},
};
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment