mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-09-22 18:08:04 +00:00
fix(ohos): 设置页插件/工具数不显示 + 聊天自动滚底时机
设置页计数(实测:后端返回 plugins=35/tools=260,卡片却一直显示 '-'): - 根因是 ArkUI 的 @Builder 按值传参是“快照”语义——父组件因 @StorageProp 变化重渲染时不会用新值重跑 builder,数值永远停在 首次渲染的 0。把 KPI 小卡从 @Builder 方法改为独立 @Component (@Prop 单向下发),父组件重渲染时子组件拿到新值并重绘。 - 已上模拟器验证:设置页显示 插件 35 / 工具 260。 聊天自动滚动: - scrollToBottom 原来只在 50ms 后滚一次;长历史/长思考卡的布局在 消息数组更新后的若干帧才稳定,一次滚动会落在“当时”的底部, 最后一条被输入区挡住。改为 50ms 与 260ms 各滚一次,480ms 后 恢复正常滚动态。
This commit is contained in:
@ -69,14 +69,20 @@ export struct ChatStream {
|
||||
|
||||
private scrollToBottom(): void {
|
||||
this.autoScrolling = true;
|
||||
// 滚两次:内容高度是在消息数组更新后的若干帧内才逐步确定的。
|
||||
// 长历史/长思考卡布局慢,只滚一次会落在“当时”的底部 —— 实测初次加载
|
||||
// 历史时最后一条被输入区挡住,再手动上滑还能露出更多内容。
|
||||
setTimeout(() => {
|
||||
this.scroller.scrollEdge(Edge.Bottom);
|
||||
}, 50);
|
||||
setTimeout(() => {
|
||||
this.scroller.scrollEdge(Edge.Bottom);
|
||||
}, 260);
|
||||
setTimeout(() => {
|
||||
this.autoScrolling = false;
|
||||
this.navHidden = false;
|
||||
navBar.setVisible(true);
|
||||
}, 450);
|
||||
}, 480);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -120,10 +120,15 @@ export struct StatusSummaryCard {
|
||||
.alignItems(VerticalAlign.Center)
|
||||
.transition(TransitionEffect.OPACITY.combine(TransitionEffect.translate({ y: 12 })).animation({ duration: ANIM_ENTER, curve: Curve.EaseOut }))
|
||||
|
||||
// 能力计数:图标 + 数字,只保留真正会变的两项(插件 / 工具)
|
||||
// 能力计数:图标 + 数字,只保留真正会变的两项(插件 / 工具)。
|
||||
//
|
||||
// 必须是**子组件**(@Prop 单向下发)而不是本组件里的 @Builder:
|
||||
// ArkUI 的 @Builder 按值传参是“快照”语义,父组件重渲染时
|
||||
// 不会用新值重跑 builder —— 实测:K_PLUGINS 已经是 35,
|
||||
// 但 @Builder 里画的还是首次的 0,永远显示 '-'。
|
||||
Row({ space: 10 }) {
|
||||
this.kpiTile($r('app.media.ic_plug'), '插件', this.plugins, COLOR_ACCENT)
|
||||
this.kpiTile($r('app.media.ic_tool'), '工具', this.tools, COLOR_CYAN)
|
||||
KpiTile({ icon: $r('app.media.ic_plug'), label: '插件', value: this.plugins, tint: COLOR_ACCENT })
|
||||
KpiTile({ icon: $r('app.media.ic_tool'), label: '工具', value: this.tools, tint: COLOR_CYAN })
|
||||
}
|
||||
.width('100%')
|
||||
.margin({ top: 14 })
|
||||
@ -214,6 +219,51 @@ export struct StatusSummaryCard {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 能力计数小卡(插件 / 工具)。
|
||||
*
|
||||
* 单独成组件而非 @Builder:@Builder 的按值参数不会随父组件重渲染而刷新,
|
||||
* 数值会永远停在首次渲染的 0。@Prop 是单向下发,父组件因 @StorageProp
|
||||
* 变化重渲染时,子组件拿到新值并重绘。
|
||||
*/
|
||||
@Component
|
||||
struct KpiTile {
|
||||
@StorageProp('themeIsDark') private isDark: boolean = true;
|
||||
@Prop icon: Resource = $r('app.media.ic_plug');
|
||||
@Prop label: string = '';
|
||||
@Prop value: number = 0;
|
||||
@Prop tint: string = '';
|
||||
|
||||
build() {
|
||||
Row({ space: 8 }) {
|
||||
Image(this.icon)
|
||||
.width(16)
|
||||
.height(16)
|
||||
.fillColor(this.tint)
|
||||
.draggable(false)
|
||||
Column({ space: 1 }) {
|
||||
Text(this.value > 0 ? this.value.toString() : '-')
|
||||
.fontSize(17)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
.fontColor(this.palette().textPrimary)
|
||||
Text(this.label)
|
||||
.fontSize(11)
|
||||
.fontColor(this.palette().textMuted)
|
||||
}
|
||||
.alignItems(HorizontalAlign.Start)
|
||||
}
|
||||
.layoutWeight(1)
|
||||
.padding({ left: 12, right: 12, top: 10, bottom: 10 })
|
||||
.borderRadius(RADIUS_SM)
|
||||
.backgroundColor(this.palette().bgHover)
|
||||
.alignItems(VerticalAlign.Center)
|
||||
}
|
||||
|
||||
private palette(): ThemePalette {
|
||||
return this.isDark ? DARK_PALETTE : LIGHT_PALETTE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 运行状态明细:设置页「运行状态」二级页面的内容。
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user