4.1.1
This commit is contained in:
parent
4c15dee33a
commit
f9a1f2ff9f
1
assets/images/svg/more.svg
Normal file
1
assets/images/svg/more.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1759238468389" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5738" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M256 512m-74.666667 0a74.666667 74.666667 0 1 0 149.333334 0 74.666667 74.666667 0 1 0-149.333334 0Z" fill="#111111" p-id="5739"></path><path d="M512 512m-74.666667 0a74.666667 74.666667 0 1 0 149.333334 0 74.666667 74.666667 0 1 0-149.333334 0Z" fill="#111111" p-id="5740"></path><path d="M768 512m-74.666667 0a74.666667 74.666667 0 1 0 149.333334 0 74.666667 74.666667 0 1 0-149.333334 0Z" fill="#111111" p-id="5741"></path></svg>
|
||||||
|
After Width: | Height: | Size: 765 B |
@ -72,6 +72,13 @@
|
|||||||
<string>App需要访问您的相册用于选择图片或视频</string>
|
<string>App需要访问您的相册用于选择图片或视频</string>
|
||||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>CFBundleLocalizations</key>
|
||||||
|
<array>
|
||||||
|
<string>en</string>
|
||||||
|
<string>zh-Hans</string>
|
||||||
|
</array>
|
||||||
|
<key>ITSAppUsesNonExemptEncryption</key>
|
||||||
|
<false/>
|
||||||
<key>UIBackgroundModes</key>
|
<key>UIBackgroundModes</key>
|
||||||
<array>
|
<array>
|
||||||
<string>remote-notification</string>
|
<string>remote-notification</string>
|
||||||
|
|||||||
@ -47,6 +47,11 @@ class IMMessage {
|
|||||||
title: myInfo.nickname.value,
|
title: myInfo.nickname.value,
|
||||||
desc: parseMessageSummary(msg),
|
desc: parseMessageSummary(msg),
|
||||||
ext: jsonEncode({"userID": myInfo.userID.value, "title": myInfo.nickname.value}),
|
ext: jsonEncode({"userID": myInfo.userID.value, "title": myInfo.nickname.value}),
|
||||||
|
//ios ios>18必须声明
|
||||||
|
iOSPushType: 0, //0=普通消息 1=语音/视频
|
||||||
|
iOSSound: 'default', // kIOSOfflinePushDefaultSound
|
||||||
|
ignoreIOSBadge: false, // 是否忽略角标
|
||||||
|
iOSInterruptionLevel: 'active', // 普通通知 active // time-sensitive
|
||||||
);
|
);
|
||||||
sendRes = await TencentImSDKPlugin.v2TIMManager.getMessageManager().sendMessage(
|
sendRes = await TencentImSDKPlugin.v2TIMManager.getMessageManager().sendMessage(
|
||||||
message: msg,
|
message: msg,
|
||||||
@ -75,7 +80,12 @@ class IMMessage {
|
|||||||
OfflinePushInfo offlinePushInfo = OfflinePushInfo(
|
OfflinePushInfo offlinePushInfo = OfflinePushInfo(
|
||||||
title: groupName,
|
title: groupName,
|
||||||
desc: parseMessageSummary(msg),
|
desc: parseMessageSummary(msg),
|
||||||
ext: jsonEncode({"groupID": groupID, "title": groupName ?? ''}),
|
ext: jsonEncode({"groupID": groupID, "title": groupName ?? '群聊'}),
|
||||||
|
//ios ios>18必须声明
|
||||||
|
iOSPushType: 0, //0=普通消息 1=语音/视频
|
||||||
|
iOSSound: 'default', // kIOSOfflinePushDefaultSound
|
||||||
|
ignoreIOSBadge: false, // 是否忽略角标
|
||||||
|
iOSInterruptionLevel: 'active', // 普通通知
|
||||||
);
|
);
|
||||||
sendRes = await TencentImSDKPlugin.v2TIMManager.getMessageManager().sendMessage(
|
sendRes = await TencentImSDKPlugin.v2TIMManager.getMessageManager().sendMessage(
|
||||||
message: msg,
|
message: msg,
|
||||||
|
|||||||
@ -124,13 +124,23 @@ class ImService {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
logger.i("IM 登录失败:${result.code} - ${result.desc}");
|
logger.i("IM 登录失败:${result.code} - ${result.desc}");
|
||||||
Get.snackbar(
|
if (result.code == 70013) {
|
||||||
'登录失败',
|
Get.snackbar(
|
||||||
'${result.code} - ${result.desc}',
|
'登录失败',
|
||||||
backgroundColor: Colors.red.withAlpha(230),
|
'请求的 Identifier 与生成 UserSig 的 Identifier 不匹配',
|
||||||
colorText: Colors.white,
|
backgroundColor: Colors.red.withAlpha(230),
|
||||||
icon: const Icon(Icons.error_outline, color: Colors.white),
|
colorText: Colors.white,
|
||||||
);
|
icon: const Icon(Icons.error_outline, color: Colors.white),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
Get.snackbar(
|
||||||
|
'登录失败',
|
||||||
|
'${result.code} - ${result.desc}',
|
||||||
|
backgroundColor: Colors.red.withAlpha(230),
|
||||||
|
colorText: Colors.white,
|
||||||
|
icon: const Icon(Icons.error_outline, color: Colors.white),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -136,12 +136,14 @@ class PushService {
|
|||||||
// "userID": "123456",
|
// "userID": "123456",
|
||||||
// "groupID": "654321",
|
// "groupID": "654321",
|
||||||
// });
|
// });
|
||||||
final isGroup = groupID != null && groupID.isNotEmpty;
|
|
||||||
|
|
||||||
final data = jsonDecode(ext);
|
final data = jsonDecode(ext);
|
||||||
logger.i(data);
|
logger.i(data);
|
||||||
|
String extGroupID = data['groupID'] ?? '';
|
||||||
|
final isGroup = extGroupID.isNotEmpty;
|
||||||
|
|
||||||
// final type = data['type'];
|
// final type = data['type'];
|
||||||
final router = conversationTypeFromString(userID); //这里就是解析用于发送消息的管理员的userID
|
|
||||||
|
final router = conversationTypeFromString(data['userID']); //这里就是解析用于发送消息的管理员的userID
|
||||||
logger.w(router);
|
logger.w(router);
|
||||||
if (router == null) {
|
if (router == null) {
|
||||||
// 聊天
|
// 聊天
|
||||||
|
|||||||
@ -50,68 +50,70 @@ class _ImageViewerState extends State<ImageViewer> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var imgCount = widget.images?.length;
|
var imgCount = widget.images?.length;
|
||||||
|
|
||||||
return Scaffold(
|
return SafeArea(
|
||||||
body: Stack(
|
child: Scaffold(
|
||||||
children: [
|
body: Stack(
|
||||||
Positioned(
|
children: [
|
||||||
top: 0,
|
Positioned(
|
||||||
left: 0,
|
top: 0,
|
||||||
bottom: 0,
|
left: 0,
|
||||||
right: 0,
|
bottom: 0,
|
||||||
child: GestureDetector(
|
right: 0,
|
||||||
child: imgCount == 1
|
child: GestureDetector(
|
||||||
? PhotoView(
|
child: imgCount == 1
|
||||||
// imageProvider: Utils.isUrl(widget.images![0]) ? NetworkImage(widget.images![0]) : AssetImage(widget.images![0]),
|
? PhotoView(
|
||||||
imageProvider: getImageProvider(widget.images![0]),
|
// imageProvider: Utils.isUrl(widget.images![0]) ? NetworkImage(widget.images![0]) : AssetImage(widget.images![0]),
|
||||||
backgroundDecoration: const BoxDecoration(
|
imageProvider: getImageProvider(widget.images![0]),
|
||||||
color: Colors.black,
|
backgroundDecoration: const BoxDecoration(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
minScale: PhotoViewComputedScale.contained,
|
||||||
|
maxScale: PhotoViewComputedScale.covered * 2,
|
||||||
|
heroAttributes: PhotoViewHeroAttributes(tag: widget.images![0]),
|
||||||
|
enableRotation: true,
|
||||||
|
)
|
||||||
|
: PhotoViewGallery.builder(
|
||||||
|
itemCount: widget.images?.length,
|
||||||
|
builder: (context, index) {
|
||||||
|
return PhotoViewGalleryPageOptions(
|
||||||
|
imageProvider: Utils.isUrl(widget.images![index]) ? NetworkImage(widget.images![index]) : AssetImage(widget.images![index]),
|
||||||
|
minScale: PhotoViewComputedScale.contained,
|
||||||
|
maxScale: PhotoViewComputedScale.covered * 2,
|
||||||
|
heroAttributes: PhotoViewHeroAttributes(tag: widget.images![index]),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
scrollPhysics: const BouncingScrollPhysics(),
|
||||||
|
backgroundDecoration: const BoxDecoration(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
pageController: PageController(initialPage: widget.index),
|
||||||
|
enableRotation: true,
|
||||||
|
onPageChanged: (index) {
|
||||||
|
setState(() {
|
||||||
|
currentIndex = index;
|
||||||
|
});
|
||||||
|
},
|
||||||
),
|
),
|
||||||
minScale: PhotoViewComputedScale.contained,
|
onTap: () {
|
||||||
maxScale: PhotoViewComputedScale.covered * 2,
|
Get.back();
|
||||||
heroAttributes: PhotoViewHeroAttributes(tag: widget.images![0]),
|
},
|
||||||
enableRotation: true,
|
|
||||||
)
|
|
||||||
: PhotoViewGallery.builder(
|
|
||||||
itemCount: widget.images?.length,
|
|
||||||
builder: (context, index) {
|
|
||||||
return PhotoViewGalleryPageOptions(
|
|
||||||
imageProvider: Utils.isUrl(widget.images![index]) ? NetworkImage(widget.images![index]) : AssetImage(widget.images![index]),
|
|
||||||
minScale: PhotoViewComputedScale.contained,
|
|
||||||
maxScale: PhotoViewComputedScale.covered * 2,
|
|
||||||
heroAttributes: PhotoViewHeroAttributes(tag: widget.images![index]),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
scrollPhysics: const BouncingScrollPhysics(),
|
|
||||||
backgroundDecoration: const BoxDecoration(
|
|
||||||
color: Colors.black,
|
|
||||||
),
|
|
||||||
pageController: PageController(initialPage: widget.index),
|
|
||||||
enableRotation: true,
|
|
||||||
onPageChanged: (index) {
|
|
||||||
setState(() {
|
|
||||||
currentIndex = index;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
onTap: () {
|
|
||||||
Get.back();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
// 图片索引index
|
|
||||||
Positioned(
|
|
||||||
top: MediaQuery.of(context).padding.top + 15,
|
|
||||||
width: MediaQuery.of(context).size.width,
|
|
||||||
child: Center(
|
|
||||||
child: Visibility(
|
|
||||||
visible: imgCount! > 1 ? true : false,
|
|
||||||
child: Text(
|
|
||||||
'${currentIndex + 1} / ${widget.images?.length}',
|
|
||||||
style: const TextStyle(color: Colors.white, fontSize: 16, fontFamily: 'arial'),
|
|
||||||
),
|
),
|
||||||
)),
|
),
|
||||||
),
|
// 图片索引index
|
||||||
],
|
Positioned(
|
||||||
|
top: MediaQuery.of(context).padding.top + 15,
|
||||||
|
width: MediaQuery.of(context).size.width,
|
||||||
|
child: Center(
|
||||||
|
child: Visibility(
|
||||||
|
visible: imgCount! > 1 ? true : false,
|
||||||
|
child: Text(
|
||||||
|
'${currentIndex + 1} / ${widget.images?.length}',
|
||||||
|
style: const TextStyle(color: Colors.white, fontSize: 16, fontFamily: 'arial'),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -502,6 +502,7 @@ class _ChatState extends State<Chat> with SingleTickerProviderStateMixin {
|
|||||||
child: NetworkOrAssetImage(
|
child: NetworkOrAssetImage(
|
||||||
imageUrl: item.videoElem?.snapshotUrl ?? '',
|
imageUrl: item.videoElem?.snapshotUrl ?? '',
|
||||||
width: 120,
|
width: 120,
|
||||||
|
placeholderAsset: 'assets/images/bk.jpg',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Align(
|
const Align(
|
||||||
@ -701,6 +702,7 @@ class _ChatState extends State<Chat> with SingleTickerProviderStateMixin {
|
|||||||
NetworkOrAssetImage(
|
NetworkOrAssetImage(
|
||||||
imageUrl: url,
|
imageUrl: url,
|
||||||
width: 160.0,
|
width: 160.0,
|
||||||
|
placeholderAsset: 'assets/images/bk.jpg',
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 10.0, vertical: 5.0),
|
padding: EdgeInsets.symmetric(horizontal: 10.0, vertical: 5.0),
|
||||||
@ -1606,10 +1608,10 @@ class _ChatState extends State<Chat> with SingleTickerProviderStateMixin {
|
|||||||
if (file != null) {
|
if (file != null) {
|
||||||
var fileSizeInBytes = await file.length();
|
var fileSizeInBytes = await file.length();
|
||||||
var sizeInMB = fileSizeInBytes / (1024 * 1024);
|
var sizeInMB = fileSizeInBytes / (1024 * 1024);
|
||||||
if (sizeInMB > 28) {
|
if (sizeInMB > 100) {
|
||||||
MyDialog.toast('图片大小不能超过28MB', icon: const Icon(Icons.check_circle), style: ToastStyle(backgroundColor: Colors.red.withAlpha(200)));
|
MyDialog.toast('文件大小不能超过100MB', icon: const Icon(Icons.check_circle), style: ToastStyle(backgroundColor: Colors.red.withAlpha(200)));
|
||||||
} else {
|
} else {
|
||||||
print("图片合法,大小:$sizeInMB MB");
|
print("视频合法,大小:$sizeInMB MB");
|
||||||
// 执行发送逻辑
|
// 执行发送逻辑
|
||||||
var snapshot = await generateVideoThumbnail(file.path);
|
var snapshot = await generateVideoThumbnail(file.path);
|
||||||
String? mimeType = await asset.mimeTypeAsync;
|
String? mimeType = await asset.mimeTypeAsync;
|
||||||
@ -1875,7 +1877,7 @@ class _ChatState extends State<Chat> with SingleTickerProviderStateMixin {
|
|||||||
title: Obx(() {
|
title: Obx(() {
|
||||||
return Text(
|
return Text(
|
||||||
// '${arguments['title']}',
|
// '${arguments['title']}',
|
||||||
'${arguments.value.showName}',
|
arguments.value.showName ?? '神秘人',
|
||||||
style: const TextStyle(fontSize: 18.0, fontFamily: 'Arial'),
|
style: const TextStyle(fontSize: 18.0, fontFamily: 'Arial'),
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
|
|||||||
@ -383,6 +383,7 @@ class _ChatGroupState extends State<ChatGroup> with SingleTickerProviderStateMix
|
|||||||
borderRadius: BorderRadius.circular(10.0),
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
child: NetworkOrAssetImage(
|
child: NetworkOrAssetImage(
|
||||||
imageUrl: item.videoElem?.snapshotUrl ?? '',
|
imageUrl: item.videoElem?.snapshotUrl ?? '',
|
||||||
|
placeholderAsset: 'assets/images/bk.jpg',
|
||||||
width: 120,
|
width: 120,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -541,6 +542,7 @@ class _ChatGroupState extends State<ChatGroup> with SingleTickerProviderStateMix
|
|||||||
children: [
|
children: [
|
||||||
NetworkOrAssetImage(
|
NetworkOrAssetImage(
|
||||||
imageUrl: url,
|
imageUrl: url,
|
||||||
|
placeholderAsset: 'assets/images/bk.jpg',
|
||||||
width: 160.0,
|
width: 160.0,
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
@ -1568,7 +1570,7 @@ class _ChatGroupState extends State<ChatGroup> with SingleTickerProviderStateMix
|
|||||||
obj['ids'] = ids.join(',');
|
obj['ids'] = ids.join(',');
|
||||||
data.customElem!.data = jsonEncode(obj);
|
data.customElem!.data = jsonEncode(obj);
|
||||||
// 修改消息体
|
// 修改消息体
|
||||||
ImService.instance.modifyMessage(message: data);
|
await ImService.instance.modifyMessage(message: data);
|
||||||
// 模拟开红包逻辑,1 秒后停止动画
|
// 模拟开红包逻辑,1 秒后停止动画
|
||||||
Future.delayed(Duration(seconds: 1), () {
|
Future.delayed(Duration(seconds: 1), () {
|
||||||
animController.stop();
|
animController.stop();
|
||||||
@ -1585,7 +1587,7 @@ class _ChatGroupState extends State<ChatGroup> with SingleTickerProviderStateMix
|
|||||||
obj['totalCount'] = 0;
|
obj['totalCount'] = 0;
|
||||||
obj['open'] = true; //总开关标记为true
|
obj['open'] = true; //总开关标记为true
|
||||||
data.customElem!.data = jsonEncode(obj);
|
data.customElem!.data = jsonEncode(obj);
|
||||||
ImService.instance.modifyMessage(message: data);
|
await ImService.instance.modifyMessage(message: data);
|
||||||
|
|
||||||
Future.delayed(Duration(seconds: 1), () {
|
Future.delayed(Duration(seconds: 1), () {
|
||||||
animController.stop();
|
animController.stop();
|
||||||
@ -1748,7 +1750,7 @@ class _ChatGroupState extends State<ChatGroup> with SingleTickerProviderStateMix
|
|||||||
),
|
),
|
||||||
titleSpacing: 1.0,
|
titleSpacing: 1.0,
|
||||||
title: Text(
|
title: Text(
|
||||||
'${arguments.showName}',
|
arguments.showName ?? '群聊',
|
||||||
style: const TextStyle(fontSize: 18.0, fontFamily: 'Arial'),
|
style: const TextStyle(fontSize: 18.0, fontFamily: 'Arial'),
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
|
|||||||
@ -441,6 +441,7 @@ class _ChatNoFriendState extends State<ChatNoFriend> with SingleTickerProviderSt
|
|||||||
child: NetworkOrAssetImage(
|
child: NetworkOrAssetImage(
|
||||||
imageUrl: item.videoElem?.snapshotUrl ?? '',
|
imageUrl: item.videoElem?.snapshotUrl ?? '',
|
||||||
width: 120,
|
width: 120,
|
||||||
|
placeholderAsset: 'assets/images/bk.jpg',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Align(
|
const Align(
|
||||||
@ -605,6 +606,7 @@ class _ChatNoFriendState extends State<ChatNoFriend> with SingleTickerProviderSt
|
|||||||
children: [
|
children: [
|
||||||
NetworkOrAssetImage(
|
NetworkOrAssetImage(
|
||||||
imageUrl: url,
|
imageUrl: url,
|
||||||
|
placeholderAsset: 'assets/images/bk.jpg',
|
||||||
width: 160.0,
|
width: 160.0,
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
@ -1515,7 +1517,7 @@ class _ChatNoFriendState extends State<ChatNoFriend> with SingleTickerProviderSt
|
|||||||
title: Obx(() {
|
title: Obx(() {
|
||||||
return Text(
|
return Text(
|
||||||
// '${arguments['title']}',
|
// '${arguments['title']}',
|
||||||
'${arguments.value.showName}',
|
arguments.value.showName ?? '陌生人',
|
||||||
style: const TextStyle(fontSize: 18.0, fontFamily: 'Arial'),
|
style: const TextStyle(fontSize: 18.0, fontFamily: 'Arial'),
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
|
|||||||
@ -103,6 +103,7 @@ class ChatPageState extends State<ChatPage> {
|
|||||||
final controller = Get.find<ImUserInfoController>();
|
final controller = Get.find<ImUserInfoController>();
|
||||||
final role = controller.role.value;
|
final role = controller.role.value;
|
||||||
final isSeller = Utils.hasRole(role, 2);
|
final isSeller = Utils.hasRole(role, 2);
|
||||||
|
// writeOffCodeId
|
||||||
if (isSeller) {
|
if (isSeller) {
|
||||||
// 带着核销码,跳转到商家的商品详情页面,引导商家去手动点击核销按钮
|
// 带着核销码,跳转到商家的商品详情页面,引导商家去手动点击核销按钮
|
||||||
Get.toNamed('/sellerOrder/detail', arguments: {'writeOffCodeId': value});
|
Get.toNamed('/sellerOrder/detail', arguments: {'writeOffCodeId': value});
|
||||||
@ -638,6 +639,8 @@ class ChatPageState extends State<ChatPage> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
// logger.e(chatList[index].isCustomAdmin);
|
||||||
|
|
||||||
if (conversationTypeFromString(chatList[index].isCustomAdmin) != null) {
|
if (conversationTypeFromString(chatList[index].isCustomAdmin) != null) {
|
||||||
// 跳转对应的通知消息页 notify下的内容
|
// 跳转对应的通知消息页 notify下的内容
|
||||||
logger.e(chatList[index].isCustomAdmin);
|
logger.e(chatList[index].isCustomAdmin);
|
||||||
|
|||||||
@ -7,13 +7,11 @@ import 'package:easy_refresh/easy_refresh.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:loopin/IM/im_service.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/behavior/custom_scroll_behavior.dart';
|
||||||
import 'package:loopin/components/empty_tip.dart';
|
import 'package:loopin/components/empty_tip.dart';
|
||||||
import 'package:loopin/components/network_or_asset_image.dart';
|
import 'package:loopin/components/network_or_asset_image.dart';
|
||||||
import 'package:loopin/models/conversation_type.dart';
|
import 'package:loopin/models/conversation_type.dart';
|
||||||
import 'package:loopin/models/notify_message.type.dart';
|
import 'package:loopin/models/notify_message.type.dart';
|
||||||
import 'package:loopin/service/http.dart';
|
|
||||||
import 'package:loopin/styles/index.dart';
|
import 'package:loopin/styles/index.dart';
|
||||||
import 'package:loopin/utils/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_conversation.dart';
|
||||||
@ -93,7 +91,7 @@ class InteractionState extends State<Interaction> with SingleTickerProviderState
|
|||||||
Future<void> getMsgData() async {
|
Future<void> getMsgData() async {
|
||||||
// 获取最旧一条消息作为游标
|
// 获取最旧一条消息作为游标
|
||||||
V2TimMessage? lastRealMsg;
|
V2TimMessage? lastRealMsg;
|
||||||
lastRealMsg = msgList.last;
|
lastRealMsg = msgList.isEmpty ? null : msgList.last;
|
||||||
final res = await ImService.instance.getHistoryMessageList(
|
final res = await ImService.instance.getHistoryMessageList(
|
||||||
userID: ConversationType.interaction.name, // userID为固定的interaction
|
userID: ConversationType.interaction.name, // userID为固定的interaction
|
||||||
lastMsg: lastRealMsg,
|
lastMsg: lastRealMsg,
|
||||||
@ -118,13 +116,34 @@ class InteractionState extends State<Interaction> with SingleTickerProviderState
|
|||||||
// 获取不同的消息分类数据
|
// 获取不同的消息分类数据
|
||||||
void _filterMessages(String filterType) async {
|
void _filterMessages(String filterType) async {
|
||||||
logger.e(filterType);
|
logger.e(filterType);
|
||||||
|
if (filterType == 'all') {
|
||||||
|
getMsgData();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 非全部
|
||||||
|
String keyword;
|
||||||
|
// interactionComment, //互动->评论
|
||||||
|
// interactionAt, //互动->视频评论中的@
|
||||||
|
// interactionLike, //互动->点赞
|
||||||
|
// interactionReply, //互动->评论回复
|
||||||
|
if (filterType == 'interactionComment') {
|
||||||
|
keyword = '评论';
|
||||||
|
} else if (filterType == 'interactionLike') {
|
||||||
|
keyword = '点赞';
|
||||||
|
} else if (filterType == 'interactionReply') {
|
||||||
|
keyword = '回复';
|
||||||
|
} else {
|
||||||
|
keyword = '视频'; //这个兜底
|
||||||
|
}
|
||||||
final res = await ImService.instance.searchLocalMessages(
|
final res = await ImService.instance.searchLocalMessages(
|
||||||
page: page,
|
page: page,
|
||||||
conversationID: 'c2c_${ConversationType.interaction.name}',
|
conversationID: 'c2c_${ConversationType.interaction.name}',
|
||||||
keywordList: ['action', filterType],
|
keywordList: [keyword],
|
||||||
|
// keywordList: ['action', filterType], //interactionLike
|
||||||
);
|
);
|
||||||
logger.e(res.data!.toLogString());
|
logger.e(res.data!.toJson());
|
||||||
if (res.success && res.data != null) {
|
if (res.success && res.data != null) {
|
||||||
|
msgList.clear();
|
||||||
final resultList = res.data?.messageSearchResultItems ?? [];
|
final resultList = res.data?.messageSearchResultItems ?? [];
|
||||||
if (resultList.isNotEmpty) {
|
if (resultList.isNotEmpty) {
|
||||||
for (var item in resultList) {
|
for (var item in resultList) {
|
||||||
@ -132,6 +151,7 @@ class InteractionState extends State<Interaction> with SingleTickerProviderState
|
|||||||
msgList.addAll(item.messageList ?? []);
|
msgList.addAll(item.messageList ?? []);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
msgList.clear();
|
||||||
logger.e('数据为空${res.desc}');
|
logger.e('数据为空${res.desc}');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -244,15 +264,15 @@ class InteractionState extends State<Interaction> with SingleTickerProviderState
|
|||||||
child: EasyRefresh.builder(
|
child: EasyRefresh.builder(
|
||||||
callLoadOverOffset: 20, //触底距离
|
callLoadOverOffset: 20, //触底距离
|
||||||
callRefreshOverOffset: 20, // 下拉距离
|
callRefreshOverOffset: 20, // 下拉距离
|
||||||
header: ClassicHeader(
|
// header: ClassicHeader(
|
||||||
dragText: '下拉刷新',
|
// dragText: '下拉刷新',
|
||||||
armedText: '释放刷新',
|
// armedText: '释放刷新',
|
||||||
readyText: '加载中...',
|
// readyText: '加载中...',
|
||||||
processingText: '加载中...',
|
// processingText: '加载中...',
|
||||||
processedText: '加载完成',
|
// processedText: '加载完成',
|
||||||
failedText: '加载失败,请重试',
|
// failedText: '加载失败,请重试',
|
||||||
messageText: '最后更新于 %T',
|
// messageText: '最后更新于 %T',
|
||||||
),
|
// ),
|
||||||
footer: ClassicFooter(
|
footer: ClassicFooter(
|
||||||
dragText: '加载更多',
|
dragText: '加载更多',
|
||||||
armedText: '释放加载',
|
armedText: '释放加载',
|
||||||
@ -263,11 +283,11 @@ class InteractionState extends State<Interaction> with SingleTickerProviderState
|
|||||||
failedText: '加载失败,请重试',
|
failedText: '加载失败,请重试',
|
||||||
messageText: '最后更新于 %T',
|
messageText: '最后更新于 %T',
|
||||||
),
|
),
|
||||||
onRefresh: () async {
|
// onRefresh: () async {
|
||||||
await handleRefresh();
|
// await handleRefresh();
|
||||||
},
|
// },
|
||||||
onLoad: () async {
|
onLoad: () async {
|
||||||
if (hasMore.value) {
|
if (selectedMessageType.value != 'all' && hasMore.value) {
|
||||||
await getMsgData();
|
await getMsgData();
|
||||||
return hasMore.value ? IndicatorResult.success : IndicatorResult.noMore;
|
return hasMore.value ? IndicatorResult.success : IndicatorResult.noMore;
|
||||||
}
|
}
|
||||||
@ -297,6 +317,8 @@ class InteractionState extends State<Interaction> with SingleTickerProviderState
|
|||||||
final desc = msgList[index].customElem!.desc!;
|
final desc = msgList[index].customElem!.desc!;
|
||||||
final jsonData = msgList[index].customElem!.data ?? '{"faceUrl":"","nickName":"data为null","userID":"213213"}';
|
final jsonData = msgList[index].customElem!.data ?? '{"faceUrl":"","nickName":"data为null","userID":"213213"}';
|
||||||
final item = jsonDecode(jsonData); // 数据
|
final item = jsonDecode(jsonData); // 数据
|
||||||
|
logger.e(item);
|
||||||
|
|
||||||
// ----测试数据
|
// ----测试数据
|
||||||
// final jsonData = '{"faceUrl":"","nickName":"测试昵称","userID":"213213"}';
|
// final jsonData = '{"faceUrl":"","nickName":"测试昵称","userID":"213213"}';
|
||||||
// final item = jsonDecode(jsonData); // 数据
|
// final item = jsonDecode(jsonData); // 数据
|
||||||
@ -310,15 +332,14 @@ class InteractionState extends State<Interaction> with SingleTickerProviderState
|
|||||||
spacing: 10.0,
|
spacing: 10.0,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
// 头像
|
// 头像
|
||||||
InkWell(
|
GestureDetector(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
// 点击头像转到对方主页
|
// 点击头像转到对方主页
|
||||||
// 先获取视频详情
|
// 先获取视频详情
|
||||||
// 如果cloudCustomData是interactionComment,interactionAt,interactionReply,传参时带上评论id,这三个是评论相关的
|
// 如果cloudCustomData是interactionComment,interactionAt,interactionReply,传参时带上评论id,这三个是评论相关的
|
||||||
//
|
//
|
||||||
final res = await Http.get('${VideoApi.detail}/${item['vlogID']}');
|
// final res = await Http.get('${VideoApi.detail}/${item['vlogID']}');
|
||||||
// 此人存在才做跳转
|
Get.toNamed('/vloger', arguments: {'memberId': item['userID']});
|
||||||
Get.toNamed('/vloger', arguments: res['data']);
|
|
||||||
},
|
},
|
||||||
child: ClipOval(
|
child: ClipOval(
|
||||||
child: NetworkOrAssetImage(
|
child: NetworkOrAssetImage(
|
||||||
@ -331,15 +352,13 @@ class InteractionState extends State<Interaction> with SingleTickerProviderState
|
|||||||
|
|
||||||
// 消息
|
// 消息
|
||||||
Expanded(
|
Expanded(
|
||||||
child: InkWell(
|
child: GestureDetector(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
// 点击头像转到对方主页
|
// 点击头像转到对方主页
|
||||||
// 先获取视频详情
|
// 先获取视频详情
|
||||||
// 如果cloudCustomData是interactionComment,interactionAt,interactionReply,传参时带上评论id,
|
// 如果cloudCustomData是interactionComment,interactionAt,interactionReply,传参时带上评论id,
|
||||||
//
|
logger.e(item);
|
||||||
final res = await Http.get('${VideoApi.detail}/${item['vlogID']}');
|
Get.toNamed('/videoDetail', arguments: {'videoId': item['vlogID']});
|
||||||
Get.toNamed('/vloger', arguments: res['data']);
|
|
||||||
// Get.toNamed('/vloger');
|
|
||||||
},
|
},
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
@ -373,26 +392,31 @@ class InteractionState extends State<Interaction> with SingleTickerProviderState
|
|||||||
),
|
),
|
||||||
|
|
||||||
// 右侧
|
// 右侧
|
||||||
Row(
|
GestureDetector(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
onTap: () {
|
||||||
children: <Widget>[
|
Get.toNamed('/videoDetail', arguments: {'videoId': item['vlogID']});
|
||||||
Visibility(
|
},
|
||||||
visible: true,
|
child: Row(
|
||||||
// 视频首图
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
child: NetworkOrAssetImage(
|
children: <Widget>[
|
||||||
imageUrl: item['firstFrameImg'],
|
Visibility(
|
||||||
placeholderAsset: 'assets/images/bk.jpg',
|
visible: true,
|
||||||
width: 40,
|
// 视频首图
|
||||||
height: 60,
|
child: NetworkOrAssetImage(
|
||||||
|
imageUrl: item['firstFrameImg'],
|
||||||
|
placeholderAsset: 'assets/images/bk.jpg',
|
||||||
|
width: 40,
|
||||||
|
height: 60,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(width: 5.0),
|
||||||
const SizedBox(width: 5.0),
|
// 角标
|
||||||
// 角标
|
Visibility(
|
||||||
Visibility(
|
visible: !(element.isRead ?? true),
|
||||||
visible: !(element.isRead ?? true),
|
child: FStyle.badge(0, isdot: true),
|
||||||
child: FStyle.badge(0, isdot: true),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@ -7,13 +7,10 @@ import 'package:easy_refresh/easy_refresh.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:loopin/IM/im_service.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/behavior/custom_scroll_behavior.dart';
|
||||||
import 'package:loopin/components/empty_tip.dart';
|
import 'package:loopin/components/empty_tip.dart';
|
||||||
import 'package:loopin/components/my_toast.dart';
|
|
||||||
import 'package:loopin/components/network_or_asset_image.dart';
|
import 'package:loopin/components/network_or_asset_image.dart';
|
||||||
import 'package:loopin/models/conversation_type.dart';
|
import 'package:loopin/models/conversation_type.dart';
|
||||||
import 'package:loopin/service/http.dart';
|
|
||||||
import 'package:loopin/styles/index.dart';
|
import 'package:loopin/styles/index.dart';
|
||||||
import 'package:loopin/utils/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_conversation.dart';
|
||||||
@ -187,6 +184,7 @@ class NewfoucsState extends State<Newfoucs> with SingleTickerProviderStateMixin
|
|||||||
jsonData = (jsonData == null || jsonData.isEmpty) ? '{"faceUrl":"","nickName":"data为空","userID":"213213"}' : jsonData;
|
jsonData = (jsonData == null || jsonData.isEmpty) ? '{"faceUrl":"","nickName":"data为空","userID":"213213"}' : jsonData;
|
||||||
|
|
||||||
final item = jsonDecode(jsonData);
|
final item = jsonDecode(jsonData);
|
||||||
|
logger.e(item);
|
||||||
|
|
||||||
logger.w(element.toJson());
|
logger.w(element.toJson());
|
||||||
|
|
||||||
@ -210,13 +208,7 @@ class NewfoucsState extends State<Newfoucs> with SingleTickerProviderStateMixin
|
|||||||
// 先获取视频详情
|
// 先获取视频详情
|
||||||
// 如果cloudCustomData是interactionComment,interactionAt,interactionReply,传参时带上评论id,
|
// 如果cloudCustomData是interactionComment,interactionAt,interactionReply,传参时带上评论id,
|
||||||
//
|
//
|
||||||
final res = await Http.get('${VideoApi.detail}/${item['vlogID']}');
|
Get.toNamed('/vloger', arguments: {'memberId': item['userID']});
|
||||||
if (res['data'] == null) {
|
|
||||||
MyToast().tip(title: '视频数据不存在', position: 'top');
|
|
||||||
} else {
|
|
||||||
// 这里跟视频首页一样,跳转博主主页时传视频详情数据
|
|
||||||
Get.toNamed('/vloger', arguments: res['data']);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
child: ClipOval(
|
child: ClipOval(
|
||||||
child: NetworkOrAssetImage(
|
child: NetworkOrAssetImage(
|
||||||
@ -232,8 +224,8 @@ class NewfoucsState extends State<Newfoucs> with SingleTickerProviderStateMixin
|
|||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
// 点击头像转到对方主页,先获取视频详情
|
// 点击头像转到对方主页,先获取视频详情
|
||||||
final res = await Http.get('${VideoApi.detail}/${item['vlogID']}');
|
Get.toNamed('/vloger', arguments: {'memberId': item['userID']});
|
||||||
Get.toNamed('/vloger', arguments: res['data']);
|
|
||||||
// Get.toNamed('/vloger');
|
// Get.toNamed('/vloger');
|
||||||
},
|
},
|
||||||
child: Column(
|
child: Column(
|
||||||
|
|||||||
@ -190,7 +190,8 @@ class _GoodsState extends State<Goods> {
|
|||||||
|
|
||||||
void handlCoverClick(V2TimConversation conv) async {
|
void handlCoverClick(V2TimConversation conv) async {
|
||||||
// 发送自定义消息 商品信息
|
// 发送自定义消息 商品信息
|
||||||
final userId = conv.userID;
|
final isGroup = conv.groupID != null && (conv.groupID ?? '').isNotEmpty;
|
||||||
|
final id = isGroup ? conv.groupID : conv.userID;
|
||||||
//price,title,url,sell
|
//price,title,url,sell
|
||||||
logger.w(shopObj['name']);
|
logger.w(shopObj['name']);
|
||||||
final makeJson = jsonEncode({
|
final makeJson = jsonEncode({
|
||||||
@ -205,7 +206,12 @@ class _GoodsState extends State<Goods> {
|
|||||||
data: makeJson,
|
data: makeJson,
|
||||||
);
|
);
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
final sendRes = await IMMessage().sendMessage(msg: res.data!.messageInfo!, toUserID: userId, cloudCustomData: SummaryType.shareTuangou);
|
final sendRes = await IMMessage().sendMessage(
|
||||||
|
msg: res.data!.messageInfo!,
|
||||||
|
groupID: isGroup ? id : null,
|
||||||
|
toUserID: isGroup ? null : id,
|
||||||
|
cloudCustomData: SummaryType.shareTuangou,
|
||||||
|
);
|
||||||
if (sendRes.success) {
|
if (sendRes.success) {
|
||||||
MyToast().tip(
|
MyToast().tip(
|
||||||
title: '分享成功',
|
title: '分享成功',
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import 'package:easy_refresh/easy_refresh.dart';
|
import 'package:easy_refresh/easy_refresh.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:loopin/IM/im_service.dart';
|
import 'package:loopin/IM/im_service.dart';
|
||||||
|
import 'package:loopin/components/network_or_asset_image.dart';
|
||||||
import 'package:loopin/styles/index.dart';
|
import 'package:loopin/styles/index.dart';
|
||||||
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart';
|
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_full_info.dart';
|
||||||
import 'package:tencent_cloud_chat_sdk/models/v2_tim_user_full_info.dart';
|
import 'package:tencent_cloud_chat_sdk/models/v2_tim_user_full_info.dart';
|
||||||
@ -184,6 +185,7 @@ class _MemberActionSheetState extends State<InviteActionSheet> {
|
|||||||
final showName = uname.isEmpty ? nickname : uname;
|
final showName = uname.isEmpty ? nickname : uname;
|
||||||
return InkWell(
|
return InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
FocusScope.of(context).unfocus();
|
||||||
setState(() {
|
setState(() {
|
||||||
if (_selectedIDs.contains(id)) {
|
if (_selectedIDs.contains(id)) {
|
||||||
_selectedIDs.remove(id);
|
_selectedIDs.remove(id);
|
||||||
@ -196,12 +198,15 @@ class _MemberActionSheetState extends State<InviteActionSheet> {
|
|||||||
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
|
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
// 左侧圆形头像
|
// 头像
|
||||||
CircleAvatar(
|
ClipOval(
|
||||||
radius: 20,
|
child: NetworkOrAssetImage(
|
||||||
backgroundImage: m.faceUrl != null ? NetworkImage(m.faceUrl!) : null,
|
imageUrl: m.faceUrl ?? '',
|
||||||
child: m.faceUrl == null ? const Icon(Icons.person) : null,
|
width: 40.0,
|
||||||
|
height: 40.0,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
const SizedBox(width: 12),
|
const SizedBox(width: 12),
|
||||||
|
|
||||||
// 用户名
|
// 用户名
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import 'package:easy_refresh/easy_refresh.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:loopin/IM/im_service.dart';
|
import 'package:loopin/IM/im_service.dart';
|
||||||
|
import 'package:loopin/components/network_or_asset_image.dart';
|
||||||
import 'package:loopin/pages/groupChat/controller/group_detail_controller.dart';
|
import 'package:loopin/pages/groupChat/controller/group_detail_controller.dart';
|
||||||
import 'package:loopin/styles/index.dart';
|
import 'package:loopin/styles/index.dart';
|
||||||
import 'package:tencent_cloud_chat_sdk/enum/group_member_filter_enum.dart';
|
import 'package:tencent_cloud_chat_sdk/enum/group_member_filter_enum.dart';
|
||||||
@ -50,6 +51,7 @@ class _MemberActionSheetState extends State<MemberActionSheet> {
|
|||||||
final self = Get.find<GroupDetailController>().selfInfo.value!;
|
final self = Get.find<GroupDetailController>().selfInfo.value!;
|
||||||
members.insert(0, self);
|
members.insert(0, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
getMemberData();
|
getMemberData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +61,7 @@ class _MemberActionSheetState extends State<MemberActionSheet> {
|
|||||||
loading = true;
|
loading = true;
|
||||||
final res = await ImService.instance.getGroupMemberList(
|
final res = await ImService.instance.getGroupMemberList(
|
||||||
groupID: widget.groupID,
|
groupID: widget.groupID,
|
||||||
filter: GroupMemberFilterTypeEnum.V2TIM_GROUP_MEMBER_FILTER_COMMON,
|
filter: GroupMemberFilterTypeEnum.V2TIM_GROUP_MEMBER_FILTER_ALL,
|
||||||
nextSeq: nextSeq,
|
nextSeq: nextSeq,
|
||||||
count: 100,
|
count: 100,
|
||||||
);
|
);
|
||||||
@ -67,8 +69,13 @@ class _MemberActionSheetState extends State<MemberActionSheet> {
|
|||||||
logger.e(res.data!.nextSeq);
|
logger.e(res.data!.nextSeq);
|
||||||
nextSeq = res.data!.nextSeq ?? '0';
|
nextSeq = res.data!.nextSeq ?? '0';
|
||||||
final mem = res.data!.memberInfoList ?? [];
|
final mem = res.data!.memberInfoList ?? [];
|
||||||
setState(() {
|
//去重自己
|
||||||
|
if (widget.showSelf) {
|
||||||
members.addAll(mem);
|
members.addAll(mem);
|
||||||
|
members = {for (var m in members) m.userID: m}.values.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(() {
|
||||||
hasMore = res.data!.nextSeq == '0' ? false : true;
|
hasMore = res.data!.nextSeq == '0' ? false : true;
|
||||||
loading = false;
|
loading = false;
|
||||||
});
|
});
|
||||||
@ -131,7 +138,7 @@ class _MemberActionSheetState extends State<MemberActionSheet> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
List filteredMembers;
|
List<V2TimGroupMemberFullInfo> filteredMembers;
|
||||||
if (_query.isEmpty) {
|
if (_query.isEmpty) {
|
||||||
filteredMembers = members;
|
filteredMembers = members;
|
||||||
} else {
|
} else {
|
||||||
@ -223,11 +230,22 @@ class _MemberActionSheetState extends State<MemberActionSheet> {
|
|||||||
final showName = uname.isEmpty ? nickname : uname;
|
final showName = uname.isEmpty ? nickname : uname;
|
||||||
return InkWell(
|
return InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
FocusScope.of(context).unfocus();
|
||||||
setState(() {
|
setState(() {
|
||||||
if (_selectedIDs.contains(id)) {
|
if (widget.showSelf) {
|
||||||
_selectedIDs.remove(id);
|
// 显示自己=查看群成员,这里后面加查看群成员资料,先跳去博主的主页吧
|
||||||
|
final selfInfo = Get.find<GroupDetailController>().selfInfo.value ?? V2TimGroupMemberFullInfo(userID: '');
|
||||||
|
final currentUserID = selfInfo.userID;
|
||||||
|
if (m.userID != currentUserID) {
|
||||||
|
Get.toNamed('/vloger', arguments: {'memberId': m.userID});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
_selectedIDs.add(id);
|
// false=移除群成员
|
||||||
|
if (_selectedIDs.contains(id)) {
|
||||||
|
_selectedIDs.remove(id);
|
||||||
|
} else {
|
||||||
|
_selectedIDs.add(id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -235,11 +253,13 @@ class _MemberActionSheetState extends State<MemberActionSheet> {
|
|||||||
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
|
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
// 左侧圆形头像
|
// 头像
|
||||||
CircleAvatar(
|
ClipOval(
|
||||||
radius: 20,
|
child: NetworkOrAssetImage(
|
||||||
backgroundImage: m.faceUrl != null ? NetworkImage(m.faceUrl!) : null,
|
imageUrl: m.faceUrl ?? '',
|
||||||
child: m.faceUrl == null ? const Icon(Icons.person) : null,
|
width: 40.0,
|
||||||
|
height: 40.0,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 12),
|
const SizedBox(width: 12),
|
||||||
|
|
||||||
|
|||||||
@ -166,51 +166,116 @@ class GroupdetailState extends State<Groupdetail> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Row(
|
||||||
Utils.handleText(controller.info.value?.groupName, '', "未命名群聊"),
|
mainAxisSize: MainAxisSize.max,
|
||||||
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
|
children: [
|
||||||
maxLines: 1,
|
Flexible(
|
||||||
overflow: TextOverflow.ellipsis,
|
child: Text(
|
||||||
|
Utils.handleText(controller.info.value?.groupName, '', "未命名群聊"),
|
||||||
|
// '很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长',
|
||||||
|
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 10,
|
||||||
|
),
|
||||||
|
if (controller.isOwner.value)
|
||||||
|
Icon(
|
||||||
|
Icons.edit,
|
||||||
|
size: 14,
|
||||||
|
)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// 群简介
|
// 群简介
|
||||||
subtitle: Obx(
|
subtitle: Padding(
|
||||||
() => GestureDetector(
|
padding: const EdgeInsets.only(top: 6.0),
|
||||||
onTap: () {
|
child: Obx(
|
||||||
// 去setinfo页
|
() => GestureDetector(
|
||||||
logger.w('点了简介绍');
|
onTap: () {
|
||||||
if (controller.isOwner.value) {
|
// 去setinfo页
|
||||||
Get.to(
|
logger.w('点了简介绍');
|
||||||
() => SetGroupInfoPage(
|
if (controller.isOwner.value) {
|
||||||
appBarTitle: "修改群简介",
|
Get.to(
|
||||||
fieldLabel: "群简介",
|
() => SetGroupInfoPage(
|
||||||
maxLines: 5,
|
appBarTitle: "修改群简介",
|
||||||
maxLength: 100,
|
fieldLabel: "群简介",
|
||||||
initialValue: controller.info.value?.introduction ?? "",
|
maxLines: 5,
|
||||||
onSubmit: (value) async {
|
maxLength: 100,
|
||||||
// 修改群名称
|
initialValue: controller.info.value?.introduction ?? "",
|
||||||
await controller.setGroupInfo(
|
onSubmit: (value) async {
|
||||||
changedInfo: V2TimGroupInfo(
|
// 修改群名称
|
||||||
groupID: controller.info.value!.groupID,
|
await controller.setGroupInfo(
|
||||||
groupType: GroupType.Work,
|
changedInfo: V2TimGroupInfo(
|
||||||
introduction: value,
|
groupID: controller.info.value!.groupID,
|
||||||
|
groupType: GroupType.Work,
|
||||||
|
introduction: value,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// 普通成员点击,查看完成的描述内容
|
||||||
|
showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
|
||||||
|
),
|
||||||
|
isScrollControlled: true, // 超出可滚动
|
||||||
|
builder: (ctx) => SafeArea(
|
||||||
|
child: Container(
|
||||||
|
width: double.infinity, // 👈 占满宽度
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min, // 根据内容自适应高度
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
const Text(
|
||||||
|
"群简介",
|
||||||
|
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
Text(
|
||||||
|
Utils.handleText(controller.info.value?.introduction, '', "暂无群介绍"),
|
||||||
|
style: const TextStyle(fontSize: 14),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
},
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Row(mainAxisSize: MainAxisSize.max, children: [
|
||||||
|
Flexible(
|
||||||
|
child: Text(
|
||||||
|
Utils.handleText(controller.info.value?.introduction, '', "暂无群介绍"),
|
||||||
|
// '非常长的内容非常长的内容非常长的内容非常长的内容非常长的内容非常长的内容',
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: const TextStyle(color: Colors.grey),
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
}
|
SizedBox(
|
||||||
},
|
width: 10,
|
||||||
child: Text(
|
),
|
||||||
Utils.handleText(controller.info.value?.introduction, '', "暂无群介绍"),
|
if (controller.isOwner.value)
|
||||||
maxLines: 1,
|
Icon(
|
||||||
overflow: TextOverflow.ellipsis,
|
Icons.edit,
|
||||||
style: const TextStyle(color: Colors.grey),
|
size: 14,
|
||||||
|
)
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
trailing: const Icon(Icons.chevron_right),
|
// trailing: const Icon(Icons.chevron_right),
|
||||||
),
|
),
|
||||||
const Divider(height: 1),
|
const Divider(height: 1),
|
||||||
|
|
||||||
@ -252,135 +317,135 @@ class GroupdetailState extends State<Groupdetail> {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
// 群成员头像区域
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||||
child: Wrap(
|
child: Obx(() {
|
||||||
spacing: 16,
|
// 成员头像
|
||||||
runSpacing: 12,
|
final memberWidgets = controller.memberList.take(8).map((m) {
|
||||||
children: [
|
return GestureDetector(
|
||||||
Obx(
|
|
||||||
() {
|
|
||||||
return Wrap(
|
|
||||||
spacing: 16,
|
|
||||||
runSpacing: 12,
|
|
||||||
children: controller.memberList.take(8).map((m) {
|
|
||||||
// 点击成员头像
|
|
||||||
return GestureDetector(
|
|
||||||
onTap: () {
|
|
||||||
final currentUserID = controller.selfInfo.value?.userID ?? '';
|
|
||||||
if (m.userID != currentUserID) {
|
|
||||||
Get.toNamed('/vloger', arguments: {'memberId': m.userID});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
ClipOval(
|
|
||||||
child: NetworkOrAssetImage(
|
|
||||||
imageUrl: m.faceUrl,
|
|
||||||
height: 50,
|
|
||||||
width: 50,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 4),
|
|
||||||
SizedBox(
|
|
||||||
width: 50,
|
|
||||||
child: Text(
|
|
||||||
m.nickName ?? '未知昵称',
|
|
||||||
maxLines: 1,
|
|
||||||
softWrap: false,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
style: const TextStyle(fontSize: 12),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}).toList(),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
// 邀请 +
|
|
||||||
GestureDetector(
|
|
||||||
onTap: () {
|
onTap: () {
|
||||||
//检测群人数上限,
|
final currentUserID = controller.selfInfo.value?.userID ?? '';
|
||||||
logger.w('当前人数${controller.info.value?.memberCount ?? 0}---上限人数${controller.info.value?.memberMaxCount ?? 0}');
|
if (m.userID != currentUserID) {
|
||||||
if ((controller.info.value?.memberCount ?? 0) < (controller.info.value?.memberMaxCount ?? 0)) {
|
Get.toNamed('/vloger', arguments: {'memberId': m.userID});
|
||||||
// 群人数未达到上限,可以继续加人
|
|
||||||
showModalBottomSheet(
|
|
||||||
context: context,
|
|
||||||
barrierColor: Colors.white,
|
|
||||||
isScrollControlled: true,
|
|
||||||
useSafeArea: true,
|
|
||||||
shape: const RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
|
|
||||||
),
|
|
||||||
builder: (context) {
|
|
||||||
return InviteActionSheet(
|
|
||||||
groupID: controller.groupID,
|
|
||||||
title: '邀请新成员',
|
|
||||||
onAction: (userIDs) {
|
|
||||||
logger.w("准备添加群成员: $userIDs");
|
|
||||||
controller.inviteUserToGroup(userList: userIDs);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
MyToast().tip(title: '群人数已达上限', position: 'top');
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Column(
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
CircleAvatar(
|
ClipOval(
|
||||||
radius: 25,
|
child: NetworkOrAssetImage(
|
||||||
child: const Icon(Icons.add),
|
imageUrl: m.faceUrl,
|
||||||
|
height: 50,
|
||||||
|
width: 50,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
const Text("邀请", style: TextStyle(fontSize: 12)),
|
SizedBox(
|
||||||
|
width: 50,
|
||||||
|
child: Text(
|
||||||
|
m.nickName ?? '未知昵称',
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
softWrap: false,
|
||||||
|
style: const TextStyle(fontSize: 12),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
);
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
// 邀请按钮
|
||||||
|
final inviteWidget = GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
logger.w('当前人数${controller.info.value?.memberCount ?? 0}---上限人数${controller.info.value?.memberMaxCount ?? 0}');
|
||||||
|
if ((controller.info.value?.memberCount ?? 0) < (controller.info.value?.memberMaxCount ?? 0)) {
|
||||||
|
showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
barrierColor: Colors.white,
|
||||||
|
isScrollControlled: true,
|
||||||
|
useSafeArea: true,
|
||||||
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
|
||||||
|
),
|
||||||
|
builder: (context) {
|
||||||
|
return InviteActionSheet(
|
||||||
|
groupID: controller.groupID,
|
||||||
|
title: '邀请新成员',
|
||||||
|
onAction: (userIDs) {
|
||||||
|
logger.w("准备添加群成员: $userIDs");
|
||||||
|
controller.inviteUserToGroup(userList: userIDs);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
MyToast().tip(title: '群人数已达上限', position: 'top');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: const [
|
||||||
|
CircleAvatar(radius: 25, child: Icon(Icons.add)),
|
||||||
|
SizedBox(height: 4),
|
||||||
|
Text("邀请", style: TextStyle(fontSize: 12)),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
// 移除 -
|
);
|
||||||
Obx(
|
|
||||||
() => controller.isOwner.value
|
// 移除按钮(只有群主显示)
|
||||||
? GestureDetector(
|
final removeWidget = controller.isOwner.value
|
||||||
onTap: () {
|
? GestureDetector(
|
||||||
showModalBottomSheet(
|
onTap: () {
|
||||||
context: context,
|
showModalBottomSheet(
|
||||||
barrierColor: Colors.white,
|
context: context,
|
||||||
isScrollControlled: true,
|
barrierColor: Colors.white,
|
||||||
useSafeArea: true,
|
isScrollControlled: true,
|
||||||
shape: const RoundedRectangleBorder(
|
useSafeArea: true,
|
||||||
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
|
shape: const RoundedRectangleBorder(
|
||||||
),
|
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
|
||||||
builder: (context) {
|
),
|
||||||
return MemberActionSheet(
|
builder: (context) {
|
||||||
groupID: controller.groupID,
|
return MemberActionSheet(
|
||||||
title: '移出成员',
|
groupID: controller.groupID,
|
||||||
onAction: (userIDs) {
|
title: '移出成员',
|
||||||
logger.w("准备移除群成员: $userIDs");
|
onAction: (userIDs) {
|
||||||
controller.kickGroupMember(userIDs);
|
logger.w("准备移除群成员: $userIDs");
|
||||||
},
|
controller.kickGroupMember(userIDs);
|
||||||
);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: Column(
|
);
|
||||||
children: [
|
},
|
||||||
const CircleAvatar(
|
child: Column(
|
||||||
radius: 25,
|
mainAxisSize: MainAxisSize.min,
|
||||||
child: Icon(Icons.remove),
|
children: const [
|
||||||
),
|
CircleAvatar(radius: 25, child: Icon(Icons.remove)),
|
||||||
const SizedBox(height: 4),
|
SizedBox(height: 4),
|
||||||
const Text("移除", style: TextStyle(fontSize: 12)),
|
Text("移除", style: TextStyle(fontSize: 12)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: SizedBox.shrink(),
|
: const SizedBox.shrink();
|
||||||
)
|
|
||||||
],
|
final allWidgets = <Widget>[
|
||||||
),
|
...memberWidgets,
|
||||||
|
inviteWidget,
|
||||||
|
];
|
||||||
|
if (controller.isOwner.value) allWidgets.add(removeWidget);
|
||||||
|
|
||||||
|
return GridView.count(
|
||||||
|
shrinkWrap: true, // 适应内容高度
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
crossAxisCount: 4, // 每行显示 4 个
|
||||||
|
mainAxisSpacing: 0, // 行间距
|
||||||
|
crossAxisSpacing: 16, // 列间距
|
||||||
|
childAspectRatio: 1, // 调整宽高比
|
||||||
|
children: allWidgets,
|
||||||
|
);
|
||||||
|
}),
|
||||||
),
|
),
|
||||||
const Divider(height: 1),
|
const Divider(height: 1),
|
||||||
|
|
||||||
|
|||||||
@ -167,6 +167,7 @@ class _IndexPageState extends State<IndexPage> with TickerProviderStateMixin {
|
|||||||
|
|
||||||
/// 切换数据
|
/// 切换数据
|
||||||
Future<void> changeData(int index) async {
|
Future<void> changeData(int index) async {
|
||||||
|
dataList.clear();
|
||||||
if (isLoading.value) return;
|
if (isLoading.value) return;
|
||||||
isLoading.value = true;
|
isLoading.value = true;
|
||||||
final res = await Http.post(ShopApi.shopList, data: {
|
final res = await Http.post(ShopApi.shopList, data: {
|
||||||
@ -178,12 +179,12 @@ class _IndexPageState extends State<IndexPage> with TickerProviderStateMixin {
|
|||||||
final data = res['data']['records'];
|
final data = res['data']['records'];
|
||||||
final total = res['data']['total'];
|
final total = res['data']['total'];
|
||||||
logger.w(res);
|
logger.w(res);
|
||||||
dataList.value = data;
|
|
||||||
if (dataList.length >= total) {
|
if (dataList.length >= total) {
|
||||||
hasMore.value = false;
|
hasMore.value = false;
|
||||||
|
isLoading.value = false;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
dataList.value = data;
|
||||||
// logger.w(res);
|
|
||||||
page += 1;
|
page += 1;
|
||||||
isLoading.value = false;
|
isLoading.value = false;
|
||||||
isInitLoading.value = false;
|
isInitLoading.value = false;
|
||||||
@ -202,13 +203,14 @@ class _IndexPageState extends State<IndexPage> with TickerProviderStateMixin {
|
|||||||
final data = res['data']['records'];
|
final data = res['data']['records'];
|
||||||
final total = res['data']['total'];
|
final total = res['data']['total'];
|
||||||
logger.w(res);
|
logger.w(res);
|
||||||
dataList.addAll(data);
|
|
||||||
if (dataList.length >= total) {
|
if (dataList.length >= total) {
|
||||||
hasMore.value = false;
|
hasMore.value = false;
|
||||||
|
isLoading.value = false;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
dataList.addAll(data);
|
||||||
// logger.w(res);
|
|
||||||
page += 1;
|
page += 1;
|
||||||
|
logger.e(page);
|
||||||
isLoading.value = false;
|
isLoading.value = false;
|
||||||
isInitLoading.value = false;
|
isInitLoading.value = false;
|
||||||
}
|
}
|
||||||
@ -528,16 +530,16 @@ class _IndexPageState extends State<IndexPage> with TickerProviderStateMixin {
|
|||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
child: Obx(
|
child: Obx(
|
||||||
() {
|
() {
|
||||||
if (isInitLoading.value) {
|
// if (isInitLoading.value) {
|
||||||
return Column(
|
// return Column(
|
||||||
children: [
|
// children: [
|
||||||
RefreshProgressIndicator(
|
// RefreshProgressIndicator(
|
||||||
backgroundColor: Colors.white,
|
// backgroundColor: Colors.white,
|
||||||
color: Color(0xFFFF5000),
|
// color: Color(0xFFFF5000),
|
||||||
),
|
// ),
|
||||||
],
|
// ],
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
if (dataList.isEmpty) {
|
if (dataList.isEmpty) {
|
||||||
return EmptyTip();
|
return EmptyTip();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -291,7 +291,6 @@ class _UserInfoState extends State<UserInfo> {
|
|||||||
} else {
|
} else {
|
||||||
print("图片合法,大小:$sizeInMB MB");
|
print("图片合法,大小:$sizeInMB MB");
|
||||||
//走upload(file)上传图片拿到url地址
|
//走upload(file)上传图片拿到url地址
|
||||||
|
|
||||||
final croppedFile = await ImageCropper().cropImage(
|
final croppedFile = await ImageCropper().cropImage(
|
||||||
sourcePath: file.path,
|
sourcePath: file.path,
|
||||||
maxWidth: 1024,
|
maxWidth: 1024,
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:get/get_rx/src/rx_typedefs/rx_typedefs.dart';
|
import 'package:get/get_rx/src/rx_typedefs/rx_typedefs.dart';
|
||||||
import 'package:loopin/IM/controller/chat_controller.dart';
|
import 'package:loopin/IM/controller/chat_controller.dart';
|
||||||
@ -271,6 +272,17 @@ class MyPageState extends State<Vloger> with SingleTickerProviderStateMixin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildIcon(String assetPath, VoidCallback onTap) {
|
||||||
|
return InkWell(
|
||||||
|
onTap: onTap,
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 5.0, vertical: 5.0),
|
||||||
|
decoration: BoxDecoration(color: Colors.black.withAlpha((0.3 * 255).round()), borderRadius: BorderRadius.circular(20.0)),
|
||||||
|
child: SvgPicture.asset(assetPath, height: 20.0, width: 20.0, colorFilter: const ColorFilter.mode(Colors.white70, BlendMode.srcIn)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return PopScope(
|
return PopScope(
|
||||||
@ -297,75 +309,70 @@ class MyPageState extends State<Vloger> with SingleTickerProviderStateMixin {
|
|||||||
pinned: true,
|
pinned: true,
|
||||||
stretch: true,
|
stretch: true,
|
||||||
actions: [
|
actions: [
|
||||||
IconButton(
|
_buildIcon('assets/images/svg/more.svg', () async {
|
||||||
icon: const Icon(
|
final paddingTop = MediaQuery.of(Get.context!).padding.top;
|
||||||
Icons.more_horiz,
|
|
||||||
color: Colors.black,
|
|
||||||
),
|
|
||||||
onPressed: () async {
|
|
||||||
final paddingTop = MediaQuery.of(Get.context!).padding.top;
|
|
||||||
|
|
||||||
final selected = await showMenu(
|
final selected = await showMenu(
|
||||||
context: Get.context!,
|
context: Get.context!,
|
||||||
position: RelativeRect.fromLTRB(
|
position: RelativeRect.fromLTRB(
|
||||||
double.infinity,
|
double.infinity,
|
||||||
kToolbarHeight + paddingTop - 12,
|
kToolbarHeight + paddingTop - 12,
|
||||||
8,
|
8,
|
||||||
double.infinity,
|
double.infinity,
|
||||||
),
|
),
|
||||||
color: FStyle.primaryColor,
|
color: FStyle.primaryColor,
|
||||||
elevation: 8,
|
elevation: 8,
|
||||||
items: [
|
items: [
|
||||||
PopupMenuItem<String>(
|
PopupMenuItem<String>(
|
||||||
value: 'block',
|
value: 'block',
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Icon(Icons.block, color: Colors.white, size: 18),
|
Icon(Icons.block, color: Colors.white, size: 18),
|
||||||
SizedBox(width: 8),
|
SizedBox(width: 8),
|
||||||
Text(
|
Text(
|
||||||
blackTxt,
|
blackTxt,
|
||||||
style: TextStyle(color: Colors.white),
|
style: TextStyle(color: Colors.white),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
);
|
],
|
||||||
|
);
|
||||||
|
|
||||||
if (selected != null) {
|
if (selected != null) {
|
||||||
switch (selected) {
|
switch (selected) {
|
||||||
case 'block':
|
case 'block':
|
||||||
// print('点击了拉黑');
|
// print('点击了拉黑');
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
content: Text('确认要$blackTxt对方吗?', style: TextStyle(fontSize: 16.0)),
|
content: Text('确认要$blackTxt对方吗?', style: TextStyle(fontSize: 16.0)),
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
surfaceTintColor: Colors.white,
|
surfaceTintColor: Colors.white,
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15.0)),
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15.0)),
|
||||||
elevation: 2.0,
|
elevation: 2.0,
|
||||||
actionsPadding: const EdgeInsets.all(15.0),
|
actionsPadding: const EdgeInsets.all(15.0),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Get.back();
|
Get.back();
|
||||||
},
|
},
|
||||||
child: const Text('取消', style: TextStyle(color: Colors.black54)),
|
child: const Text('取消', style: TextStyle(color: Colors.black54)),
|
||||||
),
|
),
|
||||||
TextButton(onPressed: _handleBlack, child: const Text('确认', style: TextStyle(color: Colors.red))),
|
TextButton(onPressed: _handleBlack, child: const Text('确认', style: TextStyle(color: Colors.red))),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
// case 'foucs':
|
// case 'foucs':
|
||||||
// print('点击了取关');
|
// print('点击了取关');
|
||||||
// break;
|
// break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
),
|
}),
|
||||||
|
const SizedBox(width: 10.0),
|
||||||
],
|
],
|
||||||
leading: IconButton(
|
leading: IconButton(
|
||||||
icon: const Icon(Icons.arrow_back),
|
icon: const Icon(Icons.arrow_back),
|
||||||
|
|||||||
@ -84,6 +84,9 @@ class _SellerOrderDetailState extends State<SellerOrderDetail> with SingleTicker
|
|||||||
logger.e('code=$code');
|
logger.e('code=$code');
|
||||||
final res = await Http.get('${ShopApi.getWriteOffDetail}?code=$code');
|
final res = await Http.get('${ShopApi.getWriteOffDetail}?code=$code');
|
||||||
logger.w('订单详情-------------->${res['data']}');
|
logger.w('订单详情-------------->${res['data']}');
|
||||||
|
if (res == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
setState(() {
|
setState(() {
|
||||||
orderGoodsInfo = res['data'];
|
orderGoodsInfo = res['data'];
|
||||||
_isLoading = false;
|
_isLoading = false;
|
||||||
@ -428,7 +431,9 @@ class _SellerOrderDetailState extends State<SellerOrderDetail> with SingleTicker
|
|||||||
body: _isLoading
|
body: _isLoading
|
||||||
? Center(child: CircularProgressIndicator())
|
? Center(child: CircularProgressIndicator())
|
||||||
: orderGoodsInfo == null
|
: orderGoodsInfo == null
|
||||||
? emptyTip()
|
? Center(
|
||||||
|
child: emptyTip(),
|
||||||
|
)
|
||||||
: ScrollConfiguration(
|
: ScrollConfiguration(
|
||||||
behavior: CustomScrollBehavior().copyWith(scrollbars: false),
|
behavior: CustomScrollBehavior().copyWith(scrollbars: false),
|
||||||
child: ListView(
|
child: ListView(
|
||||||
@ -494,7 +499,8 @@ class _SellerOrderDetailState extends State<SellerOrderDetail> with SingleTicker
|
|||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Spacer(),
|
Spacer(),
|
||||||
orderGoodsInfo['items'][0]['status'] == 1
|
// orderGoodsInfo['items'][0]['status'] == 1
|
||||||
|
orderGoodsInfo['verificationCodeStatus'] == 1
|
||||||
? Text(
|
? Text(
|
||||||
'已核销',
|
'已核销',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
@ -557,7 +563,7 @@ class _SellerOrderDetailState extends State<SellerOrderDetail> with SingleTicker
|
|||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
Column(
|
Column(
|
||||||
children: [
|
children: [
|
||||||
_buildOrderInfoRow('订单号', orderGoodsInfo?['orderId']?.toString() ?? ''),
|
_buildOrderInfoRow('订单号', orderGoodsInfo?['orderSn']?.toString() ?? ''),
|
||||||
_buildOrderInfoRow('下单时间', orderGoodsInfo?['createTime']?.toString() ?? ''),
|
_buildOrderInfoRow('下单时间', orderGoodsInfo?['createTime']?.toString() ?? ''),
|
||||||
_buildOrderInfoRow('购买数量', _calculateTotalQuantity().toString()),
|
_buildOrderInfoRow('购买数量', _calculateTotalQuantity().toString()),
|
||||||
_orderId.isNotEmpty
|
_orderId.isNotEmpty
|
||||||
@ -607,6 +613,7 @@ class _SellerOrderDetailState extends State<SellerOrderDetail> with SingleTicker
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildOrderInfoRow(String label, String value) {
|
Widget _buildOrderInfoRow(String label, String value) {
|
||||||
|
// logger.e(orderGoodsInfo);
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 6.0),
|
padding: const EdgeInsets.symmetric(vertical: 6.0),
|
||||||
child: Row(
|
child: Row(
|
||||||
|
|||||||
@ -90,6 +90,7 @@ class _UploadVideoPageState extends State<UploadVideoPage> {
|
|||||||
if (file != null) {
|
if (file != null) {
|
||||||
final fileSizeInBytes = await file.length();
|
final fileSizeInBytes = await file.length();
|
||||||
final sizeInMB = fileSizeInBytes / (1024 * 1024);
|
final sizeInMB = fileSizeInBytes / (1024 * 1024);
|
||||||
|
// 时间长度
|
||||||
if (sizeInMB > 200) {
|
if (sizeInMB > 200) {
|
||||||
MyDialog.toast('文件大小不能超过200MB', icon: const Icon(Icons.check_circle), style: ToastStyle(backgroundColor: Colors.red.withAlpha(200)));
|
MyDialog.toast('文件大小不能超过200MB', icon: const Icon(Icons.check_circle), style: ToastStyle(backgroundColor: Colors.red.withAlpha(200)));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -683,7 +683,7 @@ class _VideoDetailPageState extends State<VideoDetailPage> {
|
|||||||
),
|
),
|
||||||
child: ClipOval(
|
child: ClipOval(
|
||||||
child: NetworkOrAssetImage(
|
child: NetworkOrAssetImage(
|
||||||
imageUrl: videoData['vlogerFace'] ?? videoData['commentUserFace'],
|
imageUrl: videoData['vlogerFace'] ?? videoData['avatar'],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -808,7 +808,7 @@ class _VideoDetailPageState extends State<VideoDetailPage> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'@${videoData['vlogerNickname'] ?? videoData['commentUserNickname'] ?? '未知用户'}',
|
'@${videoData['nickname'] ?? '未知用户'}',
|
||||||
style: const TextStyle(color: Colors.white, fontSize: 16.0),
|
style: const TextStyle(color: Colors.white, fontSize: 16.0),
|
||||||
),
|
),
|
||||||
LayoutBuilder(
|
LayoutBuilder(
|
||||||
@ -1179,8 +1179,8 @@ class _CommentBottomSheetState extends State<CommentBottomSheet> {
|
|||||||
|
|
||||||
final comment = commentList[index];
|
final comment = commentList[index];
|
||||||
final hasReplies = comment['childCount'] > 0;
|
final hasReplies = comment['childCount'] > 0;
|
||||||
final isExpanded = expandedReplies[comment['id']] == true;
|
final isExpanded = expandedReplies[comment['commentId']] == true;
|
||||||
final replies = replyData[comment['id']] ?? [];
|
final replies = replyData[comment['commentId']] ?? [];
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
@ -1211,7 +1211,7 @@ class _CommentBottomSheetState extends State<CommentBottomSheet> {
|
|||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
replyingCommentId = comment['id'];
|
replyingCommentId = comment['commentId'];
|
||||||
replyingCommentUser = comment['commentUserNickname'] ?? '未知用户';
|
replyingCommentUser = comment['commentUserNickname'] ?? '未知用户';
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -1239,10 +1239,10 @@ class _CommentBottomSheetState extends State<CommentBottomSheet> {
|
|||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
expandedReplies[comment['id']] = !isExpanded;
|
expandedReplies[comment['commentId']] = !isExpanded;
|
||||||
if (expandedReplies[comment['id']] == true &&
|
if (expandedReplies[comment['commentId']] == true &&
|
||||||
(replyData[comment['id']] == null || replyData[comment['id']]!.isEmpty)) {
|
(replyData[comment['commentId']] == null || replyData[comment['commentId']]!.isEmpty)) {
|
||||||
fetchReplies(comment['id'], false);
|
fetchReplies(comment['commentId'], false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -1303,7 +1303,7 @@ class _CommentBottomSheetState extends State<CommentBottomSheet> {
|
|||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
replyingCommentId = comment['id'];
|
replyingCommentId = comment['commentId'];
|
||||||
replyingCommentUser = reply['commentUserNickname'] ?? '未知用户';
|
replyingCommentUser = reply['commentUserNickname'] ?? '未知用户';
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -1337,8 +1337,8 @@ class _CommentBottomSheetState extends State<CommentBottomSheet> {
|
|||||||
if (replies.length < comment['childCount'])
|
if (replies.length < comment['childCount'])
|
||||||
Center(
|
Center(
|
||||||
child: TextButton(
|
child: TextButton(
|
||||||
onPressed: () => fetchReplies(comment['id'], true),
|
onPressed: () => fetchReplies(comment['commentId'], true),
|
||||||
child: isLoadingReplies[comment['id']] == true ? CircularProgressIndicator() : Text('加载更多回复'),
|
child: isLoadingReplies[comment['commentId']] == true ? CircularProgressIndicator() : Text('加载更多回复'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@ -295,8 +295,8 @@ class _CommentBottomSheetState extends State<CommentBottomSheet> {
|
|||||||
|
|
||||||
final comment = commentList[index];
|
final comment = commentList[index];
|
||||||
final hasReplies = comment['childCount'] > 0;
|
final hasReplies = comment['childCount'] > 0;
|
||||||
final isExpanded = expandedReplies[comment['id']] == true;
|
final isExpanded = expandedReplies[comment['commentId']] == true;
|
||||||
final replies = replyData[comment['id']] ?? [];
|
final replies = replyData[comment['commentId']] ?? [];
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
@ -327,7 +327,7 @@ class _CommentBottomSheetState extends State<CommentBottomSheet> {
|
|||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
replyingCommentId = comment['id'];
|
replyingCommentId = comment['commentId'];
|
||||||
replyingCommentUser = comment['commentUserNickname'] ?? '未知用户';
|
replyingCommentUser = comment['commentUserNickname'] ?? '未知用户';
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -355,10 +355,10 @@ class _CommentBottomSheetState extends State<CommentBottomSheet> {
|
|||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
expandedReplies[comment['id']] = !isExpanded;
|
expandedReplies[comment['commentId']] = !isExpanded;
|
||||||
if (expandedReplies[comment['id']] == true &&
|
if (expandedReplies[comment['commentId']] == true &&
|
||||||
(replyData[comment['id']] == null || replyData[comment['id']]!.isEmpty)) {
|
(replyData[comment['commentId']] == null || replyData[comment['commentId']]!.isEmpty)) {
|
||||||
fetchReplies(comment['id'], false);
|
fetchReplies(comment['commentId'], false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -419,7 +419,7 @@ class _CommentBottomSheetState extends State<CommentBottomSheet> {
|
|||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
replyingCommentId = comment['id'];
|
replyingCommentId = comment['commentId'];
|
||||||
replyingCommentUser = reply['commentUserNickname'] ?? '未知用户';
|
replyingCommentUser = reply['commentUserNickname'] ?? '未知用户';
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -453,8 +453,8 @@ class _CommentBottomSheetState extends State<CommentBottomSheet> {
|
|||||||
if (replies.length < comment['childCount'])
|
if (replies.length < comment['childCount'])
|
||||||
Center(
|
Center(
|
||||||
child: TextButton(
|
child: TextButton(
|
||||||
onPressed: () => fetchReplies(comment['id'], true),
|
onPressed: () => fetchReplies(comment['commentId'], true),
|
||||||
child: isLoadingReplies[comment['id']] == true ? CircularProgressIndicator() : Text('加载更多回复'),
|
child: isLoadingReplies[comment['commentId']] == true ? CircularProgressIndicator() : Text('加载更多回复'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -1164,7 +1164,7 @@ class _AttentionModuleState extends State<AttentionModule> {
|
|||||||
),
|
),
|
||||||
child: ClipOval(
|
child: ClipOval(
|
||||||
child: NetworkOrAssetImage(
|
child: NetworkOrAssetImage(
|
||||||
imageUrl: videoList[index]['commentUserFace'],
|
imageUrl: videoList[index]['avatar'],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -296,8 +296,8 @@ class _CommentBottomSheetState extends State<CommentBottomSheet> {
|
|||||||
|
|
||||||
final comment = commentList[index];
|
final comment = commentList[index];
|
||||||
final hasReplies = comment['childCount'] > 0;
|
final hasReplies = comment['childCount'] > 0;
|
||||||
final isExpanded = expandedReplies[comment['id']] == true;
|
final isExpanded = expandedReplies[comment['commentId']] == true;
|
||||||
final replies = replyData[comment['id']] ?? [];
|
final replies = replyData[comment['commentId']] ?? [];
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
@ -328,7 +328,7 @@ class _CommentBottomSheetState extends State<CommentBottomSheet> {
|
|||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
replyingCommentId = comment['id'];
|
replyingCommentId = comment['commentId'];
|
||||||
replyingCommentUser = comment['commentUserNickname'] ?? '未知用户';
|
replyingCommentUser = comment['commentUserNickname'] ?? '未知用户';
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -356,10 +356,10 @@ class _CommentBottomSheetState extends State<CommentBottomSheet> {
|
|||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
expandedReplies[comment['id']] = !isExpanded;
|
expandedReplies[comment['commentId']] = !isExpanded;
|
||||||
if (expandedReplies[comment['id']] == true &&
|
if (expandedReplies[comment['commentId']] == true &&
|
||||||
(replyData[comment['id']] == null || replyData[comment['id']]!.isEmpty)) {
|
(replyData[comment['commentId']] == null || replyData[comment['commentId']]!.isEmpty)) {
|
||||||
fetchReplies(comment['id'], false);
|
fetchReplies(comment['commentId'], false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -420,7 +420,7 @@ class _CommentBottomSheetState extends State<CommentBottomSheet> {
|
|||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
replyingCommentId = comment['id'];
|
replyingCommentId = comment['commentId'];
|
||||||
replyingCommentUser = reply['commentUserNickname'] ?? '未知用户';
|
replyingCommentUser = reply['commentUserNickname'] ?? '未知用户';
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -454,8 +454,8 @@ class _CommentBottomSheetState extends State<CommentBottomSheet> {
|
|||||||
if (replies.length < comment['childCount'])
|
if (replies.length < comment['childCount'])
|
||||||
Center(
|
Center(
|
||||||
child: TextButton(
|
child: TextButton(
|
||||||
onPressed: () => fetchReplies(comment['id'], true),
|
onPressed: () => fetchReplies(comment['commentId'], true),
|
||||||
child: isLoadingReplies[comment['id']] == true ? CircularProgressIndicator() : Text('加载更多回复'),
|
child: isLoadingReplies[comment['commentId']] == true ? CircularProgressIndicator() : Text('加载更多回复'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -1169,7 +1169,7 @@ class _FriendModuleState extends State<FriendModule> {
|
|||||||
),
|
),
|
||||||
child: ClipOval(
|
child: ClipOval(
|
||||||
child: NetworkOrAssetImage(
|
child: NetworkOrAssetImage(
|
||||||
imageUrl: videoList[index]['commentUserFace'],
|
imageUrl: videoList[index]['avatar'],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -332,7 +332,7 @@ class _CommentBottomSheetState extends State<CommentBottomSheet> {
|
|||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
logger.e(comment);
|
logger.e(comment);
|
||||||
// replyingCommentId = comment['id']; //null
|
|
||||||
replyingCommentId = comment['commentId'];
|
replyingCommentId = comment['commentId'];
|
||||||
replyingCommentUser = comment['commentUserNickname'] ?? '未知用户';
|
replyingCommentUser = comment['commentUserNickname'] ?? '未知用户';
|
||||||
});
|
});
|
||||||
@ -427,7 +427,7 @@ class _CommentBottomSheetState extends State<CommentBottomSheet> {
|
|||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
replyingCommentId = comment['id'];
|
replyingCommentId = comment['commentId'];
|
||||||
replyingCommentUser = reply['commentUserNickname'] ?? '未知用户';
|
replyingCommentUser = reply['commentUserNickname'] ?? '未知用户';
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -461,8 +461,8 @@ class _CommentBottomSheetState extends State<CommentBottomSheet> {
|
|||||||
if (replies.length < comment['childCount'])
|
if (replies.length < comment['childCount'])
|
||||||
Center(
|
Center(
|
||||||
child: TextButton(
|
child: TextButton(
|
||||||
onPressed: () => fetchReplies(comment['id'], true),
|
onPressed: () => fetchReplies(comment['commentId'], true),
|
||||||
child: isLoadingReplies[comment['id']] == true ? CircularProgressIndicator() : Text('加载更多回复'),
|
child: isLoadingReplies[comment['commentId']] == true ? CircularProgressIndicator() : Text('加载更多回复'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -1169,13 +1169,14 @@ class _RecommendModuleState extends State<RecommendModule> {
|
|||||||
),
|
),
|
||||||
child: ClipOval(
|
child: ClipOval(
|
||||||
child: NetworkOrAssetImage(
|
child: NetworkOrAssetImage(
|
||||||
imageUrl: videoList[index]['commentUserFace'],
|
imageUrl: videoList[index]['avatar'],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
// 关注区域
|
||||||
Positioned(
|
Positioned(
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
left: 15.0,
|
left: 15.0,
|
||||||
|
|||||||
@ -22,7 +22,7 @@ class UpgradeService {
|
|||||||
});
|
});
|
||||||
if (!state.mounted) return;
|
if (!state.mounted) return;
|
||||||
|
|
||||||
logger.w(res);
|
logger.e(res);
|
||||||
final result = res['data']['records'] as List;
|
final result = res['data']['records'] as List;
|
||||||
if (result.isEmpty) return;
|
if (result.isEmpty) return;
|
||||||
final data = result.first;
|
final data = result.first;
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:loopin/IM/im_service.dart';
|
import 'package:loopin/IM/im_service.dart';
|
||||||
import 'package:loopin/components/network_or_asset_image.dart';
|
import 'package:loopin/components/network_or_asset_image.dart';
|
||||||
|
import 'package:loopin/models/conversation_type.dart';
|
||||||
import 'package:loopin/styles/index.dart';
|
import 'package:loopin/styles/index.dart';
|
||||||
import 'package:loopin/utils/parse_message_summary.dart';
|
import 'package:loopin/utils/parse_message_summary.dart';
|
||||||
import 'package:shirne_dialog/shirne_dialog.dart';
|
import 'package:shirne_dialog/shirne_dialog.dart';
|
||||||
@ -20,6 +21,8 @@ class NotificationBanner {
|
|||||||
name = gpInfo?.groupName ?? "未知群名";
|
name = gpInfo?.groupName ?? "未知群名";
|
||||||
avatar = gpInfo?.faceUrl ?? "";
|
avatar = gpInfo?.faceUrl ?? "";
|
||||||
} else {
|
} else {
|
||||||
|
logger.e('获取群名称失败');
|
||||||
|
logger.e(msg.toJson());
|
||||||
name = '获取群名称失败';
|
name = '获取群名称失败';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -71,18 +74,25 @@ class NotificationBanner {
|
|||||||
),
|
),
|
||||||
onTap: (_) async {
|
onTap: (_) async {
|
||||||
Get.closeCurrentSnackbar();
|
Get.closeCurrentSnackbar();
|
||||||
String? conversationID;
|
// 这里得单独处理一下消息通知
|
||||||
if (msg.groupID != null && msg.groupID!.isNotEmpty) {
|
bool isGroup = msg.groupID != null && msg.groupID!.isNotEmpty;
|
||||||
conversationID = 'group_${msg.groupID}';
|
String id = isGroup ? (msg.groupID ?? '') : (msg.userID ?? '');
|
||||||
} else if (msg.userID != null && msg.userID!.isNotEmpty) {
|
String conversationID = isGroup ? 'group_$id' : 'c2c_$id';
|
||||||
conversationID = 'c2c_${msg.userID}';
|
String? router;
|
||||||
|
// 如果是群聊,直接走,不是群聊鉴别一下
|
||||||
|
final cRes = await ImService.instance.getConversation(conversationID: conversationID);
|
||||||
|
if (!isGroup) {
|
||||||
|
// 不是群聊,去匹配是不是系统通知
|
||||||
|
router = conversationTypeFromString(msg.userID); //这里就是解析用于发送消息的管理员的userID
|
||||||
}
|
}
|
||||||
final cRes = await ImService.instance.getConversation(conversationID: conversationID!);
|
|
||||||
if (cRes.success) {
|
if (cRes.success) {
|
||||||
if (msg.userID != null) {
|
if (router != null) {
|
||||||
Get.toNamed('/chat', arguments: cRes.data);
|
// 取对应的系统通知界面
|
||||||
} else if (msg.groupID != null) {
|
Get.toNamed('/$router', arguments: cRes.data);
|
||||||
|
} else if (isGroup) {
|
||||||
Get.toNamed('/chatGroup', arguments: cRes.data);
|
Get.toNamed('/chatGroup', arguments: cRes.data);
|
||||||
|
} else {
|
||||||
|
Get.toNamed('/chat', arguments: cRes.data);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
MyDialog.toast(
|
MyDialog.toast(
|
||||||
|
|||||||
@ -233,6 +233,8 @@ String _parseCustomMessage(V2TimMessage? msg) {
|
|||||||
|
|
||||||
///系统推广类的先不管了
|
///系统推广类的先不管了
|
||||||
return elment!.desc!;
|
return elment!.desc!;
|
||||||
|
|
||||||
|
// interaction required key={type} value={interactionComment} 对应类型的枚举值
|
||||||
case NotifyMessageTypeConstants.interactionComment:
|
case NotifyMessageTypeConstants.interactionComment:
|
||||||
// 评论视频
|
// 评论视频
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
# In Windows, build-name is used as the major, minor, and patch parts
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
# of the product and file versions while build-number is used as the build suffix.
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
version: 4.1.0+407
|
version: 4.1.1+413
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.6.0
|
sdk: ^3.6.0
|
||||||
@ -205,7 +205,10 @@ flutter_native_splash:
|
|||||||
android_gravity: fill
|
android_gravity: fill
|
||||||
fullscreen: true #隐藏通知栏
|
fullscreen: true #隐藏通知栏
|
||||||
|
|
||||||
android_12:
|
android_12:
|
||||||
|
color: "#000000"
|
||||||
|
color_dark: "#000000"
|
||||||
|
|
||||||
image: assets/images/logo/androidlogo.png
|
image: assets/images/logo/androidlogo.png
|
||||||
icon_background_color: "#000000"
|
icon_background_color: "#000000"
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user