The javascript is very inconsistent between pages. I'm trying to start using a consistent pattern where the api call is kept in a separate function from the ones that buttons and input boxes talk to.
		
			
				
	
	
		
			341 lines
		
	
	
	
		
			9.1 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			341 lines
		
	
	
	
		
			9.1 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!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/hotkeys.js"></script>
 | |
|     <script src="/static/js/photoclipboard.js"></script>
 | |
|     <script src="/static/js/tag_autocomplete.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="photo_clipboard.clear_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" list="tag_autocomplete_datalist">
 | |
|         <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" list="tag_autocomplete_datalist">
 | |
|         <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", common.entry_with_history_hook);
 | |
| common.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", common.entry_with_history_hook);
 | |
| common.bind_box_to_button(remove_box, remove_button);
 | |
| 
 | |
| function recalculate_needed()
 | |
| {
 | |
|     needed = new Set();
 | |
|     photo_clipboard.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.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 = common.html_to_element(response[photo_id]);
 | |
|             divs[photo_id] = photo_div;
 | |
|             needed.delete(photo_id)
 | |
|             holder.appendChild(photo_div);
 | |
|         }
 | |
|         photo_clipboard.apply_check_all();
 | |
|     }
 | |
|     common.post(url, data, callback);
 | |
| }
 | |
| 
 | |
| function myhook()
 | |
| {
 | |
|     recalculate_needed();
 | |
|     request_more_divs();
 | |
|     refresh_divs();
 | |
| }
 | |
| 
 | |
| tag_autocomplete.init_datalist();
 | |
| photo_clipboard.on_load_hooks.push(myhook);
 | |
| photo_clipboard.on_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.clipboard.size == 0)
 | |
|         {return;}
 | |
|     var url = "/batch/photos/" + action + "_tag";
 | |
|     var photo_ids = Array.from(photo_clipboard.clipboard).join(",");
 | |
|     var data = new FormData();
 | |
|     data.append("photo_ids", photo_ids);
 | |
|     data.append("tagname", tagname);
 | |
|     common.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;}
 | |
|     }
 | |
|     common.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.clipboard.size == 0)
 | |
|         {return;}
 | |
| 
 | |
|     var url = "/batch/photos/refresh_metadata";
 | |
|     var photo_ids = Array.from(photo_clipboard.clipboard).join(",");
 | |
|     var data = new FormData();
 | |
|     data.append("photo_ids", photo_ids);
 | |
|     refresh_in_progress = true;
 | |
|     common.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"];
 | |
|         common.create_message_bubble(message_area, message_positivity, message_text, 8000);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         common.refresh();
 | |
|     }
 | |
| }
 | |
| 
 | |
| 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."
 | |
|     }
 | |
|     common.create_message_bubble(message_area, message_positivity, message_text, 8000);
 | |
| }
 | |
| function submit_set_searchhidden(callback)
 | |
| {
 | |
|     if (photo_clipboard.clipboard.size == 0)
 | |
|         {return;}
 | |
| 
 | |
|     var url = "/batch/photos/set_searchhidden";
 | |
|     var data = new FormData();
 | |
|     var photo_ids = Array.from(photo_clipboard.clipboard).join(",");
 | |
| 
 | |
|     data.append("photo_ids", photo_ids);
 | |
|     common.post(url, data, callback);
 | |
| }
 | |
| function submit_unset_searchhidden(callback)
 | |
| {
 | |
|     if (photo_clipboard.clipboard.size == 0)
 | |
|         {return;}
 | |
| 
 | |
|     var url = "/batch/photos/unset_searchhidden";
 | |
|     var data = new FormData();
 | |
|     var photo_ids = Array.from(photo_clipboard.clipboard).join(",");
 | |
| 
 | |
|     data.append("photo_ids", photo_ids);
 | |
|     common.post(url, data, callback);
 | |
| }
 | |
| </script>
 | |
| </html>
 |