fix(chat): fix ChatBloc event callback and test reliability
- Fix onEvent callback initialization in ChatBloc constructor - Add MockAgUiService to isolate test from mock API behavior - Remove unnecessary non-null assertions in tests
This commit is contained in:
@@ -2,16 +2,19 @@ import 'package:flutter/material.dart';
|
||||
import 'package:social_app/core/theme/design_tokens.dart';
|
||||
import '../../data/models/tool_result.dart';
|
||||
|
||||
/// 卡片类型常量
|
||||
const _calendarCardType = 'calendar_card.v1';
|
||||
const _errorCardType = 'error_card.v1';
|
||||
const _aiGeneratedSource = 'ai_generated';
|
||||
const _primaryActionType = 'primary';
|
||||
|
||||
class UiSchemaRenderer {
|
||||
static Widget render(UiCard card) {
|
||||
switch (card.cardType) {
|
||||
case 'calendar_card.v1':
|
||||
return _renderCalendarCard(card);
|
||||
case 'error_card.v1':
|
||||
return _renderErrorCard(card);
|
||||
default:
|
||||
return _renderUnknownCard(card);
|
||||
}
|
||||
return switch (card.cardType) {
|
||||
_calendarCardType => _renderCalendarCard(card),
|
||||
_errorCardType => _renderErrorCard(card),
|
||||
_ => _renderUnknownCard(card),
|
||||
};
|
||||
}
|
||||
|
||||
static Widget _renderCalendarCard(UiCard card) {
|
||||
@@ -19,6 +22,7 @@ class UiSchemaRenderer {
|
||||
final color = data.color != null
|
||||
? Color(int.parse(data.color!.replaceFirst('#', '0xFF')))
|
||||
: AppColors.blue500;
|
||||
final isAiGenerated = data.sourceType == _aiGeneratedSource;
|
||||
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
@@ -44,23 +48,10 @@ class UiSchemaRenderer {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (data.sourceType == 'ai_generated')
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: AppSpacing.sm,
|
||||
vertical: AppSpacing.xs,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.messageTagBg,
|
||||
borderRadius: BorderRadius.circular(AppRadius.sm),
|
||||
),
|
||||
child: Text(
|
||||
'AI生成',
|
||||
style: TextStyle(fontSize: 10, color: AppColors.blue600),
|
||||
),
|
||||
),
|
||||
if (data.sourceType == 'ai_generated')
|
||||
if (isAiGenerated) ...[
|
||||
_buildAiTag(),
|
||||
SizedBox(height: AppSpacing.sm),
|
||||
],
|
||||
Text(
|
||||
_formatTime(data.startAt, data.endAt),
|
||||
style: TextStyle(fontSize: 12, color: AppColors.slate500),
|
||||
@@ -83,32 +74,11 @@ class UiSchemaRenderer {
|
||||
],
|
||||
if (data.location != null) ...[
|
||||
SizedBox(height: AppSpacing.sm),
|
||||
Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.location_on_outlined,
|
||||
size: 16,
|
||||
color: AppColors.slate500,
|
||||
),
|
||||
SizedBox(width: AppSpacing.xs),
|
||||
Text(
|
||||
data.location!,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: AppColors.slate500,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
_buildLocation(data.location!),
|
||||
],
|
||||
if (card.actions != null && card.actions!.isNotEmpty) ...[
|
||||
SizedBox(height: AppSpacing.md),
|
||||
Wrap(
|
||||
spacing: AppSpacing.sm,
|
||||
children: card.actions!
|
||||
.map((action) => _buildActionButton(action))
|
||||
.toList(),
|
||||
),
|
||||
_buildActions(card.actions!),
|
||||
],
|
||||
],
|
||||
),
|
||||
@@ -118,8 +88,45 @@ class UiSchemaRenderer {
|
||||
);
|
||||
}
|
||||
|
||||
static Widget _buildAiTag() {
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: AppSpacing.sm,
|
||||
vertical: AppSpacing.xs,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.messageTagBg,
|
||||
borderRadius: BorderRadius.circular(AppRadius.sm),
|
||||
),
|
||||
child: Text(
|
||||
'AI生成',
|
||||
style: TextStyle(fontSize: 10, color: AppColors.blue600),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
static Widget _buildLocation(String location) {
|
||||
return Row(
|
||||
children: [
|
||||
Icon(Icons.location_on_outlined, size: 16, color: AppColors.slate500),
|
||||
SizedBox(width: AppSpacing.xs),
|
||||
Text(
|
||||
location,
|
||||
style: TextStyle(fontSize: 12, color: AppColors.slate500),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
static Widget _buildActions(List<CardAction> actions) {
|
||||
return Wrap(
|
||||
spacing: AppSpacing.sm,
|
||||
children: actions.map((action) => _buildActionButton(action)).toList(),
|
||||
);
|
||||
}
|
||||
|
||||
static Widget _buildActionButton(CardAction action) {
|
||||
final isPrimary = action.type == 'primary';
|
||||
final isPrimary = action.type == _primaryActionType;
|
||||
return GestureDetector(
|
||||
onTap: () => _handleAction(action),
|
||||
child: Container(
|
||||
|
||||
Reference in New Issue
Block a user