|
|
|
@ -1,13 +1,14 @@
|
|
|
|
|
import 'dart:convert'; |
|
|
|
|
import 'dart:io'; |
|
|
|
|
import 'dart:ui'; |
|
|
|
|
|
|
|
|
|
import 'package:dio/dio.dart'; |
|
|
|
|
import 'package:emoji_picker_flutter/emoji_picker_flutter.dart'; |
|
|
|
|
import 'package:flutter/material.dart'; |
|
|
|
|
import 'package:flutter/rendering.dart'; |
|
|
|
|
import 'package:flutter/services.dart'; |
|
|
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
|
|
|
|
import 'package:huixiang/im/database/message.dart'; |
|
|
|
|
import 'package:huixiang/im/out/message.pb.dart'; |
|
|
|
|
import 'package:huixiang/main.dart'; |
|
|
|
|
import 'package:huixiang/retrofit/data/im_user.dart'; |
|
|
|
|
import 'package:huixiang/retrofit/retrofit_api.dart'; |
|
|
|
@ -18,6 +19,9 @@ import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
|
import '../../community/release_dynamic.dart'; |
|
|
|
|
import '../../generated/l10n.dart'; |
|
|
|
|
import '../../utils/font_weight.dart'; |
|
|
|
|
import '../retrofit/data/base_data.dart'; |
|
|
|
|
import '../retrofit/data/user_info.dart'; |
|
|
|
|
import '../utils/flutter_utils.dart'; |
|
|
|
|
import '../view_widget/custom_image.dart'; |
|
|
|
|
import 'im_view/on_chat_message.dart'; |
|
|
|
|
import 'im_view/on_chat_msg_instance.dart'; |
|
|
|
@ -51,6 +55,7 @@ class _ChatDetailsPage extends State<ChatDetailsPage>
|
|
|
|
|
bool needHideMore = false; |
|
|
|
|
var commentFocus = FocusNode(); |
|
|
|
|
String hintText = "输入消息内容..."; |
|
|
|
|
UserInfo userInfo; |
|
|
|
|
final OnChatMessage _tempOnChatMessage = |
|
|
|
|
OnChatMsgInstance.instance.onChatMessage; |
|
|
|
|
final ScrollController scrollController = ScrollController(); |
|
|
|
@ -81,12 +86,29 @@ class _ChatDetailsPage extends State<ChatDetailsPage>
|
|
|
|
|
messages.insert(0, message); |
|
|
|
|
refreshState(); |
|
|
|
|
|
|
|
|
|
// if (scrollController.position != null) { |
|
|
|
|
// double offset = scrollController.position.maxScrollExtent; |
|
|
|
|
// debugPrint("offset: $offset"); |
|
|
|
|
// Future.delayed(const Duration(milliseconds: 500), () { |
|
|
|
|
// scrollController.animateTo(offset + 108, duration: const Duration(milliseconds: 500), curve: Curves.easeIn); |
|
|
|
|
// }); |
|
|
|
|
// } |
|
|
|
|
if (scrollController.position != null) { |
|
|
|
|
double offset = scrollController.position.maxScrollExtent; |
|
|
|
|
debugPrint("offset: $offset"); |
|
|
|
|
Future.delayed(const Duration(milliseconds: 500), () { |
|
|
|
|
scrollController.animateTo(offset + 108, duration: const Duration(milliseconds: 500), curve: Curves.easeIn); |
|
|
|
|
}); |
|
|
|
|
double maxScrollExtent = scrollController.position.maxScrollExtent; |
|
|
|
|
double viewportDimensions = scrollController.position.viewportDimension; |
|
|
|
|
|
|
|
|
|
// 检查是否需要滚动 |
|
|
|
|
if (maxScrollExtent > viewportDimensions) { |
|
|
|
|
double offset = maxScrollExtent; |
|
|
|
|
debugPrint("offset: $offset"); |
|
|
|
|
Future.delayed(const Duration(milliseconds: 500), () { |
|
|
|
|
scrollController.animateTo( |
|
|
|
|
offset + 108, |
|
|
|
|
duration: const Duration(milliseconds: 500), |
|
|
|
|
curve: Curves.easeIn |
|
|
|
|
); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
}); |
|
|
|
@ -97,6 +119,28 @@ class _ChatDetailsPage extends State<ChatDetailsPage>
|
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
///查询个人信息 |
|
|
|
|
queryUser() async { |
|
|
|
|
final SharedPreferences value = await SharedPreferences.getInstance(); |
|
|
|
|
if (value.containsKey('user') && |
|
|
|
|
value.getString('user') != null && |
|
|
|
|
value.getString('user') != "") { |
|
|
|
|
userInfo = UserInfo.fromJson(jsonDecode(value.getString('user'))); |
|
|
|
|
} |
|
|
|
|
if(apiService == null) |
|
|
|
|
apiService = ApiService(Dio(), context: context, token: value.getString("token")); |
|
|
|
|
BaseData<UserInfo> baseData = |
|
|
|
|
await apiService.queryInfo().catchError((onError) {}); |
|
|
|
|
if (baseData != null && baseData.isSuccess) { |
|
|
|
|
setState(() { |
|
|
|
|
userInfo = baseData.data; |
|
|
|
|
}); |
|
|
|
|
SharedPreferences.getInstance().then((value) => { |
|
|
|
|
value.setString('user', jsonEncode(baseData.data)), |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
refreshState() { |
|
|
|
|
if (mounted) setState(() {}); |
|
|
|
|
} |
|
|
|
@ -110,6 +154,7 @@ class _ChatDetailsPage extends State<ChatDetailsPage>
|
|
|
|
|
WidgetsBinding.instance.addObserver(this); |
|
|
|
|
commentFocus.addListener(_focusNodeListener); |
|
|
|
|
|
|
|
|
|
queryUser(); |
|
|
|
|
loadMessageList(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -356,7 +401,7 @@ class _ChatDetailsPage extends State<ChatDetailsPage>
|
|
|
|
|
child: Column( |
|
|
|
|
children: [ |
|
|
|
|
Text( |
|
|
|
|
"${DateTime.fromMillisecondsSinceEpoch(int.parse(message.time))}", |
|
|
|
|
AppUtils.timeFormatter(DateTime.fromMillisecondsSinceEpoch(int.parse(message.time))), |
|
|
|
|
textAlign: TextAlign.center, |
|
|
|
|
style: TextStyle( |
|
|
|
|
color: Color(0xFFA29E9E), |
|
|
|
@ -691,7 +736,7 @@ class _ChatDetailsPage extends State<ChatDetailsPage>
|
|
|
|
|
width: 12.w, |
|
|
|
|
), |
|
|
|
|
MImage( |
|
|
|
|
_toUser.avatar, |
|
|
|
|
userInfo?.headimg??"", |
|
|
|
|
isCircle: true, |
|
|
|
|
height: 44.h, |
|
|
|
|
width: 44.h, |
|
|
|
@ -826,13 +871,38 @@ class _ChatDetailsPage extends State<ChatDetailsPage>
|
|
|
|
|
chatController.clear(); |
|
|
|
|
if (mounted) setState(() {}); |
|
|
|
|
|
|
|
|
|
if (scrollController.position != null) { |
|
|
|
|
double offset = scrollController.position.maxScrollExtent; |
|
|
|
|
debugPrint("offset: $offset"); |
|
|
|
|
Future.delayed(const Duration(milliseconds: 500), () { |
|
|
|
|
scrollController.animateTo(offset + 108, duration: const Duration(milliseconds: 500), curve: Curves.easeIn); |
|
|
|
|
}); |
|
|
|
|
// if (scrollController.position != null) { |
|
|
|
|
// double offset = scrollController.position.maxScrollExtent; |
|
|
|
|
// debugPrint("offset: $offset"); |
|
|
|
|
// Future.delayed(const Duration(milliseconds: 500), () { |
|
|
|
|
// scrollController.animateTo(offset + 108, duration: const Duration(milliseconds: 500), curve: Curves.easeIn); |
|
|
|
|
// }); |
|
|
|
|
// } |
|
|
|
|
if (scrollController.position.maxScrollExtent > scrollController.offset) { |
|
|
|
|
// 如果未滑动到底部,则自动滑动到底部 |
|
|
|
|
scrollController.animateTo( |
|
|
|
|
scrollController.position.maxScrollExtent, |
|
|
|
|
duration: Duration(seconds: 1), |
|
|
|
|
curve: Curves.easeOut, |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
// if (scrollController.position != null) { |
|
|
|
|
// double maxScrollExtent = scrollController.position.maxScrollExtent; |
|
|
|
|
// double viewportDimensions = scrollController.position.viewportDimension; |
|
|
|
|
// |
|
|
|
|
// // 检查是否需要滚动 |
|
|
|
|
// if (maxScrollExtent > viewportDimensions) { |
|
|
|
|
// // double offset = maxScrollExtent; |
|
|
|
|
// // debugPrint("offset: $offset"); |
|
|
|
|
// Future.delayed(const Duration(milliseconds: 500), () { |
|
|
|
|
// scrollController.animateTo( |
|
|
|
|
// maxScrollExtent+viewportDimensions, |
|
|
|
|
// duration: const Duration(milliseconds: 500), |
|
|
|
|
// curve: Curves.easeIn |
|
|
|
|
// ); |
|
|
|
|
// }); |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
|
|
|
|
|
}); |
|
|
|
|
}, |
|
|
|
|