- Replace custom inline span+getStatusColor with Badge component in recording card
- Align admin recordings table badge to same style (outline, green/yellow)
- Use i18n label in admin table instead of raw status string
- Remove unused cn import and getStatusColor helper
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove back button from admin entity edit pages (sidebar handles navigation)
- Remove cancel button from video/article forms, make submit button full-width
- Show actual entity title + subtitle on video/article edit pages
- Remove asterisks from Title/Slug field labels in i18n
- Remove px-3 sm:px-0 from all admin list page headers/filters (fixes mobile padding)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace ← text with icon-[ri--arrow-left-line] in admin and me layouts
- Add avatar + admin shield badge to admin sidebar header
- Wrap all admin edit forms in Card (bg-card/50 border-primary/20) with styled inputs
- Fix sm:pl-6 → lg:pl-6 so extra left padding only applies when sidebar is visible
- Update security form submit button to gradient style matching profile
- Remove "View Public Profile" button from me/profile
- Use shadcn-svelte Empty component for recordings empty state
- Install empty component via shadcn-svelte
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add BullMQ to backend; mail jobs (verification, password reset) now enqueued instead of sent inline
- Mail worker processes jobs with 3-attempt exponential backoff retry
- Admin GraphQL resolvers: adminQueues, adminQueueJobs, adminRetryJob, adminRemoveJob, adminPauseQueue, adminResumeQueue
- Admin frontend page at /admin/queues: queue cards with counts, job table with status filter, retry/remove/pause actions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- #[allow(dead_code)] on FFICallbackContextWrapper, Connected variant,
Unsubscribe variant, and device_event_receiver field
- let _ = for unused Result from callback.call1() (x2) and .send().await
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Node 22.11.0 is below Vite's minimum requirement of 22.12+
- svelte-kit sync must run before vite build to generate
.svelte-kit/tsconfig.json which tsconfig.json extends
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Use Button component for photo remove, editor tab toggle, and model
pill buttons across admin/users, admin/articles, admin/videos
- Remove vite-plugin-wasm from frontend devDependencies (no longer
needed since WASM is served by the buttplug nginx container)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
--target bundler generates static WASM ESM imports that only work
through a bundler. --target web generates fetch-based WASM loading
via import.meta.url which browsers handle natively.
- Change wasm-pack build target from bundler to web
- Call wasmModule.default() (init) after import in maybeLoadWasm
- Add .gitignore to exclude dist/ and wasm/ build outputs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add a minimal Node.js static server (serve.mjs) to the buttplug package
that serves dist/ and wasm/ on port 8080 with correct MIME types.
Update dev:buttplug to use it instead of docker compose, avoiding a
full Rust/WASM Docker build on every dev start.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add Dockerfile.buttplug: builds Rust/WASM + TS, serves via nginx
- Add nginx.buttplug.conf: serves /dist and /wasm with correct MIME types
- Add .gitea/workflows/docker-build-buttplug.yml: path-filtered CI workflow
- Strip Rust toolchain and buttplug build from frontend Dockerfile
- Move buttplug to devDependencies (types only at build time)
- Remove vite-plugin-wasm from frontend (WASM now served by nginx)
- Add /buttplug proxy in vite.config (dev: localhost:8080)
- Add buttplug service to compose.yml
- Load buttplug dynamically in play page via runtime import
- Fix faq page: suppress no-unnecessary-state-wrap for reassigned SvelteSet
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The variable is fully reassigned in an \$effect, so \$state is required
for reactivity. Suppress the no-unnecessary-state-wrap lint rule with a
comment explaining the reason.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace \$state + \$effect pattern with writable \$derived (Svelte 5.25+)
for all searchValue instances across list pages — cleaner and lint-compliant
- Remove now-unused untrack imports from those files
- Drop \$state() wrapper around SvelteMap in device-mapping-dialog
(SvelteMap is already reactive)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>