Commit acb9d7e1 authored by skeyboy's avatar skeyboy

百晓通聊天列表多选分享

parent 7209ed34
...@@ -12,6 +12,7 @@ class ChatMessage { ...@@ -12,6 +12,7 @@ class ChatMessage {
this.mentions, this.mentions,
this.status = MessageStatus.none, this.status = MessageStatus.none,
this.replyTo, this.replyTo,
this.showMenu = false
}); });
/// Create a ChatMessage instance from json data /// Create a ChatMessage instance from json data
...@@ -77,6 +78,8 @@ class ChatMessage { ...@@ -77,6 +78,8 @@ class ChatMessage {
/// If the message is a reply of another one TODO: /// If the message is a reply of another one TODO:
ChatMessage? replyTo; ChatMessage? replyTo;
bool? showMenu = false;
bool? selected = false;
/// Convert a ChatMessage into a json /// Convert a ChatMessage into a json
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
......
...@@ -33,7 +33,8 @@ class MessageOptions { ...@@ -33,7 +33,8 @@ class MessageOptions {
this.messageMediaBuilder, this.messageMediaBuilder,
this.onLongPressStart, this.onLongPressStart,
this.onLongPressEnd, this.onLongPressEnd,
this.shareMenuBuilder}); this.shareMenuBuilder,
this.multiSelectedBuilder});
//长按 //长按
...@@ -158,9 +159,14 @@ class MessageOptions { ...@@ -158,9 +159,14 @@ class MessageOptions {
/// Will not work with the default video player /// Will not work with the default video player
final void Function(ChatMedia media)? onTapMedia; final void Function(ChatMedia media)? onTapMedia;
/// 多选
final ChatRowSelected? Function(ChatMessage chatMessage)?
multiSelectedBuilder;
final Widget? Function( final Widget? Function(
ChatMessage message, ChatMessage message,
CustomPopupMenuController controller, CustomPopupMenuController controller,
Widget chatMessageBody, Widget chatMessageBody,
bool? showMenus)? shareMenuBuilder; bool? showMenus)? shareMenuBuilder;
} }
typedef ChatRowSelected = void Function(ChatMessage message, bool? value);
...@@ -3,6 +3,7 @@ import 'dart:async'; ...@@ -3,6 +3,7 @@ import 'dart:async';
import 'package:chart/common/apis/apis.dart'; import 'package:chart/common/apis/apis.dart';
import 'package:chart/common/routers/routes.dart'; import 'package:chart/common/routers/routes.dart';
import 'package:chart/common/store/store.dart'; import 'package:chart/common/store/store.dart';
import 'package:chart/common/values/colors.dart';
import 'package:chart/common/values/server.dart'; import 'package:chart/common/values/server.dart';
import 'package:chart/entity/user_entity.dart'; import 'package:chart/entity/user_entity.dart';
import 'package:chart/package/chat_dash/dash_chat_2.dart' as Chat; import 'package:chart/package/chat_dash/dash_chat_2.dart' as Chat;
...@@ -45,6 +46,10 @@ class HomeController extends GetxController with SingleGetTickerProviderMixin { ...@@ -45,6 +46,10 @@ class HomeController extends GetxController with SingleGetTickerProviderMixin {
late Animation<double> _animation; late Animation<double> _animation;
bool _isRotated = false; bool _isRotated = false;
/// 选中的分享条目
RxList<ChatMessage> selectedItems = <ChatMessage>[].obs;
RxBool chatRowCheckRadioShowed = false.obs;
// ignore: prefer_typing_uninitialized_variables // ignore: prefer_typing_uninitialized_variables
late var sse; late var sse;
...@@ -73,6 +78,61 @@ class HomeController extends GetxController with SingleGetTickerProviderMixin { ...@@ -73,6 +78,61 @@ class HomeController extends GetxController with SingleGetTickerProviderMixin {
/// 事件 /// 事件
/// 右上角分享管理相关菜单
List<Widget> topRightBarMenus() {
/// 选中数据不为空 或者 展示选择菜单右侧即显示 分享相关控制
return (selectedItems.isEmpty == true && chatRowCheckRadioShowed.value == false)
? [
RotationTransition(
turns: animation,
child: IconButton(
tooltip: '重置',
icon: const Icon(
Icons.settings_backup_restore_sharp,
color: AppColors.primaryElementText,
),
onPressed: () {
reset();
},
),
),
IconButton(
tooltip: '设置',
icon: const Icon(
Icons.settings,
color: AppColors.primaryElementText,
),
onPressed: () {
share();
},
)
]
: [
IconButton(
tooltip: "分享",
onPressed: () async {
selectedItems.sort((l, r) => r.createdAt
.difference(DateTime.now())
.compareTo(l.createdAt.difference(DateTime.now())));
String sharedMsg = selectedItems.reversed
.map((element) => element.text)
.join("\n\n");
ShareResult result = await Share.shareWithResult(sharedMsg);
if (result.status == ShareResultStatus.success) {
EasyLoading.showToast("分享成功");
} else {
EasyLoading.showToast("分享取消");
}
},
icon: const Icon(Icons.share)),
IconButton(
onPressed: () {
_hideChatMessageCheckbox();
},
icon: const Icon(Icons.cancel_outlined))
];
}
bool gotoLoginPage() { bool gotoLoginPage() {
if (UserStore.to.isLogin == false) { if (UserStore.to.isLogin == false) {
Get.toNamed(AppRoutes.SIGN_IN); Get.toNamed(AppRoutes.SIGN_IN);
...@@ -420,47 +480,67 @@ class HomeController extends GetxController with SingleGetTickerProviderMixin { ...@@ -420,47 +480,67 @@ class HomeController extends GetxController with SingleGetTickerProviderMixin {
// } // }
} }
List<ItemModel> menuItems = [ List<ItemModel> get menuItems => [
ItemModel( ItemModel(
'复制', '复制',
Icons.content_copy, Icons.content_copy,
(ChatMessage message, CustomPopupMenuController controller) { (ChatMessage message, CustomPopupMenuController controller) {
FlutterClipboard.copy(message.text).then((value) { FlutterClipboard.copy(message.text).then((value) {
EasyLoading.showToast("复制成功", maskType: EasyLoadingMaskType.none); EasyLoading.showToast("复制成功", maskType: EasyLoadingMaskType.none);
controller.hideMenu(); controller.hideMenu();
// Get.back(); // Get.back();
}); });
// controller.hideMenu(); // controller.hideMenu();
}, },
), ),
ItemModel( ItemModel(
'转发', '转发',
Icons.share, Icons.share,
(ChatMessage message, CustomPopupMenuController controller) async { (ChatMessage message, CustomPopupMenuController controller) async {
if (message.text.isNotEmpty) { if (message.text.isNotEmpty) {
await Share.share( await Share.share(
"${message.text}\n\n", "${message.text}\n\n",
); );
controller.hideMenu();
} else {
EasyLoading.showToast("分享内容不能为空",
maskType: EasyLoadingMaskType.none);
}
// FlutterClipboard.copy(message.text).then((value) {
// EasyLoading.showToast("复制成功", maskType: EasyLoadingMaskType.none);
// controller.hideMenu();
// // Get.back();
// });
},
),
// ItemModel('收藏', Icons.collections),
// ItemModel('删除', Icons.delete),
ItemModel('多选', Icons.playlist_add_check, (message, controller) {
state.messageList.forEach((element) {
element.showMenu = true;
});
state.messageList
.replaceRange(0, state.messageList.length - 1, state.messageList);
controller.hideMenu(); controller.hideMenu();
} else { chatRowCheckRadioShowed.value = true;
EasyLoading.showToast("分享内容不能为空", maskType: EasyLoadingMaskType.none); }),
} // ItemModel('引用', Icons.format_quote),
// ItemModel('提醒', Icons.add_alert),
// FlutterClipboard.copy(message.text).then((value) { // ItemModel('搜一搜', Icons.search),
// EasyLoading.showToast("复制成功", maskType: EasyLoadingMaskType.none); ];
// controller.hideMenu();
// // Get.back(); _hideChatMessageCheckbox() {
// }); state.messageList.forEach((element) {
}, element.showMenu = false;
), element.selected = false;
// ItemModel('收藏', Icons.collections), });
// ItemModel('删除', Icons.delete), state.messageList
// ItemModel('多选', Icons.playlist_add_check), .replaceRange(0, state.messageList.length - 1, state.messageList);
// ItemModel('引用', Icons.format_quote), selectedItems.value.clear();
// ItemModel('提醒', Icons.add_alert), chatRowCheckRadioShowed.value = false;
// ItemModel('搜一搜', Icons.search), }
];
Widget shareMenuBody( Widget shareMenuBody(
ChatMessage message, CustomPopupMenuController controller) { ChatMessage message, CustomPopupMenuController controller) {
...@@ -506,6 +586,28 @@ class HomeController extends GetxController with SingleGetTickerProviderMixin { ...@@ -506,6 +586,28 @@ class HomeController extends GetxController with SingleGetTickerProviderMixin {
); );
} }
// 分享菜单回调事项
ChatRowSelected? multiSelectedBuilder(ChatMessage message) {
return (message, value) {
_update(message, value: value);
};
}
_update(ChatMessage message, {bool? value = false}) {
message.selected = value ?? false;
int index = state.messageList.indexWhere((element) => element == message);
state.messageList.replaceRange(index, index + 1, [message]);
if (value == false) {
selectedItems.remove(message);
} else {
selectedItems.add(message);
selectedItems.value.sort();
}
selectedItems.forEach((element) {
print(element.text);
});
}
/// 根据需要自己判断怎么构建长按菜单 /// 根据需要自己判断怎么构建长按菜单
Widget? shareMenuBuilder( Widget? shareMenuBuilder(
ChatMessage message, ChatMessage message,
......
...@@ -49,36 +49,11 @@ class _HomePageState extends State<_HomePage> ...@@ -49,36 +49,11 @@ class _HomePageState extends State<_HomePage>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final cc = Get.put(HomeController()); final cc = Get.put(HomeController());
return Obx(() => return Obx(() => Scaffold(
Scaffold(
resizeToAvoidBottomInset: false, resizeToAvoidBottomInset: false,
backgroundColor: Color.fromARGB(0, 0, 0, 0), backgroundColor: Color.fromARGB(0, 0, 0, 0),
appBar: transparentAppBar( appBar: transparentAppBar(
actions: [ actions: controller.topRightBarMenus(),
RotationTransition(
turns: controller.animation,
child: IconButton(
tooltip: '重置',
icon: const Icon(
Icons.settings_backup_restore_sharp,
color: AppColors.primaryElementText,
),
onPressed: () {
controller.reset();
},
),
),
IconButton(
tooltip: '设置',
icon: const Icon(
Icons.settings,
color: AppColors.primaryElementText,
),
onPressed: () {
controller.share();
},
)
],
title: RichText( title: RichText(
textAlign: TextAlign.center, textAlign: TextAlign.center,
text: TextSpan(children: [ text: TextSpan(children: [
...@@ -119,8 +94,7 @@ class _HomePageState extends State<_HomePage> ...@@ -119,8 +94,7 @@ class _HomePageState extends State<_HomePage>
), ),
Text("订阅", Text("订阅",
style: TextStyle( style: TextStyle(
color: Color.fromARGB(255, 95, 54, 0), color: Color.fromARGB(255, 95, 54, 0), fontSize: 16)),
fontSize: 16)),
]), ]),
callback: () => controller.virtualPay()), callback: () => controller.virtualPay()),
), ),
...@@ -148,41 +122,43 @@ class _HomePageState extends State<_HomePage> ...@@ -148,41 +122,43 @@ class _HomePageState extends State<_HomePage>
// GradientButton( // GradientButton(
// child: Icon(Icons.text_fields_sharp), callback: () {}), // child: Icon(Icons.text_fields_sharp), callback: () {}),
/*Android语音转换文字有问题暂时屏蔽掉*/ /*Android语音转换文字有问题暂时屏蔽掉*/
(Platform.isAndroid ? Container() : Container( (Platform.isAndroid
margin: const EdgeInsets.only(right: 10), ? Container()
child: InkWell( : Container(
borderRadius: BorderRadius.circular(100), margin: const EdgeInsets.only(right: 10),
onTap: cc.changeInput, child: InkWell(
child: Container( borderRadius: BorderRadius.circular(100),
decoration: const BoxDecoration( onTap: cc.changeInput,
shape: BoxShape.circle, child: Container(
border: GradientBoxBorder( decoration: const BoxDecoration(
gradient: LinearGradient(colors: [ shape: BoxShape.circle,
Color(0xFFbe6afb), border: GradientBoxBorder(
// Color(0xFF9c67f6), gradient: LinearGradient(colors: [
Color(0xFF7965f8) Color(0xFFbe6afb),
]), // Color(0xFF9c67f6),
width: 2, Color(0xFF7965f8)
), ]),
), width: 2,
padding: const EdgeInsets.all(10), ),
child: Icon( ),
!cc.state.isInputText padding: const EdgeInsets.all(10),
? Icons.keyboard child: Icon(
: Icons.keyboard_voice, !cc.state.isInputText
), ? Icons.keyboard
))) : Icons.keyboard_voice,
// padding: EdgeInsets.all(10), ),
// margin: EdgeInsets.only(right: 10), )))
// child: Icon(Icons.text_fields_sharp), // padding: EdgeInsets.all(10),
// decoration: const BoxDecoration( // margin: EdgeInsets.only(right: 10),
// shape: BoxShape.circle, // child: Icon(Icons.text_fields_sharp),
// border: GradientBoxBorder( // decoration: const BoxDecoration(
// gradient: LinearGradient( // shape: BoxShape.circle,
// colors: [Colors.pink, Colors.orange]), // border: GradientBoxBorder(
// width: 2, // gradient: LinearGradient(
// ), // colors: [Colors.pink, Colors.orange]),
// ), // width: 2,
// ),
// ),
), ),
// Container( // Container(
// padding: EdgeInsets.all(10), // padding: EdgeInsets.all(10),
...@@ -225,8 +201,8 @@ class _HomePageState extends State<_HomePage> ...@@ -225,8 +201,8 @@ class _HomePageState extends State<_HomePage>
), ),
inputToolbarMargin: EdgeInsets.all(0), inputToolbarMargin: EdgeInsets.all(0),
sendButtonBuilder: null, sendButtonBuilder: null,
inputToolbarPadding: EdgeInsets.only( inputToolbarPadding:
top: 15, right: 15, left: 15, bottom: 10), EdgeInsets.only(top: 15, right: 15, left: 15, bottom: 10),
), ),
currentUser: _user, currentUser: _user,
onSend: cc.sendMessage, onSend: cc.sendMessage,
...@@ -234,13 +210,13 @@ class _HomePageState extends State<_HomePage> ...@@ -234,13 +210,13 @@ class _HomePageState extends State<_HomePage>
messageOptions: Chat.MessageOptions( messageOptions: Chat.MessageOptions(
onPressMessage: cc.tabMessage, onPressMessage: cc.tabMessage,
onLongPressMessage: (mes) => {}, onLongPressMessage: (mes) => {},
shareMenuBuilder: cc.shareMenuBuilder shareMenuBuilder: cc.shareMenuBuilder,
// containerColor: Colors.black, multiSelectedBuilder: cc.multiSelectedBuilder
), // containerColor: Colors.black,
),
), ),
), ),
) ));
);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment