From fd66c529c2e037290d6d6dded361e6db4d89f336 Mon Sep 17 00:00:00 2001 From: "jif2.zhang" Date: Sun, 25 Oct 2026 18:38:16 +0800 Subject: [PATCH] =?UTF-8?q?fix(V0.2):=20=E6=99=BA=E8=83=BD=E6=88=AA?= =?UTF-8?q?=E6=96=AD=E5=8E=BB=E5=B0=BE=E9=83=A8=E6=A0=87=E7=82=B9;=20?= =?UTF-8?q?=E7=9C=8B=E6=9D=BF=E5=B7=A6=E5=88=97=E6=94=B6=E7=AA=84;=20?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E5=A4=B4=E5=83=8F=E4=B8=89=E5=A4=84=E7=BB=9F?= =?UTF-8?q?=E4=B8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - splitTitle: 截断后用 \p{P} 去掉标题尾部连续分隔符 (原字符类重组有 转义坑, 换 Unicode 属性类) - 看板卡片左列 (状态点+⋯) 收窄至 14px 并负外距悬进卡片内边距 - 项目头像统一: 新增 .pavatar 基类与 projectIcon.colorOfProject, 项目管理预览改用同配色/同圆角/居中首字, 修复灰底与文字歪斜 --- src/components/task/RecentProjects.jsx | 5 ++--- src/pages/task/ProjectManage.jsx | 11 +++++++---- src/pages/task/TaskPage.jsx | 5 ++--- src/pages/task/projectIcon.js | 4 ++++ src/pages/task/quickAdd.js | 5 ++++- src/styles/globals.css | 11 ++++++++++- 6 files changed, 29 insertions(+), 12 deletions(-) create mode 100644 src/pages/task/projectIcon.js diff --git a/src/components/task/RecentProjects.jsx b/src/components/task/RecentProjects.jsx index da6bc18..09ad746 100644 --- a/src/components/task/RecentProjects.jsx +++ b/src/components/task/RecentProjects.jsx @@ -1,12 +1,11 @@ import { useEffect, useMemo, useRef, useState } from 'react' import { getRecentIds, getRecentOrder, setRecentOrder } from '../../pages/task/prefs.js' +import { colorOfProject } from '../../pages/task/projectIcon.js' // 首屏最近项目条 (T-VW-08/10) // - 展示最近使用的 3 个项目 + 「更多项目」入口 // - 顺序: 手动排序(recentOrder)优先, 其次最近访问(recentIds), 兜底列表顺序 // - 长按卡片 300ms 进入拖拽态, 水平拖动实时换位, 松手持久化(设备端) -const COLORS = ['#1677ff', '#00b578', '#ff8f1f', '#a855f7', '#14b8a6', '#f43f9e'] -const colorOf = (id) => COLORS[Math.abs(id) % COLORS.length] const LONG_PRESS = 300 const MOVE_TOLERANCE = 8 @@ -127,7 +126,7 @@ export default function RecentProjects({ projects, currentId, onSelect, onMore } className="rp-ico" style={p.icon ? { background: `url(${p.icon}) center/cover no-repeat` } - : { background: colorOf(p.id) }} + : { background: colorOfProject(p) }} > {p.icon ? '' : (p.name || '?').slice(0, 1)} diff --git a/src/pages/task/ProjectManage.jsx b/src/pages/task/ProjectManage.jsx index 6fa6493..6cc4ed3 100644 --- a/src/pages/task/ProjectManage.jsx +++ b/src/pages/task/ProjectManage.jsx @@ -7,6 +7,7 @@ import useOverlayBack from '../../hooks/useOverlayBack.js' import ColumnSettings from './ColumnSettings.jsx' import ProjectMembers from './ProjectMembers.jsx' import { DEFAULT_KINDS, kindColor } from './kind.js' +import { colorOfProject } from './projectIcon.js' // 项目管理 (T-PJ-11/12): 成员 / 看板列 / 项目信息 三个分区的统一入口 // onExited: 项目被删除/退出/归档后, 上层应离开该项目(回落个人默认项目) @@ -270,11 +271,13 @@ export default function ProjectManage({ project, onClose, onChanged, onExited })
项目图标
diff --git a/src/pages/task/TaskPage.jsx b/src/pages/task/TaskPage.jsx index ae49d65..cc230c0 100644 --- a/src/pages/task/TaskPage.jsx +++ b/src/pages/task/TaskPage.jsx @@ -126,8 +126,7 @@ export default function TaskPage() { ) } -const COLORS = ['#1677ff', '#00b578', '#ff8f1f', '#a855f7', '#14b8a6', '#f43f9e'] -const colorOf = (p) => COLORS[Math.abs(p.id) % COLORS.length] +import { colorOfProject } from './projectIcon.js' const LONG_PRESS = 300 const MOVE_TOLERANCE = 8 @@ -290,7 +289,7 @@ function ProjectList({ projects, err, onRetry, onOpen, onChanged, createSignal, className="pico" style={p.icon ? { background: `url(${p.icon}) center/cover no-repeat` } - : { background: colorOf(p) }} + : { background: colorOfProject(p) }} > {p.icon ? '' : (p.name || '?').slice(0, 1)}
diff --git a/src/pages/task/projectIcon.js b/src/pages/task/projectIcon.js new file mode 100644 index 0000000..b1e7b49 --- /dev/null +++ b/src/pages/task/projectIcon.js @@ -0,0 +1,4 @@ +// 项目头像配色: 项目列表 / 最近项目 / 项目管理 三处共用, 保证观感一致 +export const PROJECT_COLORS = ['#1677ff', '#00b578', '#ff8f1f', '#a855f7', '#14b8a6', '#f43f9e'] + +export const colorOfProject = (p) => PROJECT_COLORS[Math.abs(p.id) % PROJECT_COLORS.length] diff --git a/src/pages/task/quickAdd.js b/src/pages/task/quickAdd.js index 1bc71b6..359275e 100644 --- a/src/pages/task/quickAdd.js +++ b/src/pages/task/quickAdd.js @@ -16,7 +16,10 @@ export function splitTitle(raw) { if (SEPARATOR.test(text[i - 1])) { cut = i; break } } if (cut < 0) cut = MAX_TITLE - return { title: text.slice(0, cut).trim(), desc: text } + // 截断落在分隔符上: 分隔符留在标题末尾很难看, 去掉尾部连续分隔符/空白 + // (\p{P} 覆盖中英文全部标点; 之前用 SEPARATOR.source 重组字符类有转义坑) + const title = text.slice(0, cut).replace(/[\s\p{P}]+$/u, '').trim() + return { title, desc: text } } // 时间词 → 日期 (返回 YYYY-MM-DD): diff --git a/src/styles/globals.css b/src/styles/globals.css index 9e1efc9..b623ef1 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -985,6 +985,12 @@ body.me-safe-top .app-safe-top { height: 0; } width: 34px; height: 34px; border-radius: 9px; display: flex; align-items: center; justify-content: center; color: #fff; font-size: 14px; font-weight: 700; flex-shrink: 0; } +/* 项目头像基类 (不依赖 .proj-item 作用域): 项目管理编辑页预览等裸用场景 */ +.pavatar { + display: flex; align-items: center; justify-content: center; + color: #fff; font-weight: 700; flex-shrink: 0; + background-size: cover; background-position: center; background-repeat: no-repeat; +} .proj-item .pmain { flex: 1; min-width: 0; } .proj-item .ptitle { font-size: 14.5px; font-weight: 600; display: flex; align-items: center; gap: 6px; @@ -1085,11 +1091,14 @@ body.me-safe-top .app-safe-top { height: 0; } box-shadow: 0 1px 2px rgba(0,0,0,.05); cursor: pointer; flex-shrink: 0; display: flex; gap: 7px; align-items: flex-start; } -/* 左侧竖排操作列: 状态点在上, ⋯ 沉到左下角 */ +/* 左侧竖排操作列: 状态点在上, ⋯ 沉到左下角; 负外距悬进卡片内边距, 少占横向空间 */ .bcard-left { display: flex; flex-direction: column; align-items: center; flex-shrink: 0; align-self: stretch; justify-content: space-between; padding: 1px 0 2px; + margin: 0 -5px; width: 14px; } +.bcard-left .bstat { padding: 0; } +.bcard-left .bmore-btn { font-size: 12px; padding: 0; line-height: 1.1; } .bcard-body { flex: 1; min-width: 0; } .bcard.hl { outline: 2px solid var(--color-primary); outline-offset: 1px; } .brow1 { display: flex; align-items: flex-start; gap: 6px; }