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_easyloading/flutter_easyloading.dart';
import 'package:fluwx/fluwx.dart';
import 'package:get/get.dart';
import 'package:share_plus/share_plus.dart';
......@@ -28,7 +29,13 @@ class WXShare {
} else {
model = WeChatShareTextModel(content, scene: WeChatScene.FAVORITE);
}
shareToWeChat(model);
shareToWeChat(model).then((value) {
if (value) {
EasyLoading.showToast("分享成功");
} else {
EasyLoading.showToast("分享失败");
}
});
} else {
Share.shareWithResult(content);
}
......
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
class MessageRow extends StatelessWidget {
const MessageRow({
......@@ -82,11 +156,22 @@ class MessageRow extends StatelessWidget {
child: Row(
children: [
if (message.showMenu == true)
Checkbox(
MyCheckbox(
isChecked: message.selected ?? false,
onChanged: (onChanged) {
chatRowSelected?.call(message, onChanged);
})
/*Checkbox(
value: message.selected,
activeColor: Color(0xFFbe6afb),
checkColor: Colors.white,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
visualDensity: VisualDensity.compact,
shape: const CircleBorder(),
onChanged: (onChanged) {
chatRowSelected?.call(message, onChanged);
}),
})*/,
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
......
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class ApplicationState {
......@@ -17,4 +18,11 @@ class ApplicationState {
final _isNetWorkErr = false.obs;
set isNetWorkErr(value) => _isNetWorkErr.value = value;
get isNetWorkErr => _isNetWorkErr.value;
final _showBottomMenu = false.obs;
set showBottomMenu(value) => _showBottomMenu.value = value;
get showBottomMenu => _showBottomMenu.value;
}
import 'dart:math';
import 'package:chart/common/widgets/wx_share.dart';
import 'package:chart/pages/assistant/index.dart';
import 'package:chart/pages/creation/index.dart';
import 'package:chart/pages/home/index.dart';
......@@ -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
Widget build(BuildContext context) {
CustomClipper<Path> clipper = MyCustomClipper();
......@@ -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 {
/// 右上角分享管理相关菜单
List<Widget> topRightBarMenus() {
/// 选中数据不为空 或者 展示选择菜单右侧即显示 分享相关控制
return (selectedItems.isEmpty == true &&
return /*(selectedItems.isEmpty == true &&
chatRowCheckRadioShowed.value == false)
? [
? */[
RotationTransition(
turns: animation,
child: IconButton(
......@@ -110,7 +110,7 @@ class HomeController extends GetxController with SingleGetTickerProviderMixin {
},
)
]
: [
/*: [
IconButton(
tooltip: "分享",
onPressed: () async {
......@@ -133,7 +133,7 @@ class HomeController extends GetxController with SingleGetTickerProviderMixin {
_hideChatMessageCheckbox();
},
icon: const Icon(Icons.cancel_outlined))
];
]*/;
}
bool gotoLoginPage() {
......@@ -518,17 +518,21 @@ class HomeController extends GetxController with SingleGetTickerProviderMixin {
// });
},
),
// 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();
// chatRowCheckRadioShowed.value = true;
// }),
ItemModel('多选', Icons.playlist_add_check, (message, controller) {
state.messageList.forEach((element) {
element.showMenu = true;
});
state.messageList
.replaceRange(0, state.messageList.length, state.messageList);
controller.hideMenu();
chatRowCheckRadioShowed.value = true;
final appController = Get.find<ApplicationController>();
appController.state.showBottomMenu = true;
}),
// ItemModel('引用', Icons.format_quote),
// ItemModel('提醒', Icons.add_alert),
// ItemModel('搜一搜', Icons.search),
......@@ -598,13 +602,12 @@ class HomeController extends GetxController with SingleGetTickerProviderMixin {
_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]);
// final 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);
......@@ -633,13 +636,42 @@ class HomeController extends GetxController with SingleGetTickerProviderMixin {
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) {
final appController = Get.find<ApplicationController>();
if (message.user.id == '0' && !state.isLoading) {
final textMessage = Chat.ChatMessage(
user: _user,
createdAt: DateTime.now(),
// id: const Uuid().v4(),
text: "${message.text}",
showMenu: appController.state.showBottomMenu
);
_addMessage(textMessage);
......@@ -649,6 +681,7 @@ class HomeController extends GetxController with SingleGetTickerProviderMixin {
status: MessageStatus.pending,
// id: const Uuid().v4(),
text: message.customProperties!['question'],
showMenu: appController.state.showBottomMenu
);
_addMessage(receiveMessage);
// sendMessage(Chat.ChatMessage(
......
......@@ -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_widgets/gradient_widgets.dart';
import '../../../common/widgets/app.dart';
import '../application/controller.dart';
import 'index.dart';
import 'package:chart/package/chat_dash/dash_chat_2.dart' as Chat;
......@@ -44,11 +45,13 @@ class _HomePageState extends State<_HomePage>
// TODO: implement wantKeepAlive
bool get wantKeepAlive => true;
HomeController get controller => Get.find();
HomeController get controller => Get.find<HomeController>();
@override
Widget build(BuildContext context) {
final cc = Get.put(HomeController());
final cc = controller;//Get.put(HomeController());
return Obx(() => Scaffold(
resizeToAvoidBottomInset: false,
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.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
......
......@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 51;
objectVersion = 54;
objects = {
/* Begin PBXAggregateTarget section */
......@@ -235,6 +235,7 @@
/* Begin PBXShellScriptBuildPhase section */
3399D490228B24CF009A79C7 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
......@@ -344,7 +345,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MACOSX_DEPLOYMENT_TARGET = 10.14;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
SWIFT_COMPILATION_MODE = wholemodule;
......@@ -423,7 +424,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MACOSX_DEPLOYMENT_TARGET = 10.14;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
......@@ -470,7 +471,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MACOSX_DEPLOYMENT_TARGET = 10.14;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
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