Commit Graph

241 Commits

Author SHA1 Message Date
浅念 07761b1b26 fix(app): camera preview distortion — swap sensor W/H for portrait
previewSize 报横向(W>H),竖屏直用会把画面拉扁。交换宽高转纵向比例再
FittedBox cover 铺满(裁切不变形)。397/397 全绿。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-24 16:07:44 +08:00
浅念 c199d0630c feat(embed): photo click opens album page in a new tab (user decision 2026-09-24)
Reverts the in-host detail modal interaction: click now window.open's the album page (/a/:token?lang=, no /p/ deep link) with noopener — same target for middle-click/right-click via the real <a> href. The loader's open-photo modal code remains but is no longer triggered.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-24 15:25:41 +08:00
浅念 bd4db7b458 style(viewer): 相册 banner 限高 320px + cover 裁切(PC 端观感修正)
height:100% + contain 在桌面宽屏下整图 letterbox 压扁留白——改为限高裁切。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-24 15:00:12 +08:00
浅念 32eb4ceb8e docs: 观众链接统一境外源定稿(后台分享/嵌入/App二维码均 ov 域名)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-24 14:46:54 +08:00
浅念 76380477a0 docs: 验收记录补嵌入组件 EMBED_ORIGIN 修正(cn 后台嵌入代码改指 ov 域名)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-24 14:01:12 +08:00
浅念 e5302e3929 docs: 正式环境双地域部署计划与验收记录
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-24 13:41:47 +08:00
浅念 30a3520669 fix(deploy): formalize nginx entrypoint ipv6 script removal in web.Dockerfile
G4 §4.8 事件 B:服务器新拉的 nginx:alpine 最新 digest 的
10-listen-on-ipv6-by-default.sh 在服务器上挂起(nginx 不启动、
healthcheck 拒连)。此前补丁只在服务器侧临时 Dockerfile,本次正式
进仓库;钉基础镜像版本后可移除(G4 待办)。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-24 11:53:11 +08:00
浅念 d331d55880 chore: remove temporary freeze-debug spec
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 19:03:21 +08:00
浅念 17d510ccd5 fix(embed): scroll freeze final layer — Chrome fires a queued pointerenter after pointercancel when dragging outside, permanently trapping hover pause
Sequence: drag past iframe edge -> pointercancel (clears press state) -> Chrome still delivers one pre-queued pointerenter (re-sets hover) -> no further boundary events ever reach the iframe -> hover pause stuck forever. Fix: ignore pointerenter within 500ms after a pointercancel (and while pressed); re-set hover on genuine in-frame release so post-click hover behavior is preserved.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 18:59:47 +08:00
浅念 5efb89a252 fix(deploy): remove orphaned proxy directives from template cleanup
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 18:41:31 +08:00
浅念 57394387cc fix(deploy): proxy_pass double http:// prefix — API was down
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 18:39:12 +08:00
浅念 222c44c1f7 fix(deploy): disable gzip on /v1/ API paths — Flutter release AOT gzip decompression failure
服务端 200+数据正常、debug/JIT 正常;release/AOT 的 Dart HttpClient 对
Content-Encoding: gzip 解压异常 → JSON 解析失败 → 显示 INTERNAL_ERROR。
nginx /v1/ 路径 gzip off(静态资源 gzip 不受影响);proguard keep 规则
一并保留(dio/flutter_secure_storage/全项目模型)。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 18:36:11 +08:00
浅念 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
浅念 f7f24b0a0b build(android): release signing config — key.properties based, debug fallback
正式签名(CN=PhotoLive):keystore/key.properties 不入库(gitignore 已覆盖);
无配置的构建机回退 debug 签名。首个正式签名 APK 已产出并 apksigner 验证。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 17:15:51 +08:00
浅念 1cad7823e2 fix(embed): watchdog also clears hover + releases capture (third freeze layer — capture suspends pointerleave, lost release never frees it)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 17:13:49 +08:00
浅念 74593d9953 fix(embed): scroll freeze root cause — drag-set 'manual' pause reason never cleared
setReason('manual', true) fired on >8px drag had no clear path anywhere (wheel/keyboard have 500ms timers; pointer path didn't) — one drag left the reason permanently, stopping auto-scroll until refresh. Now cleared on pointerup, watchdog, and window blur.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 17:09:17 +08:00
浅念 b414b3666e fix(embed): pointer pause watchdog — capture does not cross iframe boundary, outside-release now auto-resumes in 2s
The earlier capture+window-listener fix is insufficient: releasing outside the 195x280 window dispatches pointerup in the host document, which no in-iframe listener can observe. Deterministic fallback: 2s watchdog on pointerdown force-clears the pause reason (in-frame releases still cancel it immediately).

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 17:04:46 +08:00
浅念 2332d24591 docs(g4): clipboard HTTP-context fix record
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 17:04:45 +08:00
浅念 aaea76b0e3 fix(admin): copy buttons dead on HTTP origin — execCommand fallback
navigator.clipboard 仅安全上下文(HTTPS/localhost)可用,测试服务器经
http://IP:32005 访问时为 undefined,四处复制按钮(公开令牌/分享链接/
嵌入代码/重置密码)点击即抛 TypeError 且无提示。统一 utils/clipboard
copyText:API 优先、失败降级隐藏 textarea + execCommand。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 17:01:54 +08:00
浅念 cd8a3696e2 fix(embed): scroll freeze — pointer pause leaked when release happened outside window
Root cause: pointerup/pointercancel bound only on the viewport element; press on a photo then release outside the 195x280 window (or gesture interruption) never cleared the 'pointer' pause reason -> auto-scroll stopped permanently until page refresh.
- pointerdown now setPointerCapture (release guaranteed to return)
- window-level pointerup/pointercancel + blur fallbacks clear the reason
- rAF frame wrapped in try/catch so a single bad frame can no longer break the animation chain

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 16:57:04 +08:00
浅念 ae17776be6 feat(app): session restore on startup — no forced re-login after app restart
用户反馈:关闭 App 重开每次都要登录。根因:会话已持久化(安全存储,
服务端 TTL 30 天),但启动固定落在登录页——无人消费已存会话。

