dsh-m 0.9.65 → 0.9.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/lib/client.js +7 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,19 @@ The full release history of dsh-m, maintained bilingually: **Chinese first, Engl
|
|
|
8
8
|
|
|
9
9
|
## 中文
|
|
10
10
|
|
|
11
|
+
### 0.9.67 修复:操作记录卡移动端字号失控——显式入 12px 家族 + 折行自洽
|
|
12
|
+
|
|
13
|
+
- **根因(用户手机截图反馈)**:操作记录行 `.dsvm-oprow` 从不声明 `font-size`——桌面宿主基础字号下无感,移动端浏览器基础字号(≈15-16px)下整行被放大近一倍,与同屏设置卡的 12px 家族(`dsvm-kv` 配置地址行、`dshm-hint`、`dsvm-fold`)明显脱节,观感突兀。
|
|
14
|
+
- **修复(对齐周边卡片惯例)**:`.dsvm-oprow` 显式 `font-size:12px` 入族;状态字(完成/失败)保持 11px、错误/警告注记保持 11px 的次级层级不动;`flex-wrap:wrap` 让长目标名(如带 scope 的 npm 包名)与错误注记自然折行不挤压;单条移除 ✕ 钉行尾(`margin-left:auto`),与卡片行惯例一致。进行中/已结束分组标题(11px)与 220px 滚动区、空态 hint 均不受影响。
|
|
15
|
+
- **验证**:1289 项测试全绿、typecheck 零错误;构建产物含新规则逐字锚。
|
|
16
|
+
|
|
17
|
+
### 0.9.66 修复:触屏滑动方向与移动端惯例相反(用户实机反馈)
|
|
18
|
+
|
|
19
|
+
- **根因**:0.9.65 触屏滑动把映射锚在了键盘光标隐喻上(`ArrowRight=next` ⇒ 手指右拖=下一张),而触屏的正确隐喻是**内容拖拽**——手指拖着图像条走,**往左拖露出右边那张=下一张**(相册/微信/车龙全部如此)。`swipeDir` 返回的手指位移方向被原样喂给了 `lbStep`,致真机上「左滑出上一张、右滑出下一张」,与全部肌肉记忆相反。
|
|
20
|
+
- **修复**:调用点取反映射 `lbStep(index, -dir, …)`;`swipeDir` 纯函数语义不变(仍报手指方向),文档注释明确「返回值是手指方向而非翻页方向,调用点必须取反」。键盘 ←→ 不动(桌面光标惯例:←=上一张、→=下一张,两者隐喻各自成立互不干扰)。
|
|
21
|
+
- **探针同批修正**:`verify-lightbox.mjs` A31a/A31b 断言按正确惯例重写(修正后旧断言转红即方向确已翻转的实证);附带修正探针编号撞车——尾部既有 Primary 场景 A26–A29 保留,新特性场景编为 A30(预取命中)/A31(滑动)/A32(焦点圈闭);A19 重写为时序确定性版双断占位(当轮验证附带产出:疑似回归经消融+worktree 对比+确定性时序三重取证定谳为「预取预热了场景前提图」,非回归,取证记录见探针内注释)。
|
|
22
|
+
- **验证**:1289 项测试全绿、typecheck 零错误;浏览器探针 50/50(A31 五断言含方向翻转实证 + A32 圈闭六断言 + A30 预取命中 + A19/A20–A25 既有锚全数保持)。
|
|
23
|
+
|
|
11
24
|
### 0.9.65 优化:灯箱邻图预取 + 触屏滑动切换 + 焦点圈闭
|
|
12
25
|
|
|
13
26
|
- **邻图预取**:当前图加载完成(`useImgChain` settled)后静默预热左右邻——URL 用与灯箱真实请求**逐字节同形**的 `weservUrl(w=1600)`,翻页直接命中浏览器缓存近零等待。纯 best-effort:不碰赢家记忆/链状态,预取失败对真实链零影响(导航时照常走 weserv→原图双兜底);`prefetchedRef` Set 去重防来回翻页重复发起,Set 随灯箱挂载期生命周期(重开重新预热);单图由 `lbNeighbors` 空表自然短路。
|
|
@@ -482,6 +495,19 @@ The full release history of dsh-m, maintained bilingually: **Chinese first, Engl
|
|
|
482
495
|
|
|
483
496
|
## English
|
|
484
497
|
|
|
498
|
+
### Fixed in 0.9.67 — operations card font blows up on mobile: join the 12px family + wrap self-consistency
|
|
499
|
+
|
|
500
|
+
- **Root cause (user phone screenshot)**: the operations rows `.dsvm-oprow` never declared a `font-size` — invisible on the desktop host base size, but on mobile browsers (base ≈15-16px) the whole row rendered nearly twice the size of the settings cards around it, clashing with the 12px family (`dsvm-kv` config rows, `dshm-hint`, `dsvm-fold`) on the same screen.
|
|
501
|
+
- **Fix (aligned with surrounding card conventions)**: `.dsvm-oprow` explicitly joins the family at `font-size:12px`; the status word (done/failed) keeps its 11px and error/warning notes keep 11px secondary hierarchy; `flex-wrap:wrap` lets long targets (scoped npm names) and error notes wrap naturally instead of squeezing; the per-row remove ✕ pins to the line end (`margin-left:auto`), matching row conventions elsewhere. Group captions (11px), the 220px scroll region and the empty-state hint are untouched.
|
|
502
|
+
- **Verification**: 1289 tests green, typecheck clean; the built bundle carries the new rule verbatim.
|
|
503
|
+
|
|
504
|
+
### Fixed in 0.9.66 — touch swipe direction inverted vs mobile convention (user report from a real phone)
|
|
505
|
+
|
|
506
|
+
- **Root cause**: 0.9.65 anchored the swipe mapping on the keyboard cursor metaphor (`ArrowRight=next` ⇒ finger-right = next image), while touch follows the **content-drag** metaphor - the finger drags the filmstrip, so **swiping left reveals the image on the right = next** (photo libraries, chat apps, every carousel). `swipeDir`'s finger-direction result was fed straight into `lbStep`, producing "swipe left → previous, swipe right → next" on real devices - inverted against all muscle memory.
|
|
507
|
+
- **Fix**: the call site flips the mapping (`lbStep(index, -dir, …)`); `swipeDir` semantics unchanged (still reports the finger direction), now documented as "the return value is the finger direction, not the page direction - callers must negate". Keyboard ←→ untouched (desktop cursor convention: ←=previous, →=next - the two metaphors each hold in their own domain).
|
|
508
|
+
- **Probe fixes in the same batch**: `verify-lightbox.mjs` A31a/A31b rewritten to the correct convention (the old assertion going red after the fix is direct proof the direction flipped); probe numbering collision fixed - the pre-existing Primary scenarios keep A26-A29, the new-feature scenarios become A30 (prefetch warm-hit) / A31 (swipe) / A32 (focus trap); A19 rewritten as a timing-deterministic double-fail placeholder scenario (byproduct of this verification round: the suspected regression was triply disproven - ablation probe, worktree bisect, deterministic timing - the prefetch had legitimately pre-warmed the scenario's premise image; forensics live in the probe comments).
|
|
509
|
+
- **Verification**: 1289 tests green, typecheck clean; browser probe 50/50 (A31 five assertions incl. the flip proof + A32 six trap assertions + A30 prefetch warm-hit + A19/A20-A25 legacy anchors all held).
|
|
510
|
+
|
|
485
511
|
### Added in 0.9.65 — lightbox: neighbor prefetch + touch swipe navigation + focus trap
|
|
486
512
|
|
|
487
513
|
- **Neighbor prefetch**: once the current image settles (`useImgChain` settled), the left/right neighbors are warmed silently - using a `weservUrl(w=1600)` URL **byte-identical** to the lightbox's real request, so a swipe/arrow navigation hits the browser cache with near-zero wait. Strictly best-effort: no winner-memory or chain-state mutation, a failed prefetch leaves the real chain untouched (navigation still runs the weserv→original dual fallback); a `prefetchedRef` Set dedupes repeated crossings (no re-issuing when bouncing back), the Set lives for the lightbox mount lifetime (a fresh open warms again); single-image boxes short-circuit naturally via `lbNeighbors` returning an empty list.
|
package/lib/client.js
CHANGED
|
@@ -2438,7 +2438,12 @@ var CSS = `
|
|
|
2438
2438
|
.dshm-ops-scroll::-webkit-scrollbar-thumb:hover{background:rgba(127,127,127,.45)}
|
|
2439
2439
|
.dsvm-opgroup{display:flex;flex-direction:column;gap:3px}
|
|
2440
2440
|
.dsvm-opgroup.done{opacity:.75}
|
|
2441
|
-
.
|
|
2441
|
+
/* 0.9.67 \u79FB\u52A8\u7AEF\u5B57\u53F7\u81EA\u6D3D\uFF08\u7528\u6237\u5B9E\u673A\u622A\u56FE\u53CD\u9988\uFF09\uFF1Aoprow \u539F\u4E0D\u58F0\u660E font-size\u2014\u2014\u79FB\u52A8\u7AEF\u5BBF\u4E3B
|
|
2442
|
+
\u57FA\u7840\u5B57\u53F7\uFF08\u224815-16px\uFF09\u4E0B\u6574\u884C\u88AB\u653E\u5927\uFF0C\u4E0E\u8BBE\u7F6E\u5361 12px \u5BB6\u65CF\uFF08dsvm-kv/dshm-hint/dsvm-fold\uFF09
|
|
2443
|
+
\u660E\u663E\u8131\u8282\u3002\u663E\u5F0F 12px \u5165\u65CF\uFF08\u72B6\u6001 11px/\u6CE8\u8BB0 11px \u7684\u6B21\u7EA7\u5C42\u7EA7\u4FDD\u6301\uFF09\uFF1Bflex-wrap \u8BA9\u957F\u76EE\u6807\u540D
|
|
2444
|
+
\u4E0E\u9519\u8BEF\u6CE8\u8BB0\u81EA\u7136\u6298\u884C\u4E0D\u6324\u538B\uFF1B\u2715 \u5355\u6761\u79FB\u9664\u94AE\u9489\u884C\u5C3E\u4E0E\u793E\u533A\u5361\u884C\u60EF\u4F8B\u4E00\u81F4\u3002 */
|
|
2445
|
+
.dsvm-oprow{display:flex;align-items:center;gap:8px;min-height:22px;font-size:12px;flex-wrap:wrap}
|
|
2446
|
+
.dsvm-oprow .dshm-xbtn{margin-left:auto}
|
|
2442
2447
|
.dsvm-opstatus{min-width:44px;font-size:11px;color:var(--dsw-alias-label-caption,#6b7280)}
|
|
2443
2448
|
.dsvm-oprow.ok .dsvm-opstatus{color:#15803d}
|
|
2444
2449
|
.dsvm-oprow.warn .dsvm-opstatus, .dsvm-oprow.run .dsvm-opstatus{color:#b45309}
|
|
@@ -3235,7 +3240,7 @@ function Lightbox({ shots, index, onNav, onClose }) {
|
|
|
3235
3240
|
swipeRef.current = null;
|
|
3236
3241
|
if (!dir || single) return;
|
|
3237
3242
|
swipedAtRef.current = Date.now();
|
|
3238
|
-
onNav(lbStep2(index, dir, shots.length));
|
|
3243
|
+
onNav(lbStep2(index, -dir, shots.length));
|
|
3239
3244
|
};
|
|
3240
3245
|
const onClickCapture = (e) => {
|
|
3241
3246
|
if (Date.now() - swipedAtRef.current < 500) e.stopPropagation();
|