Add album cards and improve album pages.
- album card has placeholder for future thumbnail. - replaced nested tree hierarchy lists with separate boxes. - list/grid view also applies to the root listing. - added a sticky right panel for all the tools. not pretty yet. - mechanism for adding sticky panel changed. instead of applying it to the #right, you apply it to #content_body so that its grid layout can be updated properly.
This commit is contained in:
parent
d0208154e4
commit
707fdcc637
8 changed files with 371 additions and 191 deletions
|
@ -523,6 +523,11 @@ class Album(ObjectBase, GroupableMixin):
|
||||||
return total
|
return total
|
||||||
|
|
||||||
def sum_photos(self, recurse=True):
|
def sum_photos(self, recurse=True):
|
||||||
|
'''
|
||||||
|
If all you need is the number of photos in the album, this method is
|
||||||
|
preferable to len(album.get_photos()) because it performs the counting
|
||||||
|
in the database instead of creating the Photo objects.
|
||||||
|
'''
|
||||||
query = '''
|
query = '''
|
||||||
SELECT COUNT(photoid)
|
SELECT COUNT(photoid)
|
||||||
FROM album_photo_rel
|
FROM album_photo_rel
|
||||||
|
|
|
@ -166,7 +166,13 @@ def get_albums_core():
|
||||||
def get_albums_html():
|
def get_albums_html():
|
||||||
albums = get_albums_core()
|
albums = get_albums_core()
|
||||||
session = session_manager.get(request)
|
session = session_manager.get(request)
|
||||||
return flask.render_template('album.html', albums=albums, session=session)
|
response = flask.render_template(
|
||||||
|
'album.html',
|
||||||
|
albums=albums,
|
||||||
|
session=session,
|
||||||
|
view=request.args.get('view', 'grid'),
|
||||||
|
)
|
||||||
|
return response
|
||||||
|
|
||||||
@site.route('/albums.json')
|
@site.route('/albums.json')
|
||||||
@session_manager.give_token
|
@session_manager.give_token
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
--color_site_dropshadow: rgba(0, 0, 0, 0.25);
|
--color_site_dropshadow: rgba(0, 0, 0, 0.25);
|
||||||
--color_3d_shadow: rgba(0, 0, 0, 0.5);
|
--color_3d_shadow: rgba(0, 0, 0, 0.5);
|
||||||
--color_3d_highlight: rgba(255, 255, 255, 0.5);
|
--color_3d_highlight: rgba(255, 255, 255, 0.5);
|
||||||
|
|
||||||
|
--size_sticky_side: 300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
html
|
html
|
||||||
|
@ -34,8 +36,7 @@ input, select, textarea
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
|
|
||||||
padding: 1px;
|
padding: 2px;
|
||||||
padding-left: 2px;
|
|
||||||
|
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
|
@ -103,18 +104,50 @@ pre
|
||||||
white-space: pre-line;
|
white-space: pre-line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#left
|
||||||
|
{
|
||||||
|
grid-area: left;
|
||||||
|
}
|
||||||
|
#right
|
||||||
|
{
|
||||||
|
grid-area: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sticky_side_left
|
||||||
|
{
|
||||||
|
grid-template:
|
||||||
|
"left right"
|
||||||
|
/var(--size_sticky_side) 1fr;
|
||||||
|
}
|
||||||
.sticky_side_right
|
.sticky_side_right
|
||||||
{
|
{
|
||||||
position: fixed;
|
grid-template:
|
||||||
right: 8px;
|
"left right"
|
||||||
bottom: 8px;
|
/1fr var(--size_sticky_side);
|
||||||
top: 34px;
|
}
|
||||||
width: 300px;
|
|
||||||
overflow-y: auto;
|
.sticky_side_left #left,
|
||||||
|
.sticky_side_right #right
|
||||||
|
{
|
||||||
grid-area: right;
|
grid-area: right;
|
||||||
display: grid;
|
display: grid;
|
||||||
|
grid-auto-rows: min-content;
|
||||||
|
|
||||||
|
position: fixed;
|
||||||
|
bottom: 8px;
|
||||||
|
top: 34px;
|
||||||
|
width: var(--size_sticky_side);
|
||||||
|
overflow-y: auto;
|
||||||
background-color: var(--color_site_transparency);
|
background-color: var(--color_site_transparency);
|
||||||
}
|
}
|
||||||
|
.sticky_side_left #left
|
||||||
|
{
|
||||||
|
left: 8px;
|
||||||
|
}
|
||||||
|
.sticky_side_right #right
|
||||||
|
{
|
||||||
|
right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
.editor_input
|
.editor_input
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,3 +1,65 @@
|
||||||
|
.album_card
|
||||||
|
{
|
||||||
|
background-color: var(--color_site_secondary);
|
||||||
|
}
|
||||||
|
.album_card:hover
|
||||||
|
{
|
||||||
|
box-shadow: 2px 2px 5px 0px var(--color_site_dropshadow);
|
||||||
|
}
|
||||||
|
.album_card_list
|
||||||
|
{
|
||||||
|
display: grid;
|
||||||
|
grid-template:
|
||||||
|
"title metadata"
|
||||||
|
/1fr;
|
||||||
|
|
||||||
|
min-width: 600px;
|
||||||
|
margin: 8px;
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
.album_card_grid
|
||||||
|
{
|
||||||
|
position: relative;
|
||||||
|
display: inline-grid;
|
||||||
|
vertical-align: top;
|
||||||
|
grid-template:
|
||||||
|
"thumbnail title" auto
|
||||||
|
"thumbnail metadata" auto
|
||||||
|
/auto 1fr;
|
||||||
|
|
||||||
|
width: 400px;
|
||||||
|
margin: 8px;
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
.album_card_thumbnail
|
||||||
|
{
|
||||||
|
grid-area: thumbnail;
|
||||||
|
background-color: var(--color_site_transparency);
|
||||||
|
width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
.album_card_thumbnail img
|
||||||
|
{
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
.album_card_title
|
||||||
|
{
|
||||||
|
grid-area: title;
|
||||||
|
}
|
||||||
|
.album_card_metadata
|
||||||
|
{
|
||||||
|
grid-area: metadata;
|
||||||
|
}
|
||||||
|
.album_card_tools
|
||||||
|
{
|
||||||
|
position: absolute;
|
||||||
|
right: 4px;
|
||||||
|
bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
.photo_card
|
.photo_card
|
||||||
{
|
{
|
||||||
background-color: var(--color_site_secondary);
|
background-color: var(--color_site_secondary);
|
||||||
|
@ -5,16 +67,15 @@
|
||||||
.photo_card_list
|
.photo_card_list
|
||||||
{
|
{
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: auto 1fr auto;
|
grid-template:
|
||||||
grid-template-rows: auto;
|
"checkbox filename metadata" auto
|
||||||
grid-template-areas:
|
/auto 1fr auto;
|
||||||
"checkbox filename metadata";
|
|
||||||
|
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
margin: 8px;
|
margin: 8px;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
}
|
}
|
||||||
.photo_card_list:hover
|
.photo_card:hover
|
||||||
{
|
{
|
||||||
box-shadow: 2px 2px 5px 0px var(--color_site_dropshadow);
|
box-shadow: 2px 2px 5px 0px var(--color_site_dropshadow);
|
||||||
}
|
}
|
||||||
|
@ -31,7 +92,7 @@
|
||||||
"thumbnail thumbnail" auto
|
"thumbnail thumbnail" auto
|
||||||
"filename filename" 1fr
|
"filename filename" 1fr
|
||||||
"tags metadata" auto
|
"tags metadata" auto
|
||||||
/auto auto;
|
/10px auto;
|
||||||
min-width: 150px;
|
min-width: 150px;
|
||||||
max-width: 300px;
|
max-width: 300px;
|
||||||
height: 210px;
|
height: 210px;
|
||||||
|
@ -39,7 +100,6 @@
|
||||||
margin: 8px;
|
margin: 8px;
|
||||||
|
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
box-shadow: 2px 2px 5px 0px var(--color_site_dropshadow);
|
|
||||||
}
|
}
|
||||||
.photo_card_grid .photo_card_selector_checkbox
|
.photo_card_grid .photo_card_selector_checkbox
|
||||||
{
|
{
|
||||||
|
@ -81,12 +141,11 @@
|
||||||
max-height: 30px;
|
max-height: 30px;
|
||||||
background-color: inherit;
|
background-color: inherit;
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
|
|
||||||
font-size: 12.8px;
|
|
||||||
}
|
}
|
||||||
.photo_card_grid .photo_card_filename
|
.photo_card_grid .photo_card_filename
|
||||||
{
|
{
|
||||||
align-self: start;
|
align-self: start;
|
||||||
|
font-size: 12.8px;
|
||||||
}
|
}
|
||||||
.photo_card_list .photo_card_filename
|
.photo_card_list .photo_card_filename
|
||||||
{
|
{
|
||||||
|
@ -106,6 +165,8 @@
|
||||||
|
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
|
|
||||||
|
cursor: help;
|
||||||
}
|
}
|
||||||
.photo_card_metadata
|
.photo_card_metadata
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,42 +1,104 @@
|
||||||
<!DOCTYPE html5>
|
<!DOCTYPE html5>
|
||||||
<html>
|
<html>
|
||||||
|
|
||||||
|
{% macro shared_css() %}
|
||||||
|
<style>
|
||||||
|
h2, h3
|
||||||
|
{
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
#description_text
|
||||||
|
{
|
||||||
|
font-family: initial;
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remove_child_button
|
||||||
|
{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.remove_child_button:hover,
|
||||||
|
.album_card:hover .remove_child_button
|
||||||
|
{
|
||||||
|
display: initial;
|
||||||
|
}
|
||||||
|
#left
|
||||||
|
{
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
width: 95%;
|
||||||
|
}
|
||||||
|
#left > *
|
||||||
|
{
|
||||||
|
background-color: var(--color_site_transparency);
|
||||||
|
margin-top: 30px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
padding: 8px;
|
||||||
|
/*border: 1px solid black;*/
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 800px)
|
||||||
|
{
|
||||||
|
#content_body
|
||||||
|
{
|
||||||
|
grid-template:
|
||||||
|
"left" 1fr
|
||||||
|
"right" 150px
|
||||||
|
/1fr;
|
||||||
|
}
|
||||||
|
#right
|
||||||
|
{
|
||||||
|
top: unset !important;
|
||||||
|
width: unset !important;
|
||||||
|
left: 8px;
|
||||||
|
right: 8px;
|
||||||
|
bottom: 8px;
|
||||||
|
height: 150px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
{% if album is not defined %} {## Album listing ###################################################}
|
{% if album is not defined %} {## Album listing ###################################################}
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
{% import "header.html" as header %}
|
{% import "header.html" as header %}
|
||||||
|
{% import "album_card.html" as album_card %}
|
||||||
<title>Albums</title>
|
<title>Albums</title>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<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/css/common.css">
|
<link rel="stylesheet" href="/static/css/common.css">
|
||||||
|
<link rel="stylesheet" href="/static/css/photo_card.css">
|
||||||
<script src="/static/js/common.js"></script>
|
<script src="/static/js/common.js"></script>
|
||||||
<script src="/static/js/api.js"></script>
|
<script src="/static/js/api.js"></script>
|
||||||
|
|
||||||
<style>
|
{{shared_css()}}
|
||||||
#album_list
|
|
||||||
{
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
{{header.make_header(session=session)}}
|
{{header.make_header(session=session)}}
|
||||||
<div id="content_body">
|
<div id="content_body" class="sticky_side_right">
|
||||||
<div id="album_list">
|
<div id="left">
|
||||||
<h2>Albums</h2>
|
<div id="album_list">
|
||||||
<ul>
|
<h2>Albums</h2>
|
||||||
{% for album in albums %}
|
{% for album in albums %}
|
||||||
<li><a href="/album/{{album.id}}">{{album.display_name}}</a></li>
|
{{album_card.create_album_card(album, view=view)}}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<li>
|
</div>
|
||||||
<button id="create_child_prompt_button" class="green_button" onclick="open_create_child(event);">Create album</button>
|
</div>
|
||||||
<input type="text" id="create_child_title_entry" class="hidden" placeholder="Album title">
|
<div id="right">
|
||||||
<button id="create_child_submit_button" class="green_button hidden" onclick="create_child_form(event);">Create</button>
|
{% if view != "list" %}
|
||||||
<button id="create_child_cancel_button" class="gray_button hidden" onclick="cancel_create_child(event);">Cancel</button>
|
<a href="?view=list">List view</a>
|
||||||
</li>
|
{% else %}
|
||||||
</ul>
|
<a href="?view=grid">Grid view</a>
|
||||||
|
{% endif %}
|
||||||
|
<div>
|
||||||
|
<button id="create_child_prompt_button" class="green_button" onclick="open_create_child(event);">Create album</button>
|
||||||
|
<input type="text" id="create_child_title_entry" class="hidden" placeholder="Album title">
|
||||||
|
<button id="create_child_submit_button" class="green_button hidden" onclick="create_child_form(event);">Create</button>
|
||||||
|
<button id="create_child_cancel_button" class="gray_button hidden" onclick="cancel_create_child(event);">Cancel</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
@ -49,8 +111,9 @@ ALBUM_ID = undefined;
|
||||||
{% else %} {## Individual album ###################################################################}
|
{% else %} {## Individual album ###################################################################}
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
{% import "photo_card.html" as photo_card %}
|
|
||||||
{% import "header.html" as header %}
|
{% import "header.html" as header %}
|
||||||
|
{% import "album_card.html" as album_card %}
|
||||||
|
{% import "photo_card.html" as photo_card %}
|
||||||
{% import "clipboard_tray.html" as clipboard_tray %}
|
{% import "clipboard_tray.html" as clipboard_tray %}
|
||||||
<title>{{album.display_name}} | Albums</title>
|
<title>{{album.display_name}} | Albums</title>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
|
@ -64,68 +127,91 @@ ALBUM_ID = undefined;
|
||||||
<script src="/static/js/hotkeys.js"></script>
|
<script src="/static/js/hotkeys.js"></script>
|
||||||
<script src="/static/js/photo_clipboard.js"></script>
|
<script src="/static/js/photo_clipboard.js"></script>
|
||||||
|
|
||||||
<style>
|
{{shared_css()}}
|
||||||
p
|
|
||||||
{
|
|
||||||
word-break: break-word;
|
|
||||||
}
|
|
||||||
#album_metadata
|
|
||||||
{
|
|
||||||
max-width: 800px;
|
|
||||||
}
|
|
||||||
#description_text
|
|
||||||
{
|
|
||||||
font-family: initial;
|
|
||||||
padding: 8px;
|
|
||||||
background-color: var(--color_site_transparency);
|
|
||||||
}
|
|
||||||
|
|
||||||
ul
|
|
||||||
{
|
|
||||||
line-height: 1.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.remove_child_button
|
|
||||||
{
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.remove_child_button:hover,
|
|
||||||
li:hover .remove_child_button
|
|
||||||
{
|
|
||||||
display: initial;
|
|
||||||
}
|
|
||||||
|
|
||||||
#photo_list
|
|
||||||
{
|
|
||||||
padding-left: 40px;
|
|
||||||
padding-top: 10px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
{{header.make_header(session=session)}}
|
{{header.make_header(session=session)}}
|
||||||
<div id="content_body">
|
<div id="content_body" class="sticky_side_right">
|
||||||
<div id="album_metadata">
|
<div id="left">
|
||||||
<h2><span
|
<div id="hierarchy_self">
|
||||||
id="title_text"
|
<div id="album_metadata">
|
||||||
data-editor-id="title"
|
<h2><span
|
||||||
data-editor-empty-text="{{album.id}}"
|
id="title_text"
|
||||||
data-editor-placeholder="title"
|
data-editor-id="title"
|
||||||
>
|
data-editor-empty-text="{{album.id}}"
|
||||||
{{-album.display_name-}}
|
data-editor-placeholder="title"
|
||||||
</span></h2>
|
>
|
||||||
|
{{-album.display_name-}}
|
||||||
|
</span></h2>
|
||||||
|
|
||||||
<pre
|
<pre
|
||||||
id="description_text"
|
id="description_text"
|
||||||
data-editor-id="description"
|
data-editor-id="description"
|
||||||
data-editor-placeholder="description"
|
data-editor-placeholder="description"
|
||||||
{% if not album.description %}class="hidden"{% endif %}
|
{% if not album.description %}class="hidden"{% endif %}
|
||||||
>
|
>
|
||||||
{{-album.description-}}
|
{{-album.description-}}
|
||||||
</pre>
|
</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="hierarchy_parents">
|
||||||
|
<h3>Parents</h3>
|
||||||
|
{% set parents = album.get_parents() %}
|
||||||
|
{% if parents %}
|
||||||
|
{% for parent in parents %}
|
||||||
|
{{album_card.create_album_card(parent, view=view)}}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{{album_card.create_root_album_card(view=view)}}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% set sub_albums = album.get_children() %}
|
||||||
|
{% if sub_albums %}
|
||||||
|
<div id="hierarchy_children">
|
||||||
|
<h3>Children</h3>
|
||||||
|
{% for sub_album in sub_albums|sort(attribute='title') %}
|
||||||
|
{{album_card.create_album_card(sub_album, view=view, unlink_parent=album)}}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% set photos = album.get_photos() %}
|
||||||
|
{% if photos %}
|
||||||
|
<div id="hierarchy_photos">
|
||||||
|
<h3>{{photos|length}} Photos</h3>
|
||||||
|
<div id="photo_list">
|
||||||
|
{% for photo in photos %}
|
||||||
|
{{photo_card.create_photo_card(photo, view=view)}}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% set has_local_photos = photos|length > 0 %}
|
||||||
|
{% set has_child_photos = album.has_any_subalbum_photo() %}
|
||||||
|
{% if has_local_photos or has_child_photos %}
|
||||||
|
<div id="download_links">
|
||||||
|
<h3>Download</h3>
|
||||||
|
{% if has_local_photos %}
|
||||||
|
<p><a id="download_link_single" href="/album/{{album.id}}.zip?recursive=no">These files – {{album.sum_bytes(recurse=False)|bytestring}}</a></p>
|
||||||
|
{% endif %}
|
||||||
|
{% if has_child_photos %}
|
||||||
|
<p><a id="download_link_recursive" href="/album/{{album.id}}.zip?recursive=yes">Include children – {{album.sum_bytes(recurse=True)|bytestring}}</a></p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="right">
|
||||||
|
{% if view != "list" %}
|
||||||
|
<a href="?view=list">List view</a>
|
||||||
|
{% else %}
|
||||||
|
<a href="?view=grid">Grid view</a>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="red_button button_with_confirm"
|
class="red_button button_with_confirm"
|
||||||
|
@ -136,84 +222,20 @@ li:hover .remove_child_button
|
||||||
>
|
>
|
||||||
Delete
|
Delete
|
||||||
</button>
|
</button>
|
||||||
</div>
|
|
||||||
|
|
||||||
<ul id="hierarchy_parents">
|
<div>
|
||||||
{% set viewparam = "?view=list" if view == "list" else "" %}
|
<button id="create_child_prompt_button" class="green_button" onclick="open_create_child(event);">Create child</button>
|
||||||
{% set parents = album.get_parents() %}
|
<input type="text" id="create_child_title_entry" class="hidden" placeholder="Album title">
|
||||||
{% if parents %}
|
<button id="create_child_submit_button" class="green_button hidden" onclick="create_child_form(event);">Create</button>
|
||||||
{% for parent in parents %}
|
<button id="create_child_cancel_button" class="gray_button hidden" onclick="cancel_create_child(event);">Cancel</button>
|
||||||
<li><a href="/album/{{parent.id}}{{viewparam}}">{{parent.display_name}}</a></li>
|
|
||||||
{% endfor %}
|
|
||||||
{% else %}
|
|
||||||
<li><a href="/albums">Albums</a></li>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<ul id="hierarchy_self">
|
|
||||||
<li>{{album.display_name}}</li>
|
|
||||||
<ul id="heirarchy_children">
|
|
||||||
{% set sub_albums = album.get_children() %}
|
|
||||||
{% for sub_album in sub_albums|sort(attribute='title') %}
|
|
||||||
<li>
|
|
||||||
<a href="/album/{{sub_album.id}}{{viewparam}}">{{sub_album.display_name}}</a>
|
|
||||||
|
|
||||||
<button
|
|
||||||
class="remove_child_button button_with_confirm red_button"
|
|
||||||
data-onclick="api.albums.remove_child(ALBUM_ID, '{{sub_album.id}}', common.refresh)"
|
|
||||||
data-prompt="Remove child?"
|
|
||||||
data-holder-class="remove_child_button"
|
|
||||||
data-confirm-class="red_button"
|
|
||||||
data-cancel-class="gray_button"
|
|
||||||
>
|
|
||||||
Unlink
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
{% endfor %}
|
|
||||||
<li>
|
|
||||||
<button id="create_child_prompt_button" class="green_button" onclick="open_create_child(event);">Create child</button>
|
|
||||||
<input type="text" id="create_child_title_entry" class="hidden" placeholder="Album title">
|
|
||||||
<button id="create_child_submit_button" class="green_button hidden" onclick="create_child_form(event);">Create</button>
|
|
||||||
<button id="create_child_cancel_button" class="gray_button hidden" onclick="cancel_create_child(event);">Cancel</button>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<button id="add_child_prompt_button" class="green_button" onclick="open_add_child(event);">Add child</button>
|
|
||||||
<input type="text" id="add_child_id_entry" class="hidden" placeholder="Album ID">
|
|
||||||
<button id="add_child_submit_button" class="green_button hidden" onclick="add_child_form(event);">Add</button>
|
|
||||||
<button id="add_child_cancel_button" class="gray_button hidden" onclick="cancel_add_child(event);">Cancel</button>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</ul>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
{% set photos = album.get_photos() %}
|
|
||||||
{% if photos %}
|
|
||||||
<h3>{{photos|length}} Photos</h3>
|
|
||||||
{% if view != "list" %}
|
|
||||||
<a href="?view=list">List view</a>
|
|
||||||
{% else %}
|
|
||||||
<a href="?view=grid">Grid view</a>
|
|
||||||
{% endif %}
|
|
||||||
<div id="photo_list">
|
|
||||||
{% for photo in photos %}
|
|
||||||
{{photo_card.create_photo_card(photo, view=view)}}
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
<div>
|
||||||
|
<button id="add_child_prompt_button" class="green_button" onclick="open_add_child(event);">Add child</button>
|
||||||
{% set has_local_photos = photos|length > 0 %}
|
<input type="text" id="add_child_id_entry" class="hidden" placeholder="Album ID">
|
||||||
{% set has_child_photos = album.has_any_subalbum_photo() %}
|
<button id="add_child_submit_button" class="green_button hidden" onclick="add_child_form(event);">Add</button>
|
||||||
{% if has_local_photos or has_child_photos %}
|
<button id="add_child_cancel_button" class="gray_button hidden" onclick="cancel_add_child(event);">Cancel</button>
|
||||||
<p id="download_links">
|
</div>
|
||||||
<span>Download:</span>
|
</div>
|
||||||
{% if has_local_photos %}
|
|
||||||
<a id="download_link_single" href="/album/{{album.id}}.zip?recursive=no">These files ({{album.sum_bytes(recurse=False)|bytestring }})</a>
|
|
||||||
{% if has_child_photos %}<span>—</span>{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
{% if has_child_photos %}
|
|
||||||
<a id="download_link_recursive" href="/album/{{album.id}}.zip?recursive=yes">Include children ({{album.sum_bytes(recurse=True)|bytestring }})</a>
|
|
||||||
{% endif %}
|
|
||||||
</p>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{{clipboard_tray.clipboard_tray()}}
|
{{clipboard_tray.clipboard_tray()}}
|
||||||
<div class="my_clipboard_tray_toolbox">
|
<div class="my_clipboard_tray_toolbox">
|
||||||
|
|
65
frontends/etiquette_flask/templates/album_card.html
Normal file
65
frontends/etiquette_flask/templates/album_card.html
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
{% macro create_root_album_card(view="grid") %}
|
||||||
|
{% set viewparam = "?view=list" if view == "list" else "" %}
|
||||||
|
{% if view == "list" %}
|
||||||
|
<div class="album_card album_card_list">
|
||||||
|
<div class="album_card_title">
|
||||||
|
<a href="/albums{{viewparam}}">Albums</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="album_card album_card_grid">
|
||||||
|
<a class="album_card_thumbnail" href="/albums">
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="album_card_title">
|
||||||
|
<a href="/albums">Albums</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro create_album_card(album, view="grid", unlink_parent=none) %}
|
||||||
|
{% set viewparam = "?view=list" if view == "list" else "" %}
|
||||||
|
{% if view == "list" %}
|
||||||
|
<div class="album_card album_card_list">
|
||||||
|
<div class="album_card_title">
|
||||||
|
<a href="/album/{{album.id}}{{viewparam}}">{{album.display_name}}</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span class="album_card_metadata">
|
||||||
|
<span class="album_card_child_count">{{album.get_children()|length}}</span> children
|
||||||
|
{{-' '-}}|{{-' '-}}
|
||||||
|
<span class="album_card_photo_count">{{album.sum_photos(recurse=False)}}</span> photos
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="album_card album_card_grid" data-id="{{album.id}}">
|
||||||
|
<a class="album_card_thumbnail" href="/album/{{album.id}}{{viewparam}}">
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="album_card_title">
|
||||||
|
<a href="/album/{{album.id}}{{viewparam}}">{{album.display_name}}</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span class="album_card_metadata">
|
||||||
|
<span class="album_card_child_count">{{album.get_children()|length}}</span> children
|
||||||
|
{{-' '-}}|{{-' '-}}
|
||||||
|
<span class="album_card_photo_count">{{album.sum_photos(recurse=False)}}</span> photos
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div class="album_card_tools">
|
||||||
|
{% if unlink_parent is not none %}
|
||||||
|
<button
|
||||||
|
class="remove_child_button button_with_confirm red_button"
|
||||||
|
data-onclick="api.albums.remove_child('{{unlink_parent.id}}', '{{album.id}}', common.refresh)"
|
||||||
|
data-prompt="Remove child?"
|
||||||
|
data-holder-class="remove_child_button"
|
||||||
|
data-confirm-class="red_button"
|
||||||
|
data-cancel-class="gray_button"
|
||||||
|
>Unlink
|
||||||
|
</button>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endmacro %}
|
|
@ -16,13 +16,6 @@
|
||||||
<script src="/static/js/tag_autocomplete.js"></script>
|
<script src="/static/js/tag_autocomplete.js"></script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
#content_body
|
|
||||||
{
|
|
||||||
display: grid;
|
|
||||||
grid-template:
|
|
||||||
"left right" 1fr
|
|
||||||
/1fr 300px;
|
|
||||||
}
|
|
||||||
#header
|
#header
|
||||||
{
|
{
|
||||||
grid-area: header;
|
grid-area: header;
|
||||||
|
@ -83,8 +76,8 @@
|
||||||
}
|
}
|
||||||
#right
|
#right
|
||||||
{
|
{
|
||||||
top: unset;
|
top: unset !important;
|
||||||
width: unset;
|
width: unset !important;
|
||||||
left: 8px;
|
left: 8px;
|
||||||
right: 8px;
|
right: 8px;
|
||||||
bottom: 8px;
|
bottom: 8px;
|
||||||
|
@ -106,14 +99,14 @@
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
{{header.make_header(session=session)}}
|
{{header.make_header(session=session)}}
|
||||||
<div id="content_body">
|
<div id="content_body" class="sticky_side_right">
|
||||||
<div id="left">
|
<div id="left">
|
||||||
<span>The clipboard contains <span class="clipboard_count">0</span> items.</span>
|
<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>
|
<button id="clear_clipboard_button" class="red_button" onclick="photo_clipboard.clear_clipboard()">Clear it.</button>
|
||||||
<div id="photo_card_holder">
|
<div id="photo_card_holder">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="right" class="sticky_side_right">
|
<div id="right">
|
||||||
<div id="add_tag_area">
|
<div id="add_tag_area">
|
||||||
<input type="text" id="add_tag_textbox" list="tag_autocomplete_datalist">
|
<input type="text" id="add_tag_textbox" list="tag_autocomplete_datalist">
|
||||||
<button class="add_tag_button green_button" id="add_tag_button" onclick="add_tag_form();">Add tag</button>
|
<button class="add_tag_button green_button" id="add_tag_button" onclick="add_tag_form();">Add tag</button>
|
||||||
|
|
|
@ -20,12 +20,6 @@
|
||||||
{
|
{
|
||||||
grid-area: header;
|
grid-area: header;
|
||||||
}
|
}
|
||||||
#content_body
|
|
||||||
{
|
|
||||||
grid-template:
|
|
||||||
"left right"
|
|
||||||
/1fr 300px;
|
|
||||||
}
|
|
||||||
#left
|
#left
|
||||||
{
|
{
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
|
@ -64,12 +58,13 @@
|
||||||
{
|
{
|
||||||
grid-template:
|
grid-template:
|
||||||
"left" 1fr
|
"left" 1fr
|
||||||
"right" 150px;
|
"right" 150px
|
||||||
|
/1fr;
|
||||||
}
|
}
|
||||||
#right
|
#right
|
||||||
{
|
{
|
||||||
top: unset;
|
top: unset !important;
|
||||||
width: unset;
|
width: unset !important;
|
||||||
left: 8px;
|
left: 8px;
|
||||||
right: 8px;
|
right: 8px;
|
||||||
bottom: 8px;
|
bottom: 8px;
|
||||||
|
@ -86,7 +81,7 @@
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
{{header.make_header(session=session)}}
|
{{header.make_header(session=session)}}
|
||||||
<div id="content_body">
|
<div id="content_body" class="sticky_side_right">
|
||||||
<div id="left">
|
<div id="left">
|
||||||
{% if specific_tag %}
|
{% if specific_tag %}
|
||||||
<div id="tag_metadata">
|
<div id="tag_metadata">
|
||||||
|
@ -178,7 +173,7 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div id="right" class="sticky_side_right">
|
<div id="right">
|
||||||
<div id="editor_area">
|
<div id="editor_area">
|
||||||
<input type="text" id="add_tag_textbox" autofocus>
|
<input type="text" id="add_tag_textbox" autofocus>
|
||||||
<button class="add_tag_button green_button" id="add_tag_button" onclick="easybake_form();">bake</button>
|
<button class="add_tag_button green_button" id="add_tag_button" onclick="easybake_form();">bake</button>
|
||||||
|
|
Loading…
Reference in a new issue