- _StartupGate(home):watch sessionAccount——在场直进 HomePage,离场
  LoginPage;状态驱动(401/登出清会话后 gate 自动重建,不依赖导航时序)
- onUnauthorized 保留 push 兜底(home 路由被显式导航替换后的 401 场景)
- 测试适配(boot 401 两项重写通过;397/397 全绿)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 16:48:27 +08:00
浅念 b6daa6fa0e docs(embed): live title+modal verification — '2026届-广交会' overlay, coordinate click opens in-host detail modal with deep link, closes via button
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 16:47:27 +08:00
浅念 a5dcfffd37 docs(embed): refreshed evidence artifacts (modal screenshot, screenshots/recordings regenerated)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 16:37:17 +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
浅念 a16fa738f6 fix(app): poster — date-only text, left-aligned title/time/venue (QR stays centered)
用户反馈:海报日期仍带时间(表单已日期粒度,海报 formatAlbumDateTime 同步改
posterDate 只显 y/M/d);宣传图下标题/时间/地址居左;二维码保持居中。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 16:26:32 +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
浅念 77b1519209 docs(viewer): like-hidden live verification — feed badges/sort tabs gone, lightbox bar is share+download only
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 14:31:21 +08:00
浅念 2babd364ba feat(viewer): hide like feature — action bar like slot, photo like badges, hot sort tab, others' like bubbles (user request 2026-09-23)
- PhotoFeed: cell like badge not rendered
- AlbumHeader: sort tabs row removed (hot depends on likes; latest-only has no toggle value)
- PhotoActionBar: like slot v-if=false (share/download remain, auto re-center)
- ActivityPage: LikeBubbles hidden
- specs updated to hidden assertions; 244 green

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 14:29:22 +08:00
浅念 e44b35db28 feat(albums): date-only pickers for start/end (create & edit, admin + app)
- 管理后台:DatePicker type=datetime → date;提交归一(开始=当天 00:00、
  结束=当天 23:59 整天活动语义;契约仍 datetime 仅交互粒度)
- App:去掉时间选择步骤(选日期即定;同上归一);表单显示只显 yyyy/M/d
- e2e 日期填入改 '2026-10-01'(date 格式);widget 断言日期粒度
- admin 87/87 + build、app 397/397 全绿

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 14:13:58 +08:00
浅念 f984535c2a fix(deploy): absolute_redirect off — root redirect keeps host:port through reverse proxy
nginx 默认 absolute_redirect on:return 302 被绝对化为 scheme://Host/(经
OpenResty 反代 Host 无端口 → 32005/ 跳到无端口的 /admin/ 打不开)。
off 后发相对 Location,浏览器按当前 host:port 补全。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 13:55:46 +08:00
浅念 7ef27797ff fix(deploy): root path redirect to admin (cn) — persisted in template+compose
用户约定:32005 根路径打开即管理后台。之前是直接改在服务器容器配置上的,
历次镜像重建被冲掉——本次固化进仓库:nginx 模板 location = / → 302
${ROOT_REDIRECT};Dockerfile 默认 /admin/;compose 按栈注入(cn=/admin/,
ov=/index.html 观众端安全自指,不影响 /a/<token> 与嵌入路径)。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 13:52:29 +08:00
浅念 d7ac9420be docs(viewer): lightbox close button restored on server (transparent bg, white X, 44px circle)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 13:51:59 +08:00
浅念 85146be7ef fix(viewer): restore lightbox close button styles orphaned by menu removal (transparent bg, white X icon, hover/focus)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 13:48:03 +08:00
浅念 f2cd26e523 docs: register embed-slot soft-delete acceptance
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 13:41:27 +08:00
浅念 bdad433dae fix(viewer): remove lightbox top-bar settings menu (user request) — close button + counter only; Esc closes directly
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 13:39:53 +08:00
浅念 903962a46b feat(embed-slots): soft-delete slots — admin entry, ov shutdown via enabled=false snapshot
- 契约 deleteEmbedSlot(DELETE /admin/embed-slots/{id} → 204 幂等;admin 专属)
- cn schema:embed_slots.deletedAt(迁移 20260923120000,本地已应用)
- softDelete:乐观锁 claim + outbox slot.updated(payload enabled 强制 false
  ——ov 副本无墓碑,enabled=false 快照即公开端 404 下线;priority=high)+ audit
