diff --git a/etiquette/objects.py b/etiquette/objects.py index 2c593e7..6d5001d 100644 --- a/etiquette/objects.py +++ b/etiquette/objects.py @@ -523,6 +523,11 @@ class Album(ObjectBase, GroupableMixin): return total 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 = ''' SELECT COUNT(photoid) FROM album_photo_rel diff --git a/frontends/etiquette_flask/backend/endpoints/album_endpoints.py b/frontends/etiquette_flask/backend/endpoints/album_endpoints.py index 94ab804..48740ca 100644 --- a/frontends/etiquette_flask/backend/endpoints/album_endpoints.py +++ b/frontends/etiquette_flask/backend/endpoints/album_endpoints.py @@ -166,7 +166,13 @@ def get_albums_core(): def get_albums_html(): albums = get_albums_core() 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') @session_manager.give_token diff --git a/frontends/etiquette_flask/static/css/common.css b/frontends/etiquette_flask/static/css/common.css index 818ac04..2b5a133 100644 --- a/frontends/etiquette_flask/static/css/common.css +++ b/frontends/etiquette_flask/static/css/common.css @@ -13,6 +13,8 @@ --color_site_dropshadow: rgba(0, 0, 0, 0.25); --color_3d_shadow: rgba(0, 0, 0, 0.5); --color_3d_highlight: rgba(255, 255, 255, 0.5); + + --size_sticky_side: 300px; } html @@ -34,8 +36,7 @@ input, select, textarea margin-top: 2px; margin-bottom: 2px; - padding: 1px; - padding-left: 2px; + padding: 2px; border: none; border-radius: 2px; @@ -103,18 +104,50 @@ pre 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 { - position: fixed; - right: 8px; - bottom: 8px; - top: 34px; - width: 300px; - overflow-y: auto; + grid-template: + "left right" + /1fr var(--size_sticky_side); +} + +.sticky_side_left #left, +.sticky_side_right #right +{ grid-area: right; 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); } +.sticky_side_left #left +{ + left: 8px; +} +.sticky_side_right #right +{ + right: 8px; +} .editor_input { diff --git a/frontends/etiquette_flask/static/css/photo_card.css b/frontends/etiquette_flask/static/css/photo_card.css index 4c8289c..b5e50a5 100644 --- a/frontends/etiquette_flask/static/css/photo_card.css +++ b/frontends/etiquette_flask/static/css/photo_card.css @@ -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 { background-color: var(--color_site_secondary); @@ -5,16 +67,15 @@ .photo_card_list { display: grid; - grid-template-columns: auto 1fr auto; - grid-template-rows: auto; - grid-template-areas: - "checkbox filename metadata"; + grid-template: + "checkbox filename metadata" auto + /auto 1fr auto; max-width: 800px; margin: 8px; padding: 4px; } -.photo_card_list:hover +.photo_card:hover { box-shadow: 2px 2px 5px 0px var(--color_site_dropshadow); } @@ -31,7 +92,7 @@ "thumbnail thumbnail" auto "filename filename" 1fr "tags metadata" auto - /auto auto; + /10px auto; min-width: 150px; max-width: 300px; height: 210px; @@ -39,7 +100,6 @@ margin: 8px; border-radius: 8px; - box-shadow: 2px 2px 5px 0px var(--color_site_dropshadow); } .photo_card_grid .photo_card_selector_checkbox { @@ -81,12 +141,11 @@ max-height: 30px; background-color: inherit; word-break: break-word; - - font-size: 12.8px; } .photo_card_grid .photo_card_filename { align-self: start; + font-size: 12.8px; } .photo_card_list .photo_card_filename { @@ -106,6 +165,8 @@ font-family: monospace; font-size: 11px; + + cursor: help; } .photo_card_metadata { diff --git a/frontends/etiquette_flask/templates/album.html b/frontends/etiquette_flask/templates/album.html index d5e42b8..4597be6 100644 --- a/frontends/etiquette_flask/templates/album.html +++ b/frontends/etiquette_flask/templates/album.html @@ -1,42 +1,104 @@ +{% macro shared_css() %} + +{% endmacro %} + {% if album is not defined %} {## Album listing ###################################################} {% import "header.html" as header %} + {% import "album_card.html" as album_card %} Albums + - +{{shared_css()}} {{header.make_header(session=session)}} -
-
-

Albums

- +
+
+ @@ -49,8 +111,9 @@ ALBUM_ID = undefined; {% else %} {## Individual album ###################################################################} - {% import "photo_card.html" as photo_card %} {% 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 %} {{album.display_name}} | Albums @@ -64,68 +127,91 @@ ALBUM_ID = undefined; - +{{shared_css()}} {{header.make_header(session=session)}} -
-
-

- {{-album.display_name-}} -

+
+
+
+
+

+ {{-album.display_name-}} +

-
-            {{-album.description-}}
-        
+
+                    {{-album.description-}}
+                
+
+
+ +
+

Parents

+ {% 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 %} +
+ + {% set sub_albums = album.get_children() %} + {% if sub_albums %} +
+

Children

+ {% for sub_album in sub_albums|sort(attribute='title') %} + {{album_card.create_album_card(sub_album, view=view, unlink_parent=album)}} + {% endfor %} +
+ {% endif %} + + {% set photos = album.get_photos() %} + {% if photos %} +
+

{{photos|length}} Photos

+
+ {% for photo in photos %} + {{photo_card.create_photo_card(photo, view=view)}} + {% endfor %} +
+
+ {% 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 %} + + {% endif %} +
+ + -
    - {% set viewparam = "?view=list" if view == "list" else "" %} - {% set parents = album.get_parents() %} - {% if parents %} - {% for parent in parents %} -
  • {{parent.display_name}}
  • - {% endfor %} - {% else %} -
  • Albums
  • - {% endif %} - -
      -
    • {{album.display_name}}
    • -
        - {% set sub_albums = album.get_children() %} - {% for sub_album in sub_albums|sort(attribute='title') %} -
      • - {{sub_album.display_name}} - - -
      • - {% endfor %} -
      • - - - - -
      • -
      • - - - - -
      • -
      -
    -
- - {% set photos = album.get_photos() %} - {% if photos %} -

{{photos|length}} Photos

- {% if view != "list" %} - List view - {% else %} - Grid view - {% endif %} -
- {% for photo in photos %} - {{photo_card.create_photo_card(photo, view=view)}} - {% endfor %} +
+ + + +
- {% 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 %} - - {% endif %} +
+ + + + +
+
{{clipboard_tray.clipboard_tray()}}
diff --git a/frontends/etiquette_flask/templates/album_card.html b/frontends/etiquette_flask/templates/album_card.html new file mode 100644 index 0000000..b3cfa22 --- /dev/null +++ b/frontends/etiquette_flask/templates/album_card.html @@ -0,0 +1,65 @@ +{% macro create_root_album_card(view="grid") %} +{% set viewparam = "?view=list" if view == "list" else "" %} + {% if view == "list" %} +
+
+ Albums +
+
+ {% else %} +
+ + + +
+ Albums +
+
+ {% endif %} +{% endmacro %} + +{% macro create_album_card(album, view="grid", unlink_parent=none) %} +{% set viewparam = "?view=list" if view == "list" else "" %} + {% if view == "list" %} +
+ + + +
+ {% else %} +
+ + + + + + + +
+ {% if unlink_parent is not none %} + + {% endif %} +
+
+ {% endif %} +{% endmacro %} diff --git a/frontends/etiquette_flask/templates/clipboard.html b/frontends/etiquette_flask/templates/clipboard.html index 03bb264..7fb124f 100644 --- a/frontends/etiquette_flask/templates/clipboard.html +++ b/frontends/etiquette_flask/templates/clipboard.html @@ -16,13 +16,6 @@