ui change to improve tag list load
This commit is contained in:
+66
-22
@@ -423,27 +423,22 @@ def gallery_jump():
|
||||
)
|
||||
|
||||
|
||||
@main.route('/tags')
|
||||
def tag_list():
|
||||
def _get_tags_with_previews(kind=None, limit=35, offset=0, images_per_tag=3):
|
||||
"""
|
||||
Generic tag explorer:
|
||||
/tags -> all tags
|
||||
/tags?kind=user -> only user tags
|
||||
/tags?kind=artist -> only artist tags
|
||||
/tags?kind=archive -> only archive tags
|
||||
/tags?kind=character -> only character tags
|
||||
/tags?kind=series -> only series tags
|
||||
/tags?kind=rating -> only rating tags
|
||||
Shows a few preview images per tag.
|
||||
Helper function to get tags with counts and preview images.
|
||||
Returns (tag_data list, total_count, has_more).
|
||||
|
||||
Optimized to use 2 queries instead of N+1:
|
||||
1. Get all tags with counts
|
||||
2. Get preview images for all tags at once using window function
|
||||
1. Get tags with counts (paginated)
|
||||
2. Get preview images for those tags using window function
|
||||
"""
|
||||
images_per_tag = 3
|
||||
kind = request.args.get('kind')
|
||||
# Query for total count
|
||||
count_q = db.session.query(func.count(Tag.id))
|
||||
if kind:
|
||||
count_q = count_q.filter(Tag.kind == kind)
|
||||
total_count = count_q.scalar()
|
||||
|
||||
# Query 1: Get tags with image counts
|
||||
# Query 1: Get tags with image counts (paginated)
|
||||
q = db.session.query(
|
||||
Tag,
|
||||
func.count(image_tags.c.image_id).label('img_count')
|
||||
@@ -452,7 +447,7 @@ def tag_list():
|
||||
if kind:
|
||||
q = q.filter(Tag.kind == kind)
|
||||
|
||||
tags_with_counts = q.order_by(Tag.name.asc()).all()
|
||||
tags_with_counts = q.order_by(Tag.name.asc()).offset(offset).limit(limit).all()
|
||||
|
||||
# Build tag_id list and initialize tag_data dict
|
||||
tag_ids = [t.id for t, _ in tags_with_counts]
|
||||
@@ -469,9 +464,7 @@ def tag_list():
|
||||
}
|
||||
|
||||
# Query 2: Get preview images for all tags at once using a subquery with row_number
|
||||
# This fetches the top N images per tag in a single query
|
||||
if tag_ids:
|
||||
# Subquery to rank images within each tag
|
||||
row_num = func.row_number().over(
|
||||
partition_by=image_tags.c.tag_id,
|
||||
order_by=desc(func.coalesce(ImageRecord.taken_at, ImageRecord.imported_at))
|
||||
@@ -488,7 +481,6 @@ def tag_list():
|
||||
.subquery()
|
||||
)
|
||||
|
||||
# Get only the top N images per tag
|
||||
preview_rows = (
|
||||
db.session.query(subq.c.tag_id, ImageRecord)
|
||||
.join(ImageRecord, ImageRecord.id == subq.c.image_id)
|
||||
@@ -496,18 +488,70 @@ def tag_list():
|
||||
.all()
|
||||
)
|
||||
|
||||
# Group images by tag_id
|
||||
for tag_id, img in preview_rows:
|
||||
if tag_id in tag_map:
|
||||
tag_map[tag_id]["images"].append(img)
|
||||
|
||||
# Convert to list maintaining original order
|
||||
tag_data = [tag_map[t.id] for t, _ in tags_with_counts]
|
||||
has_more = (offset + len(tag_data)) < total_count
|
||||
|
||||
return tag_data, total_count, has_more
|
||||
|
||||
|
||||
@main.route('/tags')
|
||||
def tag_list():
|
||||
"""
|
||||
Generic tag explorer with infinite scroll:
|
||||
/tags -> all tags
|
||||
/tags?kind=user -> only user tags
|
||||
etc.
|
||||
Shows a few preview images per tag.
|
||||
Initially loads 35 tags, more loaded via API as user scrolls.
|
||||
"""
|
||||
kind = request.args.get('kind')
|
||||
limit = 35
|
||||
images_per_tag = 3
|
||||
|
||||
tag_data, total_count, has_more = _get_tags_with_previews(
|
||||
kind=kind, limit=limit, offset=0, images_per_tag=images_per_tag
|
||||
)
|
||||
|
||||
return render_template('tags_list.html',
|
||||
tag_data=tag_data,
|
||||
images_per_tag=images_per_tag,
|
||||
active_kind=kind)
|
||||
active_kind=kind,
|
||||
total_count=total_count,
|
||||
has_more=has_more,
|
||||
page_size=limit)
|
||||
|
||||
|
||||
@main.route('/api/tags/list')
|
||||
def api_tags_list():
|
||||
"""
|
||||
API endpoint for loading more tags (infinite scroll).
|
||||
Returns JSON with tag cards HTML and pagination info.
|
||||
"""
|
||||
kind = request.args.get('kind')
|
||||
offset = request.args.get('offset', 0, type=int)
|
||||
limit = request.args.get('limit', 35, type=int)
|
||||
images_per_tag = 3
|
||||
|
||||
tag_data, total_count, has_more = _get_tags_with_previews(
|
||||
kind=kind, limit=limit, offset=offset, images_per_tag=images_per_tag
|
||||
)
|
||||
|
||||
# Render tag cards to HTML
|
||||
cards_html = render_template('_tag_cards.html', tag_data=tag_data)
|
||||
|
||||
return jsonify(
|
||||
ok=True,
|
||||
html=cards_html,
|
||||
count=len(tag_data),
|
||||
total=total_count,
|
||||
has_more=has_more,
|
||||
offset=offset + len(tag_data)
|
||||
)
|
||||
|
||||
@main.route('/artists')
|
||||
def artist_list():
|
||||
|
||||
Reference in New Issue
Block a user