diff --git a/tools/public/assets/cropper/app.js b/tools/public/assets/cropper/app.js index a3b18aa..3b21782 100644 --- a/tools/public/assets/cropper/app.js +++ b/tools/public/assets/cropper/app.js @@ -3,6 +3,7 @@ the save-time OTP (required by a2loft). Notifications are Carbon toasts. */ /* global Vue, axios, Croppa, customElements */ /* window.__SESSION__ is injected server-side by /cropper */ +Vue.use(Croppa); // registers the component — without this the crop UI never renders Vue.config.ignoredElements = [/^cds-/]; (function () { @@ -15,14 +16,13 @@ Vue.config.ignoredElements = [/^cds-/]; data: { loading: true, session: null, - message: { - message: { caption: null, file_url: null, domain: '' }, - }, + message: null, // set once a picture is loaded; null hides the review panel agent: null, process: null, reviewed: false, accepted: false, cleanedImage: null, + cropPreview: '', requiresCleaning: '', otp: '', reviewOptions: [ @@ -62,6 +62,19 @@ Vue.config.ignoredElements = [/^cds-/]; canSave: function () { return !this.busy.save && this.otp.length > 0 && this.requiresCleaning !== ''; }, + otherOptionSelected: function () { + return this.selectedReviewOptions.indexOf('Others not specified.') >= 0; + }, + croppaInstance: function () { + // the v-model object is not always the live instance; the ref is + return this.$refs.croppa || this.myCroppa; + }, + }, + + watch: { + otherOptionSelected: function (selected) { + if (!selected) this.otherReviewOption = ''; // hidden field must not contribute + }, }, created: function () { @@ -96,8 +109,31 @@ Vue.config.ignoredElements = [/^cds-/]; this.toasts = this.toasts.filter(function (t) { return t.id !== id; }); }, + /** + * Current crop result — the operator should see what will be uploaded. + * croppa loads its source image asynchronously, so retry briefly until + * the canvas can produce a URL. + */ + refreshCropPreview: function (attempt) { + var self = this; + var tries = attempt || 0; + this.$nextTick(function () { + try { + var croppa = self.croppaInstance; + self.cropPreview = + croppa && croppa.generateDataUrl ? croppa.generateDataUrl('image/jpeg') || '' : ''; + } catch (error) { + self.cropPreview = ''; + } + if (!self.cropPreview && tries < 12) { + setTimeout(function () { self.refreshCropPreview(tries + 1); }, 200); + } + }); + }, + reset: function () { - this.message = { message: { caption: null, file_url: null, domain: '' } }; + this.cropPreview = ''; + this.message = null; this.agent = null; this.process = null; this.reviewed = false; @@ -137,6 +173,8 @@ Vue.config.ignoredElements = [/^cds-/]; } this.message.message.file_url = image.data.data; this.cleanedImage = null; + this.cropPreview = ''; + this.$nextTick(this.refreshCropPreview); // croppa needs the image first this.agent = null; this.process = this.message.message.process || null; if (this.message.message.upload_id) { @@ -156,7 +194,7 @@ Vue.config.ignoredElements = [/^cds-/]; var self = this; this.busy.clean = true; try { - var dataUrl = this.myCroppa.generateDataUrl('image/jpeg'); + var dataUrl = this.croppaInstance.generateDataUrl('image/jpeg'); var response = await fetch('/cropper/api/removebg', { method: 'POST', headers: { 'Content-Type': 'application/json' }, @@ -174,6 +212,7 @@ Vue.config.ignoredElements = [/^cds-/]; var fr = new FileReader(); fr.onload = function () { self.cleanedImage = fr.result; }; fr.readAsDataURL(blob); + this.refreshCropPreview(); } catch ({ message }) { this.toast('error', 'Image Cleanup Failed', message); } finally { @@ -252,7 +291,7 @@ Vue.config.ignoredElements = [/^cds-/]; var { data } = await axios.post( '/cropper/profile/picture?otp=' + encodeURIComponent(this.otp), { - pictureDataUrl: this.cleanedImage || this.myCroppa.generateDataUrl('image/jpeg'), + pictureDataUrl: this.cleanedImage || this.croppaInstance.generateDataUrl('image/jpeg'), phone: this.message.message.caption, message: this.message, requiresCleaning: this.requiresCleaning !== 'No', diff --git a/tools/public/assets/cropper/index.html b/tools/public/assets/cropper/index.html index 40e9626..7b730cf 100644 --- a/tools/public/assets/cropper/index.html +++ b/tools/public/assets/cropper/index.html @@ -81,11 +81,17 @@
-
- +
+
+