feat: Upgrade to UIKit 2.5.0
This commit is contained in:
parent
d78300178c
commit
8d34acf282
33
CHANGELOG.md
33
CHANGELOG.md
|
|
@ -1,5 +1,32 @@
|
|||
# 2.5.0
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
* Migrated to Flutter 3.19. Support for Flutter 3.16 and earlier versions has been discontinued.
|
||||
|
||||
## Notes
|
||||
|
||||
* Starting from Flutter 3.19, it is recommended to apply Flutter's Gradle plugins using Gradle's declarative plugins {} block (also known as the Plugin DSL) ([see details](https://docs.flutter.dev/release/breaking-changes/flutter-gradle-plugin-apply)).
|
||||
* In line with this, our sample app on the GitHub repo has also been migrated to this new approach. If you'd like to migrate to this new approach, please refer to our [sample app repo](https://github.com/TencentCloud/chat-demo-flutter).
|
||||
|
||||
# 2.4.3
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
* Fixed an keyboard issue on Web.
|
||||
|
||||
# 2.4.2
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
* Fixed an UI issue on Material3 mode.
|
||||
|
||||
# 2.4.1
|
||||
|
||||
## Improvements
|
||||
|
||||
* Enhanced stability for message reaction.
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
* Fixed some bugs.
|
||||
|
|
@ -8,7 +35,7 @@
|
|||
|
||||
## Breaking Changes
|
||||
|
||||
* Migrated to Flutter 3.16.0.
|
||||
* Migrated to Flutter 3.16. Support for Flutter 3.13 and earlier versions has been discontinued.
|
||||
* Upgraded the minimum supported Android Gradle Plugin to 7.3 to meet Flutter requirements.
|
||||
|
||||
# 2.3.3
|
||||
|
|
@ -44,11 +71,11 @@
|
|||
|
||||
## Breaking Changes
|
||||
|
||||
* Upgraded and migrated to support Flutter 3.13.0. Support for Flutter 3.10 and earlier versions has been dropped.
|
||||
* Upgraded and migrated to support Flutter 3.13. Support for Flutter 3.10 and earlier versions has been discontinued.
|
||||
|
||||
## Recommendations
|
||||
|
||||
* Customers who do not wish to upgrade to Flutter 3.13.0 are advised to continue using version 2.2.1 of our Chat UIKit. However, we strongly recommend upgrading to Flutter 3.13.0 as it includes numerous performance improvements and introduces cutting-edge features.
|
||||
* Customers who do not wish to upgrade to Flutter 3.13 are advised to continue using version 2.2.1 of our Chat UIKit. However, we strongly recommend upgrading to Flutter 3.13.0 as it includes numerous performance improvements and introduces cutting-edge features.
|
||||
|
||||
# 2.2.1
|
||||
|
||||
|
|
|
|||
|
|
@ -237,10 +237,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: dart_internal
|
||||
sha256: "689dccc3d5f62affd339534cca548dce12b3a6b32f0f10861569d3025efc0567"
|
||||
sha256: "04145b91ccec450325fee75692b1ab62eb615e8892c334f0f4d31c696a857873"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.9"
|
||||
version: "0.2.10"
|
||||
desktop_drop:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -301,18 +301,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: extended_text
|
||||
sha256: "7096a1e9a029534257d70f7dafb2798f932d589079e67ef3f58fdf0805f2f627"
|
||||
sha256: "7f382de3af12992e34bd72ddd36becf90c4720900af126cb9859f0189af71ffe"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "12.0.0"
|
||||
version: "13.0.0"
|
||||
extended_text_field:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: extended_text_field
|
||||
sha256: ed9655c70a47a54c7cc689cf7f89a2bde9ab7b530150b4d1808b7aa7eb8cdf90
|
||||
sha256: ee139de7c2b2a9d806ddd5fdfef5c728cf475298a7ce5834c5b822ef1e6225d7
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "13.0.0"
|
||||
version: "14.0.0"
|
||||
extended_text_library:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -470,14 +470,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.0.16"
|
||||
flutter_slidable_for_tencent_im:
|
||||
flutter_slidable:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_slidable_for_tencent_im
|
||||
sha256: "425faab6304305dd7d38aef448af02acd65f425bf2bd47ce3b70b0b4e714c17b"
|
||||
name: flutter_slidable
|
||||
sha256: "19ed4813003a6ff4e9c6bcce37e792a2a358919d7603b2b31ff200229191e44c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
version: "3.0.1"
|
||||
flutter_svg:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -680,6 +680,30 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.4.8"
|
||||
leak_tracker:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker
|
||||
sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.0.0"
|
||||
leak_tracker_flutter_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_flutter_testing
|
||||
sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
leak_tracker_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_testing
|
||||
sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
link_preview_generator_for_us:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -740,26 +764,26 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
|
||||
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.12.16"
|
||||
version: "0.12.16+1"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
|
||||
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.0"
|
||||
version: "0.8.0"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
|
||||
sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.10.0"
|
||||
version: "1.11.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -836,10 +860,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
|
||||
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.8.3"
|
||||
version: "1.9.0"
|
||||
path_drawing:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -1227,7 +1251,7 @@ packages:
|
|||
path: ".."
|
||||
relative: true
|
||||
source: path
|
||||
version: "2.4.1"
|
||||
version: "2.5.0"
|
||||
tencent_cloud_uikit_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -1492,6 +1516,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.16"
|
||||
vm_service:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "13.0.0"
|
||||
wakelock_for_us:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -1581,5 +1613,5 @@ packages:
|
|||
source: hosted
|
||||
version: "3.1.2"
|
||||
sdks:
|
||||
dart: ">=3.2.0 <3.3.0"
|
||||
flutter: ">=3.16.0"
|
||||
dart: ">=3.3.0 <3.4.0"
|
||||
flutter: ">=3.19.0"
|
||||
|
|
|
|||
|
|
@ -199,7 +199,9 @@ class TUIChatGlobalModel extends ChangeNotifier implements TIMUIKitClass {
|
|||
clearCurrentConversation() {
|
||||
// Only keep the last 20 messages when existing a chat.
|
||||
_messageListMap[currentSelectedConv] = (_messageListMap[currentSelectedConv] ?? []).sublist(max(0, ((_messageListMap[currentSelectedConv] ?? []).length - 20)));
|
||||
_currentConversationList.removeLast();
|
||||
if (_currentConversationList.isNotEmpty) {
|
||||
_currentConversationList.removeLast();
|
||||
}
|
||||
// notifyListeners();
|
||||
}
|
||||
|
||||
|
|
@ -639,6 +641,12 @@ class TUIChatGlobalModel extends ChangeNotifier implements TIMUIKitClass {
|
|||
Future<void> onMessageDownloadProgressCallback(V2TimMessageDownloadProgress messageProgress) async {
|
||||
final currentProgress = getMessageProgress(messageProgress.msgID);
|
||||
|
||||
if (messageProgress.isError || messageProgress.errorCode != 0) {
|
||||
V2TimMessage? message = await _findAndRetrieveMessage(messageProgress.msgID);
|
||||
_handleDownloadError(messageProgress, message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (messageProgress.isFinish && currentProgress < 100) {
|
||||
V2TimMessage? message = await _findAndRetrieveMessage(messageProgress.msgID);
|
||||
_handleFinishedDownload(messageProgress, message);
|
||||
|
|
@ -670,6 +678,11 @@ class TUIChatGlobalModel extends ChangeNotifier implements TIMUIKitClass {
|
|||
}
|
||||
}
|
||||
|
||||
void _handleDownloadError(V2TimMessageDownloadProgress messageProgress, V2TimMessage? message) {
|
||||
setMessageProgress(messageProgress.msgID, 0);
|
||||
downloadFile();
|
||||
}
|
||||
|
||||
void _updateMessageAndDownloadFile(V2TimMessage message, V2TimMessageDownloadProgress messageProgress) {
|
||||
updateAsyncMessage(message, TencentUtils.checkString(message.userID) ?? TencentUtils.checkString(message.groupID) ?? "");
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_slidable_for_tencent_im/flutter_slidable.dart';
|
||||
import 'package:flutter_slidable/flutter_slidable.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/block_list_life_cycle.dart';
|
||||
|
|
|
|||
|
|
@ -752,6 +752,8 @@ class _TIMUIKItHistoryMessageListItemState
|
|||
bool isRevocable(int timestamp) =>
|
||||
(DateTime.now().millisecondsSinceEpoch / 1000).ceil() - timestamp < 120;
|
||||
|
||||
// TODO : 继续看这里
|
||||
|
||||
_onOpenToolTip(
|
||||
c,
|
||||
V2TimMessage message,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import 'package:collection/collection.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
|
||||
import 'package:tencent_im_base/tencent_im_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';
|
||||
|
|
|
|||
|
|
@ -5,22 +5,22 @@ import 'dart:math';
|
|||
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:loading_animation_widget/loading_animation_widget.dart';
|
||||
import 'package:open_file/open_file.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/permission.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
|
||||
import 'package:universal_html/html.dart' as html;
|
||||
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/permission.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_wrapper.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_file_icon.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/textSize.dart';
|
||||
import 'package:universal_html/html.dart' as html;
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
class TIMUIKitFileElem extends StatefulWidget {
|
||||
final String? messageID;
|
||||
|
|
@ -32,16 +32,7 @@ class TIMUIKitFileElem extends StatefulWidget {
|
|||
final bool? isShowMessageReaction;
|
||||
final TUIChatSeparateViewModel chatModel;
|
||||
|
||||
const TIMUIKitFileElem(
|
||||
{Key? key,
|
||||
required this.chatModel,
|
||||
required this.messageID,
|
||||
required this.fileElem,
|
||||
required this.isSelf,
|
||||
required this.isShowJump,
|
||||
this.clearJump,
|
||||
required this.message,
|
||||
this.isShowMessageReaction})
|
||||
const TIMUIKitFileElem({Key? key, required this.chatModel, required this.messageID, required this.fileElem, required this.isSelf, required this.isShowJump, this.clearJump, required this.message, this.isShowMessageReaction})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
|
|
@ -56,12 +47,11 @@ class _TIMUIKitFileElemState extends TIMUIKitState<TIMUIKitFileElem> {
|
|||
late V2TimAdvancedMsgListener advancedMsgListener;
|
||||
final GlobalKey containerKey = GlobalKey();
|
||||
double? containerHeight;
|
||||
bool? _downloadFailed = false;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.removeAdvancedMsgListener(listener: advancedMsgListener);
|
||||
TencentImSDKPlugin.v2TIMManager.getMessageManager().removeAdvancedMsgListener(listener: advancedMsgListener);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
|
@ -74,19 +64,27 @@ class _TIMUIKitFileElemState extends TIMUIKitState<TIMUIKitFileElem> {
|
|||
});
|
||||
}
|
||||
advancedMsgListener = V2TimAdvancedMsgListener(
|
||||
onMessageDownloadProgressCallback:
|
||||
(V2TimMessageDownloadProgress messageProgress) async {
|
||||
onMessageDownloadProgressCallback: (V2TimMessageDownloadProgress messageProgress) async {
|
||||
if (messageProgress.msgID == widget.message.msgID) {
|
||||
if (messageProgress.isError || messageProgress.errorCode != 0) {
|
||||
setState(() {
|
||||
_downloadFailed = true;
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (messageProgress.isFinish) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
downloadProgress = 100;
|
||||
});
|
||||
|
||||
TencentImSDKPlugin.v2TIMManager.getMessageManager().removeAdvancedMsgListener(
|
||||
listener: advancedMsgListener,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
final currentProgress =
|
||||
(messageProgress.currentSize / messageProgress.totalSize * 100)
|
||||
.floor();
|
||||
final currentProgress = (messageProgress.currentSize / messageProgress.totalSize * 100).floor();
|
||||
if (mounted && currentProgress > downloadProgress) {
|
||||
setState(() {
|
||||
downloadProgress = currentProgress;
|
||||
|
|
@ -96,16 +94,11 @@ class _TIMUIKitFileElemState extends TIMUIKitState<TIMUIKitFileElem> {
|
|||
}
|
||||
},
|
||||
);
|
||||
TencentImSDKPlugin.v2TIMManager
|
||||
.getMessageManager()
|
||||
.addAdvancedMsgListener(listener: advancedMsgListener);
|
||||
TencentImSDKPlugin.v2TIMManager.getMessageManager().addAdvancedMsgListener(listener: advancedMsgListener);
|
||||
}
|
||||
|
||||
Future<String> getSavePath() async {
|
||||
String savePathWithAppPath =
|
||||
'/storage/emulated/0/Android/data/com.tencent.flutter.tuikit/cache/' +
|
||||
(widget.message.msgID ?? "") +
|
||||
widget.fileElem!.fileName!;
|
||||
String savePathWithAppPath = '/storage/emulated/0/Android/data/com.tencent.flutter.tuikit/cache/' + (widget.message.msgID ?? "") + widget.fileElem!.fileName!;
|
||||
return savePathWithAppPath;
|
||||
}
|
||||
|
||||
|
|
@ -113,11 +106,7 @@ class _TIMUIKitFileElemState extends TIMUIKitState<TIMUIKitFileElem> {
|
|||
if (PlatformUtils().isWeb) {
|
||||
return true;
|
||||
}
|
||||
String savePath = TencentUtils.checkString(
|
||||
model.getFileMessageLocation(widget.messageID)) ??
|
||||
TencentUtils.checkString(widget.message.fileElem!.localUrl) ??
|
||||
widget.message.fileElem?.path ??
|
||||
'';
|
||||
String savePath = TencentUtils.checkString(model.getFileMessageLocation(widget.messageID)) ?? TencentUtils.checkString(widget.message.fileElem!.localUrl) ?? widget.message.fileElem?.path ?? '';
|
||||
File f = File(savePath);
|
||||
if (f.existsSync() && widget.messageID != null) {
|
||||
filePath = savePath;
|
||||
|
|
@ -170,8 +159,7 @@ class _TIMUIKitFileElemState extends TIMUIKitState<TIMUIKitFileElem> {
|
|||
downloadFile(TUITheme theme) async {
|
||||
if (PlatformUtils().isMobile) {
|
||||
if (PlatformUtils().isIOS) {
|
||||
if (!await Permissions.checkPermission(
|
||||
context, Permission.photosAddOnly.value, theme, false)) {
|
||||
if (!await Permissions.checkPermission(context, Permission.photosAddOnly.value, theme, false)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -203,18 +191,13 @@ class _TIMUIKitFileElemState extends TIMUIKitState<TIMUIKitFileElem> {
|
|||
}
|
||||
|
||||
tryOpenFile(context, theme) async {
|
||||
if (!PlatformUtils().isWeb &&
|
||||
(await hasZeroSize(filePath) || widget.message.status == 3)) {
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: "不支持 0KB 文件的传输",
|
||||
infoCode: 6660417));
|
||||
if (!PlatformUtils().isWeb && (await hasZeroSize(filePath) || widget.message.status == 3)) {
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: "不支持 0KB 文件的传输", infoCode: 6660417));
|
||||
return;
|
||||
}
|
||||
if (PlatformUtils().isMobile) {
|
||||
if (PlatformUtils().isIOS) {
|
||||
if (!await Permissions.checkPermission(
|
||||
context, Permission.photosAddOnly.value, theme!, false)) {
|
||||
if (!await Permissions.checkPermission(context, Permission.photosAddOnly.value, theme!, false)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -258,8 +241,7 @@ class _TIMUIKitFileElemState extends TIMUIKitState<TIMUIKitFileElem> {
|
|||
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
|
||||
);
|
||||
|
||||
final html.AnchorElement downloadAnchor =
|
||||
html.document.createElement('a') as html.AnchorElement;
|
||||
final html.AnchorElement downloadAnchor = html.document.createElement('a') as html.AnchorElement;
|
||||
|
||||
final html.Blob blob = html.Blob([response.bodyBytes]);
|
||||
|
||||
|
|
@ -271,8 +253,7 @@ class _TIMUIKitFileElemState extends TIMUIKitState<TIMUIKitFileElem> {
|
|||
html.AnchorElement(
|
||||
href: widget.fileElem?.path ?? "",
|
||||
)
|
||||
..setAttribute(
|
||||
"download", widget.message.fileElem?.fileName ?? fileName)
|
||||
..setAttribute("download", widget.message.fileElem?.fileName ?? fileName)
|
||||
..setAttribute("target", '_blank')
|
||||
..style.display = "none"
|
||||
..click();
|
||||
|
|
@ -291,24 +272,14 @@ class _TIMUIKitFileElemState extends TIMUIKitState<TIMUIKitFileElem> {
|
|||
final fileName = widget.fileElem!.fileName ?? "";
|
||||
final fileSize = widget.fileElem!.fileSize;
|
||||
final borderRadius = widget.isSelf
|
||||
? const BorderRadius.only(
|
||||
topLeft: Radius.circular(10),
|
||||
topRight: Radius.circular(2),
|
||||
bottomLeft: Radius.circular(10),
|
||||
bottomRight: Radius.circular(10))
|
||||
: const BorderRadius.only(
|
||||
topLeft: Radius.circular(2),
|
||||
topRight: Radius.circular(10),
|
||||
bottomLeft: Radius.circular(10),
|
||||
bottomRight: Radius.circular(10));
|
||||
? const BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(2), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10))
|
||||
: const BorderRadius.only(topLeft: Radius.circular(2), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10));
|
||||
String? fileFormat;
|
||||
if (widget.fileElem?.fileName != null &&
|
||||
widget.fileElem!.fileName!.isNotEmpty) {
|
||||
if (widget.fileElem?.fileName != null && widget.fileElem!.fileName!.isNotEmpty) {
|
||||
final String fileName = widget.fileElem!.fileName!;
|
||||
fileFormat = fileName.split(".")[max(fileName.split(".").length - 1, 0)];
|
||||
}
|
||||
final RenderBox? containerRenderBox =
|
||||
containerKey.currentContext?.findRenderObject() as RenderBox?;
|
||||
final RenderBox? containerRenderBox = containerKey.currentContext?.findRenderObject() as RenderBox?;
|
||||
if (containerRenderBox != null) {
|
||||
containerHeight = containerRenderBox.size.height;
|
||||
}
|
||||
|
|
@ -333,113 +304,96 @@ class _TIMUIKitFileElemState extends TIMUIKitState<TIMUIKitFileElem> {
|
|||
isShowMessageReaction: widget.isShowMessageReaction ?? true,
|
||||
message: widget.message,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
try {
|
||||
if (PlatformUtils().isWeb) {
|
||||
if (!isWebDownloading) {
|
||||
downloadWebFile(widget.fileElem?.path ?? "");
|
||||
}
|
||||
return;
|
||||
onTap: () async {
|
||||
try {
|
||||
if (PlatformUtils().isWeb) {
|
||||
if (!isWebDownloading) {
|
||||
downloadWebFile(widget.fileElem?.path ?? "");
|
||||
}
|
||||
if (await hasFile()) {
|
||||
if (received == 100) {
|
||||
tryOpenFile(context, theme);
|
||||
} else {
|
||||
onTIMCallback(
|
||||
TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("正在下载中"),
|
||||
infoCode: 6660411,
|
||||
),
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (checkIsWaiting()) {
|
||||
return;
|
||||
}
|
||||
if (await hasFile()) {
|
||||
if (received == 100) {
|
||||
tryOpenFile(context, theme);
|
||||
} else {
|
||||
onTIMCallback(
|
||||
TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("已加入待下载队列,其他文件下载中"),
|
||||
infoCode: 6660413),
|
||||
);
|
||||
return;
|
||||
} else {
|
||||
await addUrlToWaitingPath(theme);
|
||||
}
|
||||
} catch (e) {
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: "文件处理异常",
|
||||
infoCode: 6660416));
|
||||
}
|
||||
},
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxHeight: 72),
|
||||
child: Container(
|
||||
width: 237,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: theme.weakDividerColor ??
|
||||
CommonColor.weakDividerColor,
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("正在下载中"),
|
||||
infoCode: 6660411,
|
||||
),
|
||||
borderRadius: borderRadius),
|
||||
child: Stack(children: [
|
||||
ClipRRect(
|
||||
borderRadius: borderRadius,
|
||||
child: LinearProgressIndicator(
|
||||
minHeight: ((containerHeight) ?? 72) - 6,
|
||||
value: (received == 100 ? 0 : received) / 100,
|
||||
backgroundColor: received == 100
|
||||
? theme.weakBackgroundColor
|
||||
: Colors.white,
|
||||
valueColor: AlwaysStoppedAnimation(
|
||||
theme.lightPrimaryMaterialColor.shade50),),
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (checkIsWaiting()) {
|
||||
onTIMCallback(
|
||||
TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("已加入待下载队列,其他文件下载中"), infoCode: 6660413),
|
||||
);
|
||||
return;
|
||||
} else {
|
||||
await addUrlToWaitingPath(theme);
|
||||
}
|
||||
} catch (e) {
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: "文件处理异常", infoCode: 6660416));
|
||||
}
|
||||
},
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxHeight: 72),
|
||||
child: Container(
|
||||
width: 237,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: theme.weakDividerColor ?? CommonColor.weakDividerColor,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8, horizontal: 12),
|
||||
child: Row(
|
||||
mainAxisAlignment: widget.isSelf
|
||||
? MainAxisAlignment.end
|
||||
: MainAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
constraints:
|
||||
const BoxConstraints(maxWidth: 160),
|
||||
child: LayoutBuilder(
|
||||
builder: (buildContext, boxConstraints) {
|
||||
return CustomText(
|
||||
fileName,
|
||||
width: boxConstraints.maxWidth,
|
||||
maxLines: 1,
|
||||
style: TextStyle(
|
||||
color: theme.darkTextColor,
|
||||
fontSize: 16,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
if (fileSize != null)
|
||||
Text(
|
||||
showFileSize(fileSize),
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: theme.weakTextColor),
|
||||
)
|
||||
],
|
||||
)),
|
||||
TIMUIKitFileIcon(
|
||||
fileFormat: fileFormat,
|
||||
borderRadius: borderRadius),
|
||||
child: Stack(children: [
|
||||
ClipRRect(
|
||||
borderRadius: borderRadius,
|
||||
child: LinearProgressIndicator(
|
||||
minHeight: ((containerHeight) ?? 72) - 6,
|
||||
value: (received == 100 ? 0 : received) / 100,
|
||||
backgroundColor: received == 100 ? theme.weakBackgroundColor : Colors.white,
|
||||
valueColor: AlwaysStoppedAnimation(theme.lightPrimaryMaterialColor.shade50),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12),
|
||||
child: Row(mainAxisAlignment: widget.isSelf ? MainAxisAlignment.end : MainAxisAlignment.start, children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
constraints: const BoxConstraints(maxWidth: 160),
|
||||
child: LayoutBuilder(
|
||||
builder: (buildContext, boxConstraints) {
|
||||
return CustomText(
|
||||
fileName,
|
||||
width: boxConstraints.maxWidth,
|
||||
maxLines: 1,
|
||||
style: TextStyle(
|
||||
color: theme.darkTextColor,
|
||||
fontSize: 16,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
])),
|
||||
]),
|
||||
),
|
||||
),
|
||||
if (fileSize != null)
|
||||
Text(
|
||||
showFileSize(fileSize),
|
||||
style: TextStyle(fontSize: 14, color: theme.weakTextColor),
|
||||
)
|
||||
],
|
||||
)),
|
||||
TIMUIKitFileIcon(
|
||||
fileFormat: fileFormat,
|
||||
),
|
||||
])),
|
||||
]),
|
||||
),
|
||||
),
|
||||
)),
|
||||
if (!widget.isSelf && isWebDownloading)
|
||||
Container(
|
||||
|
|
|
|||
|
|
@ -322,14 +322,14 @@ class _TIMUIKitTextFieldLayoutNarrowState extends TIMUIKitState<TIMUIKitTextFiel
|
|||
}
|
||||
|
||||
String getAbstractMessage(V2TimMessage message) {
|
||||
final String? customAbstractMessage = widget.model.abstractMessageBuilder != null ? widget.model.abstractMessageBuilder!(widget.model.repliedMessage!) : null;
|
||||
return customAbstractMessage ?? MessageUtils.getAbstractMessageAsync(widget.model.repliedMessage!, widget.model.groupMemberList ?? []);
|
||||
final String? customAbstractMessage = widget.model.abstractMessageBuilder != null ? widget.model.abstractMessageBuilder!(message) : null;
|
||||
return customAbstractMessage ?? MessageUtils.getAbstractMessageAsync(message, widget.model.groupMemberList ?? []);
|
||||
}
|
||||
|
||||
_buildRepliedMessage(V2TimMessage? repliedMessage) {
|
||||
final haveRepliedMessage = repliedMessage != null;
|
||||
if (haveRepliedMessage) {
|
||||
final text = "${MessageUtils.getDisplayName(widget.model.repliedMessage!)}:${getAbstractMessage(repliedMessage)}";
|
||||
final String text = "${MessageUtils.getDisplayName(repliedMessage)}:${getAbstractMessage(repliedMessage)}";
|
||||
return Container(
|
||||
color: widget.backgroundColor ?? hexToColor("f5f5f6"),
|
||||
alignment: Alignment.centerLeft,
|
||||
|
|
@ -400,199 +400,202 @@ class _TIMUIKitTextFieldLayoutNarrowState extends TIMUIKitState<TIMUIKitTextFiel
|
|||
bottomPadding = padding.bottom;
|
||||
}
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
_buildRepliedMessage(widget.repliedMessage),
|
||||
Container(
|
||||
color: widget.backgroundColor ?? hexToColor("f5f5f6"),
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
|
||||
constraints: const BoxConstraints(minHeight: 50),
|
||||
child: Row(
|
||||
children: [
|
||||
if (widget.forbiddenText != null)
|
||||
Expanded(
|
||||
child: Container(
|
||||
height: 35,
|
||||
color: theme.weakBackgroundColor,
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
TIM_t(widget.forbiddenText!),
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 16,
|
||||
color: theme.weakTextColor,
|
||||
return GestureDetector(
|
||||
onTap: () {},
|
||||
child: Column(
|
||||
children: [
|
||||
_buildRepliedMessage(widget.repliedMessage),
|
||||
Container(
|
||||
color: widget.backgroundColor ?? hexToColor("f5f5f6"),
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
|
||||
constraints: const BoxConstraints(minHeight: 50),
|
||||
child: Row(
|
||||
children: [
|
||||
if (widget.forbiddenText != null)
|
||||
Expanded(
|
||||
child: Container(
|
||||
height: 35,
|
||||
color: theme.weakBackgroundColor,
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
TIM_t(widget.forbiddenText!),
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 16,
|
||||
color: theme.weakTextColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
)),
|
||||
if (PlatformUtils().isMobile && widget.showSendAudio && widget.forbiddenText == null)
|
||||
InkWell(
|
||||
onTap: () async {
|
||||
showKeyboard = showSendSoundText;
|
||||
if (showSendSoundText) {
|
||||
widget.focusNode.requestFocus();
|
||||
}
|
||||
if (await Permissions.checkPermission(
|
||||
context,
|
||||
Permission.microphone.value,
|
||||
theme,
|
||||
)) {
|
||||
setState(() {
|
||||
showEmojiPanel = false;
|
||||
showMore = false;
|
||||
showSendSoundText = !showSendSoundText;
|
||||
});
|
||||
}
|
||||
},
|
||||
child: SvgPicture.asset(
|
||||
showSendSoundText ? 'images/keyboard.svg' : 'images/voice.svg',
|
||||
package: 'tencent_cloud_chat_uikit',
|
||||
color: const Color.fromRGBO(68, 68, 68, 1),
|
||||
height: 28,
|
||||
width: 28,
|
||||
),
|
||||
),
|
||||
if (widget.forbiddenText == null)
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
if (widget.forbiddenText == null)
|
||||
Expanded(
|
||||
child: showSendSoundText
|
||||
? SendSoundMessage(onDownBottom: widget.goDownBottom, conversationID: widget.conversationID, conversationType: widget.conversationType)
|
||||
: KeyboardVisibility(
|
||||
child: ExtendedTextField(
|
||||
maxLines: 4,
|
||||
minLines: 1,
|
||||
focusNode: widget.focusNode,
|
||||
onChanged: debounceFunc,
|
||||
onTap: () {
|
||||
showKeyboard = true;
|
||||
widget.goDownBottom();
|
||||
setState(() {
|
||||
showEmojiPanel = false;
|
||||
showMore = false;
|
||||
});
|
||||
},
|
||||
keyboardType: TextInputType.multiline,
|
||||
textInputAction: PlatformUtils().isAndroid ? TextInputAction.newline : TextInputAction.send,
|
||||
onEditingComplete: () {
|
||||
widget.onSubmitted();
|
||||
if (showKeyboard) {
|
||||
widget.focusNode.requestFocus();
|
||||
}
|
||||
setState(() {
|
||||
if (widget.textEditingController.text.isEmpty) {
|
||||
showMoreButton = true;
|
||||
}
|
||||
});
|
||||
},
|
||||
textAlignVertical: TextAlignVertical.top,
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
hintStyle: const TextStyle(
|
||||
// fontSize: 10,
|
||||
color: Color(0xffAEA4A3),
|
||||
),
|
||||
fillColor: Colors.white,
|
||||
filled: true,
|
||||
isDense: true,
|
||||
hintText: widget.hintText ?? ''),
|
||||
controller: widget.textEditingController,
|
||||
specialTextSpanBuilder: PlatformUtils().isWeb
|
||||
? null
|
||||
: DefaultSpecialTextSpanBuilder(
|
||||
isUseQQPackage: (widget.model.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackage ?? true) || widget.isUseDefaultEmoji,
|
||||
isUseTencentCloudChatPackage: widget.model.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackage ?? true,
|
||||
customEmojiStickerList: widget.customEmojiStickerList,
|
||||
showAtBackground: true,
|
||||
)),
|
||||
onChanged: (bool visibility) {
|
||||
if (showKeyboard != visibility) {
|
||||
setState(() {
|
||||
showKeyboard = visibility;
|
||||
});
|
||||
}
|
||||
}),
|
||||
),
|
||||
if (widget.forbiddenText == null)
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
if (widget.showSendEmoji && widget.forbiddenText == null)
|
||||
InkWell(
|
||||
onTap: () {
|
||||
_openEmojiPanel();
|
||||
widget.goDownBottom();
|
||||
},
|
||||
child: PlatformUtils().isWeb
|
||||
? Icon(showEmojiPanel ? Icons.keyboard_alt_outlined : Icons.mood_outlined, color: hexToColor("5c6168"), size: 32)
|
||||
: SvgPicture.asset(
|
||||
showEmojiPanel ? 'images/keyboard.svg' : 'images/face.svg',
|
||||
package: 'tencent_cloud_chat_uikit',
|
||||
color: const Color.fromRGBO(68, 68, 68, 1),
|
||||
height: 28,
|
||||
width: 28,
|
||||
),
|
||||
),
|
||||
if (widget.forbiddenText == null)
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
if (widget.showMorePanel && widget.forbiddenText == null && showMoreButton)
|
||||
InkWell(
|
||||
onTap: () {
|
||||
// model.sendCustomMessage(data: "a", convID: model.currentSelectedConv, convType: model.currentSelectedConvType == 1 ? ConvType.c2c : ConvType.group);
|
||||
_openMore();
|
||||
widget.goDownBottom();
|
||||
},
|
||||
child: PlatformUtils().isWeb
|
||||
? Icon(Icons.add_circle_outline_outlined, color: hexToColor("5c6168"), size: 32)
|
||||
: SvgPicture.asset(
|
||||
'images/add.svg',
|
||||
package: 'tencent_cloud_chat_uikit',
|
||||
color: const Color.fromRGBO(68, 68, 68, 1),
|
||||
height: 28,
|
||||
width: 28,
|
||||
),
|
||||
),
|
||||
if ((isAndroidDevice() || isWebDevice()) && !showMoreButton)
|
||||
SizedBox(
|
||||
height: 32.0,
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
widget.onSubmitted();
|
||||
if (showKeyboard) {
|
||||
)),
|
||||
if (PlatformUtils().isMobile && widget.showSendAudio && widget.forbiddenText == null)
|
||||
InkWell(
|
||||
onTap: () async {
|
||||
showKeyboard = showSendSoundText;
|
||||
if (showSendSoundText) {
|
||||
widget.focusNode.requestFocus();
|
||||
}
|
||||
setState(() {
|
||||
if (widget.textEditingController.text.isEmpty) {
|
||||
showMoreButton = true;
|
||||
}
|
||||
});
|
||||
if (await Permissions.checkPermission(
|
||||
context,
|
||||
Permission.microphone.value,
|
||||
theme,
|
||||
)) {
|
||||
setState(() {
|
||||
showEmojiPanel = false;
|
||||
showMore = false;
|
||||
showSendSoundText = !showSendSoundText;
|
||||
});
|
||||
}
|
||||
},
|
||||
child: Text(TIM_t("发送")),
|
||||
child: SvgPicture.asset(
|
||||
showSendSoundText ? 'images/keyboard.svg' : 'images/voice.svg',
|
||||
package: 'tencent_cloud_chat_uikit',
|
||||
color: const Color.fromRGBO(68, 68, 68, 1),
|
||||
height: 28,
|
||||
width: 28,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
if (widget.forbiddenText == null)
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
if (widget.forbiddenText == null)
|
||||
Expanded(
|
||||
child: showSendSoundText
|
||||
? SendSoundMessage(onDownBottom: widget.goDownBottom, conversationID: widget.conversationID, conversationType: widget.conversationType)
|
||||
: KeyboardVisibility(
|
||||
child: ExtendedTextField(
|
||||
maxLines: 4,
|
||||
minLines: 1,
|
||||
focusNode: widget.focusNode,
|
||||
onChanged: debounceFunc,
|
||||
onTap: () {
|
||||
showKeyboard = true;
|
||||
widget.goDownBottom();
|
||||
setState(() {
|
||||
showEmojiPanel = false;
|
||||
showMore = false;
|
||||
});
|
||||
},
|
||||
keyboardType: TextInputType.multiline,
|
||||
textInputAction: PlatformUtils().isAndroid ? TextInputAction.newline : TextInputAction.send,
|
||||
onEditingComplete: () {
|
||||
widget.onSubmitted();
|
||||
if (showKeyboard) {
|
||||
widget.focusNode.requestFocus();
|
||||
}
|
||||
setState(() {
|
||||
if (widget.textEditingController.text.isEmpty) {
|
||||
showMoreButton = true;
|
||||
}
|
||||
});
|
||||
},
|
||||
textAlignVertical: TextAlignVertical.top,
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
hintStyle: const TextStyle(
|
||||
// fontSize: 10,
|
||||
color: Color(0xffAEA4A3),
|
||||
),
|
||||
fillColor: Colors.white,
|
||||
filled: true,
|
||||
isDense: true,
|
||||
hintText: widget.hintText ?? ''),
|
||||
controller: widget.textEditingController,
|
||||
specialTextSpanBuilder: PlatformUtils().isWeb
|
||||
? null
|
||||
: DefaultSpecialTextSpanBuilder(
|
||||
isUseQQPackage: (widget.model.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackage ?? true) || widget.isUseDefaultEmoji,
|
||||
isUseTencentCloudChatPackage: widget.model.chatConfig.stickerPanelConfig?.useTencentCloudChatStickerPackage ?? true,
|
||||
customEmojiStickerList: widget.customEmojiStickerList,
|
||||
showAtBackground: true,
|
||||
)),
|
||||
onChanged: (bool visibility) {
|
||||
if (showKeyboard != visibility) {
|
||||
setState(() {
|
||||
showKeyboard = visibility;
|
||||
});
|
||||
}
|
||||
}),
|
||||
),
|
||||
if (widget.forbiddenText == null)
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
if (widget.showSendEmoji && widget.forbiddenText == null)
|
||||
InkWell(
|
||||
onTap: () {
|
||||
_openEmojiPanel();
|
||||
widget.goDownBottom();
|
||||
},
|
||||
child: PlatformUtils().isWeb
|
||||
? Icon(showEmojiPanel ? Icons.keyboard_alt_outlined : Icons.mood_outlined, color: hexToColor("5c6168"), size: 32)
|
||||
: SvgPicture.asset(
|
||||
showEmojiPanel ? 'images/keyboard.svg' : 'images/face.svg',
|
||||
package: 'tencent_cloud_chat_uikit',
|
||||
color: const Color.fromRGBO(68, 68, 68, 1),
|
||||
height: 28,
|
||||
width: 28,
|
||||
),
|
||||
),
|
||||
if (widget.forbiddenText == null)
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
if (widget.showMorePanel && widget.forbiddenText == null && showMoreButton)
|
||||
InkWell(
|
||||
onTap: () {
|
||||
// model.sendCustomMessage(data: "a", convID: model.currentSelectedConv, convType: model.currentSelectedConvType == 1 ? ConvType.c2c : ConvType.group);
|
||||
_openMore();
|
||||
widget.goDownBottom();
|
||||
},
|
||||
child: PlatformUtils().isWeb
|
||||
? Icon(Icons.add_circle_outline_outlined, color: hexToColor("5c6168"), size: 32)
|
||||
: SvgPicture.asset(
|
||||
'images/add.svg',
|
||||
package: 'tencent_cloud_chat_uikit',
|
||||
color: const Color.fromRGBO(68, 68, 68, 1),
|
||||
height: 28,
|
||||
width: 28,
|
||||
),
|
||||
),
|
||||
if ((isAndroidDevice() || isWebDevice()) && !showMoreButton)
|
||||
SizedBox(
|
||||
height: 32.0,
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
widget.onSubmitted();
|
||||
if (showKeyboard) {
|
||||
widget.focusNode.requestFocus();
|
||||
}
|
||||
if (widget.textEditingController.text.isEmpty) {
|
||||
setState(() {
|
||||
showMoreButton = true;
|
||||
});
|
||||
}
|
||||
},
|
||||
child: Text(TIM_t("发送")),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
AnimatedContainer(
|
||||
duration: Duration(milliseconds: (showKeyboard && PlatformUtils().isAndroid) ? 200 : 340),
|
||||
curve: Curves.fastOutSlowIn,
|
||||
height: max(_getBottomHeight(), 0.0),
|
||||
child: ListView(
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
children: [_getBottomContainer(theme)],
|
||||
AnimatedContainer(
|
||||
duration: Duration(milliseconds: (showKeyboard && PlatformUtils().isAndroid) ? 200 : 340),
|
||||
curve: Curves.fastOutSlowIn,
|
||||
height: max(_getBottomHeight(), 0.0),
|
||||
child: ListView(
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
children: [_getBottomContainer(theme)],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,9 +2,10 @@ import 'dart:math';
|
|||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_easyrefresh/easy_refresh.dart';
|
||||
import 'package:flutter_slidable_for_tencent_im/flutter_slidable.dart';
|
||||
import 'package:flutter_slidable/flutter_slidable.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:scroll_to_index/scroll_to_index.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/conversation_life_cycle.dart';
|
||||
|
|
@ -18,18 +19,13 @@ import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart';
|
|||
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitConversation/tim_uikit_conversation_item.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/customize_ball_pulse_header.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart';
|
||||
|
||||
typedef ConversationItemBuilder = Widget Function(
|
||||
V2TimConversation conversationItem,
|
||||
[V2TimUserStatus? onlineStatus]);
|
||||
typedef ConversationItemBuilder = Widget Function(V2TimConversation conversationItem, [V2TimUserStatus? onlineStatus]);
|
||||
|
||||
typedef ConversationItemSlideBuilder = List<ConversationItemSlidePanel>
|
||||
Function(V2TimConversation conversationItem);
|
||||
typedef ConversationItemSlideBuilder = List<ConversationItemSlidePanel> Function(V2TimConversation conversationItem);
|
||||
|
||||
typedef ConversationItemSecondaryMenuBuilder = Widget Function(
|
||||
V2TimConversation conversationItem, VoidCallback onClose);
|
||||
typedef ConversationItemSecondaryMenuBuilder = Widget Function(V2TimConversation conversationItem, VoidCallback onClose);
|
||||
|
||||
class TIMUIKitConversation extends StatefulWidget {
|
||||
/// the callback after clicking conversation item
|
||||
|
|
@ -143,12 +139,10 @@ class ConversationItemSlidePanel extends TIMUIKitStatelessWidget {
|
|||
}
|
||||
|
||||
class _TIMUIKitConversationState extends TIMUIKitState<TIMUIKitConversation> {
|
||||
final TUIConversationViewModel model =
|
||||
serviceLocator<TUIConversationViewModel>();
|
||||
final TUIConversationViewModel model = serviceLocator<TUIConversationViewModel>();
|
||||
late TIMUIKitConversationController _timuiKitConversationController;
|
||||
final TUIThemeViewModel themeViewModel = serviceLocator<TUIThemeViewModel>();
|
||||
final TUIFriendShipViewModel friendShipViewModel =
|
||||
serviceLocator<TUIFriendShipViewModel>();
|
||||
final TUIFriendShipViewModel friendShipViewModel = serviceLocator<TUIFriendShipViewModel>();
|
||||
late AutoScrollController _autoScrollController;
|
||||
|
||||
@override
|
||||
|
|
@ -172,30 +166,21 @@ class _TIMUIKitConversationState extends TIMUIKitState<TIMUIKitConversation> {
|
|||
}
|
||||
|
||||
_clearHistory(V2TimConversation conversationItem) {
|
||||
_timuiKitConversationController.clearHistoryMessage(
|
||||
conversation: conversationItem);
|
||||
_timuiKitConversationController.clearHistoryMessage(conversation: conversationItem);
|
||||
}
|
||||
|
||||
_pinConversation(V2TimConversation conversation) {
|
||||
_timuiKitConversationController.pinConversation(
|
||||
conversationID: conversation.conversationID,
|
||||
isPinned: !conversation.isPinned!);
|
||||
_timuiKitConversationController.pinConversation(conversationID: conversation.conversationID, isPinned: !conversation.isPinned!);
|
||||
}
|
||||
|
||||
_deleteConversation(V2TimConversation conversation) {
|
||||
_timuiKitConversationController.deleteConversation(
|
||||
conversationID: conversation.conversationID);
|
||||
_timuiKitConversationController.deleteConversation(conversationID: conversation.conversationID);
|
||||
}
|
||||
|
||||
List<V2TimConversation?> getFilteredConversation() {
|
||||
List<V2TimConversation?> filteredConversationList = model.conversationList
|
||||
.where(
|
||||
(element) => (element?.groupID != null || element?.userID != null))
|
||||
.toList();
|
||||
List<V2TimConversation?> filteredConversationList = model.conversationList.where((element) => (element?.groupID != null || element?.userID != null)).toList();
|
||||
if (widget.conversationCollector != null) {
|
||||
filteredConversationList = filteredConversationList
|
||||
.where(widget.conversationCollector!)
|
||||
.toList();
|
||||
filteredConversationList = filteredConversationList.where(widget.conversationCollector!).toList();
|
||||
}
|
||||
return filteredConversationList;
|
||||
}
|
||||
|
|
@ -221,8 +206,7 @@ class _TIMUIKitConversationState extends TIMUIKitState<TIMUIKitConversation> {
|
|||
}
|
||||
}
|
||||
|
||||
Widget _defaultSecondaryMenu(
|
||||
V2TimConversation conversationItem, VoidCallback onClose) {
|
||||
Widget _defaultSecondaryMenu(V2TimConversation conversationItem, VoidCallback onClose) {
|
||||
return TUIKitColumnMenu(data: [
|
||||
if (!PlatformUtils().isWeb)
|
||||
ColumnMenuItem(
|
||||
|
|
@ -234,11 +218,7 @@ class _TIMUIKitConversationState extends TIMUIKitState<TIMUIKitConversation> {
|
|||
}),
|
||||
ColumnMenuItem(
|
||||
label: conversationItem.isPinned! ? TIM_t("取消置顶") : TIM_t("置顶"),
|
||||
icon: Icon(
|
||||
conversationItem.isPinned!
|
||||
? Icons.vertical_align_bottom
|
||||
: Icons.vertical_align_top,
|
||||
size: 16),
|
||||
icon: Icon(conversationItem.isPinned! ? Icons.vertical_align_bottom : Icons.vertical_align_top, size: 16),
|
||||
onClick: () {
|
||||
onClose();
|
||||
_pinConversation(conversationItem);
|
||||
|
|
@ -263,8 +243,7 @@ class _TIMUIKitConversationState extends TIMUIKitState<TIMUIKitConversation> {
|
|||
onPressed: (context) {
|
||||
_clearHistory(conversationItem);
|
||||
},
|
||||
backgroundColor: theme.conversationItemSliderClearBgColor ??
|
||||
CommonColor.primaryColor,
|
||||
backgroundColor: theme.conversationItemSliderClearBgColor ?? CommonColor.primaryColor,
|
||||
foregroundColor: theme.conversationItemSliderTextColor,
|
||||
label: TIM_t("清除聊天"),
|
||||
spacing: 0,
|
||||
|
|
@ -274,8 +253,7 @@ class _TIMUIKitConversationState extends TIMUIKitState<TIMUIKitConversation> {
|
|||
onPressed: (context) {
|
||||
_pinConversation(conversationItem);
|
||||
},
|
||||
backgroundColor:
|
||||
theme.conversationItemSliderPinBgColor ?? CommonColor.infoColor,
|
||||
backgroundColor: theme.conversationItemSliderPinBgColor ?? CommonColor.infoColor,
|
||||
foregroundColor: theme.conversationItemSliderTextColor,
|
||||
label: conversationItem.isPinned! ? TIM_t("取消置顶") : TIM_t("置顶"),
|
||||
),
|
||||
|
|
@ -283,16 +261,14 @@ class _TIMUIKitConversationState extends TIMUIKitState<TIMUIKitConversation> {
|
|||
onPressed: (context) {
|
||||
_deleteConversation(conversationItem);
|
||||
},
|
||||
backgroundColor:
|
||||
theme.conversationItemSliderDeleteBgColor ?? Colors.red,
|
||||
backgroundColor: theme.conversationItemSliderDeleteBgColor ?? Colors.red,
|
||||
foregroundColor: theme.conversationItemSliderTextColor,
|
||||
label: TIM_t("删除"),
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
Widget _getSecondaryMenu(
|
||||
V2TimConversation conversation, VoidCallback onClose) {
|
||||
Widget _getSecondaryMenu(V2TimConversation conversation, VoidCallback onClose) {
|
||||
if (widget.itemSecondaryMenuBuilder != null) {
|
||||
return widget.itemSecondaryMenuBuilder!(conversation, onClose);
|
||||
}
|
||||
|
|
@ -311,22 +287,16 @@ class _TIMUIKitConversationState extends TIMUIKitState<TIMUIKitConversation> {
|
|||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final theme = value.theme;
|
||||
final isDesktopScreen =
|
||||
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
return MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider.value(value: model),
|
||||
ChangeNotifierProvider.value(value: friendShipViewModel)
|
||||
],
|
||||
providers: [ChangeNotifierProvider.value(value: model), ChangeNotifierProvider.value(value: friendShipViewModel)],
|
||||
builder: (BuildContext context, Widget? w) {
|
||||
final _model = Provider.of<TUIConversationViewModel>(context);
|
||||
bool haveMoreData = _model.haveMoreData;
|
||||
final _friendShipViewModel =
|
||||
Provider.of<TUIFriendShipViewModel>(context);
|
||||
final _friendShipViewModel = Provider.of<TUIFriendShipViewModel>(context);
|
||||
_model.lifeCycle = widget.lifeCycle;
|
||||
|
||||
List<V2TimConversation?> filteredConversationList =
|
||||
getFilteredConversation();
|
||||
List<V2TimConversation?> filteredConversationList = getFilteredConversation();
|
||||
|
||||
if (TencentUtils.checkString(_model.scrollToConversation) != null) {
|
||||
_onScrollToConversation(_model.scrollToConversation!);
|
||||
|
|
@ -348,21 +318,15 @@ class _TIMUIKitConversationState extends TIMUIKitState<TIMUIKitConversation> {
|
|||
|
||||
final conversationItem = filteredConversationList[index];
|
||||
|
||||
final V2TimUserStatus? onlineStatus =
|
||||
_friendShipViewModel.userStatusList.firstWhere(
|
||||
(item) => item.userID == conversationItem?.userID,
|
||||
orElse: () => V2TimUserStatus(statusType: 0));
|
||||
final V2TimUserStatus? onlineStatus = _friendShipViewModel.userStatusList.firstWhere((item) => item.userID == conversationItem?.userID, orElse: () => V2TimUserStatus(statusType: 0));
|
||||
|
||||
if (widget.itemBuilder != null) {
|
||||
return widget.itemBuilder!(
|
||||
conversationItem!, onlineStatus);
|
||||
return widget.itemBuilder!(conversationItem!, onlineStatus);
|
||||
}
|
||||
|
||||
final slideChildren =
|
||||
_getSlideBuilder()(conversationItem!);
|
||||
final slideChildren = _getSlideBuilder()(conversationItem!);
|
||||
|
||||
final isCurrent = conversationItem.conversationID ==
|
||||
model.selectedConversation?.conversationID;
|
||||
final isCurrent = conversationItem.conversationID == model.selectedConversation?.conversationID;
|
||||
|
||||
final isPined = conversationItem.isPinned ?? false;
|
||||
|
||||
|
|
@ -383,15 +347,10 @@ class _TIMUIKitConversationState extends TIMUIKitState<TIMUIKitConversation> {
|
|||
isDisturb: conversationItem.recvOpt != 0,
|
||||
lastMsg: conversationItem.lastMessage,
|
||||
isPined: isPined,
|
||||
groupAtInfoList:
|
||||
conversationItem.groupAtInfoList ?? [],
|
||||
groupAtInfoList: conversationItem.groupAtInfoList ?? [],
|
||||
unreadCount: conversationItem.unreadCount ?? 0,
|
||||
draftText: conversationItem.draftText,
|
||||
onlineStatus: (widget.isShowOnlineStatus &&
|
||||
conversationItem.userID != null &&
|
||||
conversationItem.userID!.isNotEmpty)
|
||||
? onlineStatus
|
||||
: null,
|
||||
onlineStatus: (widget.isShowOnlineStatus && conversationItem.userID != null && conversationItem.userID!.isNotEmpty) ? onlineStatus : null,
|
||||
draftTimestamp: conversationItem.draftTimestamp,
|
||||
convType: conversationItem.type),
|
||||
onTap: () => onTapConvItem(conversationItem),
|
||||
|
|
@ -408,23 +367,12 @@ class _TIMUIKitConversationState extends TIMUIKitState<TIMUIKitConversation> {
|
|||
child: InkWell(
|
||||
onSecondaryTapDown: (details) {
|
||||
TUIKitWidePopup.showPopupWindow(
|
||||
operationKey: TUIKitWideModalOperationKey
|
||||
.conversationSecondaryMenu,
|
||||
operationKey: TUIKitWideModalOperationKey.conversationSecondaryMenu,
|
||||
isDarkBackground: false,
|
||||
borderRadius: const BorderRadius.all(
|
||||
Radius.circular(4)),
|
||||
borderRadius: const BorderRadius.all(Radius.circular(4)),
|
||||
context: context,
|
||||
offset: Offset(
|
||||
min(
|
||||
details.globalPosition.dx,
|
||||
MediaQuery.of(context).size.width -
|
||||
80),
|
||||
min(
|
||||
details.globalPosition.dy,
|
||||
MediaQuery.of(context).size.height -
|
||||
130)),
|
||||
child: (onClose) => _getSecondaryMenu(
|
||||
conversationItem, onClose));
|
||||
offset: Offset(min(details.globalPosition.dx, MediaQuery.of(context).size.width - 80), min(details.globalPosition.dy, MediaQuery.of(context).size.height - 130)),
|
||||
child: (onClose) => _getSecondaryMenu(conversationItem, onClose));
|
||||
},
|
||||
child: conversationLineItem(),
|
||||
),
|
||||
|
|
@ -433,19 +381,10 @@ class _TIMUIKitConversationState extends TIMUIKitState<TIMUIKitConversation> {
|
|||
key: ValueKey(conversationItem.conversationID),
|
||||
controller: _autoScrollController,
|
||||
index: index,
|
||||
child: Slidable(
|
||||
groupTag: 'conversation-list',
|
||||
child: conversationLineItem(),
|
||||
endActionPane: ActionPane(
|
||||
extentRatio:
|
||||
slideChildren.length > 2 ? 0.77 : 0.5,
|
||||
motion: const DrawerMotion(),
|
||||
children: slideChildren)),
|
||||
child: Slidable(groupTag: 'conversation-list', child: conversationLineItem(), endActionPane: ActionPane(extentRatio: slideChildren.length > 2 ? 0.77 : 0.5, motion: const DrawerMotion(), children: slideChildren)),
|
||||
));
|
||||
})
|
||||
: (widget.emptyBuilder != null
|
||||
? widget.emptyBuilder!()
|
||||
: Container());
|
||||
: (widget.emptyBuilder != null ? widget.emptyBuilder!() : Container());
|
||||
}
|
||||
|
||||
return TUIKitScreenUtils.getDeviceWidget(
|
||||
|
|
@ -459,9 +398,7 @@ class _TIMUIKitConversationState extends TIMUIKitState<TIMUIKitConversation> {
|
|||
child: conversationList(),
|
||||
),
|
||||
),
|
||||
desktopWidget: Scrollbar(
|
||||
controller: _autoScrollController,
|
||||
child: conversationList()));
|
||||
desktopWidget: Scrollbar(controller: _autoScrollController, child: conversationList()));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,20 +2,20 @@ import 'dart:math';
|
|||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_slidable_for_tencent_im/flutter_slidable.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitProfile/widget/tim_uikit_operation_item.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/column_menu.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart';
|
||||
import 'package:tencent_im_base/tencent_im_base.dart';
|
||||
import 'package:flutter_slidable/flutter_slidable.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_group_profile_model.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitProfile/widget/tim_uikit_operation_item.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/column_menu.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/radio_button.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart';
|
||||
import 'package:tencent_im_base/tencent_im_base.dart';
|
||||
|
||||
GlobalKey<_GroupProfileAddAdminState> groupProfileAddAdminKey = GlobalKey();
|
||||
|
||||
|
|
@ -26,34 +26,23 @@ class GroupProfileGroupManage extends StatefulWidget {
|
|||
State<StatefulWidget> createState() => GroupProfileGroupManageState();
|
||||
}
|
||||
|
||||
class GroupProfileGroupManageState
|
||||
extends TIMUIKitState<GroupProfileGroupManage> {
|
||||
class GroupProfileGroupManageState extends TIMUIKitState<GroupProfileGroupManage> {
|
||||
bool isShowManageBox = false;
|
||||
|
||||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final TUITheme theme = value.theme;
|
||||
final isDesktopScreen =
|
||||
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
final model = Provider.of<TUIGroupProfileModel>(context);
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: isDesktopScreen
|
||||
? null
|
||||
: Border(
|
||||
bottom: BorderSide(
|
||||
color: theme.weakDividerColor ??
|
||||
CommonColor.weakDividerColor))),
|
||||
decoration: BoxDecoration(color: Colors.white, border: isDesktopScreen ? null : Border(bottom: BorderSide(color: theme.weakDividerColor ?? CommonColor.weakDividerColor))),
|
||||
child: Column(
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () {
|
||||
final isDesktopScreen =
|
||||
TUIKitScreenUtils.getFormFactor(context) ==
|
||||
DeviceType.Desktop;
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
if (!isDesktopScreen) {
|
||||
Navigator.push(
|
||||
context,
|
||||
|
|
@ -72,15 +61,12 @@ class GroupProfileGroupManageState
|
|||
children: [
|
||||
Text(
|
||||
TIM_t("群管理"),
|
||||
style: TextStyle(
|
||||
fontSize: isDesktopScreen ? 14 : 16,
|
||||
color: theme.darkTextColor),
|
||||
style: TextStyle(fontSize: isDesktopScreen ? 14 : 16, color: theme.darkTextColor),
|
||||
),
|
||||
AnimatedRotation(
|
||||
turns: isShowManageBox ? 0.25 : 0,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: Icon(Icons.keyboard_arrow_right,
|
||||
color: theme.weakTextColor),
|
||||
child: Icon(Icons.keyboard_arrow_right, color: theme.weakTextColor),
|
||||
)
|
||||
],
|
||||
),
|
||||
|
|
@ -108,8 +94,7 @@ class GroupProfileGroupManagePage extends StatefulWidget {
|
|||
State<StatefulWidget> createState() => _GroupProfileGroupManagePageState();
|
||||
}
|
||||
|
||||
class _GroupProfileGroupManagePageState
|
||||
extends TIMUIKitState<GroupProfileGroupManagePage> {
|
||||
class _GroupProfileGroupManagePageState extends TIMUIKitState<GroupProfileGroupManagePage> {
|
||||
int? serverTime;
|
||||
|
||||
@override
|
||||
|
|
@ -128,38 +113,20 @@ class _GroupProfileGroupManagePageState
|
|||
@override
|
||||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
return MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider.value(value: widget.model),
|
||||
ChangeNotifierProvider.value(
|
||||
value: serviceLocator<TUIThemeViewModel>())
|
||||
],
|
||||
providers: [ChangeNotifierProvider.value(value: widget.model), ChangeNotifierProvider.value(value: serviceLocator<TUIThemeViewModel>())],
|
||||
builder: (context, w) {
|
||||
final memberList =
|
||||
Provider.of<TUIGroupProfileModel>(context).groupMemberList;
|
||||
final memberList = Provider.of<TUIGroupProfileModel>(context).groupMemberList;
|
||||
final theme = Provider.of<TUIThemeViewModel>(context).theme;
|
||||
final isAllMuted = widget.model.groupInfo?.isAllMuted ?? false;
|
||||
final bool isAllowMuteMember =
|
||||
(widget.model.groupInfo?.groupType ?? "") != GroupType.Work;
|
||||
final isDesktopScreen =
|
||||
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
final bool isAllowMuteMember = (widget.model.groupInfo?.groupType ?? "") != GroupType.Work;
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
|
||||
Widget managePage() {
|
||||
return Column(
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.only(
|
||||
top: 12,
|
||||
left: isDesktopScreen ? 0 : 16,
|
||||
bottom: isDesktopScreen ? 0 : 12,
|
||||
right: isDesktopScreen ? 0 : 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: isDesktopScreen
|
||||
? null
|
||||
: Border(
|
||||
bottom: BorderSide(
|
||||
color: theme.weakDividerColor ??
|
||||
CommonColor.weakDividerColor))),
|
||||
padding: EdgeInsets.only(top: 12, left: isDesktopScreen ? 0 : 16, bottom: isDesktopScreen ? 0 : 12, right: isDesktopScreen ? 0 : 12),
|
||||
decoration: BoxDecoration(color: Colors.white, border: isDesktopScreen ? null : Border(bottom: BorderSide(color: theme.weakDividerColor ?? CommonColor.weakDividerColor))),
|
||||
child: InkWell(
|
||||
onTap: isDesktopScreen
|
||||
? null
|
||||
|
|
@ -167,8 +134,7 @@ class _GroupProfileGroupManagePageState
|
|||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
GroupProfileSetManagerPage(
|
||||
builder: (context) => GroupProfileSetManagerPage(
|
||||
model: widget.model,
|
||||
),
|
||||
));
|
||||
|
|
@ -177,22 +143,12 @@ class _GroupProfileGroupManagePageState
|
|||
? Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(TIM_t("群管理员"),
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: theme.darkTextColor)),
|
||||
Text(TIM_t("群管理员"), style: TextStyle(fontSize: 14, color: theme.darkTextColor)),
|
||||
],
|
||||
)
|
||||
: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(TIM_t("设置管理员"),
|
||||
style: TextStyle(
|
||||
fontSize: isDesktopScreen ? 14 : 16,
|
||||
color: theme.darkTextColor)),
|
||||
Icon(Icons.keyboard_arrow_right,
|
||||
color: theme.weakTextColor)
|
||||
],
|
||||
children: [Text(TIM_t("设置管理员"), style: TextStyle(fontSize: isDesktopScreen ? 14 : 16, color: theme.darkTextColor)), Icon(Icons.keyboard_arrow_right, color: theme.weakTextColor)],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -202,21 +158,14 @@ class _GroupProfileGroupManagePageState
|
|||
),
|
||||
if (!isDesktopScreen)
|
||||
Container(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 12, left: 16, bottom: 12, right: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: theme.weakDividerColor ??
|
||||
CommonColor.weakDividerColor))),
|
||||
padding: const EdgeInsets.only(top: 12, left: 16, bottom: 12, right: 12),
|
||||
decoration: BoxDecoration(color: Colors.white, border: Border(bottom: BorderSide(color: theme.weakDividerColor ?? CommonColor.weakDividerColor))),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
TIM_t("全员禁言"),
|
||||
style: TextStyle(
|
||||
fontSize: 16, color: theme.darkTextColor),
|
||||
style: TextStyle(fontSize: 16, color: theme.darkTextColor),
|
||||
),
|
||||
CupertinoSwitch(
|
||||
value: isAllMuted,
|
||||
|
|
@ -231,9 +180,7 @@ class _GroupProfileGroupManagePageState
|
|||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(TIM_t("禁言"),
|
||||
style: TextStyle(
|
||||
fontSize: 14, color: theme.darkTextColor)),
|
||||
Text(TIM_t("禁言"), style: TextStyle(fontSize: 14, color: theme.darkTextColor)),
|
||||
],
|
||||
),
|
||||
if (isDesktopScreen)
|
||||
|
|
@ -253,14 +200,12 @@ class _GroupProfileGroupManagePageState
|
|||
),
|
||||
if (!isDesktopScreen)
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 10, horizontal: 16),
|
||||
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16),
|
||||
color: theme.weakBackgroundColor,
|
||||
alignment: Alignment.topLeft,
|
||||
child: Text(
|
||||
TIM_t("全员禁言开启后,只允许群主和管理员发言。"),
|
||||
style:
|
||||
TextStyle(fontSize: 12, color: theme.weakTextColor),
|
||||
style: TextStyle(fontSize: 12, color: theme.weakTextColor),
|
||||
),
|
||||
),
|
||||
if (!isAllMuted && isAllowMuteMember)
|
||||
|
|
@ -276,14 +221,7 @@ class _GroupProfileGroupManagePageState
|
|||
: const EdgeInsets.only(
|
||||
bottom: 4,
|
||||
),
|
||||
decoration: isDesktopScreen
|
||||
? null
|
||||
: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: theme.weakDividerColor ??
|
||||
CommonColor.weakDividerColor))),
|
||||
decoration: isDesktopScreen ? null : BoxDecoration(color: Colors.white, border: Border(bottom: BorderSide(color: theme.weakDividerColor ?? CommonColor.weakDividerColor))),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
|
|
@ -304,21 +242,15 @@ class _GroupProfileGroupManagePageState
|
|||
key: groupProfileAddAdminKey,
|
||||
appbarTitle: TIM_t("设置禁言"),
|
||||
memberList: memberList.where((element) {
|
||||
final isMute = (serverTime != null
|
||||
? (element?.muteUntil ?? 0) > serverTime!
|
||||
: false);
|
||||
final isMember = element!.role ==
|
||||
GroupMemberRoleType
|
||||
.V2TIM_GROUP_MEMBER_ROLE_MEMBER;
|
||||
final isMute = (serverTime != null ? (element?.muteUntil ?? 0) > serverTime! : false);
|
||||
final isMember = element!.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_MEMBER;
|
||||
return !isMute && isMember;
|
||||
}).toList(),
|
||||
selectCompletedHandler:
|
||||
(context, selectedMember) async {
|
||||
selectCompletedHandler: (context, selectedMember) async {
|
||||
if (selectedMember.isNotEmpty) {
|
||||
for (var member in selectedMember) {
|
||||
final userID = member!.userID;
|
||||
widget.model
|
||||
.muteGroupMember(userID, true, serverTime);
|
||||
widget.model.muteGroupMember(userID, true, serverTime);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -337,48 +269,29 @@ class _GroupProfileGroupManagePageState
|
|||
},
|
||||
child: (onClose) => muteMember());
|
||||
} else {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => muteMember()));
|
||||
Navigator.push(context, MaterialPageRoute(builder: (context) => muteMember()));
|
||||
}
|
||||
},
|
||||
),
|
||||
if (!isAllMuted && isAllowMuteMember)
|
||||
...memberList
|
||||
.where((element) => (serverTime != null
|
||||
? (element?.muteUntil ?? 0) > serverTime!
|
||||
: false))
|
||||
.where((element) => (serverTime != null ? (element?.muteUntil ?? 0) > serverTime! : false))
|
||||
.map((e) => Container(
|
||||
padding: isDesktopScreen
|
||||
? const EdgeInsets.only(left: 16)
|
||||
: null,
|
||||
padding: isDesktopScreen ? const EdgeInsets.only(left: 16) : null,
|
||||
child: GestureDetector(
|
||||
onSecondaryTapDown: (details) {
|
||||
TUIKitWidePopup.showPopupWindow(
|
||||
operationKey:
|
||||
TUIKitWideModalOperationKey.setUnmute,
|
||||
operationKey: TUIKitWideModalOperationKey.setUnmute,
|
||||
isDarkBackground: false,
|
||||
borderRadius: const BorderRadius.all(
|
||||
Radius.circular(4)),
|
||||
borderRadius: const BorderRadius.all(Radius.circular(4)),
|
||||
context: context,
|
||||
offset: Offset(
|
||||
min(
|
||||
details.globalPosition.dx,
|
||||
MediaQuery.of(context).size.width -
|
||||
80),
|
||||
details.globalPosition.dy),
|
||||
offset: Offset(min(details.globalPosition.dx, MediaQuery.of(context).size.width - 80), details.globalPosition.dy),
|
||||
child: (onClose) => TUIKitColumnMenu(data: [
|
||||
ColumnMenuItem(
|
||||
label: TIM_t("删除"),
|
||||
icon: const Icon(
|
||||
Icons.remove_circle_outline,
|
||||
size: 16),
|
||||
icon: const Icon(Icons.remove_circle_outline, size: 16),
|
||||
onClick: () {
|
||||
widget.model.muteGroupMember(
|
||||
e.userID,
|
||||
false,
|
||||
serverTime);
|
||||
widget.model.muteGroupMember(e.userID, false, serverTime);
|
||||
onClose();
|
||||
}),
|
||||
]));
|
||||
|
|
@ -386,21 +299,17 @@ class _GroupProfileGroupManagePageState
|
|||
child: _buildListItem(
|
||||
context,
|
||||
e!,
|
||||
ActionPane(
|
||||
motion: const DrawerMotion(),
|
||||
children: [
|
||||
SlidableAction(
|
||||
onPressed: (_) {
|
||||
widget.model.muteGroupMember(
|
||||
e.userID, false, serverTime);
|
||||
},
|
||||
flex: 1,
|
||||
backgroundColor: theme.cautionColor ??
|
||||
CommonColor.cautionColor,
|
||||
autoClose: true,
|
||||
label: TIM_t("删除"),
|
||||
)
|
||||
])),
|
||||
ActionPane(motion: const DrawerMotion(), children: [
|
||||
SlidableAction(
|
||||
onPressed: (_) {
|
||||
widget.model.muteGroupMember(e.userID, false, serverTime);
|
||||
},
|
||||
flex: 1,
|
||||
backgroundColor: theme.cautionColor ?? CommonColor.cautionColor,
|
||||
autoClose: true,
|
||||
label: TIM_t("删除"),
|
||||
)
|
||||
])),
|
||||
),
|
||||
))
|
||||
.toList()
|
||||
|
|
@ -415,8 +324,7 @@ class _GroupProfileGroupManagePageState
|
|||
appBar: AppBar(
|
||||
title: Text(
|
||||
TIM_t("群管理"),
|
||||
style:
|
||||
TextStyle(color: theme.appbarTextColor, fontSize: 17),
|
||||
style: TextStyle(color: theme.appbarTextColor, fontSize: 17),
|
||||
),
|
||||
backgroundColor: theme.appbarBgColor ?? theme.primaryColor,
|
||||
shadowColor: theme.weakDividerColor,
|
||||
|
|
@ -461,11 +369,9 @@ _getShowName(V2TimGroupMemberFullInfo? item) {
|
|||
: userID;
|
||||
}
|
||||
|
||||
Widget _buildListItem(BuildContext context, V2TimGroupMemberFullInfo memberInfo,
|
||||
ActionPane? endActionPane) {
|
||||
Widget _buildListItem(BuildContext context, V2TimGroupMemberFullInfo memberInfo, ActionPane? endActionPane) {
|
||||
final theme = Provider.of<TUIThemeViewModel>(context).theme;
|
||||
final isDesktopScreen =
|
||||
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
|
||||
Widget nameItem() {
|
||||
return Container(
|
||||
|
|
@ -484,67 +390,42 @@ Widget _buildListItem(BuildContext context, V2TimGroupMemberFullInfo memberInfo,
|
|||
),
|
||||
title: Row(
|
||||
children: [
|
||||
Text(_getShowName(memberInfo),
|
||||
style: TextStyle(fontSize: isDesktopScreen ? 14 : 16)),
|
||||
Text(_getShowName(memberInfo), style: TextStyle(fontSize: isDesktopScreen ? 14 : 16)),
|
||||
],
|
||||
),
|
||||
onTap: () {},
|
||||
),
|
||||
if (!isDesktopScreen)
|
||||
Divider(
|
||||
thickness: 1,
|
||||
indent: 74,
|
||||
endIndent: 0,
|
||||
color: theme.weakDividerColor,
|
||||
height: 0)
|
||||
if (!isDesktopScreen) Divider(thickness: 1, indent: 74, endIndent: 0, color: theme.weakDividerColor, height: 0)
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
return TUIKitScreenUtils.getDeviceWidget(
|
||||
context: context,
|
||||
desktopWidget: nameItem(),
|
||||
defaultWidget: SingleChildScrollView(
|
||||
child: Slidable(endActionPane: endActionPane, child: nameItem())));
|
||||
return TUIKitScreenUtils.getDeviceWidget(context: context, desktopWidget: nameItem(), defaultWidget: SingleChildScrollView(child: Slidable(endActionPane: endActionPane, child: nameItem())));
|
||||
}
|
||||
|
||||
/// 选择管理员
|
||||
class GroupProfileSetManagerPage extends StatefulWidget {
|
||||
final TUIGroupProfileModel model;
|
||||
|
||||
const GroupProfileSetManagerPage({Key? key, required this.model})
|
||||
: super(key: key);
|
||||
const GroupProfileSetManagerPage({Key? key, required this.model}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _GroupProfileSetManagerPageState();
|
||||
}
|
||||
|
||||
class _GroupProfileSetManagerPageState
|
||||
extends TIMUIKitState<GroupProfileSetManagerPage> {
|
||||
List<V2TimGroupMemberFullInfo?> _getAdminMemberList(
|
||||
List<V2TimGroupMemberFullInfo?> memberList) {
|
||||
return memberList
|
||||
.where((member) =>
|
||||
member?.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_ADMIN)
|
||||
.toList();
|
||||
class _GroupProfileSetManagerPageState extends TIMUIKitState<GroupProfileSetManagerPage> {
|
||||
List<V2TimGroupMemberFullInfo?> _getAdminMemberList(List<V2TimGroupMemberFullInfo?> memberList) {
|
||||
return memberList.where((member) => member?.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_ADMIN).toList();
|
||||
}
|
||||
|
||||
List<V2TimGroupMemberFullInfo?> _getOwnerList(
|
||||
List<V2TimGroupMemberFullInfo?> memberList) {
|
||||
return memberList
|
||||
.where((member) =>
|
||||
member?.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER)
|
||||
.toList();
|
||||
List<V2TimGroupMemberFullInfo?> _getOwnerList(List<V2TimGroupMemberFullInfo?> memberList) {
|
||||
return memberList.where((member) => member?.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER).toList();
|
||||
}
|
||||
|
||||
_removeAdmin(
|
||||
BuildContext context, V2TimGroupMemberFullInfo memberFullInfo) async {
|
||||
_removeAdmin(BuildContext context, V2TimGroupMemberFullInfo memberFullInfo) async {
|
||||
final res = await widget.model.setMemberToNormal(memberFullInfo.userID);
|
||||
if (res.code == 0) {
|
||||
onTIMCallback(TIMCallback(
|
||||
type: TIMCallbackType.INFO,
|
||||
infoRecommendText: TIM_t("成功取消管理员身份"),
|
||||
infoCode: 6661003));
|
||||
onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("成功取消管理员身份"), infoCode: 6661003));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -560,8 +441,7 @@ class _GroupProfileSetManagerPageState
|
|||
final adminList = _getAdminMemberList(memberList);
|
||||
final ownerList = _getOwnerList(memberList);
|
||||
final String option2 = adminList.length.toString();
|
||||
final isDesktopScreen =
|
||||
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
|
||||
|
||||
Widget adminPage() {
|
||||
return SingleChildScrollView(
|
||||
|
|
@ -571,8 +451,7 @@ class _GroupProfileSetManagerPageState
|
|||
Container(
|
||||
alignment: Alignment.topLeft,
|
||||
color: theme.weakDividerColor,
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 6, horizontal: 16),
|
||||
padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 16),
|
||||
child: Text(
|
||||
TIM_t("群主"),
|
||||
style: TextStyle(fontSize: 14, color: theme.weakTextColor),
|
||||
|
|
@ -590,9 +469,7 @@ class _GroupProfileSetManagerPageState
|
|||
...ownerList
|
||||
.map(
|
||||
(e) => Container(
|
||||
padding: isDesktopScreen
|
||||
? const EdgeInsets.only(left: 16)
|
||||
: null,
|
||||
padding: isDesktopScreen ? const EdgeInsets.only(left: 16) : null,
|
||||
child: _buildListItem(context, e!, null),
|
||||
),
|
||||
)
|
||||
|
|
@ -601,11 +478,9 @@ class _GroupProfileSetManagerPageState
|
|||
Container(
|
||||
alignment: Alignment.topLeft,
|
||||
color: theme.weakDividerColor,
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 6, horizontal: 16),
|
||||
padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 16),
|
||||
child: Text(
|
||||
TIM_t_para("管理员 ({{option2}}/10)", "管理员 ($option2/10)")(
|
||||
option2: option2),
|
||||
TIM_t_para("管理员 ({{option2}}/10)", "管理员 ($option2/10)")(option2: option2),
|
||||
style: TextStyle(fontSize: 14, color: theme.weakTextColor),
|
||||
),
|
||||
),
|
||||
|
|
@ -614,8 +489,7 @@ class _GroupProfileSetManagerPageState
|
|||
alignment: Alignment.topLeft,
|
||||
padding: const EdgeInsets.only(top: 10, bottom: 4, left: 16),
|
||||
child: Text(
|
||||
TIM_t_para("管理员 ({{option2}}/10)", "管理员 ($option2/10)")(
|
||||
option2: option2),
|
||||
TIM_t_para("管理员 ({{option2}}/10)", "管理员 ($option2/10)")(option2: option2),
|
||||
style: TextStyle(fontSize: 14, color: theme.primaryColor),
|
||||
),
|
||||
),
|
||||
|
|
@ -627,14 +501,7 @@ class _GroupProfileSetManagerPageState
|
|||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 12,
|
||||
),
|
||||
decoration: isDesktopScreen
|
||||
? null
|
||||
: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: theme.weakDividerColor ??
|
||||
CommonColor.weakDividerColor))),
|
||||
decoration: isDesktopScreen ? null : BoxDecoration(color: Colors.white, border: Border(bottom: BorderSide(color: theme.weakDividerColor ?? CommonColor.weakDividerColor))),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
|
|
@ -662,15 +529,9 @@ class _GroupProfileSetManagerPageState
|
|||
},
|
||||
child: (onClose) => GroupProfileAddAdmin(
|
||||
key: groupProfileAddAdminKey,
|
||||
memberList: memberList
|
||||
.where((element) =>
|
||||
element?.role ==
|
||||
GroupMemberRoleType
|
||||
.V2TIM_GROUP_MEMBER_ROLE_MEMBER)
|
||||
.toList(),
|
||||
memberList: memberList.where((element) => element?.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_MEMBER).toList(),
|
||||
appbarTitle: TIM_t("设置管理员"),
|
||||
selectCompletedHandler:
|
||||
(context, selectedMember) async {
|
||||
selectCompletedHandler: (context, selectedMember) async {
|
||||
if (selectedMember.isNotEmpty) {
|
||||
for (var member in selectedMember) {
|
||||
final userID = member!.userID;
|
||||
|
|
@ -685,15 +546,9 @@ class _GroupProfileSetManagerPageState
|
|||
MaterialPageRoute(
|
||||
builder: (context) => GroupProfileAddAdmin(
|
||||
key: groupProfileAddAdminKey,
|
||||
memberList: memberList
|
||||
.where((element) =>
|
||||
element?.role ==
|
||||
GroupMemberRoleType
|
||||
.V2TIM_GROUP_MEMBER_ROLE_MEMBER)
|
||||
.toList(),
|
||||
memberList: memberList.where((element) => element?.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_MEMBER).toList(),
|
||||
appbarTitle: TIM_t("设置管理员"),
|
||||
selectCompletedHandler:
|
||||
(context, selectedMember) async {
|
||||
selectCompletedHandler: (context, selectedMember) async {
|
||||
if (selectedMember.isNotEmpty) {
|
||||
for (var member in selectedMember) {
|
||||
final userID = member!.userID;
|
||||
|
|
@ -709,22 +564,15 @@ class _GroupProfileSetManagerPageState
|
|||
.map((e) => GestureDetector(
|
||||
onSecondaryTapDown: (details) {
|
||||
TUIKitWidePopup.showPopupWindow(
|
||||
operationKey:
|
||||
TUIKitWideModalOperationKey.deleteAdmin,
|
||||
operationKey: TUIKitWideModalOperationKey.deleteAdmin,
|
||||
isDarkBackground: false,
|
||||
borderRadius:
|
||||
const BorderRadius.all(Radius.circular(4)),
|
||||
borderRadius: const BorderRadius.all(Radius.circular(4)),
|
||||
context: context,
|
||||
offset: Offset(
|
||||
min(details.globalPosition.dx,
|
||||
MediaQuery.of(context).size.width - 80),
|
||||
details.globalPosition.dy),
|
||||
offset: Offset(min(details.globalPosition.dx, MediaQuery.of(context).size.width - 80), details.globalPosition.dy),
|
||||
child: (onClose) => TUIKitColumnMenu(data: [
|
||||
ColumnMenuItem(
|
||||
label: TIM_t("删除"),
|
||||
icon: const Icon(
|
||||
Icons.remove_circle_outline,
|
||||
size: 16),
|
||||
icon: const Icon(Icons.remove_circle_outline, size: 16),
|
||||
onClick: () {
|
||||
_removeAdmin(context, e);
|
||||
onClose();
|
||||
|
|
@ -732,26 +580,21 @@ class _GroupProfileSetManagerPageState
|
|||
]));
|
||||
},
|
||||
child: Container(
|
||||
padding: isDesktopScreen
|
||||
? const EdgeInsets.only(left: 16)
|
||||
: null,
|
||||
padding: isDesktopScreen ? const EdgeInsets.only(left: 16) : null,
|
||||
child: _buildListItem(
|
||||
context,
|
||||
e!,
|
||||
ActionPane(
|
||||
motion: const DrawerMotion(),
|
||||
children: [
|
||||
SlidableAction(
|
||||
onPressed: (_) {
|
||||
_removeAdmin(context, e);
|
||||
},
|
||||
flex: 1,
|
||||
backgroundColor: theme.cautionColor ??
|
||||
CommonColor.cautionColor,
|
||||
autoClose: true,
|
||||
label: TIM_t("删除"),
|
||||
)
|
||||
])),
|
||||
ActionPane(motion: const DrawerMotion(), children: [
|
||||
SlidableAction(
|
||||
onPressed: (_) {
|
||||
_removeAdmin(context, e);
|
||||
},
|
||||
flex: 1,
|
||||
backgroundColor: theme.cautionColor ?? CommonColor.cautionColor,
|
||||
autoClose: true,
|
||||
label: TIM_t("删除"),
|
||||
)
|
||||
])),
|
||||
),
|
||||
))
|
||||
.toList(),
|
||||
|
|
@ -785,16 +628,9 @@ class _GroupProfileSetManagerPageState
|
|||
class GroupProfileAddAdmin extends StatefulWidget {
|
||||
final List<V2TimGroupMemberFullInfo?> memberList;
|
||||
final String appbarTitle;
|
||||
final void Function(BuildContext context,
|
||||
List<V2TimGroupMemberFullInfo?> selectedMemberList)?
|
||||
selectCompletedHandler;
|
||||
final void Function(BuildContext context, List<V2TimGroupMemberFullInfo?> selectedMemberList)? selectCompletedHandler;
|
||||
|
||||
const GroupProfileAddAdmin(
|
||||
{Key? key,
|
||||
required this.memberList,
|
||||
this.selectCompletedHandler,
|
||||
required this.appbarTitle})
|
||||
: super(key: key);
|
||||
const GroupProfileAddAdmin({Key? key, required this.memberList, this.selectCompletedHandler, required this.appbarTitle}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _GroupProfileAddAdminState();
|
||||
|
|
@ -828,14 +664,8 @@ class _GroupProfileAddAdminState extends TIMUIKitState<GroupProfileAddAdmin> {
|
|||
),
|
||||
...widget.memberList
|
||||
.map((e) => Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: theme.weakDividerColor ??
|
||||
CommonColor.weakDividerColor))),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 10, horizontal: 16),
|
||||
decoration: BoxDecoration(color: Colors.white, border: Border(bottom: BorderSide(color: theme.weakDividerColor ?? CommonColor.weakDividerColor))),
|
||||
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
final isChecked = selectedMemberList.contains(e);
|
||||
|
|
@ -867,8 +697,7 @@ class _GroupProfileAddAdminState extends TIMUIKitState<GroupProfileAddAdmin> {
|
|||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Text(_getShowName(e),
|
||||
style: const TextStyle(fontSize: 16))
|
||||
Text(_getShowName(e), style: const TextStyle(fontSize: 16))
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -2,17 +2,17 @@
|
|||
|
||||
import 'package:azlistview_all_platforms/azlistview_all_platforms.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_slidable_for_tencent_im/flutter_slidable.dart';
|
||||
import 'package:flutter_slidable/flutter_slidable.dart';
|
||||
import 'package:lpinyin/lpinyin.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
|
||||
import 'package:tencent_im_base/tencent_im_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/optimize_utils.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/az_list_view.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/ui/widgets/radio_button.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_im_base/tencent_im_base.dart';
|
||||
|
||||
class GroupProfileMemberList extends StatefulWidget {
|
||||
final List<V2TimGroupMemberFullInfo?> memberList;
|
||||
|
|
@ -23,8 +23,7 @@ class GroupProfileMemberList extends StatefulWidget {
|
|||
|
||||
// when the @ need filter some group types
|
||||
final String? groupType;
|
||||
final Function(List<V2TimGroupMemberFullInfo> selectedMember)?
|
||||
onSelectedMemberChange;
|
||||
final Function(List<V2TimGroupMemberFullInfo> selectedMember)? onSelectedMemberChange;
|
||||
// notice: onTapMemberItem and onSelectedMemberChange use together will triger together
|
||||
final Function(V2TimGroupMemberFullInfo memberInfo, TapDownDetails? tapDetails)? onTapMemberItem;
|
||||
// When sliding to the bottom bar callBack
|
||||
|
|
@ -53,8 +52,7 @@ class GroupProfileMemberList extends StatefulWidget {
|
|||
State<StatefulWidget> createState() => _GroupProfileMemberListState();
|
||||
}
|
||||
|
||||
class _GroupProfileMemberListState
|
||||
extends TIMUIKitState<GroupProfileMemberList> {
|
||||
class _GroupProfileMemberListState extends TIMUIKitState<GroupProfileMemberList> {
|
||||
List<V2TimGroupMemberFullInfo> selectedMember = [];
|
||||
|
||||
_getShowName(V2TimGroupMemberFullInfo? item) {
|
||||
|
|
@ -71,14 +69,12 @@ class _GroupProfileMemberListState
|
|||
: userID;
|
||||
}
|
||||
|
||||
List<ISuspensionBeanImpl> _getShowList(
|
||||
List<V2TimGroupMemberFullInfo?> memberList) {
|
||||
List<ISuspensionBeanImpl> _getShowList(List<V2TimGroupMemberFullInfo?> memberList) {
|
||||
final List<ISuspensionBeanImpl> showList = List.empty(growable: true);
|
||||
for (var i = 0; i < memberList.length; i++) {
|
||||
final item = memberList[i];
|
||||
final showName = _getShowName(item);
|
||||
if (item?.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER ||
|
||||
item?.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_ADMIN) {
|
||||
if (item?.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER || item?.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_ADMIN) {
|
||||
showList.add(ISuspensionBeanImpl(memberInfo: item, tagIndex: "@"));
|
||||
} else {
|
||||
String pinyin = PinyinHelper.getPinyinE(showName);
|
||||
|
|
@ -97,25 +93,17 @@ class _GroupProfileMemberListState
|
|||
if (widget.canAtAll) {
|
||||
final canAtGroupType = ["Work", "Public", "Meeting"];
|
||||
if (canAtGroupType.contains(widget.groupType)) {
|
||||
showList.insert(
|
||||
0,
|
||||
ISuspensionBeanImpl(
|
||||
memberInfo: V2TimGroupMemberFullInfo(
|
||||
userID: "__kImSDK_MesssageAtALL__", nickName: TIM_t("所有人")),
|
||||
tagIndex: ""));
|
||||
showList.insert(0, ISuspensionBeanImpl(memberInfo: V2TimGroupMemberFullInfo(userID: "__kImSDK_MesssageAtALL__", nickName: TIM_t("所有人")), tagIndex: ""));
|
||||
}
|
||||
}
|
||||
|
||||
return showList;
|
||||
}
|
||||
|
||||
Widget _buildListItem(
|
||||
BuildContext context, V2TimGroupMemberFullInfo memberInfo) {
|
||||
Widget _buildListItem(BuildContext context, V2TimGroupMemberFullInfo memberInfo) {
|
||||
final theme = Provider.of<TUIThemeViewModel>(context).theme;
|
||||
final isDesktopScreen =
|
||||
TUIKitScreenUtils.getFormFactor() == DeviceType.Desktop;
|
||||
final isGroupMember =
|
||||
memberInfo.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_MEMBER;
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor() == DeviceType.Desktop;
|
||||
final isGroupMember = memberInfo.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_MEMBER;
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
child: Slidable(
|
||||
|
|
@ -128,8 +116,7 @@ class _GroupProfileMemberListState
|
|||
}
|
||||
},
|
||||
flex: 1,
|
||||
backgroundColor:
|
||||
theme.cautionColor ?? CommonColor.cautionColor,
|
||||
backgroundColor: theme.cautionColor ?? CommonColor.cautionColor,
|
||||
autoClose: true,
|
||||
label: TIM_t("删除"),
|
||||
)
|
||||
|
|
@ -146,9 +133,7 @@ class _GroupProfileMemberListState
|
|||
child: CheckBoxButton(
|
||||
onChanged: (isChecked) {
|
||||
if (isChecked) {
|
||||
if (widget.maxSelectNum != null &&
|
||||
selectedMember.length >=
|
||||
widget.maxSelectNum!) {
|
||||
if (widget.maxSelectNum != null && selectedMember.length >= widget.maxSelectNum!) {
|
||||
return;
|
||||
}
|
||||
selectedMember.add(memberInfo);
|
||||
|
|
@ -172,30 +157,22 @@ class _GroupProfileMemberListState
|
|||
type: 1,
|
||||
),
|
||||
),
|
||||
Text(_getShowName(memberInfo),
|
||||
style: TextStyle(fontSize: isDesktopScreen ? 14 : 16)),
|
||||
memberInfo.role ==
|
||||
GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER
|
||||
Text(_getShowName(memberInfo), style: TextStyle(fontSize: isDesktopScreen ? 14 : 16)),
|
||||
memberInfo.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER
|
||||
? Container(
|
||||
margin: const EdgeInsets.only(left: 5),
|
||||
child: Text(TIM_t("群主"),
|
||||
style: TextStyle(
|
||||
color: theme.ownerColor,
|
||||
fontSize: isDesktopScreen ? 10 :12,
|
||||
fontSize: isDesktopScreen ? 10 : 12,
|
||||
)),
|
||||
padding: const EdgeInsets.fromLTRB(5, 0, 5, 0),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: theme.ownerColor ??
|
||||
CommonColor.ownerColor,
|
||||
width: 1),
|
||||
borderRadius:
|
||||
const BorderRadius.all(Radius.circular(4.0)),
|
||||
border: Border.all(color: theme.ownerColor ?? CommonColor.ownerColor, width: 1),
|
||||
borderRadius: const BorderRadius.all(Radius.circular(4.0)),
|
||||
),
|
||||
)
|
||||
: memberInfo.role ==
|
||||
GroupMemberRoleType
|
||||
.V2TIM_GROUP_MEMBER_ROLE_ADMIN
|
||||
: memberInfo.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_ADMIN
|
||||
? Container(
|
||||
margin: const EdgeInsets.only(left: 5),
|
||||
child: Text(TIM_t("管理员"),
|
||||
|
|
@ -205,12 +182,8 @@ class _GroupProfileMemberListState
|
|||
)),
|
||||
padding: const EdgeInsets.fromLTRB(5, 0, 5, 0),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: theme.adminColor ??
|
||||
CommonColor.adminColor,
|
||||
width: 1),
|
||||
borderRadius: const BorderRadius.all(
|
||||
Radius.circular(4.0)),
|
||||
border: Border.all(color: theme.adminColor ?? CommonColor.adminColor, width: 1),
|
||||
borderRadius: const BorderRadius.all(Radius.circular(4.0)),
|
||||
),
|
||||
)
|
||||
: Container()
|
||||
|
|
@ -225,8 +198,7 @@ class _GroupProfileMemberListState
|
|||
if (isChecked) {
|
||||
selectedMember.remove(memberInfo);
|
||||
} else {
|
||||
if (widget.maxSelectNum != null &&
|
||||
selectedMember.length >= widget.maxSelectNum!) {
|
||||
if (widget.maxSelectNum != null && selectedMember.length >= widget.maxSelectNum!) {
|
||||
return;
|
||||
}
|
||||
selectedMember.add(memberInfo);
|
||||
|
|
@ -238,17 +210,11 @@ class _GroupProfileMemberListState
|
|||
}
|
||||
},
|
||||
),
|
||||
Divider(
|
||||
thickness: 1,
|
||||
indent: 74,
|
||||
endIndent: 0,
|
||||
color: theme.weakBackgroundColor,
|
||||
height: 0)
|
||||
Divider(thickness: 1, indent: 74, endIndent: 0, color: theme.weakBackgroundColor, height: 0)
|
||||
])));
|
||||
}
|
||||
|
||||
static Widget getSusItem(BuildContext context, TUITheme theme, String tag,
|
||||
{double susHeight = 40}) {
|
||||
static Widget getSusItem(BuildContext context, TUITheme theme, String tag, {double susHeight = 40}) {
|
||||
if (tag == '@') {
|
||||
tag = TIM_t("群主、管理员");
|
||||
}
|
||||
|
|
@ -273,11 +239,9 @@ class _GroupProfileMemberListState
|
|||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final TUITheme theme = value.theme;
|
||||
|
||||
final isDesktopScreen =
|
||||
TUIKitScreenUtils.getFormFactor() == DeviceType.Desktop;
|
||||
final isDesktopScreen = TUIKitScreenUtils.getFormFactor() == DeviceType.Desktop;
|
||||
|
||||
final throteFunction =
|
||||
OptimizeUtils.throttle((ScrollNotification notification) {
|
||||
final throteFunction = OptimizeUtils.throttle((ScrollNotification notification) {
|
||||
final pixels = notification.metrics.pixels;
|
||||
// 总像素高度
|
||||
final maxScrollExtent = notification.metrics.maxScrollExtent;
|
||||
|
|
@ -305,21 +269,19 @@ class _GroupProfileMemberListState
|
|||
child: Text(TIM_t("暂无群成员")),
|
||||
)
|
||||
: Container(
|
||||
padding: isDesktopScreen ? const EdgeInsets.symmetric( horizontal: 16) : null,
|
||||
child: AZListViewContainer(
|
||||
memberList: showList,
|
||||
susItemBuilder: (context, index) {
|
||||
final model = showList[index];
|
||||
return getSusItem(
|
||||
context, theme, model.getSuspensionTag());
|
||||
},
|
||||
itemBuilder: (context, index) {
|
||||
final memberInfo = showList[index].memberInfo
|
||||
as V2TimGroupMemberFullInfo;
|
||||
padding: isDesktopScreen ? const EdgeInsets.symmetric(horizontal: 16) : null,
|
||||
child: AZListViewContainer(
|
||||
memberList: showList,
|
||||
susItemBuilder: (context, index) {
|
||||
final model = showList[index];
|
||||
return getSusItem(context, theme, model.getSuspensionTag());
|
||||
},
|
||||
itemBuilder: (context, index) {
|
||||
final memberInfo = showList[index].memberInfo as V2TimGroupMemberFullInfo;
|
||||
|
||||
return _buildListItem(context, memberInfo);
|
||||
}),
|
||||
),
|
||||
return _buildListItem(context, memberInfo);
|
||||
}),
|
||||
),
|
||||
))
|
||||
],
|
||||
)),
|
||||
|
|
|
|||
|
|
@ -235,35 +235,43 @@ class _ImageScreenState extends TIMUIKitState<ImageScreen>
|
|||
Positioned(
|
||||
left: 10,
|
||||
bottom: 50,
|
||||
child: IconButton(
|
||||
icon: Image.asset(
|
||||
'images/close.png',
|
||||
package: 'tencent_cloud_chat_uikit',
|
||||
child: SizedBox(
|
||||
width: 48,
|
||||
height: 48,
|
||||
child: IconButton(
|
||||
icon: Image.asset(
|
||||
'images/close.png',
|
||||
package: 'tencent_cloud_chat_uikit',
|
||||
),
|
||||
iconSize: 30,
|
||||
onPressed: close,
|
||||
),
|
||||
iconSize: 30,
|
||||
onPressed: close,
|
||||
)),
|
||||
if (widget.downloadFn != null)
|
||||
Positioned(
|
||||
right: 10,
|
||||
bottom: 50,
|
||||
child: IconButton(
|
||||
icon: Image.asset(
|
||||
'images/download.png',
|
||||
package: 'tencent_cloud_chat_uikit',
|
||||
),
|
||||
iconSize: 30,
|
||||
onPressed: () async {
|
||||
setState(() {
|
||||
isLoading = true;
|
||||
});
|
||||
await widget.downloadFn!();
|
||||
Future.delayed(const Duration(milliseconds: 200),(){
|
||||
child: SizedBox(
|
||||
width: 48,
|
||||
height: 48,
|
||||
child: IconButton(
|
||||
icon: Image.asset(
|
||||
'images/download.png',
|
||||
package: 'tencent_cloud_chat_uikit',
|
||||
),
|
||||
iconSize: 30,
|
||||
onPressed: () async {
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
isLoading = true;
|
||||
});
|
||||
});
|
||||
},
|
||||
await widget.downloadFn!();
|
||||
Future.delayed(const Duration(milliseconds: 200),(){
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
});
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
if (isLoading)
|
||||
|
|
|
|||
|
|
@ -3,22 +3,21 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:chewie_for_us/chewie_for_us.dart';
|
||||
import 'package:chewie_for_us/src/helpers/utils.dart';
|
||||
import 'package:chewie_for_us/src/animated_play_pause.dart';
|
||||
import 'package:chewie_for_us/src/helpers/utils.dart';
|
||||
import 'package:chewie_for_us/src/material/material_progress_bar.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:loading_animation_widget/loading_animation_widget.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart';
|
||||
|
||||
import 'package:video_player/video_player.dart';
|
||||
import 'center_play_button.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
|
||||
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';
|
||||
import 'package:video_player/video_player.dart';
|
||||
|
||||
import 'center_play_button.dart';
|
||||
|
||||
class VideoCustomControls extends StatefulWidget {
|
||||
const VideoCustomControls({required this.downloadFn, Key? key})
|
||||
: super(key: key);
|
||||
const VideoCustomControls({required this.downloadFn, Key? key}) : super(key: key);
|
||||
final Future<void> Function() downloadFn;
|
||||
|
||||
@override
|
||||
|
|
@ -27,8 +26,7 @@ class VideoCustomControls extends StatefulWidget {
|
|||
}
|
||||
}
|
||||
|
||||
class _VideoCustomControlsState extends TIMUIKitState<VideoCustomControls>
|
||||
with SingleTickerProviderStateMixin {
|
||||
class _VideoCustomControlsState extends TIMUIKitState<VideoCustomControls> with SingleTickerProviderStateMixin {
|
||||
late VideoPlayerValue _latestValue;
|
||||
bool _hideStuff = true;
|
||||
Timer? _hideTimer;
|
||||
|
|
@ -43,6 +41,7 @@ class _VideoCustomControlsState extends TIMUIKitState<VideoCustomControls>
|
|||
|
||||
late VideoPlayerController controller;
|
||||
ChewieController? _chewieController;
|
||||
|
||||
// We know that _chewieController is set in didChangeDependencies
|
||||
ChewieController get chewieController => _chewieController!;
|
||||
|
||||
|
|
@ -76,18 +75,11 @@ class _VideoCustomControlsState extends TIMUIKitState<VideoCustomControls>
|
|||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: <Widget>[
|
||||
if (_latestValue.isBuffering)
|
||||
const Center(
|
||||
child: CircularProgressIndicator(color: Colors.white))
|
||||
else
|
||||
_buildHitArea(),
|
||||
if (_latestValue.isBuffering) const Center(child: CircularProgressIndicator(color: Colors.white)) else _buildHitArea(),
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
child: Column(children: [
|
||||
_buildVideoControlBar(context),
|
||||
_buildBottomBar()
|
||||
]),
|
||||
child: Column(children: [_buildVideoControlBar(context), _buildBottomBar()]),
|
||||
),
|
||||
if (isLoading)
|
||||
Container(
|
||||
|
|
@ -143,37 +135,50 @@ class _VideoCustomControlsState extends TIMUIKitState<VideoCustomControls>
|
|||
margin: const EdgeInsets.fromLTRB(20, 0, 20, 20),
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
IconButton(
|
||||
icon: Image.asset(
|
||||
'images/close.png',
|
||||
package: 'tencent_cloud_chat_uikit',
|
||||
SizedBox(
|
||||
width: 48,
|
||||
height: 48,
|
||||
child: IconButton(
|
||||
icon: Image.asset(
|
||||
'images/close.png',
|
||||
package: 'tencent_cloud_chat_uikit',
|
||||
),
|
||||
iconSize: 30,
|
||||
onPressed: () {
|
||||
if (_latestValue.isPlaying) {
|
||||
_playPause();
|
||||
}
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
iconSize: 30,
|
||||
onPressed: () {
|
||||
if (_latestValue.isPlaying) {
|
||||
_playPause();
|
||||
}
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
Expanded(child: Container()),
|
||||
IconButton(
|
||||
icon: Image.asset(
|
||||
'images/download.png',
|
||||
package: 'tencent_cloud_chat_uikit',
|
||||
),
|
||||
iconSize: 30,
|
||||
onPressed: () async {
|
||||
setState(() {
|
||||
isLoading = true;
|
||||
});
|
||||
await widget.downloadFn();
|
||||
Future.delayed(const Duration(milliseconds: 200),(){
|
||||
SizedBox(
|
||||
width: 48,
|
||||
height: 48,
|
||||
child: IconButton(
|
||||
icon: Image.asset(
|
||||
'images/download.png',
|
||||
package: 'tencent_cloud_chat_uikit',
|
||||
),
|
||||
iconSize: 30,
|
||||
onPressed: () async {
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
isLoading = true;
|
||||
});
|
||||
});
|
||||
},
|
||||
await widget.downloadFn();
|
||||
Future.delayed(
|
||||
const Duration(milliseconds: 200),
|
||||
() {
|
||||
setState(
|
||||
() {
|
||||
isLoading = false;
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
|
|
@ -194,14 +199,8 @@ class _VideoCustomControlsState extends TIMUIKitState<VideoCustomControls>
|
|||
child: Row(
|
||||
children: <Widget>[
|
||||
_buildPlayPause(controller, iconColor),
|
||||
if (chewieController.isLive)
|
||||
const Expanded(child: Text('LIVE'))
|
||||
else
|
||||
_buildPositionStart(iconColor),
|
||||
if (chewieController.isLive)
|
||||
const SizedBox()
|
||||
else
|
||||
_buildProgressBar(),
|
||||
if (chewieController.isLive) const Expanded(child: Text('LIVE')) else _buildPositionStart(iconColor),
|
||||
if (chewieController.isLive) const SizedBox() else _buildProgressBar(),
|
||||
if (!chewieController.isLive) _buildPositionEnd(iconColor),
|
||||
],
|
||||
),
|
||||
|
|
@ -237,8 +236,7 @@ class _VideoCustomControlsState extends TIMUIKitState<VideoCustomControls>
|
|||
));
|
||||
}
|
||||
|
||||
GestureDetector _buildPlayPause(
|
||||
VideoPlayerController controller, Color color) {
|
||||
GestureDetector _buildPlayPause(VideoPlayerController controller, Color color) {
|
||||
return GestureDetector(
|
||||
onTap: _playPause,
|
||||
child: Container(
|
||||
|
|
@ -314,8 +312,7 @@ class _VideoCustomControlsState extends TIMUIKitState<VideoCustomControls>
|
|||
_hideStuff = true;
|
||||
|
||||
chewieController.toggleFullScreen();
|
||||
_showAfterExpandCollapseTimer =
|
||||
Timer(const Duration(milliseconds: 300), () {
|
||||
_showAfterExpandCollapseTimer = Timer(const Duration(milliseconds: 300), () {
|
||||
setState(() {
|
||||
_cancelAndRestartTimer();
|
||||
});
|
||||
|
|
@ -384,11 +381,7 @@ class _VideoCustomControlsState extends TIMUIKitState<VideoCustomControls>
|
|||
_startHideTimer();
|
||||
},
|
||||
colors: chewieController.materialProgressColors ??
|
||||
ChewieProgressColors(
|
||||
playedColor: Colors.white,
|
||||
handleColor: Colors.white,
|
||||
bufferedColor: Colors.white38,
|
||||
backgroundColor: Colors.white24),
|
||||
ChewieProgressColors(playedColor: Colors.white, handleColor: Colors.white, bufferedColor: Colors.white38, backgroundColor: Colors.white24),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
@ -411,8 +404,7 @@ class _PlaybackSpeedDialog extends TIMUIKitStatelessWidget {
|
|||
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
|
||||
final TUITheme theme = value.theme;
|
||||
|
||||
final Color selectedColor =
|
||||
theme.primaryColor ?? Theme.of(context).primaryColor;
|
||||
final Color selectedColor = theme.primaryColor ?? Theme.of(context).primaryColor;
|
||||
|
||||
return ListView.builder(
|
||||
shrinkWrap: true,
|
||||
|
|
|
|||
32
pubspec.lock
32
pubspec.lock
|
|
@ -301,10 +301,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: dart_internal
|
||||
sha256: "689dccc3d5f62affd339534cca548dce12b3a6b32f0f10861569d3025efc0567"
|
||||
sha256: "04145b91ccec450325fee75692b1ab62eb615e8892c334f0f4d31c696a857873"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.9"
|
||||
version: "0.2.10"
|
||||
dart_style:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -373,18 +373,18 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: extended_text
|
||||
sha256: "7096a1e9a029534257d70f7dafb2798f932d589079e67ef3f58fdf0805f2f627"
|
||||
sha256: "7f382de3af12992e34bd72ddd36becf90c4720900af126cb9859f0189af71ffe"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "12.0.0"
|
||||
version: "13.0.0"
|
||||
extended_text_field:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: extended_text_field
|
||||
sha256: ed9655c70a47a54c7cc689cf7f89a2bde9ab7b530150b4d1808b7aa7eb8cdf90
|
||||
sha256: ee139de7c2b2a9d806ddd5fdfef5c728cf475298a7ce5834c5b822ef1e6225d7
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "13.0.0"
|
||||
version: "14.0.0"
|
||||
extended_text_library:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -534,14 +534,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.0.16"
|
||||
flutter_slidable_for_tencent_im:
|
||||
flutter_slidable:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_slidable_for_tencent_im
|
||||
sha256: "425faab6304305dd7d38aef448af02acd65f425bf2bd47ce3b70b0b4e714c17b"
|
||||
name: flutter_slidable
|
||||
sha256: "19ed4813003a6ff4e9c6bcce37e792a2a358919d7603b2b31ff200229191e44c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
version: "3.0.1"
|
||||
flutter_svg:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -831,18 +831,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
|
||||
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.0"
|
||||
version: "0.8.0"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
|
||||
sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.10.0"
|
||||
version: "1.11.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -1657,5 +1657,5 @@ packages:
|
|||
source: hosted
|
||||
version: "3.1.2"
|
||||
sdks:
|
||||
dart: ">=3.2.0 <3.3.0"
|
||||
flutter: ">=3.16.0"
|
||||
dart: ">=3.3.0 <3.4.0"
|
||||
flutter: ">=3.19.0"
|
||||
|
|
|
|||
11
pubspec.yaml
11
pubspec.yaml
|
|
@ -1,11 +1,10 @@
|
|||
name: tencent_cloud_chat_uikit
|
||||
description: A powerful chat UI component library and business logic for Tencent Cloud Chat, creating seamless in-app chat modules for delightful user experiences.
|
||||
version: 2.4.1
|
||||
version: 2.5.0
|
||||
homepage: https://trtc.io/products/chat?utm_source=gfs&utm_medium=link&utm_campaign=%E6%B8%A0%E9%81%93&_channel_track_key=k6WgfCKn
|
||||
repository: https://github.com/TencentCloud/chat-uikit-flutter
|
||||
documentation: https://comm.qq.com/im/doc/flutter/en/TUIKit/readme.html
|
||||
|
||||
# publish_to: none
|
||||
platforms:
|
||||
android:
|
||||
ios:
|
||||
|
|
@ -15,7 +14,7 @@ platforms:
|
|||
|
||||
environment:
|
||||
sdk: '>=3.0.0 <4.0.0'
|
||||
flutter: ">=3.13.0"
|
||||
flutter: ">=3.19.0"
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
|
|
@ -31,7 +30,7 @@ dependencies:
|
|||
tencent_super_tooltip: ^0.0.1
|
||||
video_player: ^2.7.0
|
||||
chewie_for_us: ^1.5.0
|
||||
flutter_slidable_for_tencent_im: ^1.4.0
|
||||
flutter_slidable: ^3.0.1
|
||||
flutter_plugin_record_plus: ^0.0.16
|
||||
azlistview_all_platforms: ^2.1.2
|
||||
lpinyin: ^2.0.3
|
||||
|
|
@ -45,8 +44,8 @@ dependencies:
|
|||
wechat_camera_picker: ^4.2.0-dev.2
|
||||
flutter_easyrefresh: ^2.2.1
|
||||
extended_image: ^8.2.0
|
||||
extended_text_field: ^13.0.0
|
||||
extended_text: ^12.0.0
|
||||
extended_text_field: ^14.0.0
|
||||
extended_text: ^13.0.0
|
||||
package_info_plus: ^4.0.1
|
||||
loading_animation_widget: ^1.1.0+3
|
||||
permission_handler: ^10.2.0
|
||||
|
|
|
|||
Loading…
Reference in New Issue