Commit Graph
25 Commits
Author SHA1 Message Date
valknarandClaude Sonnet 5 c06f119dcf Fix Control view button layout and responsiveness
The scan/record button row used justify-between, spreading the two
button groups to opposite ends instead of sitting next to each other.
Also made the record-controls row and each device card's header wrap
instead of overflowing on narrow screens.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzyfRyA7h5rs5SCAahLAWd
2026-08-31 17:31:51 +02:00
valknar 20433a6749 chore: cleanup 2026-08-31 17:20:22 +02:00
valknarandClaude Sonnet 5 1d88ab96c8 Move STATUS_VARIANT out of the "use client" SessionsTable module
The session detail page (a server component) was importing STATUS_VARIANT
from SessionsTable.tsx, a "use client" file. Next.js compiles client
modules separately for the server and client bundles, and pulling a plain
value (not a component) across that boundary let the two compiler caches
drift out of sync in dev, so the same session status could render a
different Badge color depending on which page rendered it. Moved the
constant into its own plain module that both files import.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzyfRyA7h5rs5SCAahLAWd
2026-08-31 17:19:24 +02:00
valknarandClaude Sonnet 5 b0394d5c9d Size the description input to its content, like the title
Dropping flex-1 stops the textarea (and its underline) from stretching
to fill the row width regardless of text length - now it hugs the
actual content the same way the title input does.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzyfRyA7h5rs5SCAahLAWd
2026-08-30 21:21:40 +02:00
valknarandClaude Sonnet 5 5c92b416c0 Tone down the focus underline to just a step past hover
focus:border-b-muted-foreground was a big jump from the faint hover
border tone. Use foreground at 40% opacity instead - a bit more
present than hover, not a solid gray line.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzyfRyA7h5rs5SCAahLAWd
2026-08-30 21:19:07 +02:00
valknarandClaude Sonnet 5 2a52b5db9b Use a gray focus underline for the title/description inputs
focus:border-b-muted-foreground instead of the primary accent color -
matches the existing hover state's neutral tone rather than switching
to a bright accent on focus.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzyfRyA7h5rs5SCAahLAWd
2026-08-30 21:17:23 +02:00
valknarandClaude Sonnet 5 a0211f90e4 Cap title and description editor width
Both used field-sizing:content with only max-w-full, which doesn't
reliably clamp a long single-line value and could push the header row
wider than its container. Add an explicit sm:max-w-xl ceiling on both.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzyfRyA7h5rs5SCAahLAWd
2026-08-30 21:11:27 +02:00
valknarandClaude Sonnet 5 ffc63f0b03 Make the session description always visible and inline-editable
New SessionDescriptionEditor renders even when empty (with an "Add a
description..." placeholder) and autosaves on typing - same debounced,
no-Save-button pattern as the title and device name editors. Unlike
the name field, an empty description is a valid saved state.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzyfRyA7h5rs5SCAahLAWd
2026-08-30 21:08:45 +02:00
valknarandClaude Sonnet 5 e9d5bb37d2 Show session status as a badge on the detail page
Reuses SessionsTable's STATUS_VARIANT mapping (now exported) so the
detail page's status matches the table's badge instead of plain text.
Also drops the now-stale px-1.5 alignment padding on the meta lines
now that the title input carries no horizontal padding of its own.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzyfRyA7h5rs5SCAahLAWd
2026-08-30 21:03:00 +02:00
valknarandClaude Sonnet 5 354c30d641 Underline the session title input instead of a full border
Drops the boxed border-b-2/rounded treatment for just a bottom
border - transparent at rest, muted on hover, primary-colored on
focus - which reads as inline editing rather than a form field.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzyfRyA7h5rs5SCAahLAWd
2026-08-30 20:55:07 +02:00
valknarandClaude Sonnet 5 7bf4b3d4bf Fix session title input's border offset and width
The -mx-2 trick pushed the hover/focus border noticeably left of the
text, and flex-1 stretched the input across the whole header row.
Tighten the offset to px-1.5/-ml-1.5 and size the input to its content
via field-sizing:content instead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzyfRyA7h5rs5SCAahLAWd
2026-08-30 20:52:44 +02:00
valknarandClaude Sonnet 5 884ced7a47 Make the session title editable inline on the detail page
New SessionTitleEditor swaps the static <h1> for a heading-styled input
that autosaves on typing (600ms debounce, spinner-then-checkmark) - the
same click-in-place, no-Save-button pattern as the device display name.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzyfRyA7h5rs5SCAahLAWd
2026-08-30 20:49:34 +02:00
valknarandClaude Sonnet 5 005d729119 Autosave device display name instead of an explicit Save button
Typing in the name field now debounces (600ms) and saves in the
background, with an inline spinner-then-checkmark instead of a button
click - one less step, and no risk of leaving an edited name unsaved.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzyfRyA7h5rs5SCAahLAWd
2026-08-30 20:46:53 +02:00
valknarandClaude Sonnet 5 fa04cb32b4 Streamline card titles to a single color
Every CardTitle now uses the default foreground color; only size marks
the hierarchy (text-sm for stat-tile labels, text-base for section
titles, text-2xl for the login wordmark) instead of some titles being
muted-gray and others white.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzyfRyA7h5rs5SCAahLAWd
2026-08-30 20:42:41 +02:00
valknarandClaude Sonnet 5 c778ab3cf2 Add a title to the device usage table card on Stats
Matches the "History"/"Known devices" card-title pattern used on the
Sessions and Devices pages.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzyfRyA7h5rs5SCAahLAWd
2026-08-30 20:41:05 +02:00
valknarandClaude Sonnet 5 d5a8cb81cf Highlight nav link as active for sub-routes too
/sessions/16 (and any other nested route) now underlines its parent
nav link instead of only an exact pathname match, which previously
left every detail/replay page with no active tab at all.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzyfRyA7h5rs5SCAahLAWd
2026-08-30 20:37:25 +02:00
valknarandClaude Sonnet 5 c4ed849d37 Remove stats tab switcher, drop duration-per-device, show devices inline
Sessions and Devices no longer live behind a Tabs switcher on the stats
page - both sections render directly, one after the other. Also drops
the "Duration per device" list from the sessions summary cards since
DeviceUsageTable already shows per-device active time in more detail.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzyfRyA7h5rs5SCAahLAWd
2026-08-30 20:33:47 +02:00
valknarandClaude Sonnet 5 e459ccd0ed Polish replays stat into the summary card grid
The replay count was a lone plain-text bar below the three stat cards,
and read oddly as "Replayed 0x" when nothing had been replayed yet.
Fold it into the same 4-tile grid with the same styling, and show "-"
at zero instead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzyfRyA7h5rs5SCAahLAWd
2026-08-30 20:31:31 +02:00
valknarandClaude Sonnet 5 401b9b5033 Remove recordings feature, replay sessions directly, bump to 0.6.0
CI / Build and push image (push) Successful in 1m41s
CI / Static checks (push) Successful in 2m12s
Recordings were just a thin named pointer over an already-captured
session's events, so the whole separate feature (recordings table, API
routes, pages, UI) is gone: any completed session can now be named and
replayed directly. Replaying no longer creates a session or duplicates
events of its own - it just bumps the source session's playCount/lastPlayedAt.

Also renames play_sessions/playSession(s) to sessions/session(s) throughout
the schema, queries, API routes, and UI for consistency, and updates the
README to match the new flow.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-27 21:38:51 +02:00
valknarandClaude Sonnet 5 2a3c4ff1f2 Add site footer and switch display font to Sora, bump to 0.5.0
CI / Static checks (push) Successful in 1m7s
CI / Build and push image (push) Successful in 1m6s
Adds a Footer component (credit line, repo/buttplug.io links) below main
content on all app pages, with the layout shell now flex-column so it
sticks to the bottom on short pages. Also swaps the display font from
Space Grotesk to Sora (after trying Fraunces, a serif, which didn't fit).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 19:02:09 +02:00
valknarandClaude Sonnet 5 c46adf788f Add animated glass background, breadcrumbs, and brand mark polish
Cards now sit on an animated signature-gradient background and use a
translucent, blurred bp-glass surface so it shines through; extended
bp-glass to every stat surface on the Stats page and to its tab switcher.
Adds a Breadcrumbs component below the header on all app pages.

Also: drop the gradient text fill from the wordmark/heading, animate the
BrandMark's heart and curve on the dashboard hero instead of a plain pulse
ring, recenter the heart/curve artwork in icon.svg and BrandMark, close the
mobile nav menu on link click, remove the redundant "back to recordings"
button, and match the "Start session"/"Scan for devices" button sizes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 18:47:30 +02:00
valknarandClaude Sonnet 5 5484d3cefe Fix device/replay/session UX issues, add pagination, bump to 0.3.0
CI / Build and push image (push) Successful in 1m2s
CI / Static checks (push) Successful in 1m7s
- Fix device rename input collapsing on mobile (fixed width vs w-full
  inside an auto-layout table column).
- Add cascade-delete confirmation for sessions with a saved recording.
- Fix header connection LED: derive state from scanning/device-count/
  recording instead of the Buttplug client's raw connected flag; drop
  the label text and hide the indicator entirely when idle.
- Add a per-device disconnect button (stop + remove from store, the
  closest equivalent Buttplug's protocol allows per device).
- Fix replay ending early: duration now comes from the recording's
  actual durationMs, not the last event's timestamp.
- Replay robustness: show which devices are being replayed to, reset
  actuators to zero on start/play/pause, fully disconnect devices and
  the whole client on stop/unmount, surface command failures via toast.
- Stop flagging the header LED red during replay - recording is only
  for live sessions.
- Add page-number pagination to recordings/sessions/devices lists.
- Wordmark SEXY -> Sexy; add proper per-page <title>s including
  dynamic titles for recording/session detail and replay pages.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-25 21:26:18 +02:00
valknarandClaude Sonnet 5 0bd36b08c9 Upgrade to buttplug v5, add battery level display, bump to 0.2.0
CI / Static checks (push) Successful in 1m0s
CI / Build and push image (push) Successful in 1m3s
buttplug-wasm@3.0.0 still declares buttplug@^4.0.2 as its dependency,
and v5 changed the OutputCmd wire shape (Value: number[] -> number) -
a real protocol difference, not just a type mismatch. Confirmed by
testing against real Lovense hardware that device control still works
in practice, so the bump stands; the risk is documented at the
client.connect() cast in case a future device/build doesn't fare as
well.

Also fixes a Map vs ReadonlyMap mismatch in the version-agnostic
feature-type extraction (v4 returns Map, v5 returns ReadonlyMap) that
surfaced while making this change, and adds a battery indicator to each
connected device's card - reads once on connect, refreshes every 60s,
using device.hasInput("Battery") to detect support.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W8WkFF5ppURBAB918593Eb
2026-08-25 17:33:48 +02:00
valknarandClaude Sonnet 5 f7503d03d0 Restyle UI with a channel-strip console look and brand icon
CI / Static checks (push) Successful in 1m9s
CI / Build and push image (push) Failing after 1m2s
Adds a pink/purple/blue SVG brand mark (favicon + header) and reworks
the visual language around the app's actual interaction - fader-driven
device control - via LED-style indicators, mono instrument readouts,
hairline-framed cards, console-tab nav, and an oscilloscope-style
session timeline. Leaves components/ui/* untouched, restyling only via
design tokens and the app's own composed components. Also fixes a
proxy.ts matcher gap that was gating /icon.svg behind auth.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W8WkFF5ppURBAB918593Eb
2026-08-25 16:43:28 +02:00
valknarandClaude Sonnet 5 1119c8eea0 Initial implementation of Bluetooth toy control app
CI / Static checks (push) Successful in 1m27s
CI / Build and push image (push) Skipped
Next.js app with a browser-side buttplug/buttplug-wasm control layer
(server never touches real-time device commands), SQLite storage via
Drizzle, single-secret auth, recordings/replay with device remapping,
a usage stats dashboard, Docker deployment, and Gitea CI.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W8WkFF5ppURBAB918593Eb
2026-08-25 07:51:38 +02:00