etiquette/frontends/etiquette_flask/templates/clipboard.html
Ethan Dalool bea9f905bd Support downloading .zip of arbitrary photos, clipboard.
Now that creating zips of any photo set is easier, we can
let the user download whatever is on their clipboard.
2018-08-14 23:02:06 -07:00

370 lines
9.9 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 75px auto;
grid-template-areas:
"add_tag_area"
"remove_tag_area"
"refresh_metadata_area"
"searchhidden_area"
"download_zip_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;
}
#download_zip_area
{
grid-area: download_zip_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="download_zip_area">
<button class="yellow_button" id="download_zip_button" onclick="submit_download_zip(download_zip_callback)">Download .zip</button>
</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);
}
function submit_download_zip(callback)
{
if (photo_clipboard.clipboard.size == 0)
{return;}
var url = "/batch/photos/download_zip";
var photo_ids = Array.from(photo_clipboard.clipboard).join(",");
var data = new FormData();
data.append("photo_ids", photo_ids);
common.post(url, data, callback);
}
function download_zip_callback(response)
{
var zip_token = response["data"]["zip_token"];
var url = `/batch/photos/download_zip/${zip_token}.zip`;
window.location.href = url;
}
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>