flutter/lib/pages/chat/notify/newFoucs.dart
2025-09-17 15:32:18 +08:00

280 lines
11 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/// 新关注通知
library;
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:loopin/IM/im_service.dart';
import 'package:loopin/api/video_api.dart';
import 'package:loopin/behavior/custom_scroll_behavior.dart';
import 'package:loopin/components/network_or_asset_image.dart';
import 'package:loopin/models/conversation_type.dart';
import 'package:loopin/service/http.dart';
import 'package:loopin/styles/index.dart';
import 'package:loopin/utils/index.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_custom_elem.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
// interactionComment, //互动->评论
// interactionAt, //互动->视频评论中的@
// interactionLike, //互动->点赞
// interactionReply, //互动->评论回复
class Newfoucs extends StatefulWidget {
const Newfoucs({super.key});
@override
State<Newfoucs> createState() => NewfoucsState();
}
class NewfoucsState extends State<Newfoucs> with SingleTickerProviderStateMixin {
bool isLoading = false; // 是否在加载中
bool hasMore = true; // 是否还有更多数据
final RxBool _throttleFlag = false.obs; // 滚动节流锁
final ScrollController chatController = ScrollController();
String page = '';
///-------------------
V2TimConversation? conv;
RxList<V2TimMessage> msgList = <V2TimMessage>[].obs;
@override
void initState() {
super.initState();
if (Get.arguments != null && Get.arguments is V2TimConversation) {
// 如果有参数
conv = Get.arguments as V2TimConversation;
logger.e('lastmsg:$conv');
final lastmsg = conv?.lastMessage;
if (lastmsg != null) {
msgList.add(lastmsg);
}
}
chatController.addListener(() {
if (_throttleFlag.value) return;
if (chatController.position.pixels >= chatController.position.maxScrollExtent - 50) {
_throttleFlag.value = true;
getMsgData().then((_) {
// 解锁
Future.delayed(Duration(milliseconds: 1000), () {
_throttleFlag.value = false;
});
});
}
});
}
@override
void dispose() {
super.dispose();
chatController.dispose();
}
// 分页获取全部数据
Future<void> getMsgData() async {
// 获取最旧一条消息作为游标
V2TimMessage? lastRealMsg;
lastRealMsg = msgList.last;
final res = await ImService.instance.getHistoryMessageList(
userID: ConversationType.newFocus.name, // userID为固定的newFocus
lastMsg: lastRealMsg,
);
if (res.success && res.data != null) {
msgList.addAll(res.data!);
logger.e(msgList);
if (res.data!.isEmpty) {
hasMore = false;
}
logger.i('聊天数据加载成功');
} else {
logger.e('聊天数据加载失败:${res.desc}');
}
}
// 下拉刷新
Future<void> handleRefresh() async {
await Future.delayed(Duration(seconds: 5));
setState(() {});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[50],
appBar: AppBar(
centerTitle: true,
forceMaterialTransparency: true,
bottom: PreferredSize(
preferredSize: Size.fromHeight(1.0),
child: Container(
color: Colors.grey[300],
height: 1.0,
),
),
title: Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
const SizedBox(width: 4),
Text(
'新的关注',
style: TextStyle(
color: Colors.black,
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
],
),
),
actions: [],
),
body: ScrollConfiguration(
behavior: CustomScrollBehavior().copyWith(scrollbars: false),
child: Column(
children: [
Expanded(
child: RefreshIndicator(
backgroundColor: Colors.white,
color: Color(0xFFFF5000),
displacement: 10.0,
onRefresh: handleRefresh,
child: Obx(() {
return ListView.builder(
controller: chatController,
shrinkWrap: true,
physics: BouncingScrollPhysics(),
itemCount: msgList.length,
itemBuilder: (context, index) {
//检测cloudCustomData
//----正式数据
V2TimMessage msg = msgList[index];
V2TimCustomElem element = msgList[index].customElem!;
final cloudCustomData = msgList[index].cloudCustomData;
logger.w(cloudCustomData);
final desc = msgList[index].customElem!.desc!;
String? jsonData = msgList[index].customElem!.data;
jsonData = (jsonData == null || jsonData.isEmpty) ? '{"faceUrl":"","nickName":"data为空","userID":"213213"}' : jsonData;
final item = jsonDecode(jsonData ?? '{"faceUrl":"","nickName":"测试昵称","userID":"213213"}');
logger.w(element.toJson());
// ----测试数据
// final jsonData = '{"faceUrl":"","nickName":"测试昵称","userID":"213213"}';
// final item = jsonDecode(jsonData); // 数据
// final desc = '测试desc';
// final cloudCustomData = 'interactionLike';
// V2TimMessage element = V2TimMessage(elemType: 2, isRead: index > 2 ? true : false);
// -----------
return Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 10.0),
child: Row(
spacing: 10.0,
children: <Widget>[
// 头像
InkWell(
onTap: () async {
// 点击头像转到对方主页
// 先获取视频详情
// 如果cloudCustomData是interactionCommentinteractionAtinteractionReply,传参时带上评论id
//
final res = await Http.get('${VideoApi.detail}/${item['vlogID']}');
Get.toNamed('/vloger', arguments: res['data']);
// Get.toNamed('/vloger');
},
child: ClipOval(
child: NetworkOrAssetImage(
imageUrl: item['faceUrl'],
width: 50,
height: 50,
),
),
),
// 消息
Expanded(
child: InkWell(
onTap: () async {
// 点击头像转到对方主页
// 先获取视频详情
// 如果cloudCustomData是interactionCommentinteractionAtinteractionReply,传参时带上评论id
//
final res = await Http.get('${VideoApi.detail}/${item['vlogID']}');
Get.toNamed('/vloger', arguments: res['data']);
// Get.toNamed('/vloger');
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
// 昵称
Text(
item['nickName'] ?? '未知',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.normal,
),
),
const SizedBox(height: 2.0),
// 描述内容
Text(
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: const TextStyle(color: Colors.grey, fontSize: 12.0),
desc,
// '很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容',
),
Text(
Utils.formatTime(msg.timestamp ?? DateTime.now().millisecondsSinceEpoch ~/ 1000),
style: TextStyle(
color: Colors.grey[600],
fontSize: 12,
),
),
],
),
),
),
// 右侧
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Visibility(
visible: true,
// 视频首图
child: NetworkOrAssetImage(
imageUrl: item['firstFrameImg'],
placeholderAsset: 'assets/images/bk.jpg',
width: 40,
height: 60,
),
),
const SizedBox(width: 5.0),
// 角标
Visibility(
visible: !(msg.isRead ?? true),
child: FStyle.badge(0, isdot: true),
),
],
),
],
),
);
},
);
})),
),
],
),
),
);
}
}