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;
|
display:inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.photo_card
|
||||||
|
{
|
||||||
|
background-color: #ffffd4;
|
||||||
|
}
|
||||||
.photo_card_list
|
.photo_card_list
|
||||||
{
|
{
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr auto;
|
grid-template-columns: auto 1fr auto;
|
||||||
grid-template-rows: auto;
|
grid-template-rows: auto;
|
||||||
grid-template-areas:
|
grid-template-areas:
|
||||||
"filename metadata";
|
"checkbox filename metadata";
|
||||||
|
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
margin: 8px;
|
margin: 8px;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
|
|
||||||
background-color: #ffffd4;
|
|
||||||
}
|
}
|
||||||
.photo_card_list:hover
|
.photo_card_list:hover
|
||||||
{
|
{
|
||||||
box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.25);
|
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
|
.photo_card_grid
|
||||||
{
|
{
|
||||||
|
position: relative;
|
||||||
display: inline-grid;
|
display: inline-grid;
|
||||||
grid-template-columns: auto auto;
|
grid-template-columns: auto auto;
|
||||||
grid-template-rows: auto 1fr auto;
|
grid-template-rows: auto 1fr auto;
|
||||||
|
@ -165,8 +172,12 @@ is hovered over.
|
||||||
|
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.25);
|
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
|
.photo_card_thumbnail
|
||||||
{
|
{
|
||||||
|
@ -187,7 +198,6 @@ is hovered over.
|
||||||
The min-width:100% + width:0 prevent the info div from controlling
|
The min-width:100% + width:0 prevent the info div from controlling
|
||||||
card size, so we can prioritize the thumbnail instead.
|
card size, so we can prioritize the thumbnail instead.
|
||||||
*/
|
*/
|
||||||
align-self: start;
|
|
||||||
justify-self: start;
|
justify-self: start;
|
||||||
grid-area: filename;
|
grid-area: filename;
|
||||||
|
|
||||||
|
@ -202,6 +212,14 @@ is hovered over.
|
||||||
|
|
||||||
font-size: 12.8px;
|
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
|
.photo_card_filename:hover
|
||||||
{
|
{
|
||||||
overflow: visible;
|
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"/>
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
<link rel="stylesheet" href="/static/common.css">
|
<link rel="stylesheet" href="/static/common.css">
|
||||||
<script src="/static/common.js"></script>
|
<script src="/static/common.js"></script>
|
||||||
|
<script src="/static/photoclipboard.js"></script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
p
|
p
|
||||||
|
|
|
@ -17,12 +17,13 @@
|
||||||
{% macro create_photo_card(photo, view="grid") %}
|
{% macro create_photo_card(photo, view="grid") %}
|
||||||
|
|
||||||
{% if view == "list" %}
|
{% 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>
|
<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>
|
<a class="photo_card_metadata" target="_blank" href="/file/{{photo.id}}.{{photo.extension}}">{{photo.bytestring()}}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
||||||
{% if photo.thumbnail %}
|
{% if photo.thumbnail %}
|
||||||
{% set thumbnail_src = "/thumbnail/" + photo.id + ".jpg" %}
|
{% set thumbnail_src = "/thumbnail/" + photo.id + ".jpg" %}
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -37,8 +38,9 @@
|
||||||
|
|
||||||
{% set tag_names_title = [] %}
|
{% set tag_names_title = [] %}
|
||||||
{% for tag in photo.tags() %}
|
{% for tag in photo.tags() %}
|
||||||
{% do tag_names_title.append(tag.name) %}
|
{% do tag_names_title.append(tag.name) %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{% set tag_names_title = ", ".join(tag_names_title) %}
|
{% set tag_names_title = ", ".join(tag_names_title) %}
|
||||||
{% if tag_names_title %}
|
{% if tag_names_title %}
|
||||||
{% set tag_names_inner = "T" %}
|
{% set tag_names_inner = "T" %}
|
||||||
|
@ -54,7 +56,7 @@
|
||||||
{% set metadata_inner = "{m}{d}, ".format(m=metadata_inner, d=photo.duration_string) %}
|
{% set metadata_inner = "{m}{d}, ".format(m=metadata_inner, d=photo.duration_string) %}
|
||||||
{% endif %}
|
{% 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}}">
|
<a class="photo_card_thumbnail" target="_blank" href="/photo/{{photo.id}}">
|
||||||
<img height="150" src="{{thumbnail_src}}">
|
<img height="150" src="{{thumbnail_src}}">
|
||||||
</a>
|
</a>
|
||||||
|
@ -69,6 +71,8 @@
|
||||||
{{- metadata_inner|safe -}}
|
{{- metadata_inner|safe -}}
|
||||||
<a target="_blank" href="/file/{{photo.id}}.{{photo.extension}}">{{photo.bytestring()}}</a>
|
<a target="_blank" href="/file/{{photo.id}}.{{photo.extension}}">{{photo.bytestring()}}</a>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
<input type="checkbox" class="photo_card_selector_checkbox" onclick="on_photo_select(event)"/>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
<link rel="stylesheet" href="/static/common.css">
|
<link rel="stylesheet" href="/static/common.css">
|
||||||
<script src="/static/common.js"></script>
|
<script src="/static/common.js"></script>
|
||||||
|
<script src="/static/photoclipboard.js"></script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
form
|
form
|
||||||
|
|
Loading…
Reference in a new issue