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; }