diff --git a/lib/pages/message/chat_page.dart b/lib/pages/message/chat_page.dart index 3c9f60a..a7bbeed 100644 --- a/lib/pages/message/chat_page.dart +++ b/lib/pages/message/chat_page.dart @@ -10,15 +10,48 @@ import '../../generated/assets.dart'; import '../../../widget/message/chat_input_bar.dart'; import '../../../widget/message/message_item.dart'; -class ChatPage extends StatelessWidget { +class ChatPage extends StatefulWidget { final String userId; const ChatPage({required this.userId, super.key}); + @override + State createState() => _ChatPageState(); +} + +class _ChatPageState extends State { + final ScrollController _scrollController = ScrollController(); + bool _isLoadingMore = false; + late ChatController _controller; + + @override + void initState() { + super.initState(); + // 初始化 controller + _controller = Get.put(ChatController(userId: widget.userId)); + + // 监听滚动,当滚动到顶部时加载更多消息 + _scrollController.addListener(() { + if (_scrollController.hasClients && + _scrollController.position.pixels >= + _scrollController.position.maxScrollExtent - 100 && + !_isLoadingMore && + _controller.messages.isNotEmpty) { + _loadMoreMessages(); + } + }); + } + + @override + void dispose() { + _scrollController.dispose(); + super.dispose(); + } + @override Widget build(BuildContext context) { return GetBuilder( - init: ChatController(userId: userId), + init: _controller, builder: (controller) { return WillPopScope( onWillPop: () async { @@ -57,6 +90,7 @@ class ChatPage extends StatelessWidget { }, behavior: HitTestBehavior.opaque, child: ListView.builder( + controller: _scrollController, reverse: true, padding: EdgeInsets.all(16.w), itemCount: controller.messages.length, @@ -79,34 +113,53 @@ class ChatPage extends StatelessWidget { ), ), ), - // 使用抽离的聊天输入栏组件 - ChatInputBar( - onSendMessage: (message) async { - await controller.sendMessage(message); - }, - onImageSelected: (imagePaths) async { - // 为每个图片路径调用控制器的方法发送图片消息 - for (var imagePath in imagePaths) { - await controller.sendImageMessage(imagePath); - } - }, - onVoiceRecorded: (filePath, seconds) async { - // 处理语音录音完成,回传文件路径和秒数 - await controller.sendVoiceMessage(filePath, seconds); - }, - onVideoRecorded: (filePath, duration) async { - print('🎬 [ChatPage] 收到视频录制/选择回调'); - print('文件路径: $filePath'); - print('时长: $duration 秒'); - // 处理视频录制/选择完成,回传文件路径和时长 - await controller.sendVideoMessage(filePath, duration); - }, - ), - ], + // 使用抽离的聊天输入栏组件 + ChatInputBar( + onSendMessage: (message) async { + await controller.sendMessage(message); + }, + onImageSelected: (imagePaths) async { + // 为每个图片路径调用控制器的方法发送图片消息 + for (var imagePath in imagePaths) { + await controller.sendImageMessage(imagePath); + } + }, + onVoiceRecorded: (filePath, seconds) async { + // 处理语音录音完成,回传文件路径和秒数 + await controller.sendVoiceMessage(filePath, seconds); + }, + onVideoRecorded: (filePath, duration) async { + print('🎬 [ChatPage] 收到视频录制/选择回调'); + print('文件路径: $filePath'); + print('时长: $duration 秒'); + // 处理视频录制/选择完成,回传文件路径和时长 + await controller.sendVideoMessage(filePath, duration); + }, + ), + ], + ), ), - ), - ); + ); }, ); } + + // 加载更多消息 + Future _loadMoreMessages() async { + if (_isLoadingMore) return; + + setState(() { + _isLoadingMore = true; + }); + + try { + await _controller.fetchMessages(loadMore: true); + } finally { + if (mounted) { + setState(() { + _isLoadingMore = false; + }); + } + } + } }