Commit Graph

97 Commits

Author SHA1 Message Date
浅念 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
浅念 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
浅念 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
浅念 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
浅念 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
浅念 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
浅念 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
浅念 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
浅念 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
浅念 c2143e1f94 feat(app): album banner picker in edit form — show current banner, pick & upload on save
- api_client:uploadAlbumAssetFromFile 泛化(cover 为薄壳)+ fetchAlbumAssetUrl
  (GET /albums/{id}/assets → 指定 kind 全局行 URL)
- 编辑页 Details:封面下方新增「宣传图」3:1 选择器——编辑模式异步加载现有
  banner 预览(失败静默);保存成功后上传(同封面:失败不阻塞表单结果)
- 未保存变更判断纳入 banner;l10n zh/en
- 测试适配:编辑用例 pumpForm 后清空 banner 现状预检请求(397/397 全绿)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 11:07:54 +08:00
浅念 3d45350711 feat(viewer): share sheet with QR code + link + copy (replaces inline toast, App-style)
- ShareSheet.vue: bottom sheet (mobile) / centered card (desktop) — QR canvas (qrcode dep), selectable deep link, copy with on-button feedback (2.5s), optional navigator.share button, Esc/scrim/close dismiss, focus on open
- AlbumHeader + PhotoLightbox: share buttons open the sheet (album URL / photo deep link); page-level copied strips removed
- tests rewritten for sheet behavior — viewer 244 green

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 11:04:11 +08:00
浅念 63b3e539fd docs: register asset status acceptance — admin branding tab shows current banner/cover/logo
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 10:56:14 +08:00
浅念 2618ad3163 feat(assets): album asset status — show current banner/cover/logo in admin branding tab
- 契约 listAlbumAssetStatus(GET /albums/{albumId}/assets):每 (kind,locale)
  最新 effective 行 + 现签 URL;权限同详情(可见即读);deleted → 404
- 服务端 AssetsService.status(createdAt,id DESC 组内取首;presignGet 现签)
- Admin 品牌资产页签改造:进入即加载现状——三种 kind 卡片(预览图/未设置
  空态/设置时间),banner 分全局/zh/en 槽位;上传成功自动刷新(替换语义)
- API 56/56、admin 87/87 + build 全绿

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 10:51:53 +08:00
浅念 d678c8d38d style(viewer): banner-wrap drops fixed aspect-ratio and placeholder bg (user edit)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 10:42:03 +08:00
浅念 fd35c712a5 fix(viewer): remove topbar settings menu, keep locale switcher only (user request)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 10:38:23 +08:00
浅念 8e674a902e feat(albums): soft-delete albums (admin+owner, hidden & irreversible, both app entries)
契约 deleteAlbum(DELETE /albums/{albumId} → 204 幂等)+ status enum 'deleted':
- 服务端:softDelete(canView 404→canManage 403 防枚举;乐观锁 claim +
  outbox album.updated priority=high + audit album.delete);列表/详情/更新/
  成员/资产/分类/水印/照片/展示位绑定全部 deleted→404;公开端 cn
  (status!=='active')与 ov(isAlbumVisibleOv)天然屏蔽;ov 副本经
  album.updated 载荷 status 直投自动下线
