首页改造:概述跳锚点、主题色、详情卡、点击响应 (#59 #60 #61 #62 #63 #64 #65)

#59 概述四格数字可点击跳锚点
- 加 Scroller + yEvents/yTasks 坐标字段
- 两个区块挂 onAreaChange 记录 y 偏移
- FbStatCell 加 onTap(整格热区,不是只有数字两个小字)
- 今天日程 -> 今天日程区块;在做/任务/逾期 -> 近期任务区块
  (三者都是任务状态计数,点哪个都是想去看任务,让"逾期"单独跳
    一个不存在的"逾期列表"是骗人的)
- 概述数字本来就来自 d.stat.*(接口真实数据),无需改

#60 各区块标题用模块主题色 + 新建改胶囊按钮
- FbSectionTitle 加 accent 参数(默认空 = 保持原灰,老调用点不动)
- 标题有主题色时加粗一档(光换色辨识度不够)
- 新建从文字链接改成胶囊按钮:底色主题色、白字、全圆角
- 6 处调用点分别传 calAccent/taskAccent/daysAccent/moviesAccent/peopleAccent

#61 全天日程与下方白块无间距
- FbDayTimeline 全天块 bottom padding 6 -> 12
- 6vp 在全天色块实心背景下几乎看不出缝;12 才有明显呼吸
- 与 Column(space:4) 的行间距形成「行内紧、块间松」层次

#62/#63/#64/#65 四个区块加"先看后改"详情卡
根因:5 个 @Builder 全都没有 onClick(memoryRow/movieRow/recentDayRow/
personTile 各自 0 个),所以用户"点了没反应"。

- 新增状态:mvDetail/mvDetailLoading/mvDetailError/mvSeed/pfDetail/
  dayDetail/memDetail,全部计入 sheetCount(否则按返回键直接退出页面)
- openMovieDetail 照 FbMoviesPage.openDetail 的成熟写法用
  FbMovieRepo.inst().detail(),不自己拼接口(parseMovieDetail 不导出)
- 复用三张现成卡:FbMovieDetailSheet / FbPersonSheet / FbDayEditSheet
- 往年今天按 kind 分发:movie 走电影卡;trip_node 拿不到 tripId
  ⇒ 退回通用摘要卡(弹错类型的卡比不弹更糟)
- memorySheet 用 FbSheetRing 就地画,内容可滚动(用户"滑下去看信息")

联系人头像本来就有(personTile 里 if (p.avatar !== "") 分支),无需改。
This commit is contained in:
2026-11-05 13:43:03 +08:00
parent aafd83b130
commit c11548cb51
4 changed files with 477 additions and 14 deletions
@@ -443,7 +443,12 @@ export struct FbDayTimeline {
}, (e: FbCalEvent): string => 'al_' + FbTimelineUtil.keyOf(e))
}
.width('100%')
.padding({ bottom: 6 })
/* #61(用户 2026-11-05):「全天日程…跟下面那个白色的块是上边齐平的,
这样视觉效果很不好…它们之间有几个像素的空隙。」
原 6vp 在全天色块的实心背景下面几乎看不出缝,视觉上像贴着下边框。
加到 12:与 Column(space:4) 的行间距形成「行内紧、块间松」的层次。 */
.padding({ bottom: 12 })
}
// ---- 时间轴主体 ----
@@ -41,6 +41,19 @@ export struct FbStatCell {
*/
@Param alarm: boolean = false;
/**
* 点了这一格(#59)。
*
* 🔴 用户 2026-11-05:「点击上面这几个数字的时候,要滑到首页上的
* 对应位置,也就是锚点处…它是有作用的,不只是一个数字。」
*
* ⚠️ 默认空实现 ⇒ 老调用点(没有任何点击需求的地方)一行都不用改。
* ⚠️ 点击热区:整格(`layoutWeight(1)` + `height('100%')`),
* 不是只有数字那两个字 —— 手指点不准小字号。
*/
@Event onTap: () => void = (): void => {
};
build() {
Column({ space: 2 }) {
Text(this.value.toString())
@@ -54,5 +67,9 @@ export struct FbStatCell {
}
.layoutWeight(1)
.alignItems(HorizontalAlign.Center)
/* #59:整格可点(热区 = 整个格子,不是只有数字那两个小字) */
.onClick((): void => {
this.onTap();
})
}
}
+40 -7
View File
@@ -168,12 +168,34 @@ export struct FbSectionTitle {
@Event onAdd: () => void = (): void => {
};
/**
* 区块的**模块主题色**(#60)。
*
* 🔴 用户 2026-11-05:「"今天的日程",既然是日程,标题颜色就应该用日程的
* 主题色。11条后边"新建"的地方变成一个按钮,按钮颜色也是主题色。」
* 「下面的"近期任务"改法跟上面一样,还有"最近纪念日"也不说了,全都是一样的。」
*
* ⇒ 标题与「新建」按钮都用这个色。
*
* ⚠️ **空串 = 保持原来的灰色**(老调用点不受影响):
* 本组件被首页 4 个区块 + 日程页 + 任务页 + 资源页等多处引用,
* 改签名会波及所有调用点;`@Param` 带默认值则老调用点一行都不用改。
* ⚠️ 调用方**不要硬编码色值**,从模块设定取(用户可能在"模块设置"里改色)。
*/
@Param accent: string = '';
/** 标题实际用的颜色:有 accent 用之,否则退回原来的 muted 灰 */
private titleColor(): string {
return this.accent !== '' ? this.accent : '#8A7A6D';
}
build() {
Row() {
Text(this.title)
.fontSize(FbMetric.fontSmall)
.fontWeight(FontWeight.Medium)
.fontColor(FbColors.muted)
/* #60:有主题色时加粗一档 —— 光换色在浅色背景上辨识度不够 */
.fontWeight(this.accent !== '' ? FontWeight.Bold : FontWeight.Medium)
.fontColor(this.titleColor())
.letterSpacing(0.6)
if (this.extra.length > 0) {
Blank()
@@ -186,14 +208,25 @@ export struct FbSectionTitle {
if (this.extra.length === 0) {
Blank()
}
/* 🔴 #60(用户 2026-11-05):「11条后边"新建"的地方变成一个按钮,
按钮颜色也是主题色。」
改前:纯文字 + brand 色 ⇒ 看着像链接,不醒目。
改后:**胶囊按钮** —— 底色 = 模块主题色(无 accent 时退回 brand),
文字白色,圆角全圆。
⚠️ 点击热区:胶囊本身 + `padding` 撑到约 44vp 高。
原来靠 `padding({top:12,bottom:12})` 撑热区,现在胶囊有实体高度,
热区天然够大,不必再叠大 padding。
⚠️ `FbColors` 里**没有** `accent` 字段(编译会报
"Property 'accent' does not exist")⇒ 用本组件的 `this.accent`。 */
Text(this.addText)
.fontSize(FbMetric.fontTiny)
/* ⚠️ 用 `FbColors.brand`(品牌砖红),不是 `accent` ——
`FbColors` 里**没有** `accent` 这个字段(编译会报
"Property 'accent' does not exist")。 */
.fontColor(FbColors.brand)
.fontColor('#FFFFFF')
.fontWeight(FontWeight.Medium)
.padding({ left: 10, right: 2, top: 12, bottom: 12 })
.padding({ left: 10, right: 10, top: 5, bottom: 5 })
.backgroundColor(this.accent !== '' ? this.accent : '#A84A28')
.borderRadius(999)
.onClick((): void => {
this.onAdd();
})