diff --git a/client/css/post-upload.styl b/client/css/post-upload.styl
index aa36e0a..3836293 100644
--- a/client/css/post-upload.styl
+++ b/client/css/post-upload.styl
@@ -13,8 +13,10 @@ $cancel-button-color = tomato
&.inactive input[type=submit],
&.inactive .skip-duplicates
+ &.inactive .always-upload-similar
&.uploading input[type=submit],
&.uploading .skip-duplicates,
+ &.uploading .always-upload-similar
&:not(.uploading) .cancel
display: none
@@ -39,6 +41,9 @@ $cancel-button-color = tomato
.skip-duplicates
margin-left: 1em
+ .always-upload-similar
+ margin-left: 1em
+
form>.messages
margin-top: 1em
diff --git a/client/html/post_upload.tpl b/client/html/post_upload.tpl
index f1ed88f..6374fe8 100644
--- a/client/html/post_upload.tpl
+++ b/client/html/post_upload.tpl
@@ -13,6 +13,14 @@
}) %>
+
+ <%= ctx.makeCheckbox({
+ text: 'Always upload similar',
+ name: 'always-upload-similar',
+ checked: false,
+ }) %>
+
+
diff --git a/client/js/controllers/post_upload_controller.js b/client/js/controllers/post_upload_controller.js
index d317be5..a54baec 100644
--- a/client/js/controllers/post_upload_controller.js
+++ b/client/js/controllers/post_upload_controller.js
@@ -12,7 +12,7 @@ const PostUploadView = require("../views/post_upload_view.js");
const EmptyView = require("../views/empty_view.js");
const genericErrorMessage =
- "One of the posts needs your attention; " +
+ "One or more posts needs your attention; " +
'click "resume upload" when you\'re ready.';
class PostUploadController {
@@ -55,6 +55,7 @@ class PostUploadController {
_evtSubmit(e) {
this._view.disableForm();
this._view.clearMessages();
+ let anyFailures = false;
e.detail.uploadables
.reduce(
@@ -62,44 +63,51 @@ class PostUploadController {
promise.then(() =>
this._uploadSinglePost(
uploadable,
- e.detail.skipDuplicates
- )
+ e.detail.skipDuplicates,
+ e.detail.alwaysUploadSimilar
+ ).catch((error) => {
+ anyFailures = true;
+ if (error.uploadable) {
+ if (error.similarPosts) {
+ error.uploadable.lookalikes =
+ error.similarPosts;
+ this._view.updateUploadable(
+ error.uploadable
+ );
+ this._view.showInfo(
+ error.message,
+ error.uploadable
+ );
+ } else {
+ this._view.showError(
+ error.message,
+ error.uploadable
+ );
+ }
+ } else {
+ this._view.showError(
+ error.message,
+ uploadable
+ );
+ }
+ })
),
Promise.resolve()
)
- .then(
- () => {
+ .then(() => {
+ if (anyFailures) {
+ this._view.showError(genericErrorMessage);
+ this._view.enableForm();
+ } else {
this._view.clearMessages();
misc.disableExitConfirmation();
const ctx = router.show(uri.formatClientLink("posts"));
ctx.controller.showSuccess("Posts uploaded.");
- },
- (error) => {
- if (error.uploadable) {
- if (error.similarPosts) {
- error.uploadable.lookalikes = error.similarPosts;
- this._view.updateUploadable(error.uploadable);
- this._view.showInfo(genericErrorMessage);
- this._view.showInfo(
- error.message,
- error.uploadable
- );
- } else {
- this._view.showError(genericErrorMessage);
- this._view.showError(
- error.message,
- error.uploadable
- );
- }
- } else {
- this._view.showError(error.message);
- }
- this._view.enableForm();
}
- );
+ });
}
- _uploadSinglePost(uploadable, skipDuplicates) {
+ _uploadSinglePost(uploadable, skipDuplicates, alwaysUploadSimilar) {
progress.start();
let reverseSearchPromise = Promise.resolve();
if (!uploadable.lookalikesConfirmed) {
@@ -128,7 +136,10 @@ class PostUploadController {
}
// notify about similar posts
- if (searchResult.similarPosts.length) {
+ if (
+ searchResult.similarPosts.length &&
+ !alwaysUploadSimilar
+ ) {
let error = new Error(
`Found ${searchResult.similarPosts.length} similar ` +
"posts.\nYou can resume or discard this upload."
diff --git a/client/js/views/post_upload_view.js b/client/js/views/post_upload_view.js
index ce0cb42..b92a9ae 100644
--- a/client/js/views/post_upload_view.js
+++ b/client/js/views/post_upload_view.js
@@ -358,6 +358,8 @@ class PostUploadView extends events.EventTarget {
detail: {
uploadables: this._uploadables,
skipDuplicates: this._skipDuplicatesCheckboxNode.checked,
+ alwaysUploadSimilar: this._alwaysUploadSimilarCheckboxNode
+ .checked,
},
})
);
@@ -421,6 +423,12 @@ class PostUploadView extends events.EventTarget {
return this._hostNode.querySelector("form [name=skip-duplicates]");
}
+ get _alwaysUploadSimilarCheckboxNode() {
+ return this._hostNode.querySelector(
+ "form [name=always-upload-similar]"
+ );
+ }
+
get _submitButtonNode() {
return this._hostNode.querySelector("form [type=submit]");
}