From 28c6e674ba402462e3cfebe9a26121a943c0f963 Mon Sep 17 00:00:00 2001 From: laoyang Date: Thu, 5 Nov 2026 19:41:14 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E9=9D=A2=E6=9D=BF=EF=BC=9A?= =?UTF-8?q?=E5=8E=BB=E6=8E=89=E5=B7=A6=E4=B8=8A=E5=9C=86=E5=9C=88=E3=80=81?= =?UTF-8?q?=E6=A0=87=E9=A2=98=E4=B8=8B=E7=A7=BB=E6=88=90=E5=8F=AF=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E7=9A=84=E3=80=8C=E4=BB=BB=E5=8A=A1=E6=A0=87=E9=A2=98?= =?UTF-8?q?=E3=80=8D(#77)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用户 2026-11-05:「还是不对,这个弹出框的标题是编辑任务,台式机采购这样的 东西,它是一个标题,也应该可以被修改才对。所以它应该往下放,就是任务标题; 然后台式机采购计划也往下放,也是可以修改的。左上角那个标志,好像一个圆圈 什么的,那个也不要了,去掉。」 ① 删掉左上角的 FbCheckCircle("圆圈") 它是"点一下勾完成"的快捷入口,但下面「状态」区已经有三个明确的 chip, 入口重复。而且它紧贴标题左侧,视觉上像"标题前面的项目符号", 反而让人以为标题前面该有个图标。 ② 大标题从顶栏下移到「更多信息」区,成为第一项「任务标题」 原来标题画在 headBar 里,所以它是**只读**的 —— 而标题本来就该能改。 现在与截止/负责人/备注同形态:标题行 + 控件行, 点一下变成 TextArea(height 64、字号 fontTitle 17、主题色), 失焦自动保存(与备注同一套交互,不设保存按钮)。 ⚠️ 空标题不发请求:服务端会清洗成空串,等于把标题删了。 ⚠️ `saveField(title, ...)` 走的是既有 PATCH —— 服务端 ApiHandler 对未提交字段回退原值,所以只传 title 不会把 note/due_at 抹掉。 ③ headBar 只剩「状态徽标 + 关闭」,左端放「属于「父任务」」 父任务那行保留在顶栏不跟着下移:它是上下文不是内容, 跟标题走反而离"父任务"这个概念更远。 没有父任务时用 Blank() 占位,保证徽标和关闭仍在右边。 ④ 完成态标题仍是 faint + 删除线(不上主题色) 删除线是"这件事已经过去了"的信号,再上主题色会和待办标题一样抢眼。 编译通过,已装真机。 --- entry/src/main/ets/components/FbTaskPanel.ets | 145 +++++++++++++----- 1 file changed, 104 insertions(+), 41 deletions(-) diff --git a/entry/src/main/ets/components/FbTaskPanel.ets b/entry/src/main/ets/components/FbTaskPanel.ets index 8299e8b..be77e77 100644 --- a/entry/src/main/ets/components/FbTaskPanel.ets +++ b/entry/src/main/ets/components/FbTaskPanel.ets @@ -121,6 +121,10 @@ export struct FbTaskPanel { 交互(那几处都是点一下就生效)。这里多一颗按钮反而不一致。 */ @Local duePickOpen: boolean = false; @Local attPickOpen: boolean = false; + /* #77l:「任务标题」也做成可编辑(用户 2026-11-05: + 「台式机采购计划也往下放,也是可以修改的」) */ + @Local titleEdit: boolean = false; + @Local titleDraft: string = ''; @Local noteEdit: boolean = false; @Local noteDraft: string = ''; @Local inlineBusy: boolean = false; @@ -374,6 +378,19 @@ export struct FbTaskPanel { } /** 保存备注(失焦/回车时触发) */ + /** 保存任务标题(#77l) */ + private async saveTitle(): Promise { + if (!this.titleEdit) { + return; + } + this.titleEdit = false; + const v: string = this.titleDraft.trim(); + if (v === '' || v === this.titleOf()) { + return; // 空标题不发请求(服务端也会清洗成空,等于把标题删了) + } + await this.saveField('title', v, -1); + } + private async saveNote(): Promise { if (!this.noteEdit) { return; @@ -958,50 +975,39 @@ export struct FbTaskPanel { .hitTestBehavior(HitTestMode.Transparent) } - /** 标题行:状态圈(点=勾完成)+ 标题 + 状态徽标 + 关闭 */ + /** + * 顶栏:状态徽标 + 关闭。 + * + * 🔴🔴 #77l(用户 2026-11-05): + * 「这个弹出框的标题是编辑任务,台式机采购这样的东西,它是一个标题, + * 也应该可以被修改才对。所以它应该往下放,就是任务标题; + * 然后台式机采购计划也往下放,也是可以修改的。 + * 左上角那个标志,好像一个圆圈什么的,那个也不要了,去掉。」 + * + * 三处变化: + * · **删掉左上角的 FbCheckCircle**(就是用户说的"圆圈")。它是"点一下勾完成" + * 的快捷入口,但下面「状态」区已经有三个明确的 chip,入口重复; + * 而且它紧贴标题,看起来像"标题前面的项目符号",容易误解。 + * · **删掉这里的大标题**。原来标题画在这里,导致它是只读的 —— + * 标题本来就该能改,所以下移到「更多信息」区当第一个字段。 + * · 只留状态徽标 + 关闭按钮,这一条变窄(原来 30+标题+徽标+关闭很挤)。 + * + * ⚠️ 「属于「父任务」」那行**保留在这里**:它是上下文不是内容, + * 跟着标题下移反而会离"父任务"这个概念更远。 + */ @Builder headBar() { Row({ space: 10 }) { - Stack({ alignContent: Alignment.Center }) { - FbCheckCircle({ - dia: 18, - done: this.isDone(), - doing: this.statusOf() === 'doing', - color: this.accent - }) + if (this.parentOf() !== '') { + Text('属于「' + this.parentOf() + '」') + .fontSize(FbMetric.fontTiny) + .fontColor(FbColors.faint) + .maxLines(1) + .layoutWeight(1) + .flexShrink(1) + } else { + Blank() } - .width(30) - .height(30) - .onClick((): void => { - this.setStatus(this.isDone() ? 'todo' : 'done'); - }) - - Column({ space: 2 }) { - /* 🔴 #77k(用户 2026-11-05):「上面"台式机采购计划"这样的标题, - 应该是主题的颜色。」 - ⚠️ 完成态仍用 faint + 删除线:那条是"这件事已经过去了"的信号, - 再上主题色会和"待办"的标题一样抢眼,反而分不出轻重。 */ - Text(this.titleOf()) - .fontSize(FbMetric.fontTitle) - .fontWeight(FontWeight.Bold) - .fontColor(this.isDone() ? FbColors.faint : this.accent) - .decoration({ - type: this.isDone() ? TextDecorationType.LineThrough : TextDecorationType.None, - color: FbColors.faint - }) - .maxLines(2) - .width('100%') - if (this.parentOf() !== '') { - Text('属于「' + this.parentOf() + '」') - .fontSize(FbMetric.fontTiny) - .fontColor(FbColors.faint) - .maxLines(1) - .width('100%') - } - } - .alignItems(HorizontalAlign.Start) - .layoutWeight(1) - .flexShrink(1) Text(this.statusWord(this.statusOf())) .fontSize(FbMetric.fontTiny) @@ -1018,7 +1024,7 @@ export struct FbTaskPanel { }) } .width('100%') - .alignItems(VerticalAlign.Top) + .alignItems(VerticalAlign.Center) } /** 状态三段(点一下即改,没有"保存"按钮) */ @@ -1180,6 +1186,63 @@ export struct FbTaskPanel { 不给高度的话,「设置…」「未指定」这类短文字会把框压扁, 几行之间的间距就会参差不齐。 */ Column({ space: 14 }) { + /* ---- 任务标题(可编辑,#77l 从顶栏下移到这里)---- */ + Column({ space: 6 }) { + this.fieldLb('任务标题') + if (this.titleEdit) { + TextArea({ text: this.titleDraft, placeholder: '要做的事…' }) + .placeholderColor(FbColors.faint) + .placeholderFont({ size: FbMetric.fontTiny }) + .fontSize(FbMetric.fontTitle) + .fontColor(this.accent) + .backgroundColor(FbColors.inputBg) + .borderRadius(FbMetric.radiusS) + .width('100%') + .height(64) + .padding({ left: 12, right: 12, top: 10, bottom: 10 }) + .onChange((v: string): void => { + this.titleDraft = v; + }) + /* 失焦保存 —— 与备注同一套(用户改完直接点别处是最自然的动作, + 让他再去找"保存"就会以为没存上)。 */ + .onBlur((): void => { + this.saveTitle(); + }) + } else { + Row({ space: 8 }) { + Text(this.titleOf()) + .fontSize(FbMetric.fontTitle) + .fontWeight(FontWeight.Bold) + .fontColor(this.isDone() ? FbColors.faint : this.accent) + .decoration({ + type: this.isDone() ? TextDecorationType.LineThrough : TextDecorationType.None, + color: FbColors.faint + }) + .maxLines(3) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .layoutWeight(1) + Text('✎') + .fontSize(FbMetric.fontTiny) + .fontColor(this.inlineBusy ? FbColors.faint : this.accent) + } + .width('100%') + .constraintSize({ minHeight: 44 }) + .padding({ left: 12, right: 12, top: 11, bottom: 11 }) + .backgroundColor(FbColors.inputBg) + .borderRadius(FbMetric.radiusS) + .alignItems(VerticalAlign.Top) + .onClick((): void => { + if (this.titleEdit || this.inlineBusy) { + return; + } + this.titleDraft = this.titleOf(); + this.titleEdit = true; + }) + } + } + .width('100%') + .alignItems(HorizontalAlign.Start) + /* ---- 截止 ---- */ Column({ space: 6 }) { this.fieldLb('截止')