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.
This commit is contained in:
parent
f69d9d409d
commit
55f7da7bb2
5 changed files with 138 additions and 11 deletions
|
@ -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;
|
||||
|
|
103
frontends/etiquette_flask/static/photoclipboard.js
Normal file
103
frontends/etiquette_flask/static/photoclipboard.js
Normal file
|
@ -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);
|
|
@ -8,6 +8,7 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<link rel="stylesheet" href="/static/common.css">
|
||||
<script src="/static/common.js"></script>
|
||||
<script src="/static/photoclipboard.js"></script>
|
||||
|
||||
<style>
|
||||
p
|
||||
|
|
|
@ -17,12 +17,13 @@
|
|||
{% macro create_photo_card(photo, view="grid") %}
|
||||
|
||||
{% if view == "list" %}
|
||||
<div class="photo_card_list">
|
||||
<div class="photo_card photo_card_list" data-id="{{photo.id}}">
|
||||
<input type="checkbox" class="photo_card_selector_checkbox" onclick="on_photo_select(event)"/>
|
||||
<span class="photo_card_filename"><a target="_blank" href="/photo/{{photo.id}}">{{photo.basename}}</a></span>
|
||||
<a class="photo_card_metadata" target="_blank" href="/file/{{photo.id}}.{{photo.extension}}">{{photo.bytestring()}}</a>
|
||||
</div>
|
||||
|
||||
{% else %}
|
||||
|
||||
{% if photo.thumbnail %}
|
||||
{% set thumbnail_src = "/thumbnail/" + photo.id + ".jpg" %}
|
||||
{% else %}
|
||||
|
@ -37,8 +38,9 @@
|
|||
|
||||
{% set tag_names_title = [] %}
|
||||
{% for tag in photo.tags() %}
|
||||
{% do tag_names_title.append(tag.name) %}
|
||||
{% do tag_names_title.append(tag.name) %}
|
||||
{% endfor %}
|
||||
|
||||
{% set tag_names_title = ", ".join(tag_names_title) %}
|
||||
{% if tag_names_title %}
|
||||
{% set tag_names_inner = "T" %}
|
||||
|
@ -54,7 +56,7 @@
|
|||
{% set metadata_inner = "{m}{d}, ".format(m=metadata_inner, d=photo.duration_string) %}
|
||||
{% endif %}
|
||||
|
||||
<div class="photo_card_grid">
|
||||
<div class="photo_card photo_card_grid" data-id="{{photo.id}}">
|
||||
<a class="photo_card_thumbnail" target="_blank" href="/photo/{{photo.id}}">
|
||||
<img height="150" src="{{thumbnail_src}}">
|
||||
</a>
|
||||
|
@ -69,6 +71,8 @@
|
|||
{{- metadata_inner|safe -}}
|
||||
<a target="_blank" href="/file/{{photo.id}}.{{photo.extension}}">{{photo.bytestring()}}</a>
|
||||
</span>
|
||||
|
||||
<input type="checkbox" class="photo_card_selector_checkbox" onclick="on_photo_select(event)"/>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<link rel="stylesheet" href="/static/common.css">
|
||||
<script src="/static/common.js"></script>
|
||||
<script src="/static/photoclipboard.js"></script>
|
||||
|
||||
<style>
|
||||
form
|
||||
|
|
Loading…
Reference in a new issue