Commit Graph

12 Commits

Author SHA1 Message Date
浅念 fa06193a12 fix(embed): scroll freeze complete fix — remove pointer capture (broke photo clicks), keep watchdog
Capture redirected pointerup/click to the viewport element so photo <a> click handlers never fired (detail modal stopped opening). Watchdog alone is the deterministic freeze fallback: clears pointer/manual/hover/focus after 2s on lost release. A09 switched to count-based heart assertion (position check unstable under ambient bubbles + serial suite).

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 18:25:59 +08:00
浅念 65581b7920 fix(android): usesCleartextTraffic=true — release APK blocked HTTP APIs (Android 9+ default)
release 构建默认禁明文 HTTP(debug 由 Flutter 自动放行)——服务暂时不可用
即此因。当前测试服务器 API/观众页均为 http://,需显式允许;上 https 后移除。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 18:10:46 +08:00
浅念 da6f1b282e feat(embed): in-host photo detail modal + title overlay — e2e adapted (no popup, close button, some() heart attribution with ambient bubbles)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 16:36:51 +08:00
浅念 985829fee8 fix(app): poster title truly left-aligned — Column crossAxisAlignment start (QR re-centered)
Text 的 textAlign 被 Column 默认 center 吞掉(文本行收缩包裹时对齐不生效);
文字区 Column 改 CrossAxisAlignment.start,二维码+扫码说明显式 Center 回居中。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 16:30:14 +08:00
浅念 8834b1bbb9 feat(embed): album title overlay + in-host photo detail modal (replaces new-tab open)
- viewer: EmbedStream shows album title overlay top-left (ellipsis, avoids collapse zone); photo click posts open-photo {url} to host instead of window.open (direct-open still new tab)
- loader v2: open-photo message (origin+source whitelisted, URL must match widget origin) opens host overlay modal with embedded viewer deep-link iframe, close button/Esc/scrim dismiss, single instance, cleaned on destroy
- tests: click case asserts modal iframe deep link + no popup + close button dismiss; viewer 244 + loader 36 green

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 16:20:10 +08:00
浅念 5a207b395e feat(app,viewer): WeChat card share + 'Share to...' label + site og tags
- 按钮文字「分享到微信/其他应用」→「分享到...」(用户需求)
- 微信卡片分享(fluwx 6):WECHAT_APPID 经 --dart-define 注入;已配置且
  装微信 → WXWebpage 卡片(标题=相册名、描述=日期·地点、缩略图=封面压缩
  240px PNG ≤32KB、点击进观众链接);未配置/未装 → 回退系统分享面板
- viewer index.html 加站点级 og 标签(微信/QQ 抓取链接预览用;每相册动态
  og 需服务端注入,登记后续增强)
