Commit 5372aa13 authored by netyouli's avatar netyouli

AI聊天界面添加多选分享,删除功能

parent 1d049ed6
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter/widgets.dart';
import 'package:get/get.dart';
class BottomAnimation extends GetView {
const BottomAnimation(this.child, this.isExpanded, {Key? key}):super(key:key);
final Widget child;
final bool isExpanded;
@override
Widget build(BuildContext context) {
// TODO: implement build
return AnimatedAlign(
duration: Duration(milliseconds: 300),
alignment: isExpanded ? Alignment.bottomCenter : Alignment(0, 2),
child: Container(
child: child,
),
);
}
}
import 'package:flutter/material.dart';
class MyCheckbox extends StatefulWidget {
const MyCheckbox(this.onChanged, {Key? key}): super(key: key);
final void Function(bool isChecked)? onChanged;
@override
_MyCheckboxState createState() => _MyCheckboxState(onChanged);
}
class _MyCheckboxState extends State<MyCheckbox> {
_MyCheckboxState(this.onChanged): super();
bool _isChecked = false;
final void Function(bool isChecked)? onChanged;
@override
Widget build(BuildContext context) {
return InkWell(
onTap: () {
setState(() {
_isChecked = !_isChecked;
if (onChanged != null) {
onChanged!(_isChecked);
}
});
},
child: Container(
width: 20,
height: 20,
decoration: BoxDecoration(
color: _isChecked ? Colors.green : Colors.grey[300],
border: Border.all(
color: _isChecked ? Colors.green : Colors.grey[400]!,
width: 2,
),
borderRadius: BorderRadius.circular(20),
),
child: _isChecked
? Icon(
Icons.check,
size: 16,
color: Colors.white,
)
: null,
),
);
}
}
\ No newline at end of file
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:fluwx/fluwx.dart'; import 'package:fluwx/fluwx.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:share_plus/share_plus.dart'; import 'package:share_plus/share_plus.dart';
...@@ -28,7 +29,13 @@ class WXShare { ...@@ -28,7 +29,13 @@ class WXShare {
} else { } else {
model = WeChatShareTextModel(content, scene: WeChatScene.FAVORITE); model = WeChatShareTextModel(content, scene: WeChatScene.FAVORITE);
} }
shareToWeChat(model); shareToWeChat(model).then((value) {
if (value) {
EasyLoading.showToast("分享成功");
} else {
EasyLoading.showToast("分享失败");
}
});
} else { } else {
Share.shareWithResult(content); Share.shareWithResult(content);
} }
......
part of dash_chat_2; part of dash_chat_2;
class MyCheckbox extends StatefulWidget {
const MyCheckbox({Key? key, required this.isChecked, required this.onChanged}) : super(key: key);
final bool isChecked;
final ValueChanged<bool> onChanged;
@override
_MyCheckboxState createState() => _MyCheckboxState();
}
class _MyCheckboxState extends State<MyCheckbox> {
bool _isChecked = false;
@override
void initState() {
// TODO: implement initState
super.initState();
_isChecked = widget.isChecked;
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
}
@override
void didUpdateWidget(MyCheckbox oldWidget) {
// TODO: implement didUpdateWidget
super.didUpdateWidget(oldWidget);
_isChecked = widget.isChecked;
}
@override
void didChangeDependencies() {
// TODO: implement didChangeDependencies
super.didChangeDependencies();
}
@override
Widget build(BuildContext context) {
return InkWell(
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
onTap: () {
setState(() {
_isChecked = !_isChecked;
if (widget.onChanged != null) {
widget.onChanged!(_isChecked);
}
});
},
child: Container(
width: 30,
height: 30,
decoration: BoxDecoration(
color: Colors.transparent,
border: Border.all(
color: Color(0xFFbe6afb),
width: 2,
),
borderRadius: BorderRadius.circular(15),
),
child: _isChecked
? Icon(
Icons.check,
size: 16,
color: Color(0xFFbe6afb),
)
: null,
),
);
}
}
/// @nodoc /// @nodoc
class MessageRow extends StatelessWidget { class MessageRow extends StatelessWidget {
const MessageRow({ const MessageRow({
...@@ -82,11 +156,22 @@ class MessageRow extends StatelessWidget { ...@@ -82,11 +156,22 @@ class MessageRow extends StatelessWidget {
child: Row( child: Row(
children: [ children: [
if (message.showMenu == true) if (message.showMenu == true)
Checkbox( MyCheckbox(
isChecked: message.selected ?? false,
onChanged: (onChanged) {
chatRowSelected?.call(message, onChanged);
})
/*Checkbox(
value: message.selected, value: message.selected,
activeColor: Color(0xFFbe6afb),
checkColor: Colors.white,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
visualDensity: VisualDensity.compact,
shape: const CircleBorder(),
onChanged: (onChanged) { onChanged: (onChanged) {
chatRowSelected?.call(message, onChanged); chatRowSelected?.call(message, onChanged);
}), })*/,
Expanded( Expanded(
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
......
import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
class ApplicationState { class ApplicationState {
...@@ -17,4 +18,11 @@ class ApplicationState { ...@@ -17,4 +18,11 @@ class ApplicationState {
final _isNetWorkErr = false.obs; final _isNetWorkErr = false.obs;
set isNetWorkErr(value) => _isNetWorkErr.value = value; set isNetWorkErr(value) => _isNetWorkErr.value = value;
get isNetWorkErr => _isNetWorkErr.value; get isNetWorkErr => _isNetWorkErr.value;
final _showBottomMenu = false.obs;
set showBottomMenu(value) => _showBottomMenu.value = value;
get showBottomMenu => _showBottomMenu.value;
} }
import 'dart:math'; import 'dart:math';
import 'package:chart/common/widgets/wx_share.dart';
import 'package:chart/pages/assistant/index.dart'; import 'package:chart/pages/assistant/index.dart';
import 'package:chart/pages/creation/index.dart'; import 'package:chart/pages/creation/index.dart';
import 'package:chart/pages/home/index.dart'; import 'package:chart/pages/home/index.dart';
...@@ -134,6 +135,93 @@ class ApplicationPage extends GetView<ApplicationController> { ...@@ -134,6 +135,93 @@ class ApplicationPage extends GetView<ApplicationController> {
))); )));
} }
Widget makeBottomMenu() {
Get.put(HomeController());
final homeController = Get.find<HomeController>();
return AnimatedAlign(
duration: Duration(milliseconds: 300),
alignment: controller.state.showBottomMenu ? Alignment.bottomCenter : const Alignment(0, 2),
child: Container(
height: 180,
padding: const EdgeInsets.fromLTRB(20, 20, 20, 100),
decoration: BoxDecoration(
color: Colors.black.withAlpha(180),
borderRadius: const BorderRadius.all(Radius.circular(20))
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(child:
Container(
height: 44,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(22),
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Color(0xFFbe6afb),Color(0xFF7965f8)],
),
),
child: TextButton(
onPressed: homeController.deleteMessages,
child: Center(
child: Text(
'删除(${homeController.selectedItems.length})',
style: TextStyle(color: Colors.white),
),
),
))
),
SizedBox(width: 30),
Expanded(
child: Container(
height: 44,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(22),
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Color(0xFFbe6afb),Color(0xFF7965f8)],
),
),
child: TextButton(
onPressed: homeController.shareMessages,
child: Center(
child: Text(
'分享(${homeController.selectedItems.length})',
style: TextStyle(color: Colors.white),
),
),
))
),
SizedBox(width: 30),
Expanded(
child: Container(
height: 44,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(22),
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Color(0xFFbe6afb),Color(0xFF7965f8)],
),
),
child: TextButton(
onPressed: homeController.cancelShare,
child: const Center(
child: Text(
'取消',
style: TextStyle(color: Colors.white),
),
),
))
),
],
),
),
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
CustomClipper<Path> clipper = MyCustomClipper(); CustomClipper<Path> clipper = MyCustomClipper();
...@@ -413,7 +501,8 @@ class ApplicationPage extends GetView<ApplicationController> { ...@@ -413,7 +501,8 @@ class ApplicationPage extends GetView<ApplicationController> {
), ),
), ),
) )
: const SizedBox.shrink() : const SizedBox.shrink(),
makeBottomMenu()
], ],
)); ));
} }
......
...@@ -83,9 +83,9 @@ class HomeController extends GetxController with SingleGetTickerProviderMixin { ...@@ -83,9 +83,9 @@ class HomeController extends GetxController with SingleGetTickerProviderMixin {
/// 右上角分享管理相关菜单 /// 右上角分享管理相关菜单
List<Widget> topRightBarMenus() { List<Widget> topRightBarMenus() {
/// 选中数据不为空 或者 展示选择菜单右侧即显示 分享相关控制 /// 选中数据不为空 或者 展示选择菜单右侧即显示 分享相关控制
return (selectedItems.isEmpty == true && return /*(selectedItems.isEmpty == true &&
chatRowCheckRadioShowed.value == false) chatRowCheckRadioShowed.value == false)
? [ ? */[
RotationTransition( RotationTransition(
turns: animation, turns: animation,
child: IconButton( child: IconButton(
...@@ -110,7 +110,7 @@ class HomeController extends GetxController with SingleGetTickerProviderMixin { ...@@ -110,7 +110,7 @@ class HomeController extends GetxController with SingleGetTickerProviderMixin {
}, },
) )
] ]
: [ /*: [
IconButton( IconButton(
tooltip: "分享", tooltip: "分享",
onPressed: () async { onPressed: () async {
...@@ -133,7 +133,7 @@ class HomeController extends GetxController with SingleGetTickerProviderMixin { ...@@ -133,7 +133,7 @@ class HomeController extends GetxController with SingleGetTickerProviderMixin {
_hideChatMessageCheckbox(); _hideChatMessageCheckbox();
}, },
icon: const Icon(Icons.cancel_outlined)) icon: const Icon(Icons.cancel_outlined))
]; ]*/;
} }
bool gotoLoginPage() { bool gotoLoginPage() {
...@@ -518,17 +518,21 @@ class HomeController extends GetxController with SingleGetTickerProviderMixin { ...@@ -518,17 +518,21 @@ class HomeController extends GetxController with SingleGetTickerProviderMixin {
// }); // });
}, },
), ),
// ItemModel('收藏', Icons.collections), // ItemModel('收藏', Icons.collections),
// ItemModel('删除', Icons.delete), // ItemModel('删除', Icons.delete),
// ItemModel('多选', Icons.playlist_add_check, (message, controller) { ItemModel('多选', Icons.playlist_add_check, (message, controller) {
// state.messageList.forEach((element) { state.messageList.forEach((element) {
// element.showMenu = true; element.showMenu = true;
// }); });
// state.messageList
// .replaceRange(0, state.messageList.length - 1, state.messageList); state.messageList
// controller.hideMenu(); .replaceRange(0, state.messageList.length, state.messageList);
// chatRowCheckRadioShowed.value = true; controller.hideMenu();
// }), chatRowCheckRadioShowed.value = true;
final appController = Get.find<ApplicationController>();
appController.state.showBottomMenu = true;
}),
// ItemModel('引用', Icons.format_quote), // ItemModel('引用', Icons.format_quote),
// ItemModel('提醒', Icons.add_alert), // ItemModel('提醒', Icons.add_alert),
// ItemModel('搜一搜', Icons.search), // ItemModel('搜一搜', Icons.search),
...@@ -598,13 +602,12 @@ class HomeController extends GetxController with SingleGetTickerProviderMixin { ...@@ -598,13 +602,12 @@ class HomeController extends GetxController with SingleGetTickerProviderMixin {
_update(ChatMessage message, {bool? value = false}) { _update(ChatMessage message, {bool? value = false}) {
message.selected = value ?? false; message.selected = value ?? false;
int index = state.messageList.indexWhere((element) => element == message); // final index = state.messageList.indexWhere((element) => element == message);
state.messageList.replaceRange(index, index + 1, [message]); // state.messageList.replaceRange(index, index + 1, [message]);
if (value == false) { if (value == false) {
selectedItems.remove(message); selectedItems.remove(message);
} else { } else {
selectedItems.add(message); selectedItems.add(message);
selectedItems.value.sort();
} }
selectedItems.forEach((element) { selectedItems.forEach((element) {
print(element.text); print(element.text);
...@@ -633,13 +636,42 @@ class HomeController extends GetxController with SingleGetTickerProviderMixin { ...@@ -633,13 +636,42 @@ class HomeController extends GetxController with SingleGetTickerProviderMixin {
child: chatMessageBody); child: chatMessageBody);
} }
shareMessages() {
final selecteds = state.messageList.where((p0) => p0.customProperties == null && p0.selected == true).toList();
var shareContent = "";
for (var element in selecteds.reversed) {
shareContent += "${element.text}\n\n\n";
}
WXShare.shareText(shareContent);
}
deleteMessages() {
selectedItems.clear();
state.messageList.removeWhere((p0) => p0.selected == true);
}
cancelShare() {
final appController = Get.find<ApplicationController>();
appController.state.showBottomMenu = false;
for (var element in state.messageList) {
element.showMenu = false;
element.selected = false;
}
state.messageList
.replaceRange(0, state.messageList.length, state.messageList);
chatRowCheckRadioShowed.value = true;
selectedItems.clear();
}
tabMessage(ChatMessage message) { tabMessage(ChatMessage message) {
final appController = Get.find<ApplicationController>();
if (message.user.id == '0' && !state.isLoading) { if (message.user.id == '0' && !state.isLoading) {
final textMessage = Chat.ChatMessage( final textMessage = Chat.ChatMessage(
user: _user, user: _user,
createdAt: DateTime.now(), createdAt: DateTime.now(),
// id: const Uuid().v4(), // id: const Uuid().v4(),
text: "${message.text}", text: "${message.text}",
showMenu: appController.state.showBottomMenu
); );
_addMessage(textMessage); _addMessage(textMessage);
...@@ -649,6 +681,7 @@ class HomeController extends GetxController with SingleGetTickerProviderMixin { ...@@ -649,6 +681,7 @@ class HomeController extends GetxController with SingleGetTickerProviderMixin {
status: MessageStatus.pending, status: MessageStatus.pending,
// id: const Uuid().v4(), // id: const Uuid().v4(),
text: message.customProperties!['question'], text: message.customProperties!['question'],
showMenu: appController.state.showBottomMenu
); );
_addMessage(receiveMessage); _addMessage(receiveMessage);
// sendMessage(Chat.ChatMessage( // sendMessage(Chat.ChatMessage(
......
...@@ -9,6 +9,7 @@ import 'package:flutter_chat_types/flutter_chat_types.dart' as types; ...@@ -9,6 +9,7 @@ import 'package:flutter_chat_types/flutter_chat_types.dart' as types;
import 'package:gradient_borders/gradient_borders.dart'; import 'package:gradient_borders/gradient_borders.dart';
import 'package:gradient_widgets/gradient_widgets.dart'; import 'package:gradient_widgets/gradient_widgets.dart';
import '../../../common/widgets/app.dart'; import '../../../common/widgets/app.dart';
import '../application/controller.dart';
import 'index.dart'; import 'index.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;
...@@ -44,11 +45,13 @@ class _HomePageState extends State<_HomePage> ...@@ -44,11 +45,13 @@ class _HomePageState extends State<_HomePage>
// TODO: implement wantKeepAlive // TODO: implement wantKeepAlive
bool get wantKeepAlive => true; bool get wantKeepAlive => true;
HomeController get controller => Get.find(); HomeController get controller => Get.find<HomeController>();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final cc = Get.put(HomeController()); final cc = controller;//Get.put(HomeController());
return Obx(() => Scaffold( return Obx(() => Scaffold(
resizeToAvoidBottomInset: false, resizeToAvoidBottomInset: false,
backgroundColor: Color.fromARGB(0, 0, 0, 0), backgroundColor: Color.fromARGB(0, 0, 0, 0),
......
platform :osx, '10.11' platform :osx, '10.14'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency. # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true' ENV['COCOAPODS_DISABLE_STATS'] = 'true'
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
archiveVersion = 1; archiveVersion = 1;
classes = { classes = {
}; };
objectVersion = 51; objectVersion = 54;
objects = { objects = {
/* Begin PBXAggregateTarget section */ /* Begin PBXAggregateTarget section */
...@@ -235,6 +235,7 @@ ...@@ -235,6 +235,7 @@
/* Begin PBXShellScriptBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */
3399D490228B24CF009A79C7 /* ShellScript */ = { 3399D490228B24CF009A79C7 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
...@@ -344,7 +345,7 @@ ...@@ -344,7 +345,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11; MACOSX_DEPLOYMENT_TARGET = 10.14;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx; SDKROOT = macosx;
SWIFT_COMPILATION_MODE = wholemodule; SWIFT_COMPILATION_MODE = wholemodule;
...@@ -423,7 +424,7 @@ ...@@ -423,7 +424,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11; MACOSX_DEPLOYMENT_TARGET = 10.14;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx; SDKROOT = macosx;
...@@ -470,7 +471,7 @@ ...@@ -470,7 +471,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11; MACOSX_DEPLOYMENT_TARGET = 10.14;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx; SDKROOT = macosx;
SWIFT_COMPILATION_MODE = wholemodule; SWIFT_COMPILATION_MODE = wholemodule;
......
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