From 56e315f69ff29672f9226cbc4429dd1eb86c8c29 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sun, 22 Oct 2023 21:13:55 -0600 Subject: [PATCH] Update ComposeModal component, fix multi filter bug and allow media re-ordering before upload/posting --- .../assets/js/components/ComposeModal.vue | 242 +++++++++++++----- 1 file changed, 173 insertions(+), 69 deletions(-) diff --git a/resources/assets/js/components/ComposeModal.vue b/resources/assets/js/components/ComposeModal.vue index 578679d32..745284859 100644 --- a/resources/assets/js/components/ComposeModal.vue +++ b/resources/assets/js/components/ComposeModal.vue @@ -178,9 +178,13 @@ Next - Post + Post - Post + Post + Next @@ -201,10 +205,10 @@ -
+
-
+
@@ -236,7 +240,7 @@
-
+
@@ -337,7 +341,7 @@
-
+
-
+
@@ -368,7 +372,9 @@ @@ -376,20 +382,21 @@
-
-
+
@@ -524,7 +531,7 @@
-
+
When you tag someone, they are sent a notification.
For more information on tagging, click here.

-
+

Tagging someone is like mentioning them, with the option to make it private between you.

You can choose to tag someone in public or private mode. Public mode will allow others to see who you tagged in the post and private mode tagged users will not be shown to others.

-
+

Add Location