- 列表/加载/更新过滤 deletedAt → 同码 404
- Admin 列表操作「删除」(确认:已接入网站将停止展示、不可恢复)
- API 56/56、admin 87/87 + build 全绿

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 13:37:39 +08:00
浅念 aa366c4268 docs(embed): ambient hearts restored on server (7 on screen) after parallel-session image rollback
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 13:35:23 +08:00
浅念 20321f1b93 fix(app): account-switch data residue + empty-albums pull-to-refresh
- 换账号数据残留(用户报告):albumListProvider 非 autoDispose 且首页
  IndexedStack 常驻——登出与登录成功两处显式 invalidate(任务库本就按账号
  隔离键隔离,不受影响)
- 空相册无法下拉刷新(用户报告):空态原本直接 return EmptyState 无
  RefreshIndicator——被拉进相册后无法手动刷新;空态改入可滚动容器承载
  下拉刷新(保留新建入口)
- 397/397 全绿、analyze 0

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 12:05:25 +08:00
浅念 c1869d7314 feat(admin): photo upload in album photos tab (same staging pipeline as app)
- 照片页签工具栏加「上传照片」(多选 jpeg/png/heic)→ /v1/uploads
  init → PUT staging → complete(clientTaskId 幂等;categoryId 随当前分类筛选)
- 逐张结果:部分成功语义(成功 N 张 toast + 失败明细前 3 条);完成后 reload
- 类型 UploadInitPayload/UploadSession/UploadCompleteResponse + api/uploads.ts
- 问题1 修复说明:详情页 404 系并行部署把 2618ad3 server 覆盖回 8e674a9,
  已重滚双栈至 ui06-2618ad3(assets 端点恢复 200,详情页零失败请求)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 11:54:26 +08:00
浅念 7adc1b0858 docs(embed): denser/lower ambient hearts verification (6 on screen, origin band 140-244px)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 11:41:11 +08:00
浅念 f667842e9c style(embed): ambient hearts denser and lower (user feedback — spawn 160-320ms, band 140-244px)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 11:38:55 +08:00
浅念 c8a9727993 docs(embed): ambient hearts live verification — bubbles float with zero likes (steady ~3 on screen)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 11:33:25 +08:00
浅念 4d31eaf184 fix(app): poster sheet close button — header row with explicit close (drag-down not obvious on long sheet)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 11:32:02 +08:00
浅念 d11ca16d1d feat(embed): ambient heart bubbles — always floating in the right band (user request 2026-09-23)
- ReactionLayer ambient prop: self-scheduled spawn every 400-800ms (jitter), band 56-232px avoiding the 44px action zone, stops on hidden page/unmount, shares MAX_ACTIVE=8 with real bursts
- EmbedStream mounts layer with ambient = reactions && !reducedMotion — persistent decoration independent of real likes (no burst frames, no count inflation; §5.2 anti-fake semantics unaffected)
- viewer 244 green

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 11:30:53 +08:00
浅念 df0c318599 feat(app): share redesign — card share (system), QR poster (banner+title+time+venue+QR, downloadable), copy link
- 三方式(用户需求):①卡片模式默认=系统分享面板(share_plus SharePlus.
  instance,微信/其他应用,文本=标题+链接)②生成二维码=海报弹层——顶部
  宣传图(banner→cover→品牌占位回退)+ 活动标题 + 时间 + 地址 + 二维码,
  「下载海报图」RepaintBoundary 3x 渲染 PNG → gal 存相册 ③复制链接
- 依赖 share_plus + gal;分享/保存均 Provider 注入(测试替身)
- 测试适配三方式结构 + 海报弹层断言(397/397 全绿、analyze 0)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 11:27:32 +08:00
浅念 8768a04a75 docs(embed): collapsed handle right-dock verification on server (right=16px, x=1324 @ 1440 viewport)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 11:26:56 +08:00
浅念 9761eea591 fix(embed): collapsed handle positioned correctly on first creation (v2 parity with v1 applyWrapperBox call)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 11:24:47 +08:00