client/posts: add 'skip duplicates' to upload form

Closes #102
This commit is contained in:
rr- 2016-09-29 22:26:37 +02:00
parent 7862fecbc9
commit 7648f479a9
4 changed files with 68 additions and 34 deletions

View file

@ -9,9 +9,12 @@ $cancel-button-color = tomato
margin: 0 auto margin: 0 auto
text-align: left text-align: left
&.inactive &.inactive input[type=submit],
input[type=submit] &.inactive .skip-duplicates
display: none &.uploading input[type=submit],
&.uploading .skip-duplicates,
&:not(.uploading) .cancel
display: none
.dropper-container .dropper-container
margin: 0 auto margin: 0 auto
@ -21,18 +24,17 @@ $cancel-button-color = tomato
input[type=submit] input[type=submit]
margin-top: 1em margin-top: 1em
&[disabled]
display: none
.cancel .cancel
margin-top: 1em margin-top: 1em
background: $cancel-button-color background: $cancel-button-color
border-color: $cancel-button-color border-color: $cancel-button-color
&[disabled]
display: none
&:focus &:focus
border: 2px solid $text-color border: 2px solid $text-color
.skip-duplicates
margin-left: 1em
.messages .messages
margin-top: 1em margin-top: 1em

View file

@ -2,8 +2,19 @@
<form> <form>
<div class='dropper-container'></div> <div class='dropper-container'></div>
<input type='submit' value='Upload all' class='submit'/> <div class='control-strip'>
<input type='button' value='Cancel' class='cancel'/> <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> <div class='messages'></div>

View file

@ -48,25 +48,36 @@ class PostUploadController {
this._view.clearMessages(); this._view.clearMessages();
e.detail.uploadables.reduce((promise, uploadable) => { e.detail.uploadables.reduce((promise, uploadable) => {
return promise.then( return promise.then(() => {
() => { let post = new Post();
let post = new Post(); post.safety = uploadable.safety;
post.safety = uploadable.safety; if (uploadable.url) {
if (uploadable.url) { post.newContentUrl = uploadable.url;
post.newContentUrl = uploadable.url; } else {
} else { post.newContent = uploadable.file;
post.newContent = uploadable.file; }
}
let modelPromise = post.save(uploadable.anonymous); let modelPromise = post.save(uploadable.anonymous);
this._lastPromise = modelPromise; this._lastPromise = modelPromise;
return modelPromise
.then(() => { return modelPromise
this._view.removeUploadable(uploadable); .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(); return Promise.resolve();
}); }
}); return Promise.reject(errorMessage);
}, Promise.resolve()).then( });
() => { });
}, Promise.resolve())
.then(() => {
misc.disableExitConfirmation(); misc.disableExitConfirmation();
const ctx = router.show('/posts'); const ctx = router.show('/posts');
ctx.controller.showSuccess('Posts uploaded.'); ctx.controller.showSuccess('Posts uploaded.');

View file

@ -137,7 +137,6 @@ class PostUploadView extends events.EventTarget {
views.replaceContent(this._hostNode, template()); views.replaceContent(this._hostNode, template());
views.syncScrollPosition(); views.syncScrollPosition();
this._enabled = true;
this._cancelButtonNode.disabled = true; this._cancelButtonNode.disabled = true;
this._uploadables = new Map(); this._uploadables = new Map();
@ -162,13 +161,13 @@ class PostUploadView extends events.EventTarget {
enableForm() { enableForm() {
views.enableForm(this._formNode); views.enableForm(this._formNode);
this._cancelButtonNode.disabled = true; this._cancelButtonNode.disabled = true;
this._enabled = true; this._formNode.classList.remove('uploading');
} }
disableForm() { disableForm() {
views.disableForm(this._formNode); views.disableForm(this._formNode);
this._cancelButtonNode.disabled = false; this._cancelButtonNode.disabled = false;
this._enabled = false; this._formNode.classList.add('uploading');
} }
clearMessages() { clearMessages() {
@ -245,7 +244,7 @@ class PostUploadView extends events.EventTarget {
_evtRemoveClick(e, uploadable) { _evtRemoveClick(e, uploadable) {
e.preventDefault(); e.preventDefault();
if (!this._enabled) { if (this._uploading) {
return; return;
} }
this.removeUploadable(uploadable); this.removeUploadable(uploadable);
@ -253,7 +252,7 @@ class PostUploadView extends events.EventTarget {
_evtMoveUpClick(e, uploadable) { _evtMoveUpClick(e, uploadable) {
e.preventDefault(); e.preventDefault();
if (!this._enabled) { if (this._uploading) {
return; return;
} }
let sortedUploadables = this._getSortedUploadables(); let sortedUploadables = this._getSortedUploadables();
@ -268,7 +267,7 @@ class PostUploadView extends events.EventTarget {
_evtMoveDownClick(e, uploadable) { _evtMoveDownClick(e, uploadable) {
e.preventDefault(); e.preventDefault();
if (!this._enabled) { if (this._uploading) {
return; return;
} }
let sortedUploadables = this._getSortedUploadables(); let sortedUploadables = this._getSortedUploadables();
@ -306,7 +305,10 @@ class PostUploadView extends events.EventTarget {
this.dispatchEvent( this.dispatchEvent(
new CustomEvent( new CustomEvent(
eventType, eventType,
{detail: {uploadables: this._getSortedUploadables()}})); {detail: {
uploadables: this._getSortedUploadables(),
skipDuplicates: this._skipDuplicatesCheckboxNode.checked,
}}));
} }
_createRowNode(uploadable) { _createRowNode(uploadable) {
@ -342,6 +344,10 @@ class PostUploadView extends events.EventTarget {
rowNode.querySelector('.thumbnail').childNodes); rowNode.querySelector('.thumbnail').childNodes);
} }
get _uploading() {
return this._formNode.classList.contains('uploading');
}
get _listNode() { get _listNode() {
return this._hostNode.querySelector('.uploadables-container'); return this._hostNode.querySelector('.uploadables-container');
} }
@ -350,6 +356,10 @@ class PostUploadView extends events.EventTarget {
return this._hostNode.querySelector('form'); return this._hostNode.querySelector('form');
} }
get _skipDuplicatesCheckboxNode() {
return this._hostNode.querySelector('form [name=skip-duplicates]');
}
get _submitButtonNode() { get _submitButtonNode() {
return this._hostNode.querySelector('form [type=submit]'); return this._hostNode.querySelector('form [type=submit]');
} }