90 lines
2.5 KiB
Dart
90 lines
2.5 KiB
Dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import '../models/message.dart';
|
|
import '../services/api_service.dart';
|
|
|
|
class ChatState {
|
|
final List<ChatMessage> messages;
|
|
final bool isLoading;
|
|
final String? error;
|
|
|
|
const ChatState({this.messages = const [], this.isLoading = false, this.error});
|
|
|
|
ChatState copyWith({List<ChatMessage>? messages, bool? isLoading, String? error}) {
|
|
return ChatState(
|
|
messages: messages ?? this.messages,
|
|
isLoading: isLoading ?? this.isLoading,
|
|
error: error,
|
|
);
|
|
}
|
|
}
|
|
|
|
class ChatNotifier extends StateNotifier<ChatState> {
|
|
ChatNotifier() : super(const ChatState()) {
|
|
_loadHistory();
|
|
}
|
|
|
|
Future<void> _loadHistory() async {
|
|
try {
|
|
final messages = await apiService.getChatHistory();
|
|
state = state.copyWith(messages: messages);
|
|
} catch (_) {}
|
|
}
|
|
|
|
Future<void> sendMessage(String content) async {
|
|
if (content.trim().isEmpty) return;
|
|
|
|
final userMessage = ChatMessage(
|
|
id: 'msg_user_${DateTime.now().millisecondsSinceEpoch}',
|
|
content: content.trim(),
|
|
type: MessageType.text,
|
|
sender: MessageSender.user,
|
|
timestamp: DateTime.now(),
|
|
);
|
|
|
|
state = state.copyWith(
|
|
messages: [...state.messages, userMessage],
|
|
isLoading: true,
|
|
);
|
|
|
|
final loadingMessage = ChatMessage(
|
|
id: 'msg_loading_${DateTime.now().millisecondsSinceEpoch}',
|
|
content: '',
|
|
type: MessageType.loading,
|
|
sender: MessageSender.ai,
|
|
timestamp: DateTime.now(),
|
|
);
|
|
|
|
state = state.copyWith(
|
|
messages: [...state.messages, loadingMessage],
|
|
);
|
|
|
|
try {
|
|
final response = await apiService.sendMessage(content);
|
|
final updatedMessages = [...state.messages];
|
|
updatedMessages.removeLast();
|
|
updatedMessages.add(response);
|
|
state = state.copyWith(messages: updatedMessages, isLoading: false);
|
|
} catch (e) {
|
|
final updatedMessages = [...state.messages];
|
|
updatedMessages.removeLast();
|
|
updatedMessages.add(ChatMessage(
|
|
id: 'msg_err_${DateTime.now().millisecondsSinceEpoch}',
|
|
content: '抱歉,消息发送失败,请稍后重试。',
|
|
type: MessageType.text,
|
|
sender: MessageSender.ai,
|
|
timestamp: DateTime.now(),
|
|
));
|
|
state = state.copyWith(messages: updatedMessages, isLoading: false, error: e.toString());
|
|
}
|
|
}
|
|
|
|
void clearMessages() {
|
|
state = const ChatState();
|
|
_loadHistory();
|
|
}
|
|
}
|
|
|
|
final chatProvider = StateNotifierProvider<ChatNotifier, ChatState>((ref) {
|
|
return ChatNotifier();
|
|
});
|