- 397/397 全绿、analyze 0

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 16:05:53 +08:00
浅念 8c4906c2f2 feat(embed,ui04): E07 acceptance — matrix completion, hostile-CSS hardening, measurements and record closure
- E07 e2e (7 cases): 4-viewport fixed size, narrow shrink + dual-slot 12px stack, single/static + empty state + two-photo loop copies, broken-thumb drop, reducedMotion stop with manual arrows, forged postMessage rejected, hostile CSS (!important box-sizing/border) with inline-important countermeasures + duplicate script dedup
- loader v2: geometry-critical properties upgraded to inline !important (beats host stylesheet !important)
- pre-existing fixes: likes.spec view-count assertion vs concurrent session's AlbumHeader unicode icons (toContainText); embed-v2 host port moved to 3998 (3999 collides with embed-crossorigin under parallel full runs); prettier formatting of two concurrent-session files (formatting-only)
- evidence: matrix EMB-A01..A16 closed in acceptance record (mechanism-level items honestly marked), measurements (loader v2 9885B/gzip 3959B, first-load 1 GET + 1 WS, DOM<=16), refreshed screenshots/recordings, master plan UI-04 note
- regression: root lint/typecheck/test 12 packages green; embed suites 43/43; admin embed-slots 5/5; journey pre-existing env failure reproduced at clean HEAD (registered)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-22 18:56:38 +08:00
浅念 91c85e196a feat(viewer,ui04): E05 realtime hearts + effect-demo alignment (initial offset, heart params, decode gate, bidirectional manual scroll)
- reactions.ts pure fns: delta->hearts sampling, burstId dedupe (TTL/capacity), pending-visible cache (5s/50), 250ms emission throttle with merge
- useEmbedReactions: read-only RealtimeClient subscription on album.publicToken (no viewer-page side effects, A15), rebind teardown, 10s grace disconnect, no fake bubbles on WS failure
- ReactionLayer: demo-frozen heart effect (12/16/20 sizes, two colors, 110px rise, 1.6s ease-out, 300ms stagger, max 8, drop-shadow) in unscoped block (created elements lack scoped hash)
- demo alignment: initial offset 32px, decode+500ms startup gate, 1:1 drag, arrows +-40, focus-tip, bidirectional manual scroll (manualScroll), loader handle 100x44 exact styles, <=599px offset default 12
- tests: +8 reactions unit (244 viewer), e2e E05: real cross-context like -> heart on correct photo (EMB-A09), zero likes/visits submission (EMB-A15), 16s hearts recording

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-22 17:38:02 +08:00
浅念 3912279889 feat(viewer,ui04): E04 interactions — pause reason set, click lock/drag cancel, manual scrub, keyboard semantics, destroy
- pauseReasons Set (hover/focus/pointer/offscreen/hidden/manual + userPaused via Space, no auto-resume); 500ms transient resume with re-evaluation
- pointerdown target lock; >8px drag suppresses click and scrubs via nudgeOffset (window-clamped); removed photos clear pending target
- keyboard: Space pause toggle, Escape collapse, ArrowUp/Down scrub; input fields untouched
- aria-live status announcements (zh/en); viewport touch-action none
- e2e: hover freeze/resume, popup deep link hit, drag cancel, keyboard, slot disable destroy

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-22 13:28:13 +08:00
浅念 998565e439 feat(viewer,ui04): E03 continuous scroll engine — pure state machine, rAF orchestration, boundary continuity
- stream.ts: advanceStream (per-frame, dt cap 50ms), loop generation keys, window math (DOM<=16, queue<=30, 480px buffer), anchorRebuild (photo-position preserving), removePhoto, single-photo static
- useVerticalPhotoStream: rAF integration, direct transform writes (no per-frame Vue reactivity), low-frequency item sync, ResizeObserver re-anchor, stepForTest hook
- EmbedStream wired to engine; cycle copies aria-hidden; img error -> controlled drop
- tests: 14 unit cases (236 viewer total), e2e: 32px/2s speed, boundary continuity <2.5px, DOM<=16 over 20s, 32s recording with loop boundaries

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-22 13:19:21 +08:00
浅念 1d1979f540 feat(viewer,ui04): E02 static fidelity — real photo fixtures, measured shell/photo/collapse specs, edge fade
- fixtures: 8 picsum-seeded real photos (mixed ratios); seedPhoto thumbBytes/browseBytes injection
- e2e E02 block: wrapper shell (195x280/radius/border/#10161E), photo strip (193w, ratio-height, 3px gap), collapse (44/44 hit, 24 visual, sole button), desktop+mobile screenshots
- EmbedStream: top/bottom 12px dark fade (0.12, §2.3 optional item)
- fix(admin): pre-existing eslint globals gap for ElNotification (template drift, blocks lint gate)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-22 13:01:34 +08:00
浅念 66d1eb3e9f feat(embed,ui04): E01 v2 contract skeleton — displayMode/scrollSpeed/reactionsEnabled, v2 loader entry and fixed 195x280 shell
- contracts: EmbedSlotSettings optional v2 fields (carousel default) + SlotSettingsPayload; gen + redocly green
- api: DTO validation + normalization full-set (cn manage + ov public projection share normalizeStoredSettings)
- embed-loader: params v2 parse/merge/url family, loader-v2.js fixed shell (border/radius/#10161E/safe-area, resize ignored, stack gap 12), dual-artifact build+sync; v1 source frozen
- viewer: EmbedPage v=2 branch, EmbedStream (viewport/track/real anchors/collapse/empty), stream.ts pure fns, i18n zh/en
- admin: types + utils (create default vertical-stream, clampScrollSpeed, v1/v2 snippet selection)
- tests: loader 36 (+9 v2), viewer 222, admin 82, api unit 51, v1 embed e2e 20, v2 E01 gate 2 (195x280 desktop+mobile cross-origin, no footer)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-22 12:50:28 +08:00