Browse Source

Merge remote-tracking branch 'origin/wr_202303' into wr_202303

# Conflicts:
#	lib/im/chat_details_page.dart
#	lib/im/database/hx_database.dart
#	lib/im/im_view/im_page.dart
wr_202303
wurong 4 months ago
parent
commit
0a014a0d65
  1. 46
      lib/constant.dart
  2. 65
      lib/im/chat_details_page.dart
  3. 28
      lib/im/database/hx_database.dart
  4. 1
      lib/im/database/message.dart
  5. 29
      lib/im/im_view/im_page.dart

46
lib/constant.dart

@ -0,0 +1,46 @@
Map<S, List<T>> groupBy<S, T>(Iterable<T> values, S Function(T) key) {
var map = <S, List<T>>{};
for (var element in values) {
(map[key(element)] ??= []).add(element);
}
return map;
}
Map<String, int> groupCount<S, T>(Map<S, List<T>> values) {
var map = <String, int>{};
for (var element in values.keys) {
map["$element"] = values[element]?.length ?? 0;
}
return map;
}
Map<String, T> groupItem<S, T>(Map<S, List<T>> values) {
var map = <String, T>{};
for (var element in values.keys) {
if (values[element] == null) {
continue;
}
map["$element"] = values[element].first;
}
return map;
}
extension ListExtension<S, T> on Iterable<T> {
Map<S, List<T>> lGroupBy(S Function(T) key) {
return groupBy(this, key);
}
}
extension MapExtension<S, T> on Map<S, List<T>> {
Map<String, int> get mGroupCount => groupCount(this);
Map<String, T> get mGroupItem => groupItem(this);
}

65
lib/im/chat_details_page.dart

