From 55f7da7bb2d36c8e096c46fcf7814beee7a35675 Mon Sep 17 00:00:00 2001 From: Ethan Dalool Date: Sat, 9 Dec 2017 17:48:56 -0800 Subject: [PATCH] Add the photo_clipboard feature with localStorage. photo_card objects now have a checkbox which adds them to the clipboard. No pasting or other operations yet. --- frontends/etiquette_flask/static/common.css | 32 ++++-- .../etiquette_flask/static/photoclipboard.js | 103 ++++++++++++++++++ .../etiquette_flask/templates/album.html | 1 + .../etiquette_flask/templates/photo_card.html | 12 +- .../etiquette_flask/templates/search.html | 1 + 5 files changed, 138 insertions(+), 11 deletions(-) create mode 100644 frontends/etiquette_flask/static/photoclipboard.js diff --git a/frontends/etiquette_flask/static/common.css b/frontends/etiquette_flask/static/common.css index ef3f6e2..351e87a 100644 --- a/frontends/etiquette_flask/static/common.css +++ b/frontends/etiquette_flask/static/common.css @@ -130,26 +130,33 @@ is hovered over. display:inline; } +.photo_card +{ + background-color: #ffffd4; +} .photo_card_list { display: grid; - grid-template-columns: 1fr auto; + grid-template-columns: auto 1fr auto; grid-template-rows: auto; grid-template-areas: - "filename metadata"; + "checkbox filename metadata"; max-width: 800px; margin: 8px; padding: 4px; - - background-color: #ffffd4; } .photo_card_list:hover { box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.25); } +.photo_card_list .photo_card_selector_checkbox +{ + grid-area: checkbox; +} .photo_card_grid { + position: relative; display: inline-grid; grid-template-columns: auto auto; grid-template-rows: auto 1fr auto; @@ -165,8 +172,12 @@ is hovered over. border-radius: 8px; box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.25); - - background-color: #ffffd4; +} +.photo_card_grid .photo_card_selector_checkbox +{ + position:absolute; + left:5px; + top:5px; } .photo_card_thumbnail { @@ -187,7 +198,6 @@ is hovered over. The min-width:100% + width:0 prevent the info div from controlling card size, so we can prioritize the thumbnail instead. */ - align-self: start; justify-self: start; grid-area: filename; @@ -202,6 +212,14 @@ is hovered over. font-size: 12.8px; } +.photo_card_grid .photo_card_filename +{ + align-self: start; +} +.photo_card_list .photo_card_filename +{ + align-self: center; +} .photo_card_filename:hover { overflow: visible; diff --git a/frontends/etiquette_flask/static/photoclipboard.js b/frontends/etiquette_flask/static/photoclipboard.js new file mode 100644 index 0000000..af4b02b --- /dev/null +++ b/frontends/etiquette_flask/static/photoclipboard.js @@ -0,0 +1,103 @@ +var photo_clipboard = new Set(); + +function load_photo_clipboard(event) +{ + console.log("Loading photo clipboard"); + var stored = localStorage.getItem("photo_clipboard"); + if (stored === null) + { + if (photo_clipboard.size != 0) + { + photo_clipboard = new Set(); + } + } + else + { + photo_clipboard = new Set(JSON.parse(stored)); + } + + var photo_divs = Array.from(document.getElementsByClassName("photo_card")); + photo_divs.forEach(apply_check); + return photo_clipboard; +} + +function save_photo_clipboard() +{ + console.log("Saving photo clipboard"); + var serialized = JSON.stringify(Array.from(photo_clipboard)); + localStorage.setItem("photo_clipboard", serialized); +} + +function apply_check(photo_div) +{ + var checkbox = photo_div.getElementsByClassName("photo_card_selector_checkbox")[0]; + if (photo_clipboard.has(photo_div.dataset.id)) + { + checkbox.checked = true; + } + else + { + checkbox.checked = false; + } +} + +var previous_photo_select; +function on_photo_select(event) +{ + if (event.target.checked) + { + action = function(photo_div) + { + photo_div.getElementsByClassName("photo_card_selector_checkbox")[0].checked = true; + photo_clipboard.add(photo_div.dataset.id); + } + } + else + { + action = function(photo_div) + { + photo_div.getElementsByClassName("photo_card_selector_checkbox")[0].checked = false; + photo_clipboard.delete(photo_div.dataset.id); + } + } + + if (event.shiftKey && previous_photo_select !== undefined) + { + var current_photo_div = event.target.parentElement; + var previous_photo_div = previous_photo_select.target.parentElement; + var photo_divs = Array.from(current_photo_div.parentElement.children); + + var current_index = photo_divs.indexOf(current_photo_div); + var previous_index = photo_divs.indexOf(previous_photo_div); + + var slice; + if (current_index == previous_index) + { + slice = [current_photo_div]; + } + else if (previous_index < current_index) + { + slice = photo_divs.slice(previous_index, current_index + 1); + } + else + { + slice = photo_divs.slice(current_index, previous_index + 1); + } + + slice.forEach(action); + } + else + { + var photo_div = event.target.parentElement; + action(photo_div); + } + previous_photo_select = event; + save_photo_clipboard(); +} + +function onpageload() +{ + window.addEventListener("storage", load_photo_clipboard, false); + load_photo_clipboard(); +} +document.addEventListener("DOMContentLoaded", onpageload); diff --git a/frontends/etiquette_flask/templates/album.html b/frontends/etiquette_flask/templates/album.html index d4af29a..c132c0b 100644 --- a/frontends/etiquette_flask/templates/album.html +++ b/frontends/etiquette_flask/templates/album.html @@ -8,6 +8,7 @@ +