AI助手优化-头像和对话功能
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../core/network/api_env.dart';
|
||||
import 'cute_icon.dart';
|
||||
|
||||
/// 圆形头像。全 App 只有这一个头像组件 —— 人设、用户、「我的」页面、聊天气泡都用它。
|
||||
///
|
||||
/// 三种输入都要兜住:
|
||||
/// · [assetPath] 为空 → 画默认图标([fallbackIcon])
|
||||
/// · 图片加载中 → 显示一个淡淡的占位圆
|
||||
/// · 加载失败(后端文件被删了 / 网络断了)→ 退回默认图标,不显示裂图
|
||||
///
|
||||
/// 为什么不用 `CircleAvatar`:它的 backgroundImage 出错时不好接管,
|
||||
/// 会有「裂图 + 背景色」的难看状态。自己用 [ClipOval] + [Image.network] 能完全控制。
|
||||
class Avatar extends StatelessWidget {
|
||||
const Avatar({
|
||||
super.key,
|
||||
this.assetPath,
|
||||
this.size = 40,
|
||||
this.fallbackIcon = 'user',
|
||||
this.fallbackColor = const Color(0xFFC8956E),
|
||||
this.backgroundColor = const Color(0xFFFFF3E6),
|
||||
});
|
||||
|
||||
/// 后端返回的**相对路径**(如 `persona/2026/09/29/xxx.jpg`)。
|
||||
/// 传空或 null → 用默认图标。
|
||||
final String? assetPath;
|
||||
|
||||
final double size;
|
||||
|
||||
/// 没有头像时显示哪个小图标(`CuteIcon` 的名字)
|
||||
final String fallbackIcon;
|
||||
|
||||
/// 默认图标的颜色
|
||||
final Color fallbackColor;
|
||||
|
||||
/// 头像底圈的颜色
|
||||
final Color backgroundColor;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final path = assetPath?.trim() ?? '';
|
||||
|
||||
return Container(
|
||||
width: size,
|
||||
height: size,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: backgroundColor,
|
||||
),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: path.isEmpty ? _fallback() : _image(path),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _fallback() {
|
||||
return Center(
|
||||
child: CuteIcon(fallbackIcon, size: size * 0.58),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _image(String path) {
|
||||
return Image.network(
|
||||
resolveAssetUrl('/uploads/$path'),
|
||||
fit: BoxFit.cover,
|
||||
// 头像显示尺寸很小,限一下解码尺寸省内存 —— 原图可能是 400px
|
||||
cacheWidth: (size * 3).round(),
|
||||
loadingBuilder: (context, child, progress) {
|
||||
// 还没加载出来时给个纯色圆,比空白或转圈干净
|
||||
if (progress == null) return child;
|
||||
return const SizedBox.shrink();
|
||||
},
|
||||
errorBuilder: (context, _, _) {
|
||||
// 后端文件被删了也会走到这 —— 退回默认图标,不留裂图
|
||||
return _fallback();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user