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