-
+
@@ -910,6 +923,7 @@ export default { }, namedPages: [ + 'filteringMedia', 'cropPhoto', 'tagPeople', 'addLocation', @@ -943,7 +957,6 @@ export default { cb(res.data); }) .catch(err => { - console.log(err); }) }) }, @@ -957,7 +970,6 @@ export default { cb(res.data); }) .catch(err => { - console.log(err); }) }) } @@ -1032,6 +1044,10 @@ export default { collectionsPage: 1, collectionsCanLoadMore: false, spoilerText: undefined, + isFilteringMedia: false, + filteringMediaTimeout: undefined, + filteringRemainingCount: 0, + isPosting: false, } }, @@ -1242,6 +1258,50 @@ export default { }); }, + mediaReorder(dir) { + const m = this.media; + const cur = this.carouselCursor; + const pla = m[cur]; + let res = []; + let cursor = 0; + + if(dir == 'prev') { + if(cur == 0) { + for (let i = cursor; i < m.length - 1; i++) { + res[i] = m[i+1]; + } + res[m.length - 1] = pla; + cursor = 0; + } else { + res = this.handleSwap(m, cur, cur - 1); + cursor = cur - 1; + } + } else { + if(cur == m.length - 1) { + res = m; + let lastItem = res.pop(); + res.unshift(lastItem); + cursor = m.length - 1; + } else { + res = this.handleSwap(m, cur, cur + 1); + cursor = cur + 1; + } + } + this.$nextTick(() => { + this.media = res; + this.carouselCursor = cursor; + }) + }, + + handleSwap(arr, index1, index2) { + if (index1 >= 0 && index1 < arr.length && index2 >= 0 && index2 < arr.length) { + const temp = arr[index1]; + arr[index1] = arr[index2]; + arr[index2] = temp; + return arr; + } + }, + compose() { let state = this.composeState; @@ -1254,8 +1314,15 @@ export default { return; } + switch(state) { - case 'publish' : + case 'publish': + this.isPosting = true; + let count = this.media.filter(m => m.filter_class && !m.hasOwnProperty('is_filtered')).length; + if(count) { + this.applyFilterToMedia(); + return; + } if(this.composeSettings.media_descriptions === true) { let count = this.media.filter(m => { return !m.hasOwnProperty('alt') || m.alt.length < 2; @@ -1377,6 +1444,10 @@ export default { switch(this.mode) { case 'photo': switch(this.page) { + case 'filteringMedia': + this.page = 2; + break; + case 'addText': this.page = 1; break; @@ -1411,6 +1482,10 @@ export default { case 'video': switch(this.page) { + case 'filteringMedia': + this.page = 2; + break; + case 'licensePicker': this.page = 'video-2'; break; @@ -1431,6 +1506,10 @@ export default { this.page = 1; break; + case 'filteringMedia': + this.page = 2; + break; + case 'textOptions': this.page = 'addText'; break; @@ -1470,6 +1549,9 @@ export default { this.page = 2; break; + case 'filteringMedia': + break; + case 'cropPhoto': this.pageLoading = true; let self = this; @@ -1495,14 +1577,7 @@ export default { break; case 2: - if(this.currentFilter) { - if(window.confirm('Are you sure you want to apply this filter?')) { - this.applyFilterToMedia(); - this.page++; - } - } else { this.page++; - } break; case 3: this.page++; @@ -1649,43 +1724,73 @@ export default { // this is where the magic happens var ua = navigator.userAgent.toLowerCase(); if(ua.indexOf('firefox') == -1 && ua.indexOf('chrome') == -1) { + this.isPosting = false; swal('Oops!', 'Your browser does not support the filter feature.', 'error'); + this.page = 3; return; } - let medias = this.media; - let media = null; - const canvas = document.getElementById('pr_canvas'); - const ctx = canvas.getContext('2d'); - let image = document.getElementById('pr_img'); - let blob = null; - let data = null; - - for (var i = medias.length - 1; i >= 0; i--) { - media = medias[i]; - if(media.filter_class) { - image.src = media.url; - image.addEventListener('load', e => { - canvas.width = image.width; - canvas.height = image.height; - ctx.filter = App.util.filterCss[media.filter_class]; - ctx.drawImage(image, 0, 0, image.width, image.height); - ctx.save(); - canvas.toBlob(function(blob) { - data = new FormData(); - data.append('file', blob); - data.append('id', media.id); - axios.post('/api/compose/v0/media/update', data).then(res => { - }).catch(err => { - }); - }); - }, media.mime, 0.9); - ctx.clearRect(0, 0, image.width, image.height); - } - } - + let count = this.media.filter(m => m.filter_class).length; + if(count) { + this.page = 'filteringMedia'; + this.filteringRemainingCount = count; + this.$nextTick(() => { + this.isFilteringMedia = true; + this.media.forEach((media, idx) => this.applyFilterToMediaSave(media, idx)); + }) + } else { + this.page = 3; + } }, + applyFilterToMediaSave(media, idx) { + if(!media.filter_class) { + return; + } + + let self = this; + let data = null; + const canvas = document.createElement('canvas'); + const ctx = canvas.getContext('2d'); + let image = document.createElement('img'); + image.src = media.url; + image.addEventListener('load', e => { + canvas.width = image.width; + canvas.height = image.height; + ctx.filter = App.util.filterCss[media.filter_class]; + ctx.drawImage(image, 0, 0, image.width, image.height); + ctx.save(); + canvas.toBlob(function(blob) { + data = new FormData(); + data.append('file', blob); + data.append('id', media.id); + axios.post('/api/compose/v0/media/update', data) + .then(res => { + self.media[idx].is_filtered = true; + self.updateFilteringMedia(); + }).catch(err => { + }); + }); + }, media.mime, 0.9); + ctx.clearRect(0, 0, image.width, image.height); + }, + + updateFilteringMedia() { + this.filteringRemainingCount--; + this.filteringMediaTimeout = setTimeout(() => this.filteringMediaTimeoutJob(), 500); + }, + + filteringMediaTimeoutJob() { + if(this.filteringRemainingCount === 0) { + this.isFilteringMedia = false; + clearTimeout(this.filteringMediaTimeout); + setTimeout(() => this.compose(), 500); + } else { + clearTimeout(this.filteringMediaTimeout); + this.filteringMediaTimeout = setTimeout(() => this.filteringMediaTimeoutJob(), 1000); + } + }, + tagSearch(input) { if (input.length < 1) { return []; } let self = this; @@ -1800,7 +1905,6 @@ export default { } window.location.href = res.data.url; }).catch(err => { - console.log(err.response.data.error); if(err.response.data.hasOwnProperty('error')) { if(err.response.data.error == 'Duplicate detected.') { this.postingPoll = false;