diff --git a/client/css/expander-control.styl b/client/css/expander-control.styl index 8f689570..37b51d39 100644 --- a/client/css/expander-control.styl +++ b/client/css/expander-control.styl @@ -19,7 +19,7 @@ font-size: 1em color: $inactive-link-color float: right - line-height: 2em + line-height: 2rem .expander-content padding: 0.5em 0.5em 2em 0.5em diff --git a/client/css/post-upload.styl b/client/css/post-upload.styl index cb6b0067..ec4555d1 100644 --- a/client/css/post-upload.styl +++ b/client/css/post-upload.styl @@ -15,13 +15,22 @@ $cancel-button-color = tomato &.inactive .skip-duplicates &.inactive .always-upload-similar &.inactive .pause-remain-on-error + &.inactive .upload-all-anonymous + &.inactive .expander + &.inactive #common-tags, &.uploading input[type=submit], &.uploading .skip-duplicates, &.uploading .always-upload-similar &.uploading .pause-remain-on-error + &.uploading .upload-all-anonymous + &.uploading .expander &:not(.uploading) .cancel display: none + &.inactive .control-strip + &.uploading .control-strip + gap: 0 + .dropper-container margin: 0 auto .file-dropper @@ -30,28 +39,36 @@ $cancel-button-color = tomato small font-size: 60% - input[type=submit] - margin-top: 1em + .expander + &.collapsed + margin-bottom: 0 + .expander-content + padding: 0.5em .cancel - margin-top: 1em background: $cancel-button-color border-color: $cancel-button-color &:focus border: 2px solid $text-color - .skip-duplicates - margin-left: 1em - - .always-upload-similar - margin-left: 1em - - .pause-remain-on-error - margin-left: 1em - form>.messages margin-top: 1em + .control-strip + display: flex + flex-direction: column + gap: 1em + margin-top: 1em + + .control-options + display: flex + flex-wrap: wrap + gap: 0 1em + + span + flex: 1 1 30% + white-space: nowrap + .uploadables-container list-style-type: none margin: 0 diff --git a/client/html/post_upload.tpl b/client/html/post_upload.tpl index 3c1b2388..5240e306 100644 --- a/client/html/post_upload.tpl +++ b/client/html/post_upload.tpl @@ -3,32 +3,45 @@
+
+ + <%= ctx.makeCheckbox({ + text: 'Skip duplicate', + name: 'skip-duplicates', + checked: false, + }) %> + + + + <%= ctx.makeCheckbox({ + text: 'Force upload similar', + name: 'always-upload-similar', + checked: false, + }) %> + + + + <%= ctx.makeCheckbox({ + text: 'Pause on error', + name: 'pause-remain-on-error', + checked: true, + }) %> + + + + <%= ctx.makeCheckbox({ + text: 'Upload anonymously', + name: 'upload-all-anonymous', + checked: false, + }) %> + +
+ +
+ <%= ctx.makeTextInput({name: 'common-tags'}) %> +
+ - - - <%= ctx.makeCheckbox({ - text: 'Skip duplicate', - name: 'skip-duplicates', - checked: false, - }) %> - - - - <%= ctx.makeCheckbox({ - text: 'Force upload similar', - name: 'always-upload-similar', - checked: false, - }) %> - - - - <%= ctx.makeCheckbox({ - text: 'Pause on error', - name: 'pause-remain-on-error', - checked: true, - }) %> - -
diff --git a/client/js/util/views.js b/client/js/util/views.js index f6280a1c..f20c5cce 100644 --- a/client/js/util/views.js +++ b/client/js/util/views.js @@ -81,7 +81,7 @@ function makeCheckbox(options) { name: options.name, value: options.value, type: "checkbox", - checked: options.checked !== undefined ? options.checked : false, + checked: options.checked !== undefined && options.checked !== null ? options.checked : false, disabled: options.readonly, required: options.required, }), diff --git a/client/js/views/post_upload_view.js b/client/js/views/post_upload_view.js index 4ef4c1ad..77eee672 100644 --- a/client/js/views/post_upload_view.js +++ b/client/js/views/post_upload_view.js @@ -4,10 +4,14 @@ const events = require("../events.js"); const api = require("../api.js"); const views = require("../util/views.js"); const FileDropperControl = require("../controls/file_dropper_control.js"); +const ExpanderControl = require("../controls/expander_control.js"); +const TagInputControl = require("../controls/tag_input_control.js"); const template = views.getTemplate("post-upload"); const rowTemplate = views.getTemplate("post-upload-row"); +const TagList = require("../models/tag_list.js"); + function _mimeTypeToPostType(mimeType) { return ( { @@ -160,6 +164,7 @@ class PostUploadView extends events.EventTarget { this._uploadables.find = (u) => { return this._uploadables.findIndex((u2) => u.key === u2.key); }; + this._commonTags = new TagList(); this._contentFileDropper = new FileDropperControl( this._contentInputNode, @@ -185,6 +190,23 @@ class PostUploadView extends events.EventTarget { this._evtFormSubmit(e) ); this._formNode.classList.add("inactive"); + + this._commonTagsExpander = new ExpanderControl( + "common-tags", + "Common Tags (0)", + this._hostNode.querySelectorAll(".common-tags") + ); + + if (this._commonTagsInputNode) { + this._commonTagsControl = new TagInputControl( + this._commonTagsInputNode, + this._commonTags + ); + + this._commonTagsControl.addEventListener("change", (_) => { + this._commonTagsExpander.title = `Common Tags (${this._commonTags.length})`; + }); + } } enableForm() { @@ -299,14 +321,16 @@ class PostUploadView extends events.EventTarget { uploadable.safety = safetyNode.value; } - const anonymousNode = rowNode.querySelector( - ".anonymous input:checked" - ); - if (anonymousNode) { - uploadable.anonymous = true; + let anonymous = this._uploadAllAnonymous.checked; + if (!anonymous && rowNode.querySelector(".anonymous input:checked")) { + anonymous = true; } + uploadable.anonymous = anonymous; uploadable.tags = []; + if (this._commonTagsInputNode) { + uploadable.tags = this._commonTags.map((tag) => tag.names[0]); + } uploadable.relations = []; for (let [i, lookalike] of uploadable.lookalikes.entries()) { let lookalikeNode = rowNode.querySelector( @@ -441,6 +465,12 @@ class PostUploadView extends events.EventTarget { ); } + get _uploadAllAnonymous() { + return this._hostNode.querySelector( + "form [name=upload-all-anonymous]" + ); + } + get _submitButtonNode() { return this._hostNode.querySelector("form [type=submit]"); } @@ -452,6 +482,10 @@ class PostUploadView extends events.EventTarget { get _contentInputNode() { return this._formNode.querySelector(".dropper-container"); } + + get _commonTagsInputNode() { + return this._formNode.querySelector(".common-tags input"); + } } module.exports = PostUploadView;