浅念
45dbde3719
perf(app): throttle upload progress callbacks to 256KB steps
...
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-28 14:10:29 +08:00
浅念
203f62e7cb
test(app): align mockwebserver with resolved okhttp 5.2.1
...
fluwx 6.0.2 传递 okhttp 5.x,冲突调解覆盖本模块 4.12 声明(debug
运行时同为 5.2.1);mockwebserver 4.12 在 okhttp 5.x 运行时缺
okhttp3.internal.Util → 单测 setUp 即 NoClassDefFoundError(本改动
前 main 上已复现)。对齐后 11/11 通过。
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-28 14:10:14 +08:00
浅念
93e7046332
feat(app): enqueue gallery batch concurrently via Future.wait
...
Parallelize the enqueueForUpload collect loop (preparer's internal
bounded semaphore from the previous task keeps IO in check). Also two
test hardenings from that task's code review: pin that failed and
thrown prepare operations release their concurrency slot (cap=1,
subsequent prepare still completes), and pin the maxConcurrentPrepares
<1 -> 1 clamp (peak 1, no deadlock).
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-28 13:53:42 +08:00
浅念
b79edf447b
feat(app): bounded-parallel prepare (default 3) replaces serial queue
...
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-28 13:43:07 +08:00
浅念
dc5ae4a24a
feat(app): raise default upload parallelism 2 -> 4
...
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-28 13:34:48 +08:00
浅念
90dcc58c33
feat(uploads): P0-1 batch 4 — server-side duplicate photo detection (409 + force + index)
...
契约 UploadInitRequest 加 force(bool,仅 owner/admin 跳过查重)。
服务端 init 事务前置查重:同 albumId + uploaderId + bytes 的非 deleted
照片已存在 → 409 PHOTO_DUPLICATE。photos 表加 idx_photos_dedup 索引
(迁移 20260928120000)。
App UploadInitRequest 加 force 字段 + toJson 序列化。
本地查重(层 1)+ 服务端查重(层 2)双层防线到位。
API typecheck ✅ · app analyze ✅ · 397/397 ✅ · contract lint ✅
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-28 11:29:29 +08:00
浅念
33f347cdea
feat(app): P0 batch 3 — offline detection with engine pause/resume + UI banner
...
P0-4 离线感知:
- connectivity_plus → NetworkAvailability(online/offline/unknown)
- engine_scope 三重绑定:有账号+有网 → start;任一失去 → stop(在途不中断)
- 网络恢复 → start + onNetworkRestored(waitingNetwork 即时重试)
- HomePage 顶部离线黄条(wifi_off + i18n 双语)
P0-5 更正:EXIF 方向已由服务端 sharp .rotate() 自动转正——v2 分析误报
397/397 全绿、analyze 0
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-28 11:23:51 +08:00
浅念
638dd9b45d
feat(app): P0 batch 2+2.5 — local upload dedup with batch dialog, album switch check, file size guard
...
P0-1 层 1 本地查重:
- checkDuplicates:同账号+同相册+state=completed+filename+bytes 匹配
- EnqueueResult 返回 enqueued+duplicates+skipped
- capture_page + album_detail_page:批量单次弹窗(非逐张)三选一
[跳过重复上传非重复] [全部上传] [取消]
P0-8 相册上传开关预检:album_detail_page 入队前检查 uploadEnabled,
关闭时提示「该相册已关闭上传」+ 不入队
P1-8 文件大小预检:preparer 限单文件 ≤100MB(磁盘满由 on Object 兜底)
P0-7 更正:上传并发限制已有(kMaxParallelUploads=2),v2 分析误报
397/397 全绿、analyze 0
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-28 11:06:40 +08:00
浅念
9edcb3f2b1
feat(app): P0 batch 1 — photo viewer zoom, camera lifecycle, image memory management
...
P0-2 查看器缩放:InteractiveViewer(5x max,放大后平移,1x 时穿透到
PageView 滑动切页)
P0-3 相机后台释放:WidgetsBindingObserver——paused 时 dispose(省电+
隐私指示灯),resumed 时重开(沿用前后摄/闪光灯偏好)
P0-6 图片内存管理:PhotoThumbnail 加 maxCacheWidth 参数——网格/列表
缩略图限制解码宽度(600/400px),查看器大图不限
397/397 全绿、analyze 0
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-28 10:35:14 +08:00
浅念
a5d71686ff
feat(viewer): remove native share button from share sheet (user request) — copy link only
...
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-28 09:08:39 +08:00
浅念
dc8d3ff967
feat(app): launcher icon — brand logo 1024px + adaptive (blue #1A73E8 background)
...
flutter_launcher_icons 自动生成全尺寸 mipmap(48-192px + 自适应前景/背景)。
正式签名生产环境 APK 已打好。
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-24 17:07:14 +08:00
浅念
d279cefd71
feat(viewer): hide link text under QR in share sheet (user request) — QR + copy button remain
...
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-24 16:51:36 +08:00
浅念
643f837bca
feat(viewer): hide view count in album header (user request) — counting/reporting unaffected
...
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-24 16:24:05 +08:00
浅念
cf490c7892
feat(app): all album date displays date-only — formatAlbumDateTime drops HH:mm
...
相册列表卡/详情信息/分享页 meta/照片查看器日期一律纯日期(y/M/d)。
全量测试断言同步;397/397 全绿。
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-24 16:20:47 +08:00
浅念
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
浅念
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
浅念
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