From 0f0ee803eaa8deef2de9f380c16c9be8349a8df5 Mon Sep 17 00:00:00 2001 From: Justin Georgi Date: Tue, 19 Dec 2023 09:47:05 -0700 Subject: [PATCH] Complete upload framework Signed-off-by: Justin Georgi --- src/components/svg-icon.vue | 14 ++++++++++++- src/pages/detect.vue | 42 +++++++++++++++++++++++++++++-------- src/pages/submit-mixin.js | 14 ++++++++----- 3 files changed, 55 insertions(+), 15 deletions(-) diff --git a/src/components/svg-icon.vue b/src/components/svg-icon.vue index b4d2c16..a8f80b9 100644 --- a/src/components/svg-icon.vue +++ b/src/components/svg-icon.vue @@ -6,6 +6,8 @@ + + @@ -16,7 +18,17 @@ icon: { type: String, validator(value) { - return ['image','videocam','visibility','photo_library','no_photography','photo_camera'].includes(value) + const iconList = [ + 'image', + 'videocam', + 'visibility', + 'photo_library', + 'no_photography', + 'photo_camera', + 'cloud_upload', + 'cloud_done' + ] + return iconList.includes(value) } }, fillColor: { diff --git a/src/pages/detect.vue b/src/pages/detect.vue index 6662f99..2c2cf87 100644 --- a/src/pages/detect.vue +++ b/src/pages/detect.vue @@ -24,20 +24,20 @@ @delete="deleteChip(result.resultIndex)" :style="chipGradient(result.confidence)" /> - No results. + No results. - + - + - - + + @@ -56,7 +56,6 @@ - @@ -84,6 +83,9 @@ + + + @@ -248,7 +250,9 @@ serverSettings: {}, debugOn: false, debugText: ['Variables loaded'], - isCordova: !!window.cordova + isCordova: !!window.cordova, + uploadUid: null, + uploadDirty: false } }, created () { @@ -304,6 +308,7 @@ }, showResults () { var filteredResults = this.resultData.detections + if (!filteredResults) return [] var allSelect = this.detectorLabels.every( s => { return s.detect } ) var selectedLabels = this.detectorLabels .filter( l => { return l.detect }) @@ -314,6 +319,14 @@ filteredResults[i].isSearched = allSelect || selectedLabels.includes(d.label) }) return filteredResults + }, + numResults () { + return this.showResults.filter( r => { return r.aboveThreshold && r.isSearched && !r.isDeleted }).length + }, + viewedAll () { + return this.resultData.detections + .filter( s => { return s.confidence >= this.detectorLevel}) + .every( s => { return s.beenViewed }) } }, methods: { @@ -337,6 +350,7 @@ return; } self.resultData = JSON.parse(xhr.response) + self.uploadDirty = true } var doodsData = { @@ -402,11 +416,13 @@ box.style.top = `${(img.offsetHeight - imgHeight) / 2 + this.resultData.detections[iChip].top * imgHeight}px` box.style.width = `${(Math.min(this.resultData.detections[iChip].right, 1) - Math.max(this.resultData.detections[iChip].left, 0)) * imgWidth}px` box.style.height = `${(Math.min(this.resultData.detections[iChip].bottom, 1) - Math.max(this.resultData.detections[iChip].top, 0)) * imgHeight}px` + this.resultData.detections[iChip].beenViewed = true }, deleteChip ( iChip ) { f7.dialog.confirm(`${this.resultData.detections[iChip].label} is identified with ${this.resultData.detections[iChip].confidence.toFixed(1)}% confidence. Are you sure you want to delete it?`, () => { this.resultData.detections.splice(iChip, 1) this.resetView() + this.uploadDirty = true }); }, getImage (searchImage) { @@ -436,8 +452,16 @@ const box = this.$refs.structure_box box.style.display = 'none' }, - submitData () { - this.uploadData(this.imageView.split(',')[1],this.resultData.detections) + videoStream() { + //TODO + return null + }, + async submitData () { + var uploadData = this.showResults + .filter( d => { return d.aboveThreshold && d.isSearched && !d.isDeleted }) + .map( r => { return {"top": r.top, "left": r.left, "bottom": r.bottom, "right": r.right, "label": r.label}}) + this.uploadUid = await this.uploadData(this.imageView.split(',')[1],uploadData,this.uploadUid) + if (this.uploadUid) { this.uploadDirty = false } } } } diff --git a/src/pages/submit-mixin.js b/src/pages/submit-mixin.js index f5f9d03..bc46fd7 100644 --- a/src/pages/submit-mixin.js +++ b/src/pages/submit-mixin.js @@ -11,9 +11,9 @@ export default { } return uid.join('') }, - uploadData (imagePayload, classPayload) { - let uploadImage =new Promise(resolve => { - const dataUid = this.newUid(16) + uploadData (imagePayload, classPayload, prevUid) { + let uploadImage = new Promise (resolve => { + const dataUid = prevUid || this.newUid(16) var byteChars = window.atob(imagePayload) var byteArrays = [] var len = byteChars.length @@ -34,6 +34,7 @@ export default { var uploadUrl = `https://nextcloud.azgeorgis.net/public.php/webdav/${dataUid}.jpeg` xhrJpg.open("PUT", uploadUrl) xhrJpg.setRequestHeader('Content-Type', 'image/jpeg') + xhrJpg.setRequestHeader('X-Method-Override', 'PUT') xhrJpg.setRequestHeader('X-Requested-With', 'XMLHttpRequest') xhrJpg.setRequestHeader("Authorization", "Basic " + btoa("LKBm3H6JdSaywyg:")) xhrJpg.send(imageBlob) @@ -42,21 +43,24 @@ export default { var uploadUrl = `https://nextcloud.azgeorgis.net/public.php/webdav/${dataUid}.txt` xhrTxt.open("PUT", uploadUrl) xhrTxt.setRequestHeader('Content-Type', 'text/plain') + xhrTxt.setRequestHeader('X-Method-Override', 'PUT') xhrTxt.setRequestHeader('X-Requested-With', 'XMLHttpRequest') xhrTxt.setRequestHeader("Authorization", "Basic " + btoa("LKBm3H6JdSaywyg:")) xhrTxt.send(JSON.stringify(classPayload)) - resolve() + resolve(dataUid) }) - uploadImage.then(() => { + return uploadImage.then((newUid) => { var toast = f7.toast.create({ text: 'Detections Uploaded: thank you.', closeTimeout: 2000 }) toast.open() + return newUid }).catch((e) => { console.log(e.message) f7.dialog.alert(`Error uploading image: ${e.message}`) + return null }) } }