@@ -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,
}
},
@@ -1068,6 +1084,16 @@ export default {
return App.util.format.timeAgo(ts);
},
+ formatBytes(bytes, decimals = 2) {
+ if (!+bytes) {
+ return '0 Bytes'
+ }
+ const dec = decimals < 0 ? 0 : decimals
+ const units = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
+ const quotient = Math.floor(Math.log(bytes) / Math.log(1024))
+ return `${parseFloat((bytes / Math.pow(1024, quotient)).toFixed(dec))} ${units[quotient]}`
+ },
+
fetchProfile() {
let tags = {
public: 'Public',
@@ -1178,6 +1204,13 @@ export default {
}, 300);
}).catch(function(e) {
switch(e.response.status) {
+ case 413:
+ self.uploading = false;
+ io.value = null;
+ swal('File is too large', 'The file you uploaded has the size of ' + self.formatBytes(io.size) + '. Unfortunately, only images up to ' + self.formatBytes(self.config.uploader.max_photo_size * 1024) + ' are supported.\nPlease resize the file and try again.', 'error');
+ self.page = 2;
+ break;
+
case 451:
self.uploading = false;
io.value = null;
@@ -1242,6 +1275,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 +1331,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;
@@ -1263,6 +1347,7 @@ export default {
if(count.length) {
swal('Missing media descriptions', 'You have enabled mandatory media descriptions. Please add media descriptions under Advanced settings to proceed. For more information, please see the media settings page.', 'warning');
+ this.isPosting = false;
return;
}
}
@@ -1377,6 +1462,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 +1500,10 @@ export default {
case 'video':
switch(this.page) {
+ case 'filteringMedia':
+ this.page = 2;
+ break;
+
case 'licensePicker':
this.page = 'video-2';
break;
@@ -1431,6 +1524,10 @@ export default {
this.page = 1;
break;
+ case 'filteringMedia':
+ this.page = 2;
+ break;
+
case 'textOptions':
this.page = 'addText';
break;
@@ -1470,6 +1567,9 @@ export default {
this.page = 2;
break;
+ case 'filteringMedia':
+ break;
+
case 'cropPhoto':
this.pageLoading = true;
let self = this;
@@ -1495,14 +1595,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 +1742,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 +1923,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;
diff --git a/resources/assets/js/components/PortfolioSettings.vue b/resources/assets/js/components/PortfolioSettings.vue
index 6b1fbde8a..cd36cd072 100644
--- a/resources/assets/js/components/PortfolioSettings.vue
+++ b/resources/assets/js/components/PortfolioSettings.vue
@@ -238,7 +238,7 @@