moving styling and views to be more consistent and for gallery view to be less cumbersome.
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
<!-- /app/templates/_gallery_item.html -->
|
||||
<div class="gallery-item img-clickable"
|
||||
data-id="{{ image.id }}"
|
||||
data-full="{{ url_for('main.serve_image', filename=image.filepath | replace('/images/', '') ) }}"
|
||||
data-type="{{ 'video' if image.filename.lower().endswith(('.mp4', '.mov')) else 'image' }}"
|
||||
data-filename="{{ image.filename }}">
|
||||
|
||||
<div class="gallery-thumb"
|
||||
style="background-image: url('{{ url_for('main.serve_image', filename=(image.thumb_path or image.filepath) | replace('/images/', '') ) }}');"></div>
|
||||
|
||||
{% set visible_tags = image.tags | selectattr('kind', 'ne', 'archive') | list %}
|
||||
{% if visible_tags %}
|
||||
<div class="tag-overlay">
|
||||
{% for t in visible_tags %}
|
||||
<a class="tag-chip"
|
||||
href="{{ url_for('main.gallery', tag=t.name) }}"
|
||||
title="Filter by {{ t.name }}"
|
||||
onclick="event.stopPropagation()">
|
||||
{% if t.kind == 'artist' %}
|
||||
{{ t.name.split(':', 1)[1] if ':' in t.name else t.name }}
|
||||
{% elif t.kind == 'character' %}
|
||||
{{ t.name.split(':', 1)[1] if ':' in t.name else t.name }}
|
||||
{% elif t.kind == 'series' %}
|
||||
{{ t.name.split(':', 1)[1] if ':' in t.name else t.name }}
|
||||
{% elif t.kind == 'rating' %}
|
||||
{{ t.name.split(':', 1)[1] if ':' in t.name else t.name }}
|
||||
{% else %}
|
||||
#{{ t.name }}
|
||||
{% endif %}
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if image.filename.lower().endswith(('.mp4', '.mov')) %}
|
||||
<div class="play-overlay"></div>
|
||||
{% endif %}
|
||||
|
||||
<span class="image-date">{{ image.taken_at or image.imported_at | datetimeformat }}</span>
|
||||
</div>
|
||||
@@ -0,0 +1,26 @@
|
||||
<!-- /app/templates/_gallery_modal.html -->
|
||||
<div id="imageModal" class="modal">
|
||||
<div class="modal-content">
|
||||
<button id="modalClose" class="modal-close-btn" title="Close (ESC)">×</button>
|
||||
<button id="modalPrev" class="modal-button modal-prev">‹</button>
|
||||
<button id="modalNext" class="modal-button modal-next">›</button>
|
||||
<span class="modal-close-hint">ESC to close</span>
|
||||
|
||||
<div class="modal-body">
|
||||
<div id="modalImageWrapper" class="modal-image-wrapper">
|
||||
<img id="modalImage" src="" alt="Full View">
|
||||
</div>
|
||||
|
||||
<div id="modalTagEditor" class="tag-editor" data-image-id="">
|
||||
<div id="modalTagList" class="tags"></div>
|
||||
<form id="modalTagForm" class="tag-form" autocomplete="off">
|
||||
<div class="tag-form-wrapper">
|
||||
<input type="text" id="tagInput" name="name" placeholder="Add tag..." autocomplete="off">
|
||||
<div id="tagAutocomplete" class="tag-autocomplete"></div>
|
||||
</div>
|
||||
<button type="submit">Add</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -3,14 +3,73 @@
|
||||
{% block title %}Gallery{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1 style="text-align:center; margin-top: 1rem;">Gallery</h1>
|
||||
<div class="gallery-infinite-container">
|
||||
<!-- Timeline Scrollbar (left sidebar) -->
|
||||
<aside id="timelineSidebar" class="timeline-sidebar">
|
||||
<div id="timelineTrack" class="timeline-track">
|
||||
<!-- Populated by JS with year-month markers -->
|
||||
<div class="timeline-loading">Loading...</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- Gallery Grid -->
|
||||
{% include '_gallery_grid.html' %}
|
||||
<!-- Main Gallery Content -->
|
||||
<main class="gallery-main">
|
||||
<div class="gallery-header">
|
||||
<h1>Gallery</h1>
|
||||
{% if active_tag %}
|
||||
<div class="active-filter">
|
||||
Filtered by: <span class="filter-tag">{{ active_tag }}</span>
|
||||
<a href="{{ url_for('main.gallery') }}" class="clear-filter" title="Clear filter">×</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Floating Pagination Bar -->
|
||||
{% if images.pages > 1 %}
|
||||
{% include '_pagination_floating.html' %}
|
||||
{% endif %}
|
||||
<!-- Gallery Grid with Date Sections -->
|
||||
<div id="galleryInfinite" class="gallery-infinite">
|
||||
{% for year_month_key, year_month_label, images in grouped_images %}
|
||||
<section class="date-section" data-year-month="{{ year_month_key }}">
|
||||
<h2 class="date-divider" id="section-{{ year_month_key }}">
|
||||
<span class="date-divider-text">{{ year_month_label }}</span>
|
||||
<span class="date-divider-count">{{ images|length }} images</span>
|
||||
</h2>
|
||||
<div class="gallery-grid">
|
||||
{% for image in images %}
|
||||
{% include '_gallery_item.html' %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</section>
|
||||
{% else %}
|
||||
<div class="gallery-empty">
|
||||
<p>No images found{% if active_tag %} for tag "{{ active_tag }}"{% endif %}.</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<!-- Loading indicator -->
|
||||
<div id="galleryLoading" class="gallery-loading" style="display:none;">
|
||||
<span class="loading-spinner"></span>
|
||||
<span>Loading more images...</span>
|
||||
</div>
|
||||
|
||||
<!-- End of content marker -->
|
||||
<div id="galleryEnd" class="gallery-end" style="display:none;">
|
||||
No more images
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<!-- Modal -->
|
||||
{% include '_gallery_modal.html' %}
|
||||
|
||||
<!-- Pass initial state to JS -->
|
||||
<script>
|
||||
window.galleryState = {
|
||||
cursor: {{ initial_cursor | tojson | safe if initial_cursor else 'null' }},
|
||||
hasMore: {{ 'true' if has_more else 'false' }},
|
||||
activeTag: {{ active_tag | tojson | safe if active_tag else 'null' }}
|
||||
};
|
||||
</script>
|
||||
|
||||
<script src="{{ url_for('static', filename='js/gallery-infinite.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/modal-pagination.js') }}"></script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -37,12 +37,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if request.endpoint == 'main.gallery' %}
|
||||
<input type="hidden" id="hasNextPage" value="{{ has_next|lower }}">
|
||||
<input type="hidden" id="nextPageUrl" value="{{ next_page_url }}">
|
||||
<input type="hidden" id="hasPrevPage" value="{{ has_prev|lower }}">
|
||||
<input type="hidden" id="prevPageUrl" value="{{ prev_page_url }}">
|
||||
{% endif %}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user