纪念日编辑框:五项文案与形态调整 (#91)
用户 2026-11-05 五点:
「只记"几月几号,每年自动提醒"这句话,把它去掉。」
「"叫什么"不应该这么叫,应该换成"纪念日"标题。」
「"按什么重复"也太复杂了,就写"重复"。」
「日期右边为什么有个箭头呢?不要。」
「分类这个地方平铺。关联人这个地方也显示出来:
这个人已经关联的人是谁?名字、头像。」
① 删掉副标题「只记几月几号,每年自动提醒」
标题已经说清这是纪念日,副标题在解释"格式",用户不需要看第二遍。
② 「叫什么」→「纪念日」
③ 「按什么重复」→「重复」
④ 日期行去掉右侧 ›
`FbDateTimeRow` 内部的 `›` 是**写死的**(给"点开会选"的暗示)。
不用它、改成手画一个与其它字段同形态的框(40 高 / inputBg / radiusS):
⚠️ 不动那个组件:它还有自己的标签行、42 高、箭头,三样都与本框不一致;
硬改成参数化会波及任务/日程/观影几处的用法。
⚠️ 点击整框(不只文字)都能开选择器 —— Row 的 onClick。
⑤ 分类改平铺
横滑 Scroll → `Flex(wrap: FlexWrap.Wrap)`,全部一眼看全。
⚠️ 不能用 Row:ArkUI 的 Row 不换行,塞不下会横向溢出
(任务面板看板 chips 踩过:最后一个被裁掉且点不到)。
⚠️ Flex 里 `space` 不生效 ⇒ 间距靠 chip 自己的 margin。
⑥ 关联人改成「头像 + 名字」chips
改前:一行纯文字(「张三、李四」/「全家的事」)
改后:换行平铺的 chips,每个 = 24vp 头像 + 名字
一个都没关联时显示「全家的事」框;下面单独一颗「+ 指定人 / 更换」按钮
(只点 chips 会让人以为只能取消,看不出能加人 —— 与任务面板
「负责人」那颗「更换」同一手法)。
⚠️ 顺序按 personIds(用户点选顺序)而不是名册顺序,
否则"刚加的人跑到最后去了",看着像没加上。
⚠️ 顺手删掉已无人调用的 peopleText()(520 字符死代码)。
编译通过,已装真机。
This commit is contained in:
@@ -23,6 +23,10 @@ import { FbSheetClose } from './FbSheetClose';
|
|||||||
import { FbSheetRing } from './FbSheetRing';
|
import { FbSheetRing } from './FbSheetRing';
|
||||||
import { FbDateTimeRow, FbDateTimePicker, fbToday } from './FbDateTimeField';
|
import { FbDateTimeRow, FbDateTimePicker, fbToday } from './FbDateTimeField';
|
||||||
import { FbPersonPickSheet } from './FbPersonPickSheet';
|
import { FbPersonPickSheet } from './FbPersonPickSheet';
|
||||||
|
/* #91:关联人 chips 要画头像 / 日期行要格式化中文日期 */
|
||||||
|
import { FbAvatar } from './Widgets';
|
||||||
|
import { fbImageSrc } from '../data/FbAttachQueue';
|
||||||
|
import { fbCnDate } from './FbDateTimeField';
|
||||||
import { FbRosterPerson } from '../data/FbPersonRepo';
|
import { FbRosterPerson } from '../data/FbPersonRepo';
|
||||||
import { FB_TOKEN_STORE } from '../data/FbTokenStore';
|
import { FB_TOKEN_STORE } from '../data/FbTokenStore';
|
||||||
import { createDay, updateDay, deleteDay, FbDayDraft } from '../data/FbDayRepo';
|
import { createDay, updateDay, deleteDay, FbDayDraft } from '../data/FbDayRepo';
|
||||||
@@ -94,20 +98,33 @@ export struct FbDayEditSheet {
|
|||||||
return idx >= 0 && idx < REPEAT_LABELS.length ? REPEAT_LABELS[idx] : REPEAT_LABELS[0];
|
return idx >= 0 && idx < REPEAT_LABELS.length ? REPEAT_LABELS[idx] : REPEAT_LABELS[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 已选的关联人显示名(「全家的事」= 一个都没选) */
|
private token(): string {
|
||||||
private peopleText(): string {
|
return FB_TOKEN_STORE.get();
|
||||||
if (this.personIds.length === 0) {
|
}
|
||||||
return '全家的事';
|
|
||||||
}
|
/**
|
||||||
const names: string[] = [];
|
* 已选的关联人(按 `personIds` 的顺序返回,找不到的跳过)。
|
||||||
|
*
|
||||||
|
* 🔴 #91(用户 2026-11-05):「关联人这个地方也显示出来:这个人已经关联的人
|
||||||
|
* 是谁?名字、头像。」
|
||||||
|
*
|
||||||
|
* ⚠️ 返回**对象数组**而不是名字字符串:调用方要画头像(`avatar`/`avatarColor`)。
|
||||||
|
* ⚠️ 原来还有个 `peopleText()` 生成「张三、李四」这种纯文字串 ——
|
||||||
|
改成 chips 之后**没人用了**,已删。别再写回来:
|
||||||
|
名字串在人多时要靠省略号截断,看不出「关联了几个」。
|
||||||
|
* ⚠️ 顺序按 `personIds`(用户在选人弹窗里的点选顺序),
|
||||||
|
* 不按名册顺序 —— 否则"我刚加的人跑到最后去了",看着像没加上。
|
||||||
|
*/
|
||||||
|
private pickedPeople(): FbRosterPerson[] {
|
||||||
|
const out: FbRosterPerson[] = [];
|
||||||
for (const id of this.personIds) {
|
for (const id of this.personIds) {
|
||||||
const p: FbRosterPerson | undefined =
|
const p: FbRosterPerson | undefined =
|
||||||
this.roster.find((x: FbRosterPerson): boolean => x.id === id);
|
this.roster.find((x: FbRosterPerson): boolean => x.id === id);
|
||||||
if (p !== undefined) {
|
if (p !== undefined) {
|
||||||
names.push(p.shown !== '' ? p.shown : p.name);
|
out.push(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return names.length > 0 ? names.join('、') : ('已选 ' + this.personIds.length.toString() + ' 人');
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 分类清单:预置 + 当前值(老数据里的自定义分类不能丢) */
|
/** 分类清单:预置 + 当前值(老数据里的自定义分类不能丢) */
|
||||||
@@ -176,10 +193,10 @@ export struct FbDayEditSheet {
|
|||||||
.fontWeight(FontWeight.Bold)
|
.fontWeight(FontWeight.Bold)
|
||||||
.fontColor(this.accent)
|
.fontColor(this.accent)
|
||||||
.maxLines(1)
|
.maxLines(1)
|
||||||
Text('只记几月几号,每年自动提醒')
|
/* 🔴 #91(用户 2026-11-05):「只记"几月几号,每年自动提醒"
|
||||||
.fontSize(FbMetric.fontTiny)
|
这句话,把它去掉。」
|
||||||
.fontColor(FbColors.faint)
|
⇒ 删掉。标题已经说清这是纪念日,这行副标题是解释"格式",
|
||||||
.maxLines(1)
|
用户不需要看第二遍。 */
|
||||||
}
|
}
|
||||||
.alignItems(HorizontalAlign.Start)
|
.alignItems(HorizontalAlign.Start)
|
||||||
.layoutWeight(1)
|
.layoutWeight(1)
|
||||||
@@ -210,7 +227,8 @@ export struct FbDayEditSheet {
|
|||||||
Column({ space: 14 }) {
|
Column({ space: 14 }) {
|
||||||
// ---- 名称 ----
|
// ---- 名称 ----
|
||||||
Column({ space: 6 }) {
|
Column({ space: 6 }) {
|
||||||
this.fieldLb('叫什么')
|
/* 🔴 #91:「"叫什么"不应该这么叫,应该换成"纪念日"标题。」 */
|
||||||
|
this.fieldLb('纪念日')
|
||||||
TextInput({ text: this.title, placeholder: '如:结婚纪念日' })
|
TextInput({ text: this.title, placeholder: '如:结婚纪念日' })
|
||||||
.placeholderColor(FbColors.faint)
|
.placeholderColor(FbColors.faint)
|
||||||
.placeholderFont({ size: FbMetric.fontSmall })
|
.placeholderFont({ size: FbMetric.fontSmall })
|
||||||
@@ -231,7 +249,8 @@ export struct FbDayEditSheet {
|
|||||||
|
|
||||||
// ---- 重复方式 ----
|
// ---- 重复方式 ----
|
||||||
Column({ space: 6 }) {
|
Column({ space: 6 }) {
|
||||||
this.fieldLb('按什么重复')
|
/* 🔴 #91:「"按什么重复"也太复杂了,就写"重复"。」 */
|
||||||
|
this.fieldLb('重复')
|
||||||
Row({ space: 8 }) {
|
Row({ space: 8 }) {
|
||||||
ForEach(REPEAT_KEYS, (k: string, idx: number) => {
|
ForEach(REPEAT_KEYS, (k: string, idx: number) => {
|
||||||
Text(this.repeatLabel(idx))
|
Text(this.repeatLabel(idx))
|
||||||
@@ -253,14 +272,28 @@ export struct FbDayEditSheet {
|
|||||||
// ---- 日期 ----
|
// ---- 日期 ----
|
||||||
Column({ space: 6 }) {
|
Column({ space: 6 }) {
|
||||||
this.fieldLb('日期')
|
this.fieldLb('日期')
|
||||||
FbDateTimeRow({
|
/* 🔴 #91(用户 2026-11-05):「日期右边为什么有个箭头呢?不要。」
|
||||||
label: '',
|
`FbDateTimeRow` 内部的 `›` 是写死的(给"点开会选"的暗示),
|
||||||
date: this.pickDate,
|
这里不能用它 —— 改成直接画一个与其它控件同形态的框。
|
||||||
allDay: true,
|
⚠️ 不用 `FbDateTimeRow` 而手画:那个组件还有自己的标签行、
|
||||||
accent: this.accent,
|
42 高、箭头,三样都与本框的字段样式不一致,
|
||||||
onTap: (): void => {
|
硬改组件参数会波及任务/日程/观影那边的用法。
|
||||||
this.pickOpen = true;
|
⚠️ 点击整框(不只是文字)都要能开选择器 —— 用 Row 的 onClick,
|
||||||
}
|
与「截止」「负责人」那些可点行同一手法。 */
|
||||||
|
Row({ space: 8 }) {
|
||||||
|
Text(fbCnDate(this.pickDate))
|
||||||
|
.fontSize(FbMetric.fontSmall)
|
||||||
|
.fontColor(FbColors.ink)
|
||||||
|
.layoutWeight(1)
|
||||||
|
}
|
||||||
|
.width('100%')
|
||||||
|
.height(40)
|
||||||
|
.padding({ left: 12, right: 12 })
|
||||||
|
.backgroundColor(FbColors.inputBg)
|
||||||
|
.borderRadius(FbMetric.radiusS)
|
||||||
|
.alignItems(VerticalAlign.Center)
|
||||||
|
.onClick((): void => {
|
||||||
|
this.pickOpen = true;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
.width('100%')
|
.width('100%')
|
||||||
@@ -269,43 +302,86 @@ export struct FbDayEditSheet {
|
|||||||
// ---- 分类 ----
|
// ---- 分类 ----
|
||||||
Column({ space: 6 }) {
|
Column({ space: 6 }) {
|
||||||
this.fieldLb('分类')
|
this.fieldLb('分类')
|
||||||
Scroll() {
|
/* 🔴 #91(用户 2026-11-05):「分类这个地方平铺。」
|
||||||
Row({ space: 8 }) {
|
⇒ 从横滑改成 **Flex(wrap) 换行平铺**,全部一眼看全。
|
||||||
ForEach(this.kinds(), (k: string) => {
|
⚠️ 不能用 `Row`:ArkUI 的 Row 不换行,塞不下会横向溢出
|
||||||
Text(k)
|
(任务面板的看板 chips 踩过:最后一个被裁掉且点不到)。
|
||||||
.fontSize(FbMetric.fontTiny)
|
⚠️ Flex 里 `space` 不生效 ⇒ 间距靠每个 chip 的 margin。 */
|
||||||
.fontColor(this.kind === k ? '#FFFFFF' : FbColors.muted)
|
Flex({ wrap: FlexWrap.Wrap }) {
|
||||||
.padding({ left: 10, right: 10, top: 6, bottom: 6 })
|
ForEach(this.kinds(), (k: string) => {
|
||||||
.backgroundColor(this.kind === k ? this.accent : FbColors.inputBg)
|
Text(k)
|
||||||
.borderRadius(FbMetric.radiusPill)
|
.fontSize(FbMetric.fontTiny)
|
||||||
.onClick((): void => {
|
.fontColor(this.kind === k ? '#FFFFFF' : FbColors.muted)
|
||||||
// 再点一下 = 取消分类(不分类是合法状态)
|
.padding({ left: 10, right: 10, top: 6, bottom: 6 })
|
||||||
this.kind = this.kind === k ? '' : k;
|
.backgroundColor(this.kind === k ? this.accent : FbColors.inputBg)
|
||||||
})
|
.borderRadius(FbMetric.radiusPill)
|
||||||
}, (k: string): string => 'kd_' + k)
|
.margin({ right: 8, bottom: 8 })
|
||||||
}
|
.onClick((): void => {
|
||||||
.padding({ right: 4 })
|
// 再点一下 = 取消分类(不分类是合法状态)
|
||||||
|
this.kind = this.kind === k ? '' : k;
|
||||||
|
})
|
||||||
|
}, (k: string): string => 'kd_' + k)
|
||||||
}
|
}
|
||||||
.scrollable(ScrollDirection.Horizontal)
|
|
||||||
.scrollBar(BarState.Off)
|
|
||||||
.width('100%')
|
.width('100%')
|
||||||
}
|
}
|
||||||
.width('100%')
|
.width('100%')
|
||||||
.alignItems(HorizontalAlign.Start)
|
.alignItems(HorizontalAlign.Start)
|
||||||
|
|
||||||
// ---- 关联人 ----
|
// ---- 关联人 ----
|
||||||
|
/* 🔴 #91(用户 2026-11-05):「关联人这个地方也显示出来:
|
||||||
|
这个人已经关联的人是谁?名字、头像。」
|
||||||
|
⇒ 从"一行纯文字"改成**头像 + 名字的 chip 列表**,
|
||||||
|
一眼看出关联了谁。一个都没关联时显示「全家的事」(语义同前)。 */
|
||||||
Column({ space: 6 }) {
|
Column({ space: 6 }) {
|
||||||
this.fieldLb('关联人')
|
this.fieldLb('关联人')
|
||||||
Text(this.peopleText())
|
if (this.personIds.length === 0) {
|
||||||
.fontSize(FbMetric.fontSmall)
|
Text('全家的事')
|
||||||
.fontColor(this.personIds.length > 0 ? FbColors.ink : FbColors.muted)
|
.fontSize(FbMetric.fontSmall)
|
||||||
.maxLines(1)
|
.fontColor(FbColors.muted)
|
||||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
.width('100%')
|
||||||
|
.height(40)
|
||||||
|
.padding({ left: 12, right: 12 })
|
||||||
|
.backgroundColor(FbColors.inputBg)
|
||||||
|
.borderRadius(FbMetric.radiusS)
|
||||||
|
.onClick((): void => {
|
||||||
|
this.personPickOpen = true;
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
/* 多个关联人:换行平铺的 chips(同分类的排法) */
|
||||||
|
Flex({ wrap: FlexWrap.Wrap }) {
|
||||||
|
ForEach(this.pickedPeople(), (p: FbRosterPerson) => {
|
||||||
|
Row({ space: 6 }) {
|
||||||
|
FbAvatar({
|
||||||
|
name: p.shown !== '' ? p.shown : p.name,
|
||||||
|
color: p.avatarColor !== '' ? p.avatarColor : this.accent,
|
||||||
|
imageUrl: p.avatar !== '' ? fbImageSrc(p.avatar, this.token()) : '',
|
||||||
|
dia: 24,
|
||||||
|
fontSizeVp: 11
|
||||||
|
})
|
||||||
|
Text(p.shown !== '' ? p.shown : p.name)
|
||||||
|
.fontSize(FbMetric.fontSmall)
|
||||||
|
.fontColor(FbColors.ink)
|
||||||
|
.maxLines(1)
|
||||||
|
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||||
|
.constraintSize({ maxWidth: 110 })
|
||||||
|
}
|
||||||
|
.padding({ left: 4, right: 10, top: 4, bottom: 4 })
|
||||||
|
.backgroundColor(FbColors.inputBg)
|
||||||
|
.borderRadius(FbMetric.radiusPill)
|
||||||
|
.margin({ right: 8, bottom: 8 })
|
||||||
|
}, (p: FbRosterPerson): string => 'pp_' + p.id.toString())
|
||||||
|
}
|
||||||
.width('100%')
|
.width('100%')
|
||||||
.height(40)
|
}
|
||||||
.padding({ left: 12, right: 12 })
|
/* 「更换」入口单独一行:与任务面板「负责人」那颗「更换」按钮同一手法
|
||||||
.backgroundColor(FbColors.inputBg)
|
(chips 本身可点,但只点 chips 会让人以为只能取消,看不出能加人)。 */
|
||||||
.borderRadius(FbMetric.radiusS)
|
Text(this.personIds.length === 0 ? '+ 指定人' : '更换')
|
||||||
|
.fontSize(FbMetric.fontTiny)
|
||||||
|
.fontWeight(FontWeight.Medium)
|
||||||
|
.fontColor(this.accent)
|
||||||
|
.padding({ left: 10, right: 10, top: 6, bottom: 6 })
|
||||||
|
.backgroundColor(fbAlpha(this.accent, 0.10))
|
||||||
|
.borderRadius(FbMetric.radiusPill)
|
||||||
.onClick((): void => {
|
.onClick((): void => {
|
||||||
this.personPickOpen = true;
|
this.personPickOpen = true;
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user