aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrr-2016-09-29 22:26:37 +0200
committerrr-2016-09-29 22:26:37 +0200
commit7648f479a9660794700a51dc9f9ca51264a1dd71 (patch)
tree5ce9a813c80f5983e59f94f63eab46eb617feaf1
parent7862fecbc990a580970aaeef9de5667da268cc9f (diff)
client/posts: add 'skip duplicates' to upload form
Closes #102
-rw-r--r--client/css/post-upload.styl16
-rw-r--r--client/html/post_upload.tpl15
-rw-r--r--client/js/controllers/post_upload_controller.js47
-rw-r--r--client/js/views/post_upload_view.js24
4 files changed, 68 insertions, 34 deletions
diff --git a/client/css/post-upload.styl b/client/css/post-upload.styl
index 7bf9fbe..b9d18a5 100644
--- a/client/css/post-upload.styl
+++ b/client/css/post-upload.styl
@@ -9,9 +9,12 @@ $cancel-button-color = tomato
margin: 0 auto
text-align: left
- &.inactive
- input[type=submit]
- display: none
+ &.inactive input[type=submit],
+ &.inactive .skip-duplicates
+ &.uploading input[type=submit],
+ &.uploading .skip-duplicates,
+ &:not(.uploading) .cancel
+ display: none
.dropper-container
margin: 0 auto
@@ -21,18 +24,17 @@ $cancel-button-color = tomato
input[type=submit]
margin-top: 1em
- &[disabled]
- display: none
.cancel
margin-top: 1em
background: $cancel-button-color
border-color: $cancel-button-color
- &[disabled]
- display: none
&:focus
border: 2px solid $text-color
+ .skip-duplicates
+ margin-left: 1em
+
.messages
margin-top: 1em
diff --git a/client/html/post_upload.tpl b/client/html/post_upload.tpl
index 1dcfba4..f1ed88f 100644
--- a/client/html/post_upload.tpl
+++ b/client/html/post_upload.tpl
@@ -2,8 +2,19 @@
<form>
<div class='dropper-container'></div>
- <input type='submit' value='Upload all' class='submit'/>
- <input type='button' value='Cancel' class='cancel'/>
+ <div class='control-strip'>
+ <input type='submit' value='Upload all' class='submit'/>
+
+ <span class='skip-duplicates'>
+ <%= ctx.makeCheckbox({
+ text: 'Skip duplicates',
+ name: 'skip-duplicates',
+ checked: false,
+ }) %>
+ </span>
+
+ <input type='button' value='Cancel' class='cancel'/>
+ </div>
<div class='messages'></div>
diff --git a/client/js/controllers/post_upload_controller.js b/client/js/controllers/post_upload_controller.js
index 4defd5e..3ec86a9 100644
--- a/client/js/controllers/post_upload_controller.js
+++ b/client/js/controllers/post_upload_controller.js
@@ -48,25 +48,36 @@ class PostUploadController {
this._view.clearMessages();
e.detail.uploadables.reduce((promise, uploadable) => {
- return promise.then(
- () => {
- let post = new Post();
- post.safety = uploadable.safety;
- if (uploadable.url) {
- post.newContentUrl = uploadable.url;
- } else {
- post.newContent = uploadable.file;
- }
- let modelPromise = post.save(uploadable.anonymous);
- this._lastPromise = modelPromise;
- return modelPromise
- .then(() => {
- this._view.removeUploadable(uploadable);
+ return promise.then(() => {
+ let post = new Post();
+ post.safety = uploadable.safety;
+ if (uploadable.url) {
+ post.newContentUrl = uploadable.url;
+ } else {
+ post.newContent = uploadable.file;
+ }
+
+ let modelPromise = post.save(uploadable.anonymous);
+ this._lastPromise = modelPromise;
+
+ return modelPromise
+ .then(() => {
+ this._view.removeUploadable(uploadable);
+ return Promise.resolve();
+ }).catch(errorMessage => {
+ // XXX:
+ // lame, API eats error codes so we need to match
+ // messages instead
+ if (e.detail.skipDuplicates &&
+ errorMessage.match(/already uploaded/)) {
return Promise.resolve();
- });
- });
- }, Promise.resolve()).then(
- () => {
+ }
+ return Promise.reject(errorMessage);
+ });
+ });
+ }, Promise.resolve())
+
+ .then(() => {
misc.disableExitConfirmation();
const ctx = router.show('/posts');
ctx.controller.showSuccess('Posts uploaded.');
diff --git a/client/js/views/post_upload_view.js b/client/js/views/post_upload_view.js
index 98b8021..fd60f4e 100644
--- a/client/js/views/post_upload_view.js
+++ b/client/js/views/post_upload_view.js
@@ -137,7 +137,6 @@ class PostUploadView extends events.EventTarget {
views.replaceContent(this._hostNode, template());
views.syncScrollPosition();
- this._enabled = true;
this._cancelButtonNode.disabled = true;
this._uploadables = new Map();
@@ -162,13 +161,13 @@ class PostUploadView extends events.EventTarget {
enableForm() {
views.enableForm(this._formNode);
this._cancelButtonNode.disabled = true;
- this._enabled = true;
+ this._formNode.classList.remove('uploading');
}
disableForm() {
views.disableForm(this._formNode);
this._cancelButtonNode.disabled = false;
- this._enabled = false;
+ this._formNode.classList.add('uploading');
}
clearMessages() {
@@ -245,7 +244,7 @@ class PostUploadView extends events.EventTarget {
_evtRemoveClick(e, uploadable) {
e.preventDefault();
- if (!this._enabled) {
+ if (this._uploading) {
return;
}
this.removeUploadable(uploadable);
@@ -253,7 +252,7 @@ class PostUploadView extends events.EventTarget {
_evtMoveUpClick(e, uploadable) {
e.preventDefault();
- if (!this._enabled) {
+ if (this._uploading) {
return;
}
let sortedUploadables = this._getSortedUploadables();
@@ -268,7 +267,7 @@ class PostUploadView extends events.EventTarget {
_evtMoveDownClick(e, uploadable) {
e.preventDefault();
- if (!this._enabled) {
+ if (this._uploading) {
return;
}
let sortedUploadables = this._getSortedUploadables();
@@ -306,7 +305,10 @@ class PostUploadView extends events.EventTarget {
this.dispatchEvent(
new CustomEvent(
eventType,
- {detail: {uploadables: this._getSortedUploadables()}}));
+ {detail: {
+ uploadables: this._getSortedUploadables(),
+ skipDuplicates: this._skipDuplicatesCheckboxNode.checked,
+ }}));
}
_createRowNode(uploadable) {
@@ -342,6 +344,10 @@ class PostUploadView extends events.EventTarget {
rowNode.querySelector('.thumbnail').childNodes);
}
+ get _uploading() {
+ return this._formNode.classList.contains('uploading');
+ }
+
get _listNode() {
return this._hostNode.querySelector('.uploadables-container');
}
@@ -350,6 +356,10 @@ class PostUploadView extends events.EventTarget {
return this._hostNode.querySelector('form');
}
+ get _skipDuplicatesCheckboxNode() {
+ return this._hostNode.querySelector('form [name=skip-duplicates]');
+ }
+
get _submitButtonNode() {
return this._hostNode.querySelector('form [type=submit]');
}

© 2015 - 2026 Jakob L. Kreuze