Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
ChatGPT
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
关振斌
ChatGPT
Commits
5372aa13
Commit
5372aa13
authored
May 22, 2023
by
netyouli
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
AI聊天界面添加多选分享,删除功能
parent
1d049ed6
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
325 additions
and
27 deletions
+325
-27
lib/common/widgets/bottom_animation.dart
lib/common/widgets/bottom_animation.dart
+23
-0
lib/common/widgets/my_checkbox.dart
lib/common/widgets/my_checkbox.dart
+49
-0
lib/common/widgets/wx_share.dart
lib/common/widgets/wx_share.dart
+8
-1
lib/package/chat_dash/src/widgets/message_row/message_row.dart
...ackage/chat_dash/src/widgets/message_row/message_row.dart
+87
-2
lib/pages/application/state.dart
lib/pages/application/state.dart
+8
-0
lib/pages/application/view.dart
lib/pages/application/view.dart
+90
-1
lib/pages/home/controller.dart
lib/pages/home/controller.dart
+49
-16
lib/pages/home/view.dart
lib/pages/home/view.dart
+5
-2
macos/Podfile
macos/Podfile
+1
-1
macos/Runner.xcodeproj/project.pbxproj
macos/Runner.xcodeproj/project.pbxproj
+5
-4
No files found.
lib/common/widgets/bottom_animation.dart
0 → 100644
View file @
5372aa13
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
,
),
);
}
}
lib/common/widgets/my_checkbox.dart
0 → 100644
View file @
5372aa13
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
lib/common/widgets/wx_share.dart
View file @
5372aa13
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
);
}
...
...
lib/package/chat_dash/src/widgets/message_row/message_row.dart
View file @
5372aa13
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
,
...
...
lib/pages/application/state.dart
View file @
5372aa13
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
;
}
lib/pages/application/view.dart
View file @
5372aa13
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
()
],
));
}
...
...
lib/pages/home/controller.dart
View file @
5372aa13
...
...
@@ -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(
...
...
lib/pages/home/view.dart
View file @
5372aa13
...
...
@@ -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
),
...
...
macos/Podfile
View file @
5372aa13
platform
:osx
,
'10.1
1
'
platform
:osx
,
'10.1
4
'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV
[
'COCOAPODS_DISABLE_STATS'
]
=
'true'
...
...
macos/Runner.xcodeproj/project.pbxproj
View file @
5372aa13
...
...
@@ -3,7 +3,7 @@
archiveVersion
=
1
;
classes
=
{
};
objectVersion
=
5
1
;
objectVersion
=
5
4
;
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.1
1
;
MACOSX_DEPLOYMENT_TARGET
=
10.1
4
;
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.1
1
;
MACOSX_DEPLOYMENT_TARGET
=
10.1
4
;
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.1
1
;
MACOSX_DEPLOYMENT_TARGET
=
10.1
4
;
MTL_ENABLE_DEBUG_INFO
=
NO
;
SDKROOT
=
macosx
;
SWIFT_COMPILATION_MODE
=
wholemodule
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment