refactor: 重构聊天模块支持 SSE 断线重连及用户上下文隔离

This commit is contained in:
zl-q
2026-03-30 09:06:10 +08:00
parent 1aac62f39e
commit 4285b4ec80
28 changed files with 1624 additions and 658 deletions
@@ -10,14 +10,15 @@ import '../../../../core/utils/tool_name_localizer.dart';
import '../../../../shared/widgets/app_loading_indicator.dart';
import '../../../../shared/widgets/ui_schema/ui_schema_renderer.dart';
const _messagePaddingH = 13.0;
const _messagePaddingV = 9.0;
const _cornerRadius = 12.0;
const _attachmentPreviewSize = 88.0;
const _attachmentPreviewRadius = 10.0;
const _attachmentPreviewGap = 8.0;
const _toolResultWidthFactor = 0.9;
const _iconSize = 24.0;
const _messageMaxWidthFactor = 0.82;
const _messagePaddingH = AppSpacing.md;
const _messagePaddingV = AppSpacing.sm;
const _cornerRadius = AppRadius.lg;
const _attachmentPreviewSize = AppSpacing.xxl * 3 + AppSpacing.xs;
const _attachmentPreviewRadius = AppRadius.md;
const _attachmentPreviewGap = AppSpacing.sm;
const _toolResultWidthFactor = 0.88;
const _iconSize = AppSpacing.xxl;
class HomeChatItemRenderer {
static Widget build(BuildContext context, ChatListItem item) {
@@ -34,6 +35,8 @@ class HomeChatItemRenderer {
static Widget _buildMessageItem(BuildContext context, TextMessageItem item) {
final colorScheme = Theme.of(context).colorScheme;
final isUser = item.sender == MessageSender.user;
final maxMessageWidth =
MediaQuery.sizeOf(context).width * _messageMaxWidthFactor;
final imageAttachments = _collectRenderableImageAttachments(
item.attachments,
);
@@ -49,7 +52,8 @@ class HomeChatItemRenderer {
: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Flexible(
ConstrainedBox(
constraints: BoxConstraints(maxWidth: maxMessageWidth),
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: _messagePaddingH,
@@ -58,21 +62,24 @@ class HomeChatItemRenderer {
decoration: BoxDecoration(
color: isUser
? colorScheme.primaryContainer
: colorScheme.surface,
: colorScheme.surfaceContainerLow,
borderRadius: BorderRadius.only(
topLeft: const Radius.circular(_cornerRadius),
topRight: const Radius.circular(_cornerRadius),
bottomLeft: Radius.circular(isUser ? _cornerRadius : 0),
bottomRight: Radius.circular(isUser ? 0 : _cornerRadius),
),
border: isUser
? null
: Border.all(color: colorScheme.outlineVariant),
border: Border.all(
color: isUser
? colorScheme.primary.withValues(alpha: 0.12)
: colorScheme.outlineVariant,
),
),
child: Text(
item.content,
style: TextStyle(
fontSize: 14,
fontSize: AppSpacing.md,
height: 1.45,
color: isUser
? colorScheme.onPrimaryContainer
: colorScheme.onSurface,
@@ -302,6 +309,7 @@ class HomeChatItemRenderer {
: null;
final needsOuterCard = appearance == null || appearance == 'plain';
final schemaContent = UiSchemaRenderer(
context,
colorScheme,
).renderSchema(item.uiSchema);
final wrappedContent = needsOuterCard
@@ -309,9 +317,11 @@ class HomeChatItemRenderer {
width: double.infinity,
padding: const EdgeInsets.all(AppSpacing.md),
decoration: BoxDecoration(
color: colorScheme.surface,
color: colorScheme.surfaceContainerLow.withValues(alpha: 0.65),
borderRadius: BorderRadius.circular(AppRadius.lg),
border: Border.all(color: colorScheme.outlineVariant),
border: Border.all(
color: colorScheme.outlineVariant.withValues(alpha: 0.25),
),
),
child: schemaContent,
)