var photo_clipboard = new Set(); var on_clipboard_load_hooks = []; var on_clipboard_save_hooks = []; // Load save /////////////////////////////////////////////////////////////////////////////////////// function clear_photo_clipboard() { photo_clipboard.clear(); save_photo_clipboard(); } 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)); } for (var index = 0; index < on_clipboard_load_hooks.length; index += 1) { on_clipboard_load_hooks[index](); } 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); update_pagestate(); for (var index = 0; index < on_clipboard_save_hooks.length; index += 1) { on_clipboard_save_hooks[index](); } } // Card management ///////////////////////////////////////////////////////////////////////////////// function apply_check(photo_card) { /* Given a photo card div, set its checkbox to the correct value based on whether the clipboard contains this card's ID. */ var checkbox = photo_card.getElementsByClassName("photo_card_selector_checkbox")[0]; if (photo_clipboard.has(photo_card.dataset.id)) { checkbox.checked = true; } else { checkbox.checked = false; } } function apply_check_all() { /* Run through all the photo cards on the page and set their checkbox to the correct value. */ var photo_divs = Array.from(document.getElementsByClassName("photo_card")); photo_divs.forEach(apply_check); } var _action_select = function(photo_div){photo_clipboard.add(photo_div.dataset.id)} var _action_unselect = function(photo_div){photo_clipboard.delete(photo_div.dataset.id)} var previous_photo_select; function on_photo_select(event) { /* Select or unselect the clicked photo, with support for Shift-click to action everything between the previous click and this one inclusively. Those middle items will be set to the same state as the new state of the clicked item. */ if (event.target.checked) { action = _action_select; } else { action = _action_unselect; } if (event.shiftKey && previous_photo_select) { 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 select_photo(photo_div) { photo_div.getElementsByClassName("photo_card_selector_checkbox")[0].checked = true; _action_select(photo_div); save_photo_clipboard(); } function unselect_photo(photo_div) { photo_div.getElementsByClassName("photo_card_selector_checkbox")[0].checked = false; _action_unselect(photo_div) save_photo_clipboard(); } function select_all_photos() { var photo_divs = Array.from(document.getElementsByClassName("photo_card")); photo_divs.forEach(_action_select); apply_check_all(); save_photo_clipboard(); } function unselect_all_photos() { var photo_divs = Array.from(document.getElementsByClassName("photo_card")); photo_divs.forEach(_action_unselect); apply_check_all() previous_photo_select = null; save_photo_clipboard(); } function set_keybinds() { window.addEventListener("keydown", function(event) { if (event.key == "a" && event.ctrlKey) { select_all_photos(); event.preventDefault(); } }); window.addEventListener("keydown", function(event) { if (event.key == "d" && event.ctrlKey) { unselect_all_photos(); event.preventDefault(); } }); } // Tray management ///////////////////////////////////////////////////////////////////////////////// function clipboard_tray_collapse() { var tray_body = document.getElementById("clipboard_tray_body"); tray_body.classList.add("hidden"); } function clipboard_tray_uncollapse() { var tray_body = document.getElementById("clipboard_tray_body"); tray_body.classList.remove("hidden"); update_clipboard_tray(); } function clipboard_tray_collapse_toggle() { /* Show or hide the clipboard. */ var tray_body = document.getElementById("clipboard_tray_body"); if (tray_body.classList.contains("hidden") && photo_clipboard.size > 0) { clipboard_tray_uncollapse(); } else { clipboard_tray_collapse(); } } function on_tray_delete_button(event) { /* Remove the clicked row from the clipboard. */ var clipboard_line = event.target.parentElement; var photo_id = clipboard_line.dataset.id; photo_clipboard.delete(photo_id); save_photo_clipboard(); } function update_clipboard_tray() { /* Rebuild the rows if the tray is open. */ var clipboard_tray = document.getElementById("clipboard_tray"); if (clipboard_tray === null) { return; } if (photo_clipboard.size == 0) { clipboard_tray_collapse(); } var tray_lines = document.getElementById("clipboard_tray_lines"); if (!clipboard_tray.classList.contains("hidden")) { delete_all_children(tray_lines); var photo_ids = Array.from(photo_clipboard); photo_ids.sort(); for (var i = 0; i < photo_ids.length; i += 1) { var clipboard_line = document.createElement("div"); clipboard_line.classList.add("clipboard_tray_line"); clipboard_line.dataset.id = photo_ids[i]; var clipboard_line_delete_button = document.createElement("button"); clipboard_line_delete_button.classList.add("remove_tag_button_perm"); clipboard_line_delete_button.classList.add("red_button"); clipboard_line_delete_button.onclick = on_tray_delete_button; var clipboard_line_link = document.createElement("a"); clipboard_line_link.target = "_blank"; clipboard_line_link.href = "/photo/" + photo_ids[i]; clipboard_line_link.innerText = photo_ids[i]; clipboard_line.appendChild(clipboard_line_delete_button); clipboard_line.appendChild(clipboard_line_link); tray_lines.appendChild(clipboard_line); } } } function update_clipboard_count() { var elements = document.getElementsByClassName("clipboard_count"); for (var index = 0; index < elements.length; index += 1) { elements[index].innerText = photo_clipboard.size; } } function on_storage() { /* Receive storage events from other tabs and update our state to match. */ load_photo_clipboard(); update_pagestate(); } function update_pagestate() { update_clipboard_count(); update_clipboard_tray(); apply_check_all(); } function on_pageload() { window.addEventListener("storage", on_storage, false); set_keybinds(); load_photo_clipboard(); update_pagestate(); } document.addEventListener("DOMContentLoaded", on_pageload);