v29 第 29 批(9 条):日程定位/复选框提示/名册错乱三处真因修复 + 读书落盘 + 导航四设置 + 笔记阅读态与共享
前 4 条是"上批改了但用户仍报"的,这次先拿真机证据再动手,三处真因如下:
1. 首页没定位到红线 —— 真根因:定位脚本的 PHP 条件是
`if (!$todayEvents || empty($timed))`,**今天只有全天日程时整段脚本不渲染**
(实测 hasScript=False、scrollTop=0),而 .ag-grid(0–24h) 与红线都在。
有分时段日程时定位其实完全正确(偏差 0px)。已改成 `if (!$todayEvents)`。
2. 任务复选框提示还在 —— 真根因:`_task_check.php` 里那句无障碍文字
`<span class="visually-hidden">` 用的类名**在 app.css 里从来没有定义过**
(项目一直只用 .sr-only)→ 没有规则 = 普通 span = 直接可见。
已把两个类名合并到同一条规则(clip 隐藏,仍可读屏)。
3. 名册完全错乱 —— 真根因:v29 重写平铺列表时**漏了一个 `</div>`**(闭合 .person),
浏览器把下一张卡嵌进上一张里,实测 .person-main 只剩 24~151px(本该 ~800px)。
`php -l` 与全部静态断言都抓不到,只有真机量 DOM 才现形。已补上闭合。
另把 v28 引入的多列 grid 改回单列(它与 content-visibility 冲突)+窄屏动作区折行。
4. 读书慢 —— 按用户给的思路「做一个同步,然后落盘」:
新增 weread_snapshots 表 + App\WeReadCache(按人+数据集存 JSON);
渲染路径改走 notebooksCached()/readStatsCached()(永不联网);
同步从"渲染之前"挪到"**响应之后**"(queueBackgroundSync + fastcgi_finish_request)。
5. 导航设置改成右上角**下拉菜单 + 四视图**(addr/general/board/engine),
表单带 back 域 → 保存后回原来那一项。
🔴 顺带修掉一个真 bug:`if (!$inSettings && $canWrite)` 的 endif 漂到了文件末尾,
把 board/engine 两个视图也包进了"非设置态" → 打开时标题对、**内容是空的**。
6. 笔记列表缩略图:cover → contain + 固定高度(按比例完整显示,不裁切)。
7. 笔记段落编辑器:加 Markdown 工具条 + 斜线命令(行首打 /co → 回车补全代码块),
两者共用同一份命令表。
8. 笔记点进来默认**阅读态**(图文混排、附件在最下方、图片四档宽度、点「编辑」才可改);
清单块并入 Markdown —— 但**历史 list 块转写成 `- 项` 文本,老数据不丢**。
9. 笔记共享改成**逐人 + 权限**(note_shares,与 resource_shares 同构);
可见性收敛成全站唯一的 Note::VIS_COND;迁移用一次性哨兵。
This commit is contained in:
+125
-14
@@ -1089,8 +1089,18 @@ body[class] .semi-datepicker-day-inhover { background-color: color-mix(in srgb,
|
||||
以下都是 2026-09-30 那一批反馈加的东西
|
||||
============================================================ */
|
||||
|
||||
/* 只给读屏用的标签:视觉上不占地,但无障碍名还在(别用 display:none,那会一起藏掉) */
|
||||
.sr-only {
|
||||
/* 只给读屏用的标签:视觉上不占地,但无障碍名还在(别用 display:none,那会一起藏掉)
|
||||
🔴 v29 用户第 2 条:「任务完成复选框的提示文字还在」——
|
||||
真根因:`_task_check.php` 与任务看板用的是 `class="visually-hidden"`,
|
||||
而**本文件里从来没有这个类**(项目一直只定义 `.sr-only`)。
|
||||
CSS 里查不到的类 = 没有任何样式 → 那段文字是**普通 inline span,直接显示出来**,
|
||||
就贴在复选框旁边(用户看到的就是「标记完成:待办」)。
|
||||
⇒ 修法:把两个名字指向同一条规则(两种写法都认)。
|
||||
为什么不是"把模板改成 sr-only 了事":这个类名在下游(别的模板、以后新写的)
|
||||
同样可能被用到,名字不再是隐患;而只改调用点的话,下次谁再写
|
||||
`visually-hidden` 就又漏了。这里是"给能力补上定义",不是"给某一处打补丁"。*/
|
||||
.sr-only,
|
||||
.visually-hidden {
|
||||
position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
|
||||
overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
|
||||
}
|
||||
@@ -4611,17 +4621,23 @@ button.btn, a.btn, summary.btn, .seg-btn, .icon-btn, .rv-act-btn, .cs-btn, .bf-b
|
||||
.roster-tagbar-k { font-size: 12.5px; color: var(--faint); margin-right: 2px; }
|
||||
.roster-tagbar-clear { margin-left: auto; font-size: 12.5px; }
|
||||
|
||||
/* ---- 平铺列表:卡片单列铺开,不再有"栏"的分隔线 ----
|
||||
⚠️ `.people-grid` 原来在多栏里是 grid;平铺后让它 2 列自适应(宽屏两列、
|
||||
窄屏一列),既不像单列那样长得没边,也不至于把姓名行挤断。
|
||||
用 auto-fill + minmax 而不是写死列数:名册人数从 3 到 1000+ 都用同一套。 */
|
||||
.roster.is-flat .people-grid {
|
||||
display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
|
||||
gap: 8px;
|
||||
}
|
||||
@media (max-width: 720px) {
|
||||
.roster.is-flat .people-grid { grid-template-columns: 1fr; }
|
||||
}
|
||||
/* ---- 平铺列表:**仍然单列**(只是不再有"栏"的分隔线)----
|
||||
🔴🔴 v29 用户第 3 条:「名册页面完全错乱」—— 这个 bug 是 v28 **我自己引入的**。
|
||||
v28 我把这里写成了多列 grid(`repeat(auto-fill, minmax(320px,1fr))`),
|
||||
真实后果有两个,都实测到了:
|
||||
① 卡片上有 `content-visibility: auto` + `contain-intrinsic-size: auto 68px`
|
||||
(v24 为"千人名册不卡死"加的)。它在**单列流**里是安全的,
|
||||
一旦卡片变成 grid item,屏外卡片的"估算高度"与网格轨道互相打架,
|
||||
布局当场乱掉;
|
||||
② 每列只剩 ~339px(1280 宽 ÷ 3),而卡片里是
|
||||
[拖柄][头像 52px + 姓名/徽标][标签+编辑+删除 三个按钮 ≈213px] ——
|
||||
实测 `person-main` 只分到 **106px**(含 52px 头像 → 姓名区仅 42px),
|
||||
姓名、徽标全被挤碎,动作区还会折行。
|
||||
⇒ 修法:**回到单列**(`.people-grid` 本来就是单列 flex,见文件上方 328 行),
|
||||
把 v28 那条 grid 规则整个删掉。名册人数从 3 到 1000+ 都是单列,
|
||||
与"分栏时代每一栏的卡片"同宽 —— 那才是这套卡片的原始设计宽度。
|
||||
⚠️ 别再用"多列网格"来塞名册卡片:它的内容是**横向三段式**的,
|
||||
天生吃宽度;窄了就一定碎。 */
|
||||
|
||||
/* ---- 🔴 用户第 6 条:「名册,每个人后面的按钮,也是要有背景颜色的。」
|
||||
原来三颗按钮全是 .btn-ghost(白底 + 极浅描边),在纸白卡片上几乎看不见边界。
|
||||
@@ -4756,8 +4772,16 @@ button.btn, a.btn, summary.btn, .seg-btn, .icon-btn, .rv-act-btn, .cs-btn, .bf-b
|
||||
.note-ex-empty { color: var(--faint); font-style: italic; }
|
||||
/* 图片:等比缩放到卡片宽,放在摘要下方(用户:"图片缩放后,放在下面") */
|
||||
.note-thumb { margin-top: 8px; flex: 0 0 auto; overflow: hidden; border-radius: var(--radius-s); }
|
||||
/* 🔴 v29 第 6 条:「笔记,首页显示的时候,里面的图片,和行程的类似,
|
||||
把图片按照比例缩放到固定的高度或者宽度,放在下面就行了。」
|
||||
⇒ 固定高度 + **等比完整显示**(contain),不再 cover 裁切。
|
||||
⚠️ 从 cover 改 contain 是有意的取舍:
|
||||
cover 能让每张图铺满、看着"实",但**看不到完整内容**(横图两端被切掉)——
|
||||
用户要的是"按比例缩小放在下面",那就是要看到**整张**。
|
||||
代价是宽高比与格子不一致时两侧留浅底,所以给个底色让留白显得是有意的。 */
|
||||
.note-thumb img {
|
||||
width: 100%; height: 88px; object-fit: cover; display: block;
|
||||
width: 100%; height: 110px; object-fit: contain; display: block;
|
||||
background: #F6F4F0;
|
||||
border: 1px solid var(--line); border-radius: var(--radius-s);
|
||||
}
|
||||
.note-card .note-tags-inline { margin-top: auto; padding-top: 8px; flex: 0 0 auto; }
|
||||
@@ -4872,3 +4896,90 @@ h5.md-h, h6.md-h { font-size: 14px; }
|
||||
/* 姓名那一栏允许收缩并截断,否则长名字也会顶破 */
|
||||
.pname { overflow-wrap: anywhere; }
|
||||
}
|
||||
/* 🔴 v29 第 3 条(窄屏半边):360px 下卡片只有 328px,
|
||||
[拖柄 24][头像 52 + 姓名][标签+编辑+删除 ≈197] 硬塞在一行 → 姓名区只剩 ~40px。
|
||||
⇒ 窄屏把动作区**整体折到第二行**(卡片改纵向),姓名那一行就宽裕了。
|
||||
用 flex-direction: column 而不是给动作区定宽:后者的宽度随标签数变化,
|
||||
定了也会被长标签顶开(v28 就是这么栽的)。 */
|
||||
@media (max-width: 640px) {
|
||||
.person { flex-wrap: wrap; }
|
||||
.person .person-main { flex: 1 1 calc(100% - 40px); }
|
||||
.person-actions {
|
||||
flex: 1 1 100%; justify-content: flex-start;
|
||||
padding: 0 10px 10px 34px; /* 左边缩进到与姓名对齐(躲开拖柄) */
|
||||
}
|
||||
.person-tag-btn { max-width: 46vw; }
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
v29 用户第 7 / 8 / 9 条:笔记 —— 阅读态 / 工具条 / 斜线命令 / 图片调大小
|
||||
============================================================ */
|
||||
|
||||
/* ---- 阅读态(第 8 条:点进来默认是"看")----
|
||||
与编辑态的区别要**一眼看得出**:没有虚线框、没有按钮,就是一篇排好版的文档。 */
|
||||
.note-read { max-width: 820px; }
|
||||
.note-read-title { margin: 0 0 6px; font-size: 22px; font-weight: 600; color: var(--ink); }
|
||||
.note-read-tags { margin: 0 0 14px; }
|
||||
.note-read-body { display: flex; flex-direction: column; gap: 14px; }
|
||||
.note-read-block { font-size: 15px; line-height: 1.8; color: var(--ink); }
|
||||
/* 图片:默认满宽,可调(内联 style 给百分比);圆角与卡片一致 */
|
||||
.note-read-fig { margin: 0; }
|
||||
.note-read-fig img {
|
||||
max-width: 100%; height: auto; display: block;
|
||||
border: 1px solid var(--line); border-radius: var(--radius-s);
|
||||
}
|
||||
.note-read-fig a { display: inline-block; max-width: 100%; }
|
||||
.note-read-h2 {
|
||||
margin: 0 0 8px; font-size: 14px; font-weight: 600; color: var(--muted);
|
||||
letter-spacing: .5px;
|
||||
}
|
||||
/* 附件区:一条细线把它与正文分开("在最下方"要看得出来是**另一块**) */
|
||||
.note-read-files { margin-top: 20px; padding-top: 14px; border-top: 1px solid var(--line-2); }
|
||||
.note-read .note-share-now { margin-top: 16px; }
|
||||
|
||||
/* ---- 编辑态:Markdown 工具条(第 7 条"要么有工具条")---- */
|
||||
.note-cmdbar {
|
||||
display: flex; align-items: center; gap: 4px; flex-wrap: wrap;
|
||||
padding: 6px 8px; margin-bottom: 8px;
|
||||
border: 1px solid var(--line); border-radius: var(--radius-s);
|
||||
background: #FDFCFA;
|
||||
}
|
||||
.note-cmdbar .cmd {
|
||||
min-width: 28px; height: 26px; padding: 0 7px;
|
||||
border: 1px solid var(--line); border-radius: 5px; background: #fff;
|
||||
color: var(--ink); cursor: pointer; font-size: 13px; line-height: 1;
|
||||
}
|
||||
.note-cmdbar .cmd:hover { border-color: var(--brand-2); color: var(--brand-ink); background: var(--brand-soft, #FDF3EC); }
|
||||
.note-cmdbar .cmd-sep { width: 1px; height: 18px; background: var(--line); margin: 0 4px; }
|
||||
.note-cmdbar .note-live { margin-left: auto; }
|
||||
|
||||
/* ---- 斜线命令菜单(第 7 条"要么有代码提示")----
|
||||
⚠️ 绝对定位在**块内**(不是 body):跟着块走,块删除/移动时不会留孤儿菜单。 */
|
||||
.note-block-body { position: relative; }
|
||||
.slash-menu {
|
||||
position: absolute; left: 0; top: 100%; z-index: 30; display: none;
|
||||
min-width: 190px; max-height: 220px; overflow-y: auto;
|
||||
background: #fff; border: 1px solid var(--line); border-radius: var(--radius-s);
|
||||
box-shadow: var(--shadow); padding: 4px;
|
||||
}
|
||||
.slash-menu.is-on { display: block; }
|
||||
.slash-item {
|
||||
display: flex; align-items: baseline; gap: 8px; width: 100%;
|
||||
padding: 5px 8px; border: 0; border-radius: 5px; background: transparent;
|
||||
cursor: pointer; text-align: left; font-size: 13px; color: var(--ink);
|
||||
}
|
||||
.slash-item b { color: var(--brand); font-family: ui-monospace, Consolas, monospace; }
|
||||
.slash-item span { color: var(--muted); font-size: 12px; }
|
||||
.slash-item:hover, .slash-item.is-on { background: var(--brand-soft, #FDF3EC); }
|
||||
|
||||
/* ---- 图片块:尺寸档位(第 8 条"图文混排时,需要可以调整大小")---- */
|
||||
.note-img-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
|
||||
.note-img-sizes { display: inline-flex; gap: 3px; margin-left: auto; }
|
||||
.note-img-size {
|
||||
padding: 2px 7px; border: 1px solid var(--line); border-radius: 5px;
|
||||
background: #fff; color: var(--muted); cursor: pointer; font-size: 11.5px;
|
||||
}
|
||||
.note-img-size:hover { border-color: var(--brand-2); color: var(--brand-ink); }
|
||||
.note-img-size.is-on { border-color: var(--brand); background: var(--brand-soft, #FDF3EC); color: var(--brand-ink); }
|
||||
/* 图上标着当前档位,编辑器里一眼能看出"这张被缩过了" */
|
||||
.note-block[data-kind="image"] .note-block-img { transition: width .12s ease; }
|
||||
|
||||
Reference in New Issue
Block a user