@ -17,8 +17,6 @@ import 'package:shared_preferences/shared_preferences.dart';
import '../../community/release_dynamic.dart';
import '../../generated/l10n.dart';
import '../../utils/font_weight.dart';
import '../retrofit/data/im_user_list.dart';
import '../view_widget/custom_image.dart';
import 'im_view/on_chat_message.dart';
import 'im_view/on_chat_msg_instance.dart';
@ -72,7 +70,6 @@ class _ChatDetailsPage extends State<ChatDetailsPage>
socketClient.addCallback(_toUser.mid, (Message message) {
messages.add(message);
refreshState();
});
refreshState();
@ -155,7 +152,7 @@ class _ChatDetailsPage extends State<ChatDetailsPage>
WidgetsBinding.instance.removeObserver(this);
commentFocus.removeListener(_focusNodeListener);
socketClient.removeCallback(_toUser.mid);
socketClient.removeCallback(toUserId);
}
@ -251,7 +248,7 @@ class _ChatDetailsPage extends State<ChatDetailsPage>
// resizeToAvoidBottomInset: false,
backgroundColor: Color(0xFFF6F6F6),
appBar: MyAppBar(
title: _toUser.nickname,
title: "哈哈哈哈",
titleColor: Color(0xFF0D0D0D),
titleSize: 17.sp,
leading: true,
@ -368,7 +365,6 @@ class _ChatDetailsPage extends State<ChatDetailsPage>
height: 16.h,
),
if (copyIndex == 1)
///
Stack(
alignment: Alignment.bottomCenter,
children: [
@ -458,14 +454,19 @@ class _ChatDetailsPage extends State<ChatDetailsPage>
padding: EdgeInsets.only(left: 17.w, right: 39.w),
child: Row(
children: [
MImage(
_toUser.avatar,
isCircle: true,
// MImage(
// "",
// isCircle: true,
// width: 44,
// height: 44,
// fit: BoxFit.cover,
// errorSrc: "assets/image/default_user.webp",
// fadeSrc: "assets/image/default_user.webp",
// ),
Image.asset(
"assets/image/fuka_zj.webp",
height: 44.h,
width: 44.h,
fit: BoxFit.cover,
errorSrc: "assets/image/default_1.webp",
fadeSrc: "assets/image/default_1.webp",
),
SizedBox(
width: 12.w,
@ -655,14 +656,19 @@ class _ChatDetailsPage extends State<ChatDetailsPage>
SizedBox(
width: 12.w,
),
MImage(
"",
isCircle: true,
height: 44.h,
width: 44.h,
fit: BoxFit.cover,
errorSrc: "assets/image/default_1.webp",
fadeSrc: "assets/image/default_1.webp",
// MImage(
// "",
// isCircle: true,
// width: 44,
// height: 44,
// fit: BoxFit.cover,
// errorSrc: "assets/image/default_user.webp",
// fadeSrc: "assets/image/default_user.webp",
// ),
Image.asset(
"assets/image/fuka_zj.webp",
height: 44,
width: 44,
),
],
),
@ -674,14 +680,19 @@ class _ChatDetailsPage extends State<ChatDetailsPage>
padding: EdgeInsets.only(left: 17.w, right: 39.w, top: 20.h),
child: Row(
children: [
MImage(
_toUser.avatar,
isCircle: true,
// MImage(
// "",
// isCircle: true,
// width: 44,
// height: 44,
// fit: BoxFit.cover,
// errorSrc: "assets/image/default_user.webp",
// fadeSrc: "assets/image/default_user.webp",
// ),
Image.asset(
"assets/image/fuka_zj.webp",
height: 44.h,
width: 44.h,
fit: BoxFit.cover,
errorSrc: "assets/image/default_1.webp",
fadeSrc: "assets/image/default_1.webp",
),
SizedBox(
width: 12.w,
@ -773,7 +784,7 @@ class _ChatDetailsPage extends State<ChatDetailsPage>
if (commentText.trim() == "") {
return;
}
socketClient.sendMessage(_toUser.mid, commentText).then((value) {
socketClient.sendMessage(toUserId, commentText).then((value) {
Message message = value;
messages.insert(0, message);
chatController.clear();

28
lib/im/database/hx_database.dart

@ -45,11 +45,11 @@ class HxDatabase {
List<Message> messages =
await db.rawQuery(sql, [userId, userId]).then((value) {
return value.map((e) {
debugPrint("Message: ${e}");
debugPrint("Message: $e");
return Message.fromJson(e);
}).toList();
}, onError: (error) {
debugPrint("Messageerror: $error");
debugPrint("Message_error: $error");
});
return (messages?.isNotEmpty ?? false) ? messages.first : null;
}
@ -83,6 +83,22 @@ class HxDatabase {
});
}
Future<Map<String, int>> messageUnreadCount(List<String> userIds, String selfUserId) async {
if (db == null) {
return Future.value({});
}
List<Message> messages = await db.query(
"Message",
where: 'fromId IN (?) AND toId = ? AND state = 0 AND isDelete = 0',
whereArgs: []..addAll(userIds)..add(selfUserId)
).then((value) {
return value.map((e) => Message.fromJson(e)).toList();
}, onError: (error) {
debugPrint("Message-error: $error");
});
return messages.lGroupBy((p)=> p.fromId).mGroupCount;
}
Future<List<Map>> queryListAll() {
if (db == null) {
return Future.value();
@ -111,7 +127,13 @@ class HxDatabase {
debugPrint("Message_insert: $message");
return db.insert("Message", message);
}
/// update message read state
readMessage(String selfUserId, String userId) {
if (db == null) {
return Future.value(<Message>[]);
}
db.update("Message", {"state": 1}, where: "fromId = ? AND toId = ? AND state = 0 AND isDelete = 0", whereArgs: [userId, selfUserId]);
}
Future<int> insertOrUpdateImUser(Map imUserMap) async {
if (db == null) {
return Future.value(0);

1
lib/im/database/message.dart

@ -16,6 +16,7 @@ class Message {
String time;
/// 0 unread, 1 read, 2
int state;
int isDelete;

29
lib/im/im_view/im_page.dart

@ -88,6 +88,8 @@ class _IMPage extends State<IMPage> implements OnChatMessage {
List<String> userIds = [];
Map<String, Message> lastMessageMap = {};
Stream streamSubscription;
Map<String, int> unreadCountMap = {};
Stream streamSubscription ;
loadMessageList() async {
SharedPreferences shared = await SharedPreferences.getInstance();
@ -120,9 +122,10 @@ class _IMPage extends State<IMPage> implements OnChatMessage {
.map((e) => e.toId != userId ? e.toId : e.fromId)
.toSet()
.where((element) => element != userId)
.toList(); //
.toList();
List<ImUserList> contacts = (await hxDatabase.queryImUser(userIds)) ?? [];
unreadCountMap = await hxDatabase.messageUnreadCount(userIds, userId);
if (contacts.isNotEmpty) imUserList = groupBy(contacts, (p0) => p0.mid);
lastMessageMap =
@ -138,15 +141,19 @@ class _IMPage extends State<IMPage> implements OnChatMessage {
Message message = await hxDatabase.lastMessage(userId);
if (message != null) {
lastMessageMap[userId] = message;
refreshState();
}
}
Map<S, T> groupBy<S, T>(Iterable<T> values, S Function(T) key) {
var map = <S, T>{};
for (var element in values) {
map[key(element)] ??= element;
}
return map;
void updateUnreadCount() async {
SharedPreferences shared = await SharedPreferences.getInstance();
String userId = shared.getString("userId");
unreadCountMap = await hxDatabase.messageUnreadCount(userIds, userId);
refreshState();
}
refreshState() {
if (mounted) setState(() {});
}
// queryMessage() async {
@ -195,8 +202,9 @@ class _IMPage extends State<IMPage> implements OnChatMessage {
token: value.getString("token"),
);
}
BaseData<List<MsgStats>> baseData =
await apiService.stats().catchError((onError) {});
BaseData<List<MsgStats>> baseData = await apiService.stats().catchError((onError) {
debugPrint("stats.error: $onError");
});
if (baseData != null && baseData.isSuccess) {
setState(() {
msgNumber.forEach((key, value) {
@ -302,8 +310,7 @@ class _IMPage extends State<IMPage> implements OnChatMessage {
behavior: HitTestBehavior.opaque,
onTap: () {
Navigator.of(context)
.pushNamed('/router/chat_friend_group')
.then((value) {
.pushNamed('/router/chat_friend_group').then((value) {
_refresh();
});
},

Loading…
Cancel
Save