- Admin:列表表格操作「删除」+ 详情页头「删除相册」(确认含不可恢复说明)
- App:操作面板「删除相册」(红字、二次确认、成功退回列表并刷新)
- 验证:API 56/56、App 397/397(analyze 0)、admin typecheck/lint/test/build 绿

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 10:13:08 +08:00
浅念 aa78855657 fix(viewer): remove tap-more like hint from photo action bar (user request)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 09:31:26 +08:00
浅念 452cdf496c style(ui06): full-width pages — hand padding back to Art/ElMain container (user adjustment)
用户将全局 .ui06-page 的 30px 边距/1660 限宽注释(内容铺满,边距交还
ElMain 默认 20px);manage 页 scoped 同名类同步、清理媒体查询死引用。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 09:26:16 +08:00
浅念 d08d8f5a6d fix(ui06): embed-slots menu icon — invalid remix name (picture-carousel-line) 404s on iconify; use slideshow-line
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 09:21:12 +08:00
浅念 1a52d0a028 fix(ui06): grouped sidebar menu items missing click navigation
B1 分组展平渲染的 ElMenuItem 只渲染了标题插槽,未绑定跳转——点击无反应。
补 onGroupedItemClick:handleMenuJump(外链/iframe/普通路由统一语义,同
SidebarSubmenu.goPage)+ 移动端关闭抽屉。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 09:15:14 +08:00
浅念 6074fc8ed3 feat(ui06): App line A0-A7 — nav pill removal, light segments, bare summary, token alignment to app-preview
- tokens:次文字 #69778E、soft/card-border/seg 色组、输入圆角 10(kRadiusField)
- theme:导航 indicatorColor 透明+显式选中蓝;卡片去阴影改 1px #EDF0F5 边框;输入边框同步
- 新组件 SegmentTabs(#EDF1F6 轨道/选中实蓝/light 浅蓝变体/null 无高亮)替换 M3 SegmentedButton
- 上传中心:摘要去白卡直排+主数字 32/40;completed 次级筛选无高亮语义保留
- 相册卡 scrim 30% 起 #0C1728E8;导航角标红底白字白边;登录主标题 27/700
- theme_test 三处旧规格断言随 UI06 值更新;397/397 全绿、analyze 0 issues
- 真机证据:MuMu + 测试服务器 API,登录/相册/详情/上传 4 页截图确认达标
- 登记偏差:语义色保持对比度合规深色版;视口矩阵随 G2;详见验收记录 §6

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 08:09:20 +08:00
浅念 9471562f67 feat(ui06): B3d governance + B3e closing — page headings, stat cards, info strip, embed slots
- 治理页通用层(ui06.scss):.ui06-page 工作区 / .ui06-page-heading 27px 页头 / .ui06-stats
  三列统计卡 / .ui06-info-strip 提示条 / .ui06-card-title 17px 卡头
- 10 账号:页头(查看同步入口)+ 来源提示条;分页/同步档案列/G4 功能零改动
- 11 同步:页头(手动补拉上移);状态卡/历史/失败明细抽屉保留
- 12 用量:页头(阈值设置上移)+ 统计卡对齐示例(数字 27px + 注脚 10px)
- 13 展示位:页头 + 卡片标题(配置对话框沿用 UI-04 真实组件)
- 17-19 异常页:沿用 ArtException(大数字+文案+回退,语义等同示例;登记偏差)
- i18n zh/en;typecheck/lint/vitest/build 全绿

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 07:04:18 +08:00
浅念 352d7405c2 feat(ui06): B3c form batch — full-page create/edit form + assets tab
- 新增 /albums/form/create 与 /albums/form/:albumId 整页表单路由(隐藏路由,父菜单高亮)
- 编辑模式资料/访问页签(访问=开关行卡:标题+说明+开关);创建模式契约约束下载开关+解释提示
- 校验/提交逻辑与原对话框一致(契约镜像校验;translations 全量替换;创建仅 download 开关)
- 保存成功跳相册详情;manage/detail 两处入口改路由跳转,删除 AlbumFormDialog
- banner 上传收进详情「品牌资产」独立页签(15)
- e2e 适配:整页表单流程(form-page/goback/访问页签)、详情锚点改 summary、banner 页签
- typecheck/lint/vitest/build 全绿

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 06:58:01 +08:00
浅念 d6d012b992 feat(ui06): B3b management tabs — members/categories/watermark/share aligned to preview
- 成员:卡片头(标题+说明+搜索邀请)+ 成员列(首字头像+姓名)+ 角色 pill + 权限范围
  + owner 行「交接相册」入口(父组件开确认);移除/邀请语义不变
- 分类:卡片头(双语提示+新增)+ 分类列(图标 avatar+默认语言名)+ 中英同屏列
  + 底部「已有照片的分类不能直接删除」提示
- 水印:双栏卡片(配置卡 v{version} pill / 预览卡)——预览改摄影底(相册 cover)+
  白字水印叠加;生成任务独立卡片 + 重新生成入口;轮询/受理语义不变
- 分享:居中分享卡(封面/标题/日期地点/QR 160px/Copy link 全宽/小字链接);
  QR 仍真实编码 viewer 链接
- i18n zh/en 补全;typecheck/lint/vitest/build 全绿

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 06:52:23 +08:00
浅念 1531d3d99b fix(ui06): template single-expression for visibility segment (vite build parse)
教训登记:typecheck/vitest 不覆盖模板属性 parse——每批提交前本地 pnpm build 必须通过

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-22 23:24:00 +08:00
浅念 4f6790d630 feat(ui06): B2 shared components + B3a core pages — album cards, photo grid, viewer, summary header
- 类型补齐契约字段:Summary.cover / AdminPhoto.preview(SignedUrl;服务端已返回,B0 核对)
- AlbumCoverCard:封面卡(公开/状态/上传 pill,无封面中性占位,不显示 owner 名)
- 相册列表:默认封面卡片网格(3列/1700+4列)+ 表格切换 + 已加载内搜索 + 公开状态筛选 + 摘要行
- AlbumSummaryHeader:300×144 封面 + 两列紧凑资料 + 高级折叠(ownerId/统计时间收敛)
- 详情页壳:页头(编辑/分享固定主操作)替换 ElDescriptions 大区;banner 区 B3c 收纳
- PhotoGrid + PhotoPreviewDialog:照片网格默认(preview.thumb 签名 URL)+ 深色大图(browse URL、
  行内隐藏/恢复/软删除复用表格状态机);网格勾选与表格 selection 合并批量目标
- e2e 适配默认网格视图(albums/governance 断言前切表格);batchHide fixture 补 preview
- typecheck/lint/vitest 87 项全绿

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-22 23:19:21 +08:00
浅念 fb3743d32c feat(ui06): B1 theme tokens + layout shell + login redesign
- 主色 #1A73E8(systemMainColor 首位,运行时自动派生 Element 系列)
- 状态色对齐示例(success #15966d / warning #c78a27 / danger #df5366)
- 侧栏 216px、顶栏 64px(h-16)、内容 max-width 1660px(WIDE 枚举)、隐藏标签页条
- 菜单分组(工作空间/组织与治理):meta.menuGroup + 侧栏展平渲染 + i18n key;路由路径与权限不变
- ui06.scss 全局视觉层:字体栈 13px、卡片 12px 圆角+1px 边框、按钮/输入 38px、
  表格浅底表头、对话框 16px、分段 #edf1f7、焦点可见
- 登录页重做:摄影底+深蓝叠层+品牌大标题(占位素材=概念图裁片,待正式品牌素材)、
  右栏 350px 表单 29px 标题
- typecheck/lint/vitest 87 项全绿

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-22 23:00:36 +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
浅念 80a7658f81 feat(admin): users list page-size options [15,20,50,100] with default 15
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-22 18:36:16 +08:00
浅念 3bba8d1dc5 feat(admin,viewer,ui04): E06 management preview and v2 integration — real-component preview page, form mode fields, README
- viewer /embed-preview route: real EmbedStream with sample photography (picsum seeds), zero requests/WS (preview mode), postMessage config + simulated bursts through the real validation pipeline
- EmbedStream: preview prop (disables real WS subscription per §8.2 isolation) + exposed simulateBurst
- admin form: displayMode radio (new default), fixed 195x280 readonly, speed slider, reactions switch; v1 layout fields hidden in v2 (not silently effective)
- admin preview: v2 branch embeds the real preview iframe, white v2 handle, simulate-like tool button with sample-data note
- README-embed: v2 section (integration, hard sizing/docking, interactions/limits, artifact/version caching)
- tests: admin vitest 83 (+1 v2 placement), admin e2e 5 (v1 pinned carousel regression + full v2 chain incl. preview WYSIWYG heart and ov settings projection), viewer 244, v2 e2e 16

Note: part of the admin-side E06 changes (form/preview/utils/locales, mid-state of e2e spec) was swept into parallel commit eebf3b3 by a concurrent session's git add; this commit carries the final state of the remaining files and completes the set.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-22 18:20:50 +08:00
浅念 eebf3b3334 feat(admin): standard pagination + synced profile columns on users list
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-22 18:10:53 +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
浅念 f193e4f085 fix(viewer): remove extra closing brace in AlbumHeader CSS
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-22 13:59:14 +08:00
浅念 b353a3de06 fix(viewer): replace text arrow share icon with SVG share glyph
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-22 13:55:37 +08:00
浅念 900ff2a74d feat(viewer): refine visual details to match design reference
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-22 13:49:15 +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