2025-09-09 10:57:52 +08:00
|
|
|
/// 已加入的群列表
|
|
|
|
library;
|
|
|
|
|
|
|
|
import 'package:easy_refresh/easy_refresh.dart';
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:get/get.dart';
|
|
|
|
import 'package:loopin/IM/im_service.dart';
|
|
|
|
import 'package:loopin/behavior/custom_scroll_behavior.dart';
|
2025-09-22 14:41:47 +08:00
|
|
|
import 'package:loopin/components/empty_tip.dart';
|
2025-09-09 10:57:52 +08:00
|
|
|
import 'package:loopin/components/network_or_asset_image.dart';
|
|
|
|
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
|
|
|
|
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_info.dart';
|
|
|
|
|
|
|
|
class Grouplist extends StatefulWidget {
|
|
|
|
const Grouplist({super.key});
|
|
|
|
|
|
|
|
@override
|
|
|
|
State<Grouplist> createState() => GrouplistState();
|
|
|
|
}
|
|
|
|
|
|
|
|
class GrouplistState extends State<Grouplist> with SingleTickerProviderStateMixin {
|
|
|
|
bool isLoading = false; // 是否在加载中
|
|
|
|
bool hasMore = true; // 是否还有更多数据
|
|
|
|
String page = '';
|
|
|
|
List<V2TimGroupInfo> dataList = <V2TimGroupInfo>[];
|
|
|
|
|
|
|
|
///-------------------
|
|
|
|
|
|
|
|
@override
|
|
|
|
void initState() {
|
|
|
|
super.initState();
|
|
|
|
getData();
|
|
|
|
}
|
|
|
|
|
|
|
|
// 分页获取已加入的群聊数据
|
|
|
|
Future<void> getData() async {
|
|
|
|
final res = await ImService.instance.getJoinedGroupList();
|
|
|
|
if (res.success && res.data != null) {
|
|
|
|
for (var item in res.data!) {
|
|
|
|
logger.i('获取成功:${item.toLogString()}');
|
|
|
|
}
|
|
|
|
|
|
|
|
final isFinished = true;
|
|
|
|
if (isFinished) {
|
|
|
|
setState(() {
|
|
|
|
hasMore = false;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
setState(() {
|
|
|
|
dataList.addAll(res.data!);
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
logger.e('获取数据失败:${res.desc}');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 下拉刷新
|
|
|
|
Future<void> handleRefresh() async {
|
|
|
|
dataList.clear();
|
|
|
|
page = '';
|
|
|
|
getData();
|
|
|
|
setState(() {});
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
return Scaffold(
|
|
|
|
backgroundColor: Colors.grey[50],
|
|
|
|
appBar: AppBar(
|
|
|
|
centerTitle: true,
|
|
|
|
forceMaterialTransparency: true,
|
|
|
|
bottom: PreferredSize(
|
|
|
|
preferredSize: const Size.fromHeight(1.0),
|
|
|
|
child: Container(
|
|
|
|
color: Colors.grey[300],
|
|
|
|
height: 1.0,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
title: const Text(
|
|
|
|
'群聊',
|
|
|
|
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
|
|
|
|
),
|
|
|
|
actions: [],
|
|
|
|
),
|
|
|
|
body: ScrollConfiguration(
|
|
|
|
behavior: CustomScrollBehavior().copyWith(scrollbars: false),
|
|
|
|
child: Column(
|
|
|
|
children: [
|
|
|
|
Expanded(
|
|
|
|
child: EasyRefresh.builder(
|
|
|
|
callLoadOverOffset: 20, //触底距离
|
|
|
|
callRefreshOverOffset: 20, // 下拉距离
|
|
|
|
header: ClassicHeader(
|
|
|
|
dragText: '下拉刷新',
|
|
|
|
armedText: '释放刷新',
|
|
|
|
readyText: '加载中...',
|
|
|
|
processingText: '加载中...',
|
|
|
|
processedText: '加载完成',
|
|
|
|
failedText: '加载失败,请重试',
|
|
|
|
messageText: '最后更新于 %T',
|
|
|
|
),
|
|
|
|
footer: ClassicFooter(
|
|
|
|
dragText: '加载更多',
|
|
|
|
armedText: '释放加载',
|
|
|
|
readyText: '加载中...',
|
|
|
|
processingText: '加载中...',
|
2025-09-22 14:41:47 +08:00
|
|
|
processedText: '加载完成',
|
|
|
|
noMoreText: '没有更多了~',
|
2025-09-09 10:57:52 +08:00
|
|
|
failedText: '加载失败,请重试',
|
|
|
|
messageText: '最后更新于 %T',
|
|
|
|
),
|
|
|
|
onRefresh: () async {
|
|
|
|
await handleRefresh();
|
|
|
|
},
|
|
|
|
onLoad: () async {
|
|
|
|
if (hasMore) {
|
|
|
|
await getData();
|
2025-09-22 14:41:47 +08:00
|
|
|
return hasMore ? IndicatorResult.success : IndicatorResult.noMore;
|
2025-09-09 10:57:52 +08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
childBuilder: (context, physics) {
|
2025-09-22 14:41:47 +08:00
|
|
|
if (dataList.isEmpty) return EmptyTip();
|
|
|
|
|
2025-09-09 10:57:52 +08:00
|
|
|
return ListView.builder(
|
|
|
|
physics: physics,
|
|
|
|
itemCount: dataList.length,
|
|
|
|
itemBuilder: (context, index) {
|
|
|
|
final item = dataList[index];
|
|
|
|
return Ink(
|
|
|
|
key: ValueKey(item.groupID),
|
|
|
|
child: Container(
|
|
|
|
padding: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 10.0),
|
|
|
|
child: Row(
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
|
|
children: <Widget>[
|
|
|
|
// 左侧部分(头像 + 群名称 + 群介绍)
|
|
|
|
Expanded(
|
|
|
|
child: InkWell(
|
|
|
|
onTap: () async {
|
|
|
|
// 这里点击跳转去群聊,先获取会话
|
|
|
|
final res = await ImService.instance.getConversation(conversationID: 'group_${item.groupID}');
|
|
|
|
if (res.success) {
|
|
|
|
V2TimConversation conversation = res.data;
|
|
|
|
logger.w(conversation.toLogString());
|
|
|
|
conversation.showName = conversation.showName ?? item.groupName;
|
|
|
|
Get.toNamed(
|
|
|
|
'/chatGroup',
|
|
|
|
arguments: conversation,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
child: Row(
|
|
|
|
children: [
|
|
|
|
ClipOval(
|
|
|
|
child: NetworkOrAssetImage(
|
|
|
|
imageUrl: item.faceUrl,
|
|
|
|
width: 50,
|
|
|
|
height: 50,
|
|
|
|
placeholderAsset: 'assets/images/group.png',
|
|
|
|
),
|
|
|
|
),
|
|
|
|
const SizedBox(width: 10),
|
|
|
|
Expanded(
|
|
|
|
child: Column(
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
children: <Widget>[
|
2025-09-13 17:01:01 +08:00
|
|
|
// 群名称
|
2025-09-09 10:57:52 +08:00
|
|
|
Text(
|
|
|
|
item.groupName?.isNotEmpty == true ? item.groupName! : '群聊',
|
|
|
|
style: const TextStyle(
|
|
|
|
fontSize: 16,
|
|
|
|
fontWeight: FontWeight.normal,
|
|
|
|
),
|
|
|
|
),
|
2025-09-13 17:01:01 +08:00
|
|
|
// 群介绍
|
2025-09-09 10:57:52 +08:00
|
|
|
if (item.introduction?.isNotEmpty ?? false) ...[
|
|
|
|
const SizedBox(height: 2.0),
|
|
|
|
Text(
|
|
|
|
item.introduction!,
|
|
|
|
style: const TextStyle(
|
|
|
|
color: Colors.grey,
|
|
|
|
fontSize: 13.0,
|
|
|
|
),
|
|
|
|
maxLines: 2,
|
|
|
|
overflow: TextOverflow.ellipsis,
|
|
|
|
),
|
|
|
|
],
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
},
|
|
|
|
);
|
|
|
|
},
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|