diff --git a/src/components/image_cropper/image_cropper.js b/src/components/image_cropper/image_cropper.js index b258024014..4eaa08d4d4 100644 --- a/src/components/image_cropper/image_cropper.js +++ b/src/components/image_cropper/image_cropper.js @@ -1,5 +1,4 @@ import Cropper from 'cropperjs' -import Modal from '../modal/modal.vue' import 'cropperjs/dist/cropper.css' const ImageCropper = { @@ -8,6 +7,10 @@ const ImageCropper = { type: [String, window.Element], required: true }, + submitHandler: { + type: Function, + required: true + }, cropperOptions: { type: Object, default () { @@ -25,10 +28,10 @@ const ImageCropper = { type: String, default: 'image/png, image/gif, image/jpeg, image/bmp, image/x-icon' }, - title: { + saveButtonLabel: { type: String }, - saveButtonLabel: { + cancelButtonLabel: { type: String } }, @@ -36,18 +39,17 @@ const ImageCropper = { return { cropper: undefined, dataUrl: undefined, - filename: undefined + filename: undefined, + submitting: false, + submitError: null } }, - components: { - Modal - }, computed: { - modalTitle () { - return this.title || this.$t('image_cropper.crop_picture') - }, - modalSaveButtonLabel () { + saveText () { return this.saveButtonLabel || this.$t('image_cropper.save') + }, + cancelText () { + return this.cancelButtonLabel || this.$t('image_cropper.cancel') } }, methods: { @@ -57,10 +59,15 @@ const ImageCropper = { } this.$refs.input.value = '' this.dataUrl = undefined + this.$emit('close') }, submit () { - this.$emit('submit', this.cropper, this.filename) - this.destroy() + this.submitting = true + this.avatarUploadError = null + this.submitHandler(this.cropper, this.filename) + .then(() => this.destroy()) + .catch(err => this.submitError = err) + .finally(() => this.submitting = false) }, pickImage () { this.$refs.input.click() @@ -77,11 +84,15 @@ const ImageCropper = { let reader = new window.FileReader() reader.onload = (e) => { this.dataUrl = e.target.result + this.$emit('open') } reader.readAsDataURL(fileInput.files[0]) this.filename = fileInput.files[0].name || 'unknown' this.$emit('changed', fileInput.files[0], reader) } + }, + clearError () { + this.submitError = null } }, mounted () { diff --git a/src/components/image_cropper/image_cropper.vue b/src/components/image_cropper/image_cropper.vue index b2367128df..aa895863a2 100644 --- a/src/components/image_cropper/image_cropper.vue +++ b/src/components/image_cropper/image_cropper.vue @@ -1,15 +1,19 @@ @@ -31,9 +35,8 @@ } } - &-btn { - display: block; - width: 100%; + &-buttons-wrapper { + margin-top: 15px; } } diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js index 8987c6911d..2d521c14c0 100644 --- a/src/components/user_settings/user_settings.js +++ b/src/components/user_settings/user_settings.js @@ -21,13 +21,12 @@ const UserSettings = { followImportError: false, followsImported: false, enableFollowsExport: true, - avatarUploading: false, + pickAvatarBtnVisible: true, bannerUploading: false, backgroundUploading: false, followListUploading: false, bannerPreview: null, backgroundPreview: null, - avatarUploadError: null, bannerUploadError: null, backgroundUploadError: null, deletingAccount: false, @@ -120,15 +119,13 @@ const UserSettings = { }, submitAvatar (cropper) { const img = cropper.getCroppedCanvas({ minWidth: 150, minHeight: 150 }).toDataURL('image/jpeg') - this.avatarUploading = true - this.$store.state.api.backendInteractor.updateAvatar({ params: { img } }).then((user) => { + return this.$store.state.api.backendInteractor.updateAvatar({ params: { img } }).then((user) => { if (!user.error) { this.$store.commit('addNewUsers', [user]) this.$store.commit('setCurrentUser', user) } else { - this.avatarUploadError = this.$t('upload.error.base') + user.error + throw this.$t('upload.error.base') + user.error } - this.avatarUploading = false }) }, clearUploadError (slot) { diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue index 9fcd375255..8ab92e95ef 100644 --- a/src/components/user_settings/user_settings.vue +++ b/src/components/user_settings/user_settings.vue @@ -47,20 +47,11 @@

{{$t('settings.avatar')}}

{{$t('settings.avatar_size_instruction')}}

-
-
- -
- -
-
-
- -
- Error: {{ avatarUploadError }} - -
- +

{{$t('settings.current_avatar')}}

+ +

{{$t('settings.set_new_avatar')}}

+ +

{{$t('settings.profile_banner')}}

@@ -196,29 +187,7 @@ max-width: 100%; } - .avatar-upload { - display: inline-block; - position: relative; - } - - .avatar-upload-loading-wrapper { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - display: flex; - justify-content: center; - align-items: center; - background: rgba(0,0,0,.3); - - i { - font-size: 50px; - color: #FFF; - } - } - - .avatar { + .current-avatar { display: block; width: 150px; height: 150px; diff --git a/src/i18n/en.json b/src/i18n/en.json index 3e9ac15742..af62acfc04 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -23,7 +23,8 @@ }, "image_cropper": { "crop_picture": "Crop picture", - "save": "Save" + "save": "Save", + "cancel": "Cancel" }, "login": { "login": "Log in", @@ -116,7 +117,6 @@ "collapse_subject": "Collapse posts with subjects", "composing": "Composing", "confirm_new_password": "Confirm new password", - "crop_your_new_avatar": "Crop your new avatar", "current_avatar": "Your current avatar", "current_password": "Current password", "current_profile_banner": "Your current profile banner", @@ -211,6 +211,7 @@ "theme_help_v2_1": "You can also override certain component's colors and opacity by toggling the checkbox, use \"Clear all\" button to clear all overrides.", "theme_help_v2_2": "Icons underneath some entries are background/text contrast indicators, hover over for detailed info. Please keep in mind that when using transparency contrast indicators show the worst possible case.", "tooltipRadius": "Tooltips/alerts", + "upload_a_photo": "Upload a photo", "user_settings": "User Settings", "values": { "false": "no",