Commit Graph

5 Commits

Author SHA1 Message Date
football2801 cf6623de67 feat(rotation): per-device image-selection preferences
CI / test (push) Has been cancelled
Adds two settings exposed in the PWA frame-settings sheet:

- rotationMode (enum: random | least_recently_shown | oldest_upload |
  newest_upload). Default oldest_upload preserves the legacy
  hard-coded sort, so existing devices behave identically until the
  user changes it.
- prioritizeNeverShown (bool). When set, the candidate set is narrowed
  to never-shown images first (if any exist) before the mode runs —
  useful for "burn through new uploads before re-shuffling the catalog."

RotationService pipeline:
  1. Pull approved/ready pool.
  2. Drop the last `uniquenessWindow` served (existing).
  3. If prioritizeNeverShown AND any candidates have never been served,
     narrow to those.
  4. Apply the selection mode.

Backend: enum, entity columns + accessors, migration, serializer,
PATCH validator. Frontend: types, stores, settings sheet section
(dropdown + checkbox), test fixtures, save-flow test.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 16:37:14 -04:00
football2801 70d48f9b11 fix: rotate portrait renders to EPD-native byte layout
CI / test (push) Has been cancelled
The .bin file for portrait orientation was packed as 480-pixel rows ×
800 rows, but firmware streams blindly at 800×480 (the EPD's native
scan order). Both layouts hit the same 192000-byte total, so the size
guard in epd_draw_image_with_border passed and the row-stride mismatch
showed up on the panel as the photo tiling/repeating.

Renderer now rotates the cropped photo 90° CW before dithering when
orientation is portrait, so the packed bytes always match the EPD's
800-pixel scan order. Firmware stays orientation-unaware (per the
"ESP32 never transforms images" decision in webApp/CLAUDE.md). Preview
decoder rotates -90° on the way out so the in-browser frame preview
stays upright.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 14:06:41 -04:00
football2801 12245759ac chore: stage all in-progress work before repo split
CI / test (push) Has been cancelled
Web app: new entities (Image, RenderedAsset, SharedImage, Token,
DeviceImageHistory), enums, repositories, controllers, message handlers,
migrations, tests, frontend upload/library/sticker UI, Vue components.

Firmware: EPD background screen binaries + gen scripts, setup_bg header.

Infra: ddev config, test bundle, gitignore coverage dir.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 12:11:31 -04:00
football2801 6c891d6fad feat: orientation model, password confirm, frontend build
- Collapse orientation to landscape/portrait (ribbon left = portrait standard)
- Add OrientationPicker component and wire settings sheet in HomeView
- Add password confirmation field to registration form (RepeatedType)
- Build frontend SPA to public/build/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 16:59:03 -04:00
football2801 fb380c45bd feat(story-2.2+2.3): device setup page, account linking, naming & configuration
Story 2.2 — /setup/{mac} Twig page (no Vue, works JS-disabled):
- Register tab: creates account + logs in + links device → /setup/{mac}/configure
- Login tab: manual credential check via UserPasswordHasherInterface + Security::login()
  + links device → /setup/{mac}/configure
- Re-provisioning: DeviceService.linkToUser() atomically transfers ownership + stubs
  purgeDeviceHistory() (completed in Epic 3 when Image/Approval entities exist)

Story 2.3 — /setup/{mac}/configure (requires auth):
- GET: device name, orientation (landscape/portrait), rotation interval (6/12/24/48/168h),
  uniqueness window (5/10/20/50 cycles)
- POST: validates name, saves to Device entity, redirects to Vue SPA
- Device entity: mac, name, orientation (Orientation enum), rotationIntervalHours,
  uniquenessWindow, user (ManyToOne), linkedAt
- PATCH /api/devices/{id}: Vue SPA can edit any device field (Story 2.3 "edit from app")
- GET /api/devices: list authenticated user's devices
- Migration: create device table with Orientation enum column

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 00:47:14 -04:00