<!DOCTYPE html5> <html> <head> {% import "header.html" as header %} {% import "clipboard_tray.html" as clipboard_tray %} <title>Clipboard</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <link rel="stylesheet" href="/static/css/common.css"> <link rel="stylesheet" href="/static/css/photo_card.css"> <link rel="stylesheet" href="/static/css/clipboard_tray.css"> <script src="/static/js/common.js"></script> <script src="/static/js/photoclipboard.js"></script> <style> body { display: grid; grid-template-rows: auto 1fr; grid-template-columns: 1fr 300px; grid-template-areas: "header header" "left right"; } #header { grid-area: header; } #left { word-break: break-word; grid-area: left; } #right { position: fixed; right: 8px; bottom: 8px; top: 30px; width: 300px; grid-area: right; display: grid; grid-template-rows: 75px 75px 75px 75px auto; grid-template-areas: "add_tag_area" "remove_tag_area" "refresh_metadata_area" "searchhidden_area" "message_area"; background-color: rgba(0, 0, 0, 0.1); } #add_tag_area { grid-area: add_tag_area; margin: auto; } #remove_tag_area { grid-area: remove_tag_area; margin: auto; } #refresh_metadata_area { grid-area: refresh_metadata_area; margin: auto; } #searchhidden_area { grid-area: searchhidden_area; margin: auto; } #message_area { grid-area: message_area; margin: 8px; } </style> </head> <body> {{header.make_header(session=session)}} <div id="left"> <span>The clipboard contains <span class="clipboard_count">0</span> items.</span> <button id="clear_clipboard_button" class="red_button" onclick="clear_photo_clipboard()">Clear it.</button> <div id="photo_card_holder"> </div> </div> <div id="right"> <div id="add_tag_area"> <input type="text" id="add_tag_textbox"> <button class="add_tag_button green_button" id="add_tag_button" onclick="submit_add_tag(add_remove_callback);">Add tag</button> </div> <div id="remove_tag_area"> <input type="text" id="remove_tag_textbox"> <button class="red_button" id="remove_tag_button" onclick="submit_remove_tag(add_remove_callback);">Remove tag</button> </div> <div id="refresh_metadata_area"> <button class="green_button" id="refresh_metadata_button" onclick="submit_refresh_metadata(refresh_metadata_callback);">Refresh metadata</button> </div> <div id="searchhidden_area"> <span> <button class="yellow_button" id="set_searchhidden_button" onclick="submit_set_searchhidden(searchhidden_callback)">Searchhide</button> <button class="yellow_button" id="unset_searchhidden_button" onclick="submit_unset_searchhidden(searchhidden_callback)">Unhide</button> </span> </div> <div id="message_area"> </div> </div> </body> <script type="text/javascript"> var divs = {}; var needed = new Set(); var holder = document.getElementById("photo_card_holder"); var add_box = document.getElementById("add_tag_textbox"); var add_button = document.getElementById("add_tag_button"); add_box.addEventListener("keyup", entry_with_history_hook); bind_box_to_button(add_box, add_button); var remove_box = document.getElementById("remove_tag_textbox"); var remove_button = document.getElementById("remove_tag_button"); remove_box.addEventListener("keyup", entry_with_history_hook); bind_box_to_button(remove_box, remove_button); function recalculate_needed() { needed = new Set(); photo_clipboard.forEach(function(photo_id) { if (!(photo_id in divs)) { needed.add(photo_id); } }); } function refresh_divs() { for (var photo_id in divs) { var photo_div = divs[photo_id]; var should_keep = photo_clipboard.has(photo_id); var on_page = holder.contains(photo_div); if (on_page && !should_keep) { holder.removeChild(photo_div) } if (!on_page && should_keep) { holder.appendChild(photo_div) } } } function request_more_divs() { if (needed.size == 0) { return; } var url = "/batch/photos/photo_card"; var data = new FormData(); var photo_ids = Array.from(needed).join(","); data.append("photo_ids", photo_ids); function callback(response) { if (response["meta"]["status"] !== 200) { return; } response = response["data"]; var holder = document.getElementById("photo_card_holder"); for (photo_id in response) { photo_div = html_to_element(response[photo_id]); divs[photo_id] = photo_div; needed.delete(photo_id) holder.appendChild(photo_div); } apply_check_all(); } post(url, data, callback); } function myhook() { recalculate_needed(); request_more_divs(); refresh_divs(); } on_clipboard_load_hooks.push(myhook); on_clipboard_save_hooks.push(myhook); function submit_add_tag(callback) { var box = document.getElementById("add_tag_textbox"); var tagname = box.value.trim(); if (! tagname) {return} box.value = ""; return submit_add_remove_tag("add", tagname, callback); } function submit_remove_tag(callback) { var box = document.getElementById("remove_tag_textbox"); var tagname = box.value.trim(); if (! tagname) {return} box.value = ""; return submit_add_remove_tag("remove", tagname, callback); } function submit_add_remove_tag(action, tagname, callback) { if (photo_clipboard.size == 0) {return;} var url = "/batch/photos/" + action + "_tag"; var photo_ids = Array.from(photo_clipboard).join(","); var data = new FormData(); data.append("photo_ids", photo_ids); data.append("tagname", tagname); post(url, data, callback); } function add_remove_callback(response) { response = response["data"]; var tagname = response["tagname"]; var message_area = document.getElementById("message_area"); var message_positivity; var message_text; if ("error_type" in response) { message_positivity = "message_negative"; message_text = response["error_message"]; } else if ("action" in response) { var action = response["action"]; message_positivity = "message_positive"; if (action == "add") {message_text = "Added tag " + tagname;} else if (action == "remove") {message_text = "Removed tag " + tagname;} } create_message_bubble(message_area, message_positivity, message_text, 8000); } var refresh_in_progress = false; function submit_refresh_metadata(callback) { if (refresh_in_progress) {return;} if (photo_clipboard.size == 0) {return;} var url = "/batch/photos/refresh_metadata"; var photo_ids = Array.from(photo_clipboard).join(","); var data = new FormData(); data.append("photo_ids", photo_ids); refresh_in_progress = true; post(url, data, callback); } function refresh_metadata_callback(response) { response = response["data"]; refresh_in_progress = false; if ("error_type" in response) { var message_area = document.getElementById("message_area"); var message_positivity = "message_negative"; var message_text = response["error_message"]; create_message_bubble(message_area, message_positivity, message_text, 8000); } else { location.reload(); } } function searchhidden_callback(response) { response = response["data"]; var message_area = document.getElementById("message_area"); var message_positivity; var message_text; if ("error_type" in response) { message_positivity = "message_negative"; message_text = response["error_message"]; } else { message_positivity = "message_positive"; message_text = "Success." } create_message_bubble(message_area, message_positivity, message_text, 8000); } function submit_set_searchhidden() { var url = "/batch/photos/set_searchhidden"; var data = new FormData(); data.append("photo_ids", Array.from(photo_clipboard).join(",")); post(url, data, searchhidden_callback); } function submit_unset_searchhidden() { var url = "/batch/photos/unset_searchhidden"; var data = new FormData(); data.append("photo_ids", Array.from(photo_clipboard).join(",")); post(url, data, searchhidden_callback); } </script> </html>