Commit Graph

8 Commits

Author SHA1 Message Date
football2801 6c9959c00d fix(pwa): serve apple-touch-icon + favicons from root, add sizes hint
CI / test (push) Has been cancelled
iOS Safari's Add-to-Home-Screen flow probes /apple-touch-icon.png at the
site root in addition to the <link rel> on the page. Those root paths
currently 302 through Symfony's auth firewall to /login, so iOS gets HTML
where it expects a PNG and falls back to whatever it cached from earlier
installs (the 1 KB placeholder icon). Dropping the real PNG (and the
-precomposed alias) directly in public/ makes nginx serve them as static
files, ahead of the firewall.

Also adds favicon.svg and a multi-size favicon.ico at the root for
browsers/bots that probe / paths instead of reading <link>, and adds
sizes="180x180" to every apple-touch-icon link so iOS doesn't have to
guess.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 00:48:01 -04:00
football2801 40581cb98b feat(brand): wire new favicon set into every standalone Twig template
CI / test (push) Has been cancelled
Login, register, help, token-approve/decline, and setup pages each have
their own <head> (don't extend base.html.twig), so updating base alone
left them without favicon refs. Adds the same four <link> tags after the
viewport meta in each standalone template.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 00:43:29 -04:00
football2801 e7e9202a11 feat(brand): official WeVisto logo + linked badge on user-facing pages
CI / test (push) Has been cancelled
- frontend/public/logo.svg: Camogli photo with We[V]isto knockout wordmark
  (yellow V accent), embedded base64 so the SVG is self-contained
- brand/: raw source (15.7MB Camogli original) + 900x900 crop used in the
  SVG, plus a short README documenting both
- Login, register, setup index/configure, help: linked logo badge above
  the page heading
- Email template: logo bumped to 64x64 (was 30 tall — wordmark unreadable)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 22:33:28 -04:00
football2801 db80ea5262 feat(brand): swap recipient-facing pictureFrame strings to WeVisto
CI / test (push) Has been cancelled
Updated: SPA <title>, PWA manifest name/short_name, iOS web-app title,
"Install"/"Pin to home screen" copy, HomeView empty state, all Twig page
titles (login/register/setup/token/help), and the share-notification
email header. Left alone: the firmware-broadcast SSID PictureFrame-XXXX
(coordinated firmware change needed) and internal code/comment refs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 21:42:50 -04:00
football2801 5a0db3cd60 fix(uploader,setup): beta-test polish — crop overlay, sticker delete, emoji keyboard, copy
- crop: invert overlay shading; the destination-out trick on a
  semi-transparent fill was leaving the *inside* of the crop more
  transparent than the outside, so the keep-area read as darker
  than the discard-area. Replace with 4 explicit dim-strips.
- stickers: floating trash handle now glues to the selected
  sticker's top-right corner instead of an off-canvas X that
  testers missed.
- stickers: replace the curated grid with an emoji-keyboard
  picker — recently-used row, custom-sprite row (santa hat as
  inline SVG), then an input that pops the OS emoji keyboard.
  Recents persist in localStorage; legacy stickers fall back to
  the old STICKERS table.
- pwa-install modal: drop "browser chrome" — beta tester read it
  as the literal Chrome browser.
- /setup landing page: tighten "Set up your frame" copy.
2026-05-09 15:17:06 -04:00
football2801 ece0defe3f feat(setup): "Claim this frame" checkbox for previously-bound MACs
CI / test (push) Has been cancelled
Use case: old owner sells the device to a friend. Friend holds the BOOT
button to wipe NVS, joins the device's AP, sets new WiFi. The old
owner's account is still bound to the MAC server-side, so without
explicit consent the friend would silently take over (or, worse, the
old owner's photos would keep displaying until claim).

Flow now:
  - GET /setup/{mac} detects MAC bound to anyone and renders a
    "Claim this frame as my own" checkbox + a banner explaining what
    the takeover wipes. Both register and login panels carry the
    checkbox; submitting either form without it bounces back through
    the index with a session-flashed error.
  - DeviceService::linkToUser now requires allowClaim=true to
    transfer ownership. Without it, throws DeviceClaimRequiredException
    that the controller catches and turns into the bounce-with-error.
  - On a successful claim, the takeover wipes:
      * old image-device approvals
      * device_image_history rows for the device
      * name, wakeTimes, currentImage*, lockedImage, nextPollExpectedAt
    so the new owner starts from a fresh slate, not inheriting the
    seller's "Living Room / 4:30 AM" preset.
  - Already-logged-in user visiting /setup/{mac} for someone else's
    device falls through to the form (instead of silently transferring
    on page load) so the checkbox is the only path.

Test matrix:
  - SetupControllerTest: 5 new functional cases — checkbox renders for
    bound MACs, register/login without checkbox bounce + retain old
    ownership, register WITH checkbox transfers + purges, logged-in
    other-user falls through to form.
  - DeviceServiceTest: 3 new unit cases — throw without consent,
    isClaimedByAnotherUser true/false matrix, takeover resets device
    state.

Coverage: 99.70% lines / 98.19% methods backend, 333 frontend tests
green via ddev tests.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 14:45:52 -04:00
football2801 7408dc9d1a fix: render plainPassword first/second fields separately in setup form
RepeatedType renders as a wrapper div when called as a single widget,
producing unstyled inputs with no mismatch error handling.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 21:30:02 -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