diff options
| author | Jules Laplace <julescarbon@gmail.com> | 2018-05-05 13:19:01 +0200 |
|---|---|---|
| committer | Jules Laplace <julescarbon@gmail.com> | 2018-05-05 13:19:01 +0200 |
| commit | a9f4d77593640388eb07dfdf0d4e3a0bf17416a2 (patch) | |
| tree | 74167377d91aec45a56125e811f3766b8f181f8e | |
| parent | e443b704c5f45b5e9cfdec762f837a0981cffe97 (diff) | |
interface to move files to other threads
| -rw-r--r-- | bucky/db/index.js | 3 | ||||
| -rw-r--r-- | public/assets/css/bucky.css | 22 | ||||
| -rw-r--r-- | public/assets/js/lib/views/details/details.js | 4 | ||||
| -rw-r--r-- | public/assets/js/lib/views/details/settings.js | 80 | ||||
| -rw-r--r-- | public/assets/js/vendor/util.js | 3 | ||||
| -rw-r--r-- | views/partials/files.ejs | 2 | ||||
| -rw-r--r-- | views/partials/settings.ejs | 10 |
7 files changed, 119 insertions, 5 deletions
diff --git a/bucky/db/index.js b/bucky/db/index.js index a147cd8..51c024b 100644 --- a/bucky/db/index.js +++ b/bucky/db/index.js @@ -191,6 +191,9 @@ db.moveFile = function(file, thread_id){ reject(err) }) }) + }).on('error', err => { + console.error('/!\\ error connecting to s3') + reject(err) }).end() }) return copyPromise diff --git a/public/assets/css/bucky.css b/public/assets/css/bucky.css index 56cdc5e..bfbed71 100644 --- a/public/assets/css/bucky.css +++ b/public/assets/css/bucky.css @@ -292,6 +292,12 @@ tr:nth-child(odd).file td { background-color: #e6f0f0; } tr:nth-child(even).file td { background-color: #e0e8e8; } .desktop tr:nth-child(even).file:hover td { background-color: #d8e0ec; color: #000000; } +tr:nth-child(odd).file.checked td { background-color: #c6d0d0; } +.desktop tr:nth-child(odd).file.checked:hover td { background-color: #c8d0dc; color: #000000; } +tr:nth-child(even).file.checked td { background-color: #c0c8c8; } +.desktop tr:nth-child(even).file.checked:hover td { background-color: #b8c0cc; color: #000000; } + + tr:nth-child(odd) td.row { background-color: #e6f0f0; } .desktop tr:nth-child(odd) td.row:hover { background-color: #d8e0ec; color: #000000; } tr:nth-child(even) td.row { background-color: #e0e8e8; } @@ -614,10 +620,10 @@ pre br { padding: 5px; font-size: 11px; } -.files td:first-child { +.files td.name { padding: 0; } -.files td:first-child a { +.files td.name a { display: block; padding: 5px 0 5px 4px; text-overflow: ellipsis; @@ -629,7 +635,7 @@ pre br { .desktop .files user a:hover { text-decoration: underline; } -.files td:first-child { +.files td.name { text-align: left; } .files td { @@ -770,9 +776,17 @@ pre br { max-height: 70vh; overflow: auto; } -#thread_settings .files td:first-child a { +#thread_settings .files td.name a { min-width: 130px; } +.move_files_select { + display: flex; + flex-direction: row; + justify-content: space-between; +} +.move_files_select select { + flex: 1; +} /* SEARCH */ diff --git a/public/assets/js/lib/views/details/details.js b/public/assets/js/lib/views/details/details.js index 6d208da..49230a3 100644 --- a/public/assets/js/lib/views/details/details.js +++ b/public/assets/js/lib/views/details/details.js @@ -43,6 +43,9 @@ var DetailsView = View.extend({ if (data.thread.keyword) { $.get(this.keywordAction + data.thread.keyword, this.populateKeyword.bind(this)) } + else { + this.settings.loadThreads(null) + } if (this.options.settings) { this.openSettings() } @@ -50,6 +53,7 @@ var DetailsView = View.extend({ populateKeyword: function(data){ this.threadbox.load(data) + this.settings.loadThreads(data.threads) }, openSettings: function(e){ diff --git a/public/assets/js/lib/views/details/settings.js b/public/assets/js/lib/views/details/settings.js index b1fd956..c2ff078 100644 --- a/public/assets/js/lib/views/details/settings.js +++ b/public/assets/js/lib/views/details/settings.js @@ -14,6 +14,9 @@ var ThreadSettingsForm = FormView.extend({ "click #allowed_names [type=checkbox]": "removeAllowed", "keydown [name=allowed_field]": "keydownAllowed", "blur [name=allowed_field]": "updateAllowed", + "click [name=file_id]": "toggleFile", + "click tr.file": "toggleFileRow", + "click #move_files": "moveFiles", }, action: "", @@ -111,6 +114,28 @@ var ThreadSettingsForm = FormView.extend({ }.bind(this)) }, + loadThreads: function(threads){ + // update the dropdown list of threads + var $thread_select = this.$('[name=thread]') + if (!threads || !threads.length) { + $thread_select.parent().hide() + return + } + $thread_select.parent().show() + threads + .map( (a) => [a.title.toLowerCase(), a]) + .sort( (a,b) => a[0].localeCompare(b[0]) ) + .forEach((pair) => { + const thread = pair[1] + var option = document.createElement('option') + option.value = thread.id + // console.log(thread, get_revision(thread)) + option.innerHTML = '[' + thread.id + get_revision(thread) + '] ' + sanitize(thread.title) + $thread_select.append(option) + }) + // console.log(threads) + }, + toggleAllowed: function(e){ var checked = this.$('[name=privacy]').prop('checked') this.$(".allowed_field_container").toggle(checked) @@ -228,6 +253,61 @@ var ThreadSettingsForm = FormView.extend({ app.view.files.resort(sort_name) }, + toggleFile: function(e){ + // e.preventDefault() + e.stopPropagation() + const $input = $(e.currentTarget) + const $tr = $input.closest('tr.file') + const value = e.currentTarget.checked + // $(e.currentTarget).prop('checked', value) + // console.log('check', $input, value) + this.toggleFileChecked($tr, null, value) + }, + toggleFileRow: function(e){ + // e.preventDefault() + e.stopPropagation() + const $tr = $(e.currentTarget) + const $input = $tr.find('input[type="checkbox"]') + const value = ! $input.prop('checked') + this.toggleFileChecked($tr, $input, value) + }, + toggleFileChecked: function($tr, $input, value){ + $tr.toggleClass('checked', value) + if ($input) $input.prop('checked', value) + }, + + moveFiles: function(){ + var thread_id = this.$("[name=thread]").val() + // if (!thread_id) return alert("Please choose a thread") + var file_ids = toArray(this.el.querySelectorAll("[name=file_id]:checked")).map(input => input.value) + console.log("thread:", thread_id) + console.log("files:", file_ids) + var promises = file_ids.map(file_id => { + return new Promise((resolve, reject) => { + $.ajax({ + method: "GET", + url: '/api/file/' + file_id + '/move/' + thread_id, + headers: { "csrf-token": $("[name=_csrf]").attr("value") }, + dataType: "json", + success: function(data){ + console.log('moved', file_id) + resolve(data) + }, + error: function(){ + console.log('error moving', file_id) + reject() + } + }) + }) + }) + Promise.all(promises).then( () => { + window.location.href = '/details/' + thread_id + }).catch(() =>{ + console.error('whaaaaa') + alert('there was a problem moving the files...') + }) + }, + deleteThread: function(e){ var data = this.options.parent.data var id = data.thread.id diff --git a/public/assets/js/vendor/util.js b/public/assets/js/vendor/util.js index 7244d5a..3d206f5 100644 --- a/public/assets/js/vendor/util.js +++ b/public/assets/js/vendor/util.js @@ -219,6 +219,9 @@ if (!Function.prototype.bind) { }; } +function toArray(a_like){ + return Array.prototype.slice.call(a_like) +} // rAF polyfill (function() { var lastTime = 0; diff --git a/views/partials/files.ejs b/views/partials/files.ejs index 0ad8317..e785099 100644 --- a/views/partials/files.ejs +++ b/views/partials/files.ejs @@ -1,7 +1,7 @@ <table class="files" id="files"> <script class="template" type="text/html"> <tr class="file"> - <td> + <td class="name"> <a href="{{link}}" title="{{id}}" class="file">{{filename}}</a> </td> <td class="{{date_class}}"> diff --git a/views/partials/settings.ejs b/views/partials/settings.ejs index df19981..65fdf43 100644 --- a/views/partials/settings.ejs +++ b/views/partials/settings.ejs @@ -79,10 +79,20 @@ <div id="right_side"> + <div class='move_files_select'> + <select name="thread"> + <option value="">Move files to another thread</option> + </select> + <button id="move_files">move</button> + </div> + <table class="files" id="settings_files"> <script class="settingsFilesTemplate" type="text/html"> <tr class="file"> <td> + <input type="checkbox" name="file_id" value="{{id}}"> + </td> + <td class='name'> <a href="{{link}}" class="file">{{filename}}</a> </td> <td class="{{date_class}}"> |
