v72:日历本显示与管理合并成一张清单,颜色改用内置调色模态框
用户 2026-10-21 两条:
「日历设置里面日历本显示和日历管理可以放在一起」
「预制的颜色点了之后没反应……选颜色那个地方点了之后是弹出 Windows 的
一个颜色选择框,这个不好,我们把它改成内置的」
改动:
· calendar/display 整页删除,并入 calendar/calendars(保留 302 老地址)
· 新增 templates/_color_picker.php(按钮 + 值载体,表单/独立双模式)
· 新增 templates/_color_picker_modal.php(全页唯一模态框,预置色 + hex 手输)
· 共享本提到同一清单,标注归属与权限;owner 校验服务端做
· 清掉 display.php 时代遗留的死 CSS(.cal-set-page / .cal-set-book* 等)
部署中抓出并修掉两处真问题:
· 部署脚本「清掉被取代文件」清单漏了 display.php —— tar 只新增/覆盖,
git rm 掉的文件在线上永远留着,被第 7 段断言拦下(断言是对的,缺的是删除步骤)
· _color_picker.php 里残留 <input type="color" class="cp-trigger">:
原生取色控件既不能有子元素、也没有 data-cp-open ⇒
按钮回显失效(找不到 .cp-trigger-dot/hex)+ 模态框永远打不开,
用户点到的还是 Windows 取色框。改成 <button type="button"> + 色点 + hex
(v72 探针在修复前实测 2 条红,修复后 50/0)
This commit is contained in:
+196
-28
@@ -170,39 +170,207 @@ a:hover { text-decoration: underline; }
|
||||
否则菜单会顶出屏幕、底下的「保存」按钮够不着。 */
|
||||
.cal-set .menu-list { min-width: 260px; max-width: min(320px, 92vw); }
|
||||
.cal-set-list { padding: 10px; gap: 0; }
|
||||
.cal-set-form { display: block; }
|
||||
.cal-set-block { padding: 6px 2px; }
|
||||
.cal-set-block + .cal-set-block { border-top: 1px solid var(--line-2); margin-top: 4px; }
|
||||
.cal-set-h { font-size: 12px; color: var(--muted); margin-bottom: 6px; }
|
||||
.cal-set-views { display: flex; gap: 12px; flex-wrap: wrap; }
|
||||
.cal-set-view { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; cursor: pointer; }
|
||||
.cal-set-view input { accent-color: var(--brand); }
|
||||
/* 本子清单:最多占 42vh,超了内部滚动 —— 菜单本身不滚,否则保存按钮会被推出可视区 */
|
||||
.cal-set-books { max-height: 42vh; overflow-y: auto; }
|
||||
/* 🔴 v51(用户 2026-10-15 第 6 条):显示设置**独立成页之后**,
|
||||
`.cal-set-books` 那条 `max-height:42vh; overflow-y:auto` 就不该再套用了 ——
|
||||
它是"塞在下拉里"时的妥协(下拉不能太高)。整页里再套一个 42vh 的滚动区,
|
||||
等于"页面里再开一个小窗",日历本多的时候要**滚动两次**才能看完。
|
||||
⚠️ 用 `.cal-set-page` 作用域覆盖,**不动**上面那条基础规则 ——
|
||||
它现在没有别的使用者,但留着万一将来又要在别处(弹框里)用同一套列表。 */
|
||||
.cal-set-page .cal-set-books { max-height: none; overflow-y: visible; }
|
||||
/* 页面上把每一本排成一行(与下拉里同一套行样式,只是不滚动) */
|
||||
.cal-set-page .cal-set-book { font-size: 14px; }
|
||||
.cal-set-book {
|
||||
display: flex; align-items: center; gap: 7px; padding: 5px 4px;
|
||||
font-size: 13px; cursor: pointer; border-radius: 6px; white-space: normal;
|
||||
/* 🔴 v72(用户 2026-10-21)—— 这里原有一段 `.cal-set-books / .cal-set-book* /
|
||||
.cal-set-page / .cal-set-form|block|foot|links` 的样式,随 `calendar/display`
|
||||
整页删除(显隐与管理合并进 `calendar/calendars`)**全部失去了使用者**,
|
||||
已在本轮清掉。留着的代价不只是"没用":
|
||||
· 其中 `.cal-set-page .cal-set-books { max-height:none; overflow-y:visible; }`
|
||||
曾被 v51 的反向验证当成"守内滚动"的锚点 —— 规则在、页面没了 ⇒
|
||||
注入照旧命中文本、页面照旧全绿 ⇒ **那条反向验证变成空转**,
|
||||
在输出上却看起来"这条断言很结实"(实测踩中,见 `_b51_falsify.py` 注释)。
|
||||
· ⇐ 教训:**断言只能锚"当前真有使用者"的规则**;删模板时必须同步删死 CSS,
|
||||
否则验证脚本会静默退化成摆设。
|
||||
现在"日历本清单不套内滚动"这件事由 `.cal-books` 守(它才是页面上真实的清单容器)。 */
|
||||
|
||||
/* ============================================================================
|
||||
v72(用户 2026-10-21):日历本「显隐 + 管理」合并成一张清单
|
||||
----------------------------------------------------------------------------
|
||||
用户原话:「日历设置里面日历本显示和日历管理可以放在一起啊。就是把日历本全都
|
||||
列出来,然后显示不显示,加个复选框就行了。另外把下面别人共享给我的
|
||||
也提到上面来,把所有的日历都放在一块,只不过在后面标注出来,
|
||||
这个是别人谁谁谁共享给我的?是只读的还是可写的,什么的就可以了呀。」
|
||||
|
||||
⇒ 每行从左到右读下来就是一整句答案:
|
||||
[✓] ■ 名字 [谁·只读/可写] 共享 导出 编辑 删除
|
||||
⚠️ 用 grid 而不是 flex:归属那一列要**对齐**(否则每行标签长短不一时,
|
||||
后面的操作按钮会跟着左右乱跳,看着很脏)。
|
||||
⚠️ 窄屏(<640px)改成两行:第一行勾选+色块+名字+归属,第二行操作。
|
||||
44 行日历本在手机上横着排会挤成碎片(用户可能在手机浏览器里管日历)。
|
||||
========================================================================== */
|
||||
.cal-books { display: flex; flex-direction: column; gap: 2px; }
|
||||
|
||||
/* 分组分隔线:从"我的"切到"共享给我的" */
|
||||
.cal-books-sep {
|
||||
display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
|
||||
margin: 14px 0 6px; padding-top: 12px;
|
||||
border-top: 1px solid var(--line);
|
||||
font-size: 13px; font-weight: 600; color: var(--muted);
|
||||
}
|
||||
.cal-set-book:hover { background: var(--line-2); }
|
||||
.cal-set-book input { accent-color: var(--brand); flex: 0 0 auto; }
|
||||
.cal-set-book .color-preview { width: 11px; height: 11px; border-radius: 3px; flex: 0 0 auto; }
|
||||
.cal-set-book .cal-name { overflow: hidden; text-overflow: ellipsis; }
|
||||
.cal-set-book .node-badge { margin-left: auto; flex: 0 0 auto; }
|
||||
.cal-set-foot { margin-top: 10px; }
|
||||
.cal-set-foot .btn { width: 100%; justify-content: center; }
|
||||
.cal-set-links { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line-2); }
|
||||
.cal-set-links a { display: flex; align-items: center; gap: 10px; white-space: normal; }
|
||||
.cal-set-links a .mi { flex: 0 0 16px; color: var(--muted); }
|
||||
.cal-set-links a:hover .mi { color: currentColor; }
|
||||
.cal-books-sep-note { font-size: 12px; font-weight: 400; color: var(--faint); }
|
||||
|
||||
.cal-book-row {
|
||||
display: grid;
|
||||
grid-template-columns: 22px 30px minmax(0, 1fr) auto auto;
|
||||
align-items: center; gap: 10px;
|
||||
padding: 8px 6px; border-radius: 8px;
|
||||
}
|
||||
.cal-book-row:hover { background: var(--line-2); }
|
||||
/* 关掉的本子整行变淡 —— 一眼看出"这本现在不显示",
|
||||
但**不 disable**:点一下就能重新勾上(disable 会让人以为"这行坏了") */
|
||||
.cal-book-row.is-off .cal-book-name,
|
||||
.cal-book-row.is-off .cal-book-dot,
|
||||
.cal-book-row.is-off .cp-trigger-dot { opacity: .45; }
|
||||
|
||||
.cal-book-show { display: inline-flex; align-items: center; cursor: pointer; }
|
||||
.cal-book-show input { accent-color: var(--brand); width: 16px; height: 16px; cursor: pointer; }
|
||||
|
||||
.cal-book-dot {
|
||||
display: inline-block; width: 13px; height: 13px; border-radius: 3px;
|
||||
border: 1px solid var(--line); justify-self: center; flex: 0 0 auto;
|
||||
}
|
||||
.cal-book-name { font-size: 14px; font-weight: 500; overflow: hidden; text-overflow: ellipsis; }
|
||||
|
||||
.cal-book-tags { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
|
||||
.cal-owner { font-size: 12.5px; color: var(--muted); white-space: nowrap; }
|
||||
.node-badge-quiet { opacity: .7; }
|
||||
/* 可写 / 只读两个徽标要**一眼能分**:可写用品牌色,只读用中性灰。
|
||||
⚠️ 别用"同色深浅"区分 —— 用户要的正是在列表里快速扫出"哪些我能动"。 */
|
||||
.node-badge.is-write { background: var(--brand-soft, rgba(74, 124, 130, .12)); color: var(--brand-ink, var(--brand)); }
|
||||
.node-badge.is-read { background: var(--line-2); color: var(--muted); }
|
||||
|
||||
.cal-book-acts { display: inline-flex; align-items: center; gap: 12px; flex-wrap: wrap; justify-content: flex-end; }
|
||||
.cal-book-acts .link-quiet { background: none; border: 0; padding: 0; cursor: pointer; font: inherit; font-size: 13px; }
|
||||
.cal-book-acts .link-quiet:hover { color: var(--brand); text-decoration: underline; }
|
||||
.cal-book-acts .link-danger:hover { color: var(--danger, #C0533F); }
|
||||
.cal-book-acts .inline-form { display: inline; margin: 0; }
|
||||
|
||||
/* 已共享给谁:第二行,靠名字下方 */
|
||||
.cal-book-shares {
|
||||
grid-column: 3 / -1; display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
|
||||
margin-top: 4px; font-size: 12.5px; color: var(--muted);
|
||||
}
|
||||
.cal-book-shares-label { color: var(--faint); }
|
||||
.cal-book-shares .inline-form { display: inline; margin: 0; }
|
||||
.cal-book-shares .link-quiet { background: none; border: 0; padding: 0; cursor: pointer; font: inherit; font-size: 12.5px; }
|
||||
.cal-book-shares .link-danger:hover { color: var(--danger, #C0533F); }
|
||||
|
||||
@media (max-width: 640px) {
|
||||
/* 窄屏:勾选+色块+名字+归属 一行,操作另起一行靠右 */
|
||||
.cal-book-row { grid-template-columns: 22px 26px minmax(0, 1fr); row-gap: 6px; }
|
||||
.cal-book-tags { grid-column: 3 / -1; }
|
||||
.cal-book-acts { grid-column: 1 / -1; justify-content: flex-start; padding-left: 2px; }
|
||||
.cal-book-shares { grid-column: 1 / -1; }
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
v72:内置调色器(替代 `<input type="color">`,不再弹 Windows 系统取色框)
|
||||
----------------------------------------------------------------------------
|
||||
用户原话:「选颜色那个地方点了之后是弹出 Windows 的一个颜色选择框,这个不好,
|
||||
我们把它改成内置的,就是就是在网页上弹出一个模态框或者一个什么样的,
|
||||
然后选颜色,不要弹 Windows 的,那个一个体验也不好,另外一个也不好看。」
|
||||
========================================================================== */
|
||||
.cp-field { display: inline-flex; align-items: center; }
|
||||
|
||||
/* 触发按钮:小色块 + hex 值,长得像"一个可点的胶囊"而不是原生控件 */
|
||||
.cp-trigger {
|
||||
display: inline-flex; align-items: center; gap: 7px;
|
||||
padding: 3px 9px 3px 4px; border: 1px solid var(--line); border-radius: 999px;
|
||||
background: var(--surface); cursor: pointer; font: inherit; color: var(--ink);
|
||||
transition: border-color .15s, box-shadow .15s;
|
||||
}
|
||||
.cp-trigger:hover { border-color: var(--brand); }
|
||||
.cp-trigger:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
|
||||
.cp-trigger-dot {
|
||||
width: 18px; height: 18px; border-radius: 50%; flex: 0 0 auto;
|
||||
border: 1px solid rgba(0, 0, 0, .12);
|
||||
}
|
||||
.cp-trigger-hex {
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
||||
font-size: 11.5px; color: var(--muted); letter-spacing: .3px;
|
||||
}
|
||||
/* 行内(日历本清单里)那个调色器更紧凑一点,别把行撑高 */
|
||||
.cal-book-row .cp-trigger { padding: 2px 4px; border-color: transparent; background: transparent; }
|
||||
.cal-book-row .cp-trigger:hover { border-color: var(--line); background: var(--surface); }
|
||||
.cal-book-row .cp-trigger-hex { display: none; }
|
||||
.cal-book-row .cp-trigger-dot { width: 15px; height: 15px; }
|
||||
|
||||
/* 模态框:与 .cal-modal 同一套"遮罩 + 居中面板",但独立命名
|
||||
—— 它可能在**没有日历**的页面上也用(影院管理等),别跟日历耦合。 */
|
||||
.cp-modal {
|
||||
position: fixed; inset: 0; z-index: 2000;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
padding: 16px; background: var(--mask, rgba(20, 24, 26, .42));
|
||||
}
|
||||
.cp-modal[hidden] { display: none; }
|
||||
.cp-modal-panel {
|
||||
width: min(420px, 100%); max-height: calc(100vh - 48px);
|
||||
display: flex; flex-direction: column;
|
||||
background: var(--surface); border-radius: 14px;
|
||||
box-shadow: 0 18px 48px rgba(0, 0, 0, .22);
|
||||
}
|
||||
.cp-modal-head {
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
padding: 14px 16px 10px; font-size: 15px;
|
||||
}
|
||||
.cp-modal-body { padding: 0 16px 4px; overflow-y: auto; }
|
||||
.cp-modal-foot {
|
||||
display: flex; gap: 10px; justify-content: flex-end;
|
||||
padding: 12px 16px 16px;
|
||||
}
|
||||
|
||||
/* 大预览块:让用户看到"日程条上白字压在这个颜色上"的真实效果 */
|
||||
.cp-preview {
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
height: 62px; padding: 0 14px; border-radius: 10px; background: #4A7C82;
|
||||
color: #fff; transition: background .12s;
|
||||
}
|
||||
.cp-preview-chip { font-size: 13.5px; font-weight: 600; }
|
||||
.cp-preview-hex {
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
||||
font-size: 12px; opacity: .8;
|
||||
}
|
||||
|
||||
.cp-swatches {
|
||||
display: grid; grid-template-columns: repeat(8, 1fr);
|
||||
gap: 8px; margin: 14px 0 12px;
|
||||
}
|
||||
.cp-swatch {
|
||||
aspect-ratio: 1 / 1; border-radius: 8px; border: 2px solid transparent;
|
||||
cursor: pointer; padding: 0; transition: transform .12s, border-color .12s;
|
||||
}
|
||||
.cp-swatch:hover { transform: scale(1.08); }
|
||||
/* 选中态:白环 + 深色外环,任何底色上都看得见(只用深色环时,
|
||||
深色块上的环就"消失"了 —— 那正是"点了没反应"的观感来源之一) */
|
||||
.cp-swatch.active {
|
||||
border-color: var(--surface);
|
||||
box-shadow: 0 0 0 2px var(--ink);
|
||||
}
|
||||
.cp-swatch:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
|
||||
|
||||
.cp-custom { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding-bottom: 8px; }
|
||||
.cp-custom label { font-size: 13px; color: var(--muted); }
|
||||
.cp-hash { font-family: ui-monospace, monospace; color: var(--faint); }
|
||||
.cp-hex-input { width: 96px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; text-transform: uppercase; }
|
||||
.cp-hex-input.is-bad { border-color: var(--danger, #C0533F); }
|
||||
.cp-bad { font-size: 12px; color: var(--danger, #C0533F); }
|
||||
|
||||
/* 改色成功/失败的小浮条 */
|
||||
.cp-toast {
|
||||
position: fixed; left: 50%; bottom: 28px; transform: translateX(-50%);
|
||||
z-index: 2100; padding: 9px 16px; border-radius: 999px;
|
||||
background: var(--ink); color: var(--surface); font-size: 13px;
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, .2);
|
||||
transition: opacity .3s, transform .3s;
|
||||
}
|
||||
.cp-toast.is-err { background: var(--danger, #C0533F); }
|
||||
.cp-toast.is-out { opacity: 0; transform: translateX(-50%) translateY(6px); }
|
||||
|
||||
/* 模态框开着时锁住背景滚动(否则鼠标滚轮会滚到背后的长清单) */
|
||||
body.cp-lock { overflow: hidden; }
|
||||
|
||||
/* 点了日历空白处就建日程(能力保留,见 templates/calendar/index.php 的 data-new-at)。
|
||||
🔴 v48(用户 2026-10-14 第 3 条):「现在鼠标放在视图上时,变成了一个十字。
|
||||
|
||||
Reference in New Issue
Block a user