Commit Graph
11 Commits
Author SHA1 Message Date
JakeBreath e97c3b9da0 Toast action results and confirm destructive actions in one dialog
Inline banners and per-row status text reported action results all over
the app; they are replaced by a small toast stack (bottom-right, Level 3
floating well styling) that only speaks for actions: successes fade,
errors stay until dismissed, and form-field validation stays inline.

Destructive actions no longer use bespoke inline confirm steps (the
library detail's Confirm delete button) or fire immediately (duplicate
copies/items, delete page selections, temp cleanup, upload discard, job
cancellation): they all go through one promise-based confirm dialog
(confirmAction) with a danger variant, Escape/backdrop to cancel.
2026-09-17 22:19:54 -05:00
JakeBreath cad659b75f Add a blacklist editor that saves to e621
The Online sidebar's "Your blacklist" section is editable now: typing a
tag appends it and each entry gets an x to remove it. Changes are written
straight to the e621 account (PATCH /users/{id}.json with
user[blacklisted_tags]); the store keeps the fetched profile for the id,
updates the list optimistically and reloads it from e621. The Followed
page's blacklist cloud is rebuilt afterwards via the new
/api/follows/cloud/?refresh=1 force flag.

Verified against the live API with a reversible add/verify/restore test.
2026-09-17 20:35:23 -05:00
JakeBreath e95dc5f265 Clear the query cache when the signed-in account changes
Logging out or switching accounts kept the previous user's React Query
cache (follows, feed, cloud, e621 pages), so the new account briefly
saw the old one's followed tags/pools until each query refetched. The
query client now lives in lib/queryClient.ts and login/register/logout
clear it alongside the e621 credential store.
2026-09-17 14:41:56 -05:00
JakeBreath 4df573da43 Library search upgrades: tag search, tag cloud, status filter
Backend:
- MediaItem gains search_tags (custom + e621 tags, lowercase) and
  has_custom_data, maintained on save with a data migration backfill
- File list search accepts search_type=filename|tags|both (tag search is
  word-AND across the flattened tag text) and status=matched|custom|
  unknown filters
- New /api/tags/cloud/ endpoint (cached 2 min per guest/auth, invalidated
  on item changes and deletions) returning the most-used tags, honouring
  guest visibility

Frontend:
- Library sidebar: Filename/Tags/Both selector, status pill toggles
  (persisted), and a clickable tag cloud that runs a tag search
- Roadmap updated
2026-09-17 13:19:17 -05:00
JakeBreath 75b7ed35eb Live worker counts and an e621 request-history dropdown
- Status polling drops from 30s to 5s, and download start/finish/cancel
  invalidates it immediately, so the footer's Active Workers reflects
  running download tasks in near real time
- The e621 time in the status pill is now a button: it opens a dropdown
  with the session's request history (clock time, endpoint, duration,
  colour-coded) plus totals; closes on outside click or Escape
- Metrics store keeps the last 50 requests
2026-09-17 12:20:27 -05:00
JakeBreath afca89de8f Show SPA e621 request times in the status pill
- New e621 metrics store tracks request count, cumulative time and the
  last request (path + duration) for the session
- The e621 client measures each request around fetch and JSON parsing
- Status pill appends a teal 'e621: <total>' segment with a tooltip
  showing request count and the last request; a server-side e621 time
  is shown separately if the backend ever reports one
2026-09-17 10:32:51 -05:00
JakeBreath 04448bf615 Online browser + post detail: SPA talks to e621 directly
Backend:
- POST /api/files/lookup/ reports which MD5s are already in the library

Frontend:
- e621 client extended with post/tag/favorite types and helpers: post
  search, post detail, batch posts by id, tag autocomplete, toggle
  favorite
- /online: tag search with autocomplete, post grid with rating colors
  and in-library badges, numbered pagination, page tag cloud, blacklist
  panel and filtered counts from /users/me.json, anonymous hint
- /online/view/🆔 media viewer (sample or original, video support),
  taxonomy-colored tags by category, specs sheet, favorite/unfavorite,
  description, sources, pools and parent/children thumbnails
- Shared CollapsibleSidebar extracted from the library page; Online
  added to the nav, command palette and sidebar toggle
2026-09-17 09:00:17 -05:00
JakeBreath b6409523e6 e621 credentials: user fields, API endpoint, Account screen
Backend:
- User model gains e621_username / e621_api_key / e621_base_url
- GET/PUT /api/auth/e621/ for the owner's credentials; /me exposes only
  the username and a configured flag, never the key

Frontend:
- e621 client core: Basic auth, _client param (browsers cannot set a
  User-Agent), serialized queue throttled to 1 request/second, readable
  error mapping
- Account screen (/account): username, API key with reveal toggle,
  base URL (e621 / e926 / custom), Save + Test connection
- Credentials are fetched from the backend and held in memory only,
  cleared on logout
2026-09-17 08:49:00 -05:00
JakeBreath a09ab8a160 Shell shortcuts: /, D, [ ], Ctrl+K palette + neighbors endpoint
Backend:
- GET /api/files/{md5}/neighbors/ returns previous/next items in the
  current ordering (name, size, created_at) for keyboard navigation

Frontend:
- / focuses the library search input
- D downloads the file on the detail page
- [ and ] navigate to the previous/next item; hint shown on the page
- Ctrl/Cmd+K opens a command palette (navigation, toggle filters,
  focus search, log in/out); Escape closes it
- Sort order now persists alongside the other library filters so
  prev/next stays consistent
2026-09-17 08:33:22 -05:00
JakeBreath 3aa42f3703 Shell polish: storage line, status pill, footer strip, sidebar
Backend:
- apps.core with GET /api/status/ (env, git hash, OS, watched folder,
  worker counts) and a TimingMiddleware adding X-Server-Time-Ms
- status endpoint reports its own server-side assembly time

Frontend:
- top bar shows the storage line (watched folder) and a status pill
  with ENV, git hash, host OS, server time (e621 time once it exists)
- fixed 32px footer strip: storage path, active workers, build version
- collapsible filter sidebar: closed by default, Ctrl/Cmd+B toggle,
  overlay drawer with backdrop blur under 1024px
- rating filters, per-page and sidebar state persist in localStorage
2026-09-17 08:19:27 -05:00
JakeBreath 555c25d77b M0: scaffold SPA + API monorepo
Backend (Django 6.1 + DRF):
- Token auth with a custom User model (register/login/logout/me)
- Library models (MediaItem, MediaLocation) and REST endpoints
- File list/detail with search, rating filter, sorting, pagination
- Multipart upload with optional rating/tags/notes
- Range-aware media serving (video seeking) and ffmpeg thumbnails
- scan_files management command for the watched folder

Frontend (React 19 + Vite + TypeScript):
- Catppuccin Mocha design tokens from the design docs
- App shell, token persistence, protected routes
- Library grid with filters, file detail with custom data editor
- Upload page with per-file progress via XHR
- Dev proxy to the Django API
2026-09-17 07:56:47 -05:00