Gallery speed + fandom editing + filters + pinned filter bar #61
Reference in New Issue
Block a user
Delete Branch "dev"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Batch of dev work since the last main cut. All CI-green on dev HEAD
6d630d1.Gallery load (speed + feel)
@load(cascade in load order) instead of popping in together; single 50-item initial fetch instead of 10 serial round-trips.image_record.effective_date(alembic 0035) so/scrollis an index range scan instead of a COALESCE-across-join sort per page.Fandom editing
TagService.set_fandom(set / change / clear) with cross-fandom merge on name collisions;PATCH /tags/<id>extended; UI in both the tags-directory card kebab and the image-modal tag-chip kebab.Filter clearing
:mandatorybug fix so it deselects.Pinned gallery filter bar (Phase 1)
/scroll+/timeline+/jump: multi-tag AND, artist, media type, newest/oldest sort (post_id stays exclusive).top:64pxfilter bar matching the app'sv-tabschrome: tag+artist autocomplete, closable chips, media toggle, sort, clear. URL-driven (deep-linkable, back-button).Also untracks the transient
.claude/scheduled_tasks.lock.🤖 Generated with Claude Code
Adds the missing UI to change a character tag's fandom, in both places: - FandomSetDialog (shared): pick an existing fandom, create a new one, or clear it; on a name collision in the target fandom it surfaces a merge confirmation and resolves via setFandom(merge:true). Reuses the tags store's fandom cache. - TagCard kebab gains "Set fandom…" for character tags (→ TagsView opens the dialog, reloads on success). - TagPanel chip kebab gains "Set fandom…" for character tags (→ reloads the modal's tag list on success). - tags store: setFandom(tagId, fandomId, {merge}) action + test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>Two gaps where a filter couldn't be removed: - Gallery: a tag_id filter (from clicking a tag) had no indicator or clear control — only post_id did (PostInfoHeader). Add an "Tag: <name> ✕" chip that clears the filter by dropping tag_id from the URL. New lightweight GET /api/tags/<id> resolves the name; the store fetches it on filter set. - Tags view: the kind chip-group used mandatory="false" — a STRING ("false" is truthy in JS), which made the group mandatory so the active kind chip couldn't be deselected. Fixed to :mandatory="false" so the filter clears. Tests: GET /tags/<id> shape + 404; gallery store resolves filterTagName. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>Phase 1 backend for the gallery filter bar. Extends scroll/timeline/jump from a single mutually-exclusive filter to a composable one: - tag_ids: image must carry ALL of them (one correlated EXISTS per tag — AND, no row multiplication), replacing the single-tag JOIN. - artist_id composes with tags; media_type ('image'|'video') narrows by mime; post_id stays the exclusive post-detail path. - sort ('newest'|'oldest') flips the effective_date/id cursor comparison and ordering; the cursor value is unchanged (direction comes from the request). jump_cursor honors sort too. - Shared _apply_scope helper applied across scroll/timeline/jump so the timeline sidebar reflects the filtered set. API _parse_filters parses tag_id (comma list), artist_id, media, sort. Tests: multi-tag AND, media filter, sort reversal (service + API); post_id-excludes-others; single tag_id back-compat. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>Gallery now has in-view filtering, styled like the app's sticky v-tabs chrome (pinned at top:64px under TopNav). - GalleryFilterBar: combined tag+artist autocomplete (searches /api/tags + /api/artists), closable filter chips (multi-tag AND), media toggle (All/Images/Videos), Newest/Oldest sort, Clear. Writes all state to the URL via router.push. - gallery store: filter is now { tag_ids, artist_id, media_type, sort, post_id }; applyFilterFromQuery makes the URL the single source of truth (deep-linkable, back-button works); chip labels resolved by id or pre-noted on pick. Replaces the standalone tag chip + setTag/PostFilter. - GalleryView: renders the bar (hidden in post-detail), syncs route.query → store on mount + every query change. Also untracks the transient .claude/scheduled_tasks.lock committed in3f30327and gitignores it. Tests: store parses query → composable scroll params, post_id exclusivity, newest-sort omitted, label pre-seed, single initial fetch. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>