change hoshan Appbar Header and create Tools and ToolBox page and change AiChatPage,
This commit is contained in:
parent
3f6957ae15
commit
2f4e049ce0
Binary file not shown.
|
After Width: | Height: | Size: 802 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 792 KiB |
|
|
@ -43,6 +43,8 @@ class Assets {
|
||||||
|
|
||||||
static String loadingAnimation = '$_baseAnimationsPath/loading.gif';
|
static String loadingAnimation = '$_baseAnimationsPath/loading.gif';
|
||||||
static String bookmarkAnimation = '$_baseAnimationsPath/bookmark.gif';
|
static String bookmarkAnimation = '$_baseAnimationsPath/bookmark.gif';
|
||||||
|
static String boxAnimation =
|
||||||
|
'$_baseAnimationsPath/onlinegiftools-$_themeSuffix.gif';
|
||||||
|
|
||||||
static String get businessCategoryIcon =>
|
static String get businessCategoryIcon =>
|
||||||
'$_baseCategoriesPath/business-$_themeSuffix.svg';
|
'$_baseCategoriesPath/business-$_themeSuffix.svg';
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,9 @@ import 'package:didvan/services/media/media.dart';
|
||||||
import 'package:didvan/services/notification/firebase_api.dart';
|
import 'package:didvan/services/notification/firebase_api.dart';
|
||||||
import 'package:didvan/services/notification/notification_service.dart';
|
import 'package:didvan/services/notification/notification_service.dart';
|
||||||
import 'package:didvan/utils/my_custom_scroll_behavior.dart';
|
import 'package:didvan/utils/my_custom_scroll_behavior.dart';
|
||||||
|
import 'package:didvan/views/ai/ai_state.dart';
|
||||||
import 'package:didvan/views/ai/history_ai_chat_state.dart';
|
import 'package:didvan/views/ai/history_ai_chat_state.dart';
|
||||||
|
import 'package:didvan/views/ai/tools_state.dart';
|
||||||
import 'package:didvan/views/podcasts/podcasts_state.dart';
|
import 'package:didvan/views/podcasts/podcasts_state.dart';
|
||||||
import 'package:didvan/views/podcasts/studio_details/studio_details_state.dart';
|
import 'package:didvan/views/podcasts/studio_details/studio_details_state.dart';
|
||||||
import 'package:firebase_core/firebase_core.dart';
|
import 'package:firebase_core/firebase_core.dart';
|
||||||
|
|
@ -170,6 +172,12 @@ class _DidvanState extends State<Didvan> with WidgetsBindingObserver {
|
||||||
ChangeNotifierProvider<HistoryAiChatState>(
|
ChangeNotifierProvider<HistoryAiChatState>(
|
||||||
create: (context) => HistoryAiChatState(),
|
create: (context) => HistoryAiChatState(),
|
||||||
),
|
),
|
||||||
|
ChangeNotifierProvider<AiState>(
|
||||||
|
create: (context) => AiState(),
|
||||||
|
),
|
||||||
|
ChangeNotifierProvider<ToolsState>(
|
||||||
|
create: (context) => ToolsState(),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
child: Consumer<ThemeProvider>(
|
child: Consumer<ThemeProvider>(
|
||||||
builder: (context, themeProvider, child) => Container(
|
builder: (context, themeProvider, child) => Container(
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
import 'package:didvan/models/ai/bots_model.dart';
|
||||||
|
|
||||||
|
class ToolsModel {
|
||||||
|
List<Tools>? tools;
|
||||||
|
|
||||||
|
ToolsModel({this.tools});
|
||||||
|
|
||||||
|
ToolsModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
if (json['tools'] != null) {
|
||||||
|
tools = <Tools>[];
|
||||||
|
json['tools'].forEach((v) {
|
||||||
|
tools!.add(Tools.fromJson(v));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
if (tools != null) {
|
||||||
|
data['tools'] = tools!.map((v) => v.toJson()).toList();
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Tools {
|
||||||
|
int? id;
|
||||||
|
String? name;
|
||||||
|
String? image;
|
||||||
|
String? description;
|
||||||
|
String? guide;
|
||||||
|
int? order;
|
||||||
|
List<BotsModel>? bots;
|
||||||
|
|
||||||
|
Tools(
|
||||||
|
{this.id,
|
||||||
|
this.name,
|
||||||
|
this.image,
|
||||||
|
this.description,
|
||||||
|
this.guide,
|
||||||
|
this.order,
|
||||||
|
this.bots});
|
||||||
|
|
||||||
|
Tools.fromJson(Map<String, dynamic> json) {
|
||||||
|
id = json['id'];
|
||||||
|
name = json['name'];
|
||||||
|
image = json['image'];
|
||||||
|
description = json['description'];
|
||||||
|
guide = json['guide'];
|
||||||
|
order = json['order'];
|
||||||
|
if (json['bots'] != null) {
|
||||||
|
bots = <BotsModel>[];
|
||||||
|
json['bots'].forEach((v) {
|
||||||
|
bots!.add(BotsModel.fromJson(v));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['id'] = id;
|
||||||
|
data['name'] = name;
|
||||||
|
data['image'] = image;
|
||||||
|
data['description'] = description;
|
||||||
|
data['guide'] = guide;
|
||||||
|
data['order'] = order;
|
||||||
|
if (bots != null) {
|
||||||
|
data['bots'] = bots!.map((v) => v.toJson()).toList();
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -205,7 +205,7 @@ class RequestHelper {
|
||||||
static String aiArchived() => '$baseUrl/ai/chat${_urlConcatGenerator([
|
static String aiArchived() => '$baseUrl/ai/chat${_urlConcatGenerator([
|
||||||
const MapEntry('archived', true),
|
const MapEntry('archived', true),
|
||||||
])}';
|
])}';
|
||||||
static String aiBots() => '$baseUrl/ai/bot';
|
static String aiBots() => '$baseUrl/ai/bot/v2';
|
||||||
static String aiSearchBots(String q) =>
|
static String aiSearchBots(String q) =>
|
||||||
'$baseUrl/ai/bot${_urlConcatGenerator([
|
'$baseUrl/ai/bot${_urlConcatGenerator([
|
||||||
MapEntry('q', q),
|
MapEntry('q', q),
|
||||||
|
|
@ -229,6 +229,7 @@ class RequestHelper {
|
||||||
static String deleteAllChats() => '$baseUrl/ai/chat/all';
|
static String deleteAllChats() => '$baseUrl/ai/chat/all';
|
||||||
static String archivedChat(int id) => '$baseUrl/ai/chat/$id/archive';
|
static String archivedChat(int id) => '$baseUrl/ai/chat/$id/archive';
|
||||||
static String placeholder(int id) => '$baseUrl/ai/chat/$id/placeholder';
|
static String placeholder(int id) => '$baseUrl/ai/chat/$id/placeholder';
|
||||||
|
static String tools() => '$baseUrl/ai/tool';
|
||||||
|
|
||||||
static String _urlConcatGenerator(List<MapEntry<String, dynamic>> additions) {
|
static String _urlConcatGenerator(List<MapEntry<String, dynamic>> additions) {
|
||||||
String result = '';
|
String result = '';
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,10 @@ import 'package:didvan/constants/assets.dart';
|
||||||
import 'package:didvan/models/ai/ai_chat_args.dart';
|
import 'package:didvan/models/ai/ai_chat_args.dart';
|
||||||
import 'package:didvan/routes/routes.dart';
|
import 'package:didvan/routes/routes.dart';
|
||||||
import 'package:didvan/utils/action_sheet.dart';
|
import 'package:didvan/utils/action_sheet.dart';
|
||||||
|
import 'package:didvan/views/ai/ai_state.dart';
|
||||||
import 'package:didvan/views/ai/history_ai_chat_state.dart';
|
import 'package:didvan/views/ai/history_ai_chat_state.dart';
|
||||||
|
import 'package:didvan/views/ai/tool_screen.dart';
|
||||||
|
import 'package:didvan/views/ai/tools_screen.dart';
|
||||||
import 'package:didvan/views/ai/widgets/message_bar_btn.dart';
|
import 'package:didvan/views/ai/widgets/message_bar_btn.dart';
|
||||||
import 'package:didvan/views/home/home.dart';
|
import 'package:didvan/views/home/home.dart';
|
||||||
import 'package:didvan/views/widgets/didvan/text.dart';
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||||
|
|
@ -44,255 +47,281 @@ class _AiState extends State<Ai> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Consumer<HistoryAiChatState>(
|
return Stack(
|
||||||
builder: (context, state, child) {
|
children: [
|
||||||
if (state.bots.isEmpty) {
|
Consumer<AiState>(
|
||||||
return Center(
|
builder: (BuildContext context, state, Widget? child) {
|
||||||
child: Image.asset(
|
switch (state.page) {
|
||||||
Assets.loadingAnimation,
|
case 0:
|
||||||
width: 60,
|
return Consumer<HistoryAiChatState>(
|
||||||
height: 60,
|
builder: (context, state, child) {
|
||||||
),
|
if (state.bots.isEmpty) {
|
||||||
);
|
return Center(
|
||||||
}
|
child: Image.asset(
|
||||||
final bot = state.bot!;
|
Assets.loadingAnimation,
|
||||||
return Stack(
|
width: 60,
|
||||||
children: [
|
height: 60,
|
||||||
Column(
|
),
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
);
|
||||||
children: [
|
}
|
||||||
Expanded(
|
final bot = state.bot!;
|
||||||
child: SingleChildScrollView(
|
return Column(
|
||||||
child: Padding(
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
padding: const EdgeInsets.only(bottom: 24),
|
children: [
|
||||||
child: Column(
|
Expanded(
|
||||||
children: [
|
child: SingleChildScrollView(
|
||||||
const SizedBox(
|
child: Padding(
|
||||||
height: 24,
|
padding: const EdgeInsets.only(bottom: 24),
|
||||||
),
|
child: Column(
|
||||||
Icon(
|
children: [
|
||||||
DidvanIcons.ai_solid,
|
const SizedBox(
|
||||||
size: MediaQuery.sizeOf(context).width / 5,
|
height: 24,
|
||||||
color: Theme.of(context).colorScheme.title,
|
),
|
||||||
),
|
Icon(
|
||||||
DidvanText(
|
DidvanIcons.ai_solid,
|
||||||
'هوشان',
|
size: MediaQuery.sizeOf(context).width / 5,
|
||||||
color: Theme.of(context).colorScheme.title,
|
color: Theme.of(context).colorScheme.title,
|
||||||
),
|
),
|
||||||
const SizedBox(
|
DidvanText(
|
||||||
height: 24,
|
'هوشان',
|
||||||
),
|
color: Theme.of(context).colorScheme.title,
|
||||||
InkWell(
|
),
|
||||||
onTap: () => ActionSheetUtils(context)
|
const SizedBox(
|
||||||
.botsDialogSelect(
|
height: 24,
|
||||||
context: context, state: state),
|
),
|
||||||
child: Container(
|
InkWell(
|
||||||
decoration: BoxDecoration(
|
onTap: () => ActionSheetUtils(context)
|
||||||
borderRadius: BorderRadius.circular(360),
|
.botsDialogSelect(
|
||||||
border: Border.all(
|
context: context, state: state),
|
||||||
width: 1,
|
child: Container(
|
||||||
color:
|
decoration: BoxDecoration(
|
||||||
Theme.of(context).colorScheme.text)),
|
borderRadius:
|
||||||
child: Padding(
|
BorderRadius.circular(360),
|
||||||
padding: const EdgeInsets.symmetric(
|
border: Border.all(
|
||||||
vertical: 8.0, horizontal: 18),
|
width: 1,
|
||||||
child: Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment:
|
|
||||||
MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Column(
|
|
||||||
children: [
|
|
||||||
Transform.rotate(
|
|
||||||
angle: 180 * pi / 180,
|
|
||||||
child: Icon(
|
|
||||||
DidvanIcons.caret_down_solid,
|
|
||||||
color: Theme.of(context)
|
|
||||||
.colorScheme
|
|
||||||
.title,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Icon(
|
|
||||||
DidvanIcons.caret_down_solid,
|
|
||||||
color: Theme.of(context)
|
color: Theme.of(context)
|
||||||
.colorScheme
|
.colorScheme
|
||||||
.title,
|
.text)),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 8.0, horizontal: 18),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment:
|
||||||
|
CrossAxisAlignment.center,
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
Transform.rotate(
|
||||||
|
angle: 180 * pi / 180,
|
||||||
|
child: Icon(
|
||||||
|
DidvanIcons
|
||||||
|
.caret_down_solid,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.title,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Icon(
|
||||||
|
DidvanIcons
|
||||||
|
.caret_down_solid,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.title,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 12,
|
||||||
|
),
|
||||||
|
DidvanText(bot.name.toString(),
|
||||||
|
color: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.title),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 12,
|
||||||
|
),
|
||||||
|
ClipOval(
|
||||||
|
child: CachedNetworkImage(
|
||||||
|
width: 46,
|
||||||
|
height: 46,
|
||||||
|
imageUrl: bot.image.toString(),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(
|
|
||||||
width: 12,
|
|
||||||
),
|
|
||||||
DidvanText(bot.name.toString(),
|
|
||||||
color: Theme.of(context)
|
|
||||||
.colorScheme
|
|
||||||
.title),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
width: 12,
|
|
||||||
),
|
|
||||||
ClipOval(
|
|
||||||
child: CachedNetworkImage(
|
|
||||||
width: 46,
|
|
||||||
height: 46,
|
|
||||||
imageUrl: bot.image.toString(),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
const SizedBox(
|
||||||
|
height: 24,
|
||||||
|
),
|
||||||
|
const Padding(
|
||||||
|
padding:
|
||||||
|
EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
|
child: Text(
|
||||||
|
"به هوشان؛ هوش مصنوعی دیدوان خوش آمدید. \nبرای شروع گفتگو پیام مورد نظر خود را در کادر زیر بنویسید.",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(
|
),
|
||||||
height: 24,
|
Padding(
|
||||||
),
|
padding: const EdgeInsets.fromLTRB(20, 0, 20, 12),
|
||||||
const Padding(
|
child: InkWell(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 20.0),
|
onTap: () =>
|
||||||
child: Text(
|
Navigator.of(context).pushNamed(Routes.aiChat,
|
||||||
"به هوشان؛ هوش مصنوعی دیدوان خوش آمدید. \nبرای شروع گفتگو پیام مورد نظر خود را در کادر زیر بنویسید.",
|
arguments: AiChatArgs(
|
||||||
textAlign: TextAlign.center,
|
bot: bot,
|
||||||
),
|
)),
|
||||||
)
|
child: Column(
|
||||||
],
|
children: [
|
||||||
),
|
Row(
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.fromLTRB(20, 0, 20, 12),
|
|
||||||
child: InkWell(
|
|
||||||
onTap: () =>
|
|
||||||
Navigator.of(context).pushNamed(Routes.aiChat,
|
|
||||||
arguments: AiChatArgs(
|
|
||||||
bot: bot,
|
|
||||||
)),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
boxShadow: DesignConfig.defaultShadow,
|
|
||||||
color:
|
|
||||||
Theme.of(context).colorScheme.surface,
|
|
||||||
border: Border.all(
|
|
||||||
color: Theme.of(context)
|
|
||||||
.colorScheme
|
|
||||||
.border),
|
|
||||||
borderRadius:
|
|
||||||
DesignConfig.highBorderRadius),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Padding(
|
child: Container(
|
||||||
padding:
|
decoration: BoxDecoration(
|
||||||
const EdgeInsets.symmetric(
|
boxShadow:
|
||||||
horizontal: 8.0,
|
DesignConfig.defaultShadow,
|
||||||
),
|
color: Theme.of(context)
|
||||||
child: Form(
|
.colorScheme
|
||||||
child: Row(
|
.surface,
|
||||||
children: [
|
border: Border.all(
|
||||||
const MessageBarBtn(
|
color: Theme.of(context)
|
||||||
enable: true,
|
.colorScheme
|
||||||
icon: DidvanIcons
|
.border),
|
||||||
.mic_regular),
|
borderRadius: DesignConfig
|
||||||
const SizedBox(
|
.highBorderRadius),
|
||||||
width: 8,
|
child: Row(
|
||||||
),
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: TextFormField(
|
child: Padding(
|
||||||
textInputAction:
|
padding: const EdgeInsets
|
||||||
TextInputAction
|
.symmetric(
|
||||||
.newline,
|
horizontal: 8.0,
|
||||||
style: Theme.of(context)
|
|
||||||
.textTheme
|
|
||||||
.bodyMedium,
|
|
||||||
minLines: 1,
|
|
||||||
enabled: false,
|
|
||||||
decoration:
|
|
||||||
InputDecoration(
|
|
||||||
border:
|
|
||||||
InputBorder.none,
|
|
||||||
hintText: 'بنویسید...',
|
|
||||||
hintStyle: Theme.of(
|
|
||||||
context)
|
|
||||||
.textTheme
|
|
||||||
.bodySmall!
|
|
||||||
.copyWith(
|
|
||||||
color: Theme.of(
|
|
||||||
context)
|
|
||||||
.colorScheme
|
|
||||||
.disabledText),
|
|
||||||
),
|
),
|
||||||
),
|
child: Form(
|
||||||
),
|
child: Row(
|
||||||
const SizedBox(
|
children: [
|
||||||
width: 8,
|
const MessageBarBtn(
|
||||||
),
|
enable: true,
|
||||||
MessageBarBtn(
|
icon: DidvanIcons
|
||||||
click: () {
|
.mic_regular),
|
||||||
Navigator.of(context)
|
const SizedBox(
|
||||||
.pushNamed(
|
width: 8,
|
||||||
Routes.aiChat,
|
),
|
||||||
arguments:
|
Expanded(
|
||||||
AiChatArgs(
|
child:
|
||||||
|
TextFormField(
|
||||||
|
textInputAction:
|
||||||
|
TextInputAction
|
||||||
|
.newline,
|
||||||
|
style: Theme.of(
|
||||||
|
context)
|
||||||
|
.textTheme
|
||||||
|
.bodyMedium,
|
||||||
|
minLines: 1,
|
||||||
|
enabled: false,
|
||||||
|
decoration:
|
||||||
|
InputDecoration(
|
||||||
|
border:
|
||||||
|
InputBorder
|
||||||
|
.none,
|
||||||
|
hintText:
|
||||||
|
'بنویسید...',
|
||||||
|
hintStyle: Theme.of(
|
||||||
|
context)
|
||||||
|
.textTheme
|
||||||
|
.bodySmall!
|
||||||
|
.copyWith(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.disabledText),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 8,
|
||||||
|
),
|
||||||
|
MessageBarBtn(
|
||||||
|
click: () {
|
||||||
|
Navigator.of(context).pushNamed(
|
||||||
|
Routes
|
||||||
|
.aiChat,
|
||||||
|
arguments: AiChatArgs(
|
||||||
bot:
|
bot:
|
||||||
bot,
|
bot,
|
||||||
attach:
|
attach:
|
||||||
true));
|
true));
|
||||||
},
|
},
|
||||||
enable: false,
|
enable: false,
|
||||||
icon: Icons
|
icon: Icons
|
||||||
.attach_file_rounded),
|
.attach_file_rounded),
|
||||||
],
|
],
|
||||||
))))
|
))))
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
const Padding(
|
||||||
),
|
padding: EdgeInsets.fromLTRB(8, 8, 8, 4),
|
||||||
],
|
child: DidvanText(
|
||||||
),
|
'مدلهای هوش مصنوعی میتوانند اشتباه کنند، صحت اطلاعات مهم را بررسی کنید.',
|
||||||
const Padding(
|
fontSize: 12,
|
||||||
padding: EdgeInsets.fromLTRB(8, 8, 8, 4),
|
),
|
||||||
child: DidvanText(
|
)
|
||||||
'مدلهای هوش مصنوعی میتوانند اشتباه کنند، صحت اطلاعات مهم را بررسی کنید.',
|
],
|
||||||
fontSize: 12,
|
)),
|
||||||
),
|
),
|
||||||
)
|
],
|
||||||
],
|
);
|
||||||
)),
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
return const ToolsScreen();
|
||||||
|
case 2:
|
||||||
|
return const ToolScreen();
|
||||||
|
|
||||||
|
default:
|
||||||
|
return const SizedBox();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
top: 32,
|
||||||
|
right: 0,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () => homeScaffKey.currentState!.openDrawer(),
|
||||||
|
child: Container(
|
||||||
|
width: 46,
|
||||||
|
height: 46,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).colorScheme.surface,
|
||||||
|
borderRadius: const BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(12),
|
||||||
|
bottomLeft: Radius.circular(12)),
|
||||||
|
boxShadow: DesignConfig.defaultShadow),
|
||||||
|
child: Icon(
|
||||||
|
DidvanIcons.angle_left_light,
|
||||||
|
color: Theme.of(context).colorScheme.title,
|
||||||
),
|
),
|
||||||
],
|
)),
|
||||||
),
|
)
|
||||||
Positioned(
|
],
|
||||||
top: 32,
|
|
||||||
right: 0,
|
|
||||||
child: InkWell(
|
|
||||||
onTap: () => homeScaffKey.currentState!.openDrawer(),
|
|
||||||
child: Container(
|
|
||||||
width: 46,
|
|
||||||
height: 46,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Theme.of(context).colorScheme.surface,
|
|
||||||
borderRadius: const BorderRadius.only(
|
|
||||||
topLeft: Radius.circular(12),
|
|
||||||
bottomLeft: Radius.circular(12)),
|
|
||||||
boxShadow: DesignConfig.defaultShadow),
|
|
||||||
child: Icon(
|
|
||||||
DidvanIcons.angle_left_light,
|
|
||||||
color: Theme.of(context).colorScheme.title,
|
|
||||||
),
|
|
||||||
)),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ import 'package:didvan/models/ai/chats_model.dart';
|
||||||
import 'package:didvan/models/ai/files_model.dart';
|
import 'package:didvan/models/ai/files_model.dart';
|
||||||
import 'package:didvan/models/ai/messages_model.dart';
|
import 'package:didvan/models/ai/messages_model.dart';
|
||||||
import 'package:didvan/models/enums.dart';
|
import 'package:didvan/models/enums.dart';
|
||||||
import 'package:didvan/models/view/action_sheet_data.dart';
|
|
||||||
import 'package:didvan/models/view/alert_data.dart';
|
import 'package:didvan/models/view/alert_data.dart';
|
||||||
import 'package:didvan/routes/routes.dart';
|
import 'package:didvan/routes/routes.dart';
|
||||||
import 'package:didvan/services/media/media.dart';
|
import 'package:didvan/services/media/media.dart';
|
||||||
|
|
@ -25,9 +24,9 @@ import 'package:didvan/views/ai/ai_chat_state.dart';
|
||||||
import 'package:didvan/views/ai/history_ai_chat_state.dart';
|
import 'package:didvan/views/ai/history_ai_chat_state.dart';
|
||||||
import 'package:didvan/views/ai/widgets/ai_message_bar.dart';
|
import 'package:didvan/views/ai/widgets/ai_message_bar.dart';
|
||||||
import 'package:didvan/views/ai/widgets/audio_wave.dart';
|
import 'package:didvan/views/ai/widgets/audio_wave.dart';
|
||||||
import 'package:didvan/views/widgets/didvan/button.dart';
|
import 'package:didvan/views/ai/widgets/hoshan_drawer.dart';
|
||||||
import 'package:didvan/views/widgets/didvan/icon_button.dart';
|
|
||||||
import 'package:didvan/views/widgets/didvan/text.dart';
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||||
|
import 'package:didvan/views/widgets/hoshan_app_bar.dart';
|
||||||
import 'package:didvan/views/widgets/marquee_text.dart';
|
import 'package:didvan/views/widgets/marquee_text.dart';
|
||||||
import 'package:didvan/views/widgets/skeleton_image.dart';
|
import 'package:didvan/views/widgets/skeleton_image.dart';
|
||||||
import 'package:didvan/views/widgets/video/chat_video_player.dart';
|
import 'package:didvan/views/widgets/video/chat_video_player.dart';
|
||||||
|
|
@ -49,7 +48,9 @@ class AiChatPage extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AiChatPageState extends State<AiChatPage> {
|
class _AiChatPageState extends State<AiChatPage> {
|
||||||
|
final GlobalKey<ScaffoldState> scaffKey = GlobalKey<ScaffoldState>();
|
||||||
FocusNode focusNode = FocusNode();
|
FocusNode focusNode = FocusNode();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
final state = context.read<AiChatState>();
|
final state = context.read<AiChatState>();
|
||||||
|
|
@ -101,196 +102,13 @@ class _AiChatPageState extends State<AiChatPage> {
|
||||||
},
|
},
|
||||||
child: Consumer<AiChatState>(
|
child: Consumer<AiChatState>(
|
||||||
builder: (context, state, child) => Scaffold(
|
builder: (context, state, child) => Scaffold(
|
||||||
appBar: AppBar(
|
appBar: HoshanAppBar(
|
||||||
shadowColor: Theme.of(context).colorScheme.border,
|
onBack: () {
|
||||||
title: Text(widget.args.bot.name.toString()),
|
Navigator.pop(context);
|
||||||
leading: Row(
|
},
|
||||||
children: [
|
|
||||||
DidvanIconButton(
|
|
||||||
icon: DidvanIcons.angle_right_solid,
|
|
||||||
onPressed: () {
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
if (context.read<HistoryAiChatState>().refresh) {
|
|
||||||
context.read<HistoryAiChatState>().getChats();
|
|
||||||
context.read<HistoryAiChatState>().refresh = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
actions: [
|
|
||||||
if (state.chatId != null)
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(left: 8.0),
|
|
||||||
child: InkWell(
|
|
||||||
onTap: () {
|
|
||||||
final TextEditingController placeholder =
|
|
||||||
TextEditingController(
|
|
||||||
text: state.chat?.placeholder);
|
|
||||||
ActionSheetUtils(context).openDialog(
|
|
||||||
data: ActionSheetData(
|
|
||||||
hasConfirmButtonClose: false,
|
|
||||||
hasConfirmButton: false,
|
|
||||||
hasDismissButton: false,
|
|
||||||
content: ValueListenableBuilder<bool>(
|
|
||||||
valueListenable: state.changingPlaceHolder,
|
|
||||||
builder: (context, value, child) =>
|
|
||||||
Container(
|
|
||||||
constraints: BoxConstraints(
|
|
||||||
maxHeight: MediaQuery.sizeOf(context)
|
|
||||||
.height /
|
|
||||||
3),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Stack(
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment:
|
|
||||||
MainAxisAlignment
|
|
||||||
.center,
|
|
||||||
children: [
|
|
||||||
DidvanText(
|
|
||||||
'شخصیسازی دستورات',
|
|
||||||
style: Theme.of(
|
|
||||||
context)
|
|
||||||
.textTheme
|
|
||||||
.titleMedium,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Positioned(
|
|
||||||
right: 0,
|
|
||||||
top: 0,
|
|
||||||
bottom: 0,
|
|
||||||
child: Center(
|
|
||||||
child: InkWell(
|
|
||||||
onTap: () {
|
|
||||||
ActionSheetUtils(
|
|
||||||
context)
|
|
||||||
.pop();
|
|
||||||
},
|
|
||||||
child: const Icon(
|
|
||||||
DidvanIcons
|
|
||||||
.close_solid,
|
|
||||||
size: 24,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 12,
|
|
||||||
),
|
|
||||||
const DidvanText(
|
|
||||||
'دوست دارید هوشان چه چیزهایی را درباره شما بداند تا بتواند پاسخهای بهتری ارائه دهد؟ '),
|
|
||||||
const SizedBox(
|
|
||||||
height: 12,
|
|
||||||
),
|
|
||||||
value
|
|
||||||
? Center(
|
|
||||||
child: Image.asset(
|
|
||||||
Assets
|
|
||||||
.loadingAnimation,
|
|
||||||
width: 60,
|
|
||||||
height: 60,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: TextField(
|
|
||||||
controller:
|
|
||||||
placeholder,
|
|
||||||
style: (Theme.of(
|
|
||||||
context)
|
|
||||||
.textTheme
|
|
||||||
.bodyMedium)!
|
|
||||||
.copyWith(
|
|
||||||
fontFamily: DesignConfig
|
|
||||||
.fontFamily
|
|
||||||
.padRight(
|
|
||||||
3)),
|
|
||||||
minLines: 5,
|
|
||||||
maxLines: 5,
|
|
||||||
keyboardType:
|
|
||||||
TextInputType
|
|
||||||
.multiline,
|
|
||||||
decoration:
|
|
||||||
InputDecoration(
|
|
||||||
filled: true,
|
|
||||||
fillColor: Theme.of(
|
|
||||||
context)
|
|
||||||
.colorScheme
|
|
||||||
.secondCTA,
|
|
||||||
contentPadding:
|
|
||||||
const EdgeInsets
|
|
||||||
.fromLTRB(
|
|
||||||
10,
|
|
||||||
18,
|
|
||||||
10,
|
|
||||||
0),
|
|
||||||
border: const OutlineInputBorder(
|
|
||||||
borderRadius:
|
|
||||||
DesignConfig
|
|
||||||
.lowBorderRadius),
|
|
||||||
errorStyle:
|
|
||||||
const TextStyle(
|
|
||||||
height:
|
|
||||||
0.01),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 12,
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: DidvanButton(
|
|
||||||
onPressed: () {
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
},
|
|
||||||
title: 'بازگشت',
|
|
||||||
style:
|
|
||||||
ButtonStyleMode.secondary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 20),
|
|
||||||
Expanded(
|
|
||||||
child: DidvanButton(
|
|
||||||
style:
|
|
||||||
ButtonStyleMode.primary,
|
|
||||||
onPressed: () async {
|
|
||||||
await state
|
|
||||||
.changePlaceHolder(
|
|
||||||
placeholder.text);
|
|
||||||
Future.delayed(
|
|
||||||
Duration.zero,
|
|
||||||
() => ActionSheetUtils(
|
|
||||||
context)
|
|
||||||
.pop(),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
title: 'تایید',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)));
|
|
||||||
},
|
|
||||||
child: const Icon(DidvanIcons.note_regular)),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
centerTitle: true,
|
|
||||||
automaticallyImplyLeading: false,
|
|
||||||
),
|
),
|
||||||
|
key: scaffKey,
|
||||||
|
drawer: const HoshanDrawer(),
|
||||||
body: state.loading
|
body: state.loading
|
||||||
? Center(
|
? Center(
|
||||||
child: Image.asset(
|
child: Image.asset(
|
||||||
|
|
@ -299,85 +117,110 @@ class _AiChatPageState extends State<AiChatPage> {
|
||||||
height: 60,
|
height: 60,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: state.messages.isEmpty
|
: Stack(
|
||||||
? Column(
|
children: [
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
Column(
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(
|
Column(
|
||||||
height: 12,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
),
|
|
||||||
Center(
|
|
||||||
child: Icon(
|
|
||||||
DidvanIcons.ai_solid,
|
|
||||||
size: MediaQuery.sizeOf(context).width / 5,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const DidvanText('هوشان'),
|
|
||||||
const SizedBox(
|
|
||||||
height: 24,
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
children: [
|
||||||
DidvanText(widget.args.bot.name.toString()),
|
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 12,
|
height: 24,
|
||||||
),
|
),
|
||||||
ClipOval(
|
ClipOval(
|
||||||
child: CachedNetworkImage(
|
child: CachedNetworkImage(
|
||||||
width: 46,
|
width: 75,
|
||||||
height: 46,
|
height: 75,
|
||||||
imageUrl: widget.args.bot.image.toString(),
|
imageUrl: widget.args.bot.image.toString(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 12,
|
||||||
|
),
|
||||||
|
DidvanText(
|
||||||
|
widget.args.bot.name.toString(),
|
||||||
|
fontSize: 17,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
if (state.messages.isEmpty)
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
const SizedBox(
|
||||||
|
height: 16,
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 20.0),
|
||||||
|
child: Center(
|
||||||
|
child: DidvanText(
|
||||||
|
widget.args.bot.description ??
|
||||||
|
'')),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(
|
if (state.messages.isNotEmpty)
|
||||||
height: 24,
|
SingleChildScrollView(
|
||||||
),
|
reverse: true,
|
||||||
const Padding(
|
controller: state.scrollController,
|
||||||
padding: EdgeInsets.symmetric(horizontal: 20.0),
|
child: ListView.builder(
|
||||||
child: Text(
|
itemCount: state.messages.length,
|
||||||
"به هوشان؛ هوش مصنوعی دیدوان خوش آمدید. \nبرای شروع گفتگو پیام مورد نظر خود را در کادر زیر بنویسید.",
|
shrinkWrap: true,
|
||||||
textAlign: TextAlign.center,
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
),
|
padding: EdgeInsets.only(
|
||||||
)
|
bottom: state.file != null &&
|
||||||
],
|
!(state.file!.isRecorded)
|
||||||
)
|
? 180
|
||||||
: SingleChildScrollView(
|
: 100),
|
||||||
reverse: true,
|
itemBuilder: (context, mIndex) {
|
||||||
controller: state.scrollController,
|
final prompts =
|
||||||
child: ListView.builder(
|
state.messages[mIndex].prompts;
|
||||||
itemCount: state.messages.length,
|
final time =
|
||||||
shrinkWrap: true,
|
state.messages[mIndex].dateTime;
|
||||||
physics: const NeverScrollableScrollPhysics(),
|
return Column(
|
||||||
padding: EdgeInsets.only(
|
children: [
|
||||||
bottom: state.file != null &&
|
timeLabel(context, time),
|
||||||
!(state.file!.isRecorded)
|
ListView.builder(
|
||||||
? 180
|
itemCount: prompts.length,
|
||||||
: 100),
|
shrinkWrap: true,
|
||||||
itemBuilder: (context, mIndex) {
|
physics:
|
||||||
final prompts = state.messages[mIndex].prompts;
|
const NeverScrollableScrollPhysics(),
|
||||||
final time = state.messages[mIndex].dateTime;
|
itemBuilder: (context, index) {
|
||||||
return Column(
|
final message = prompts[index];
|
||||||
children: [
|
|
||||||
timeLabel(context, time),
|
|
||||||
ListView.builder(
|
|
||||||
itemCount: prompts.length,
|
|
||||||
shrinkWrap: true,
|
|
||||||
physics:
|
|
||||||
const NeverScrollableScrollPhysics(),
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
final message = prompts[index];
|
|
||||||
|
|
||||||
return messageBubble(message, context,
|
return messageBubble(message,
|
||||||
state, index, mIndex);
|
context, state, index, mIndex);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
|
Positioned(
|
||||||
|
top: 32,
|
||||||
|
right: 0,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () => scaffKey.currentState!.openDrawer(),
|
||||||
|
child: Container(
|
||||||
|
width: 46,
|
||||||
|
height: 46,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).colorScheme.surface,
|
||||||
|
borderRadius: const BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(12),
|
||||||
|
bottomLeft: Radius.circular(12)),
|
||||||
|
boxShadow: DesignConfig.defaultShadow),
|
||||||
|
child: Icon(
|
||||||
|
DidvanIcons.angle_left_light,
|
||||||
|
color: Theme.of(context).colorScheme.title,
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
bottomSheet: Column(
|
bottomSheet: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
import 'package:didvan/models/ai/tools_model.dart';
|
||||||
|
import 'package:didvan/providers/core.dart';
|
||||||
|
|
||||||
|
class AiState extends CoreProvier {
|
||||||
|
int page = 0;
|
||||||
|
Tools? tool;
|
||||||
|
|
||||||
|
void goToAi() {
|
||||||
|
page = 0;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void goToTools() {
|
||||||
|
page = 1;
|
||||||
|
tool = null;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void goToToolBox({required final Tools tool}) {
|
||||||
|
page = 2;
|
||||||
|
this.tool = tool;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,119 @@
|
||||||
|
import 'package:didvan/config/design_config.dart';
|
||||||
|
import 'package:didvan/models/ai/ai_chat_args.dart';
|
||||||
|
import 'package:didvan/models/ai/tools_model.dart';
|
||||||
|
import 'package:didvan/routes/routes.dart';
|
||||||
|
import 'package:didvan/views/ai/ai_state.dart';
|
||||||
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||||
|
import 'package:didvan/views/widgets/skeleton_image.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class ToolScreen extends StatefulWidget {
|
||||||
|
const ToolScreen({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<ToolScreen> createState() => _ToolScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ToolScreenState extends State<ToolScreen> {
|
||||||
|
late Tools tool = context.read<AiState>().tool!;
|
||||||
|
|
||||||
|
get itemBuilder => null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SingleChildScrollView(
|
||||||
|
physics: const BouncingScrollPhysics(),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 32),
|
||||||
|
SvgPicture.network(
|
||||||
|
tool.image!,
|
||||||
|
width: 64,
|
||||||
|
height: 64,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 4,
|
||||||
|
),
|
||||||
|
DidvanText(
|
||||||
|
tool.name!,
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: const Color(0xff1B3C59),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 32),
|
||||||
|
child: DidvanText(
|
||||||
|
tool.guide!,
|
||||||
|
fontSize: 12,
|
||||||
|
color: const Color(0xff666666),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 24),
|
||||||
|
GridView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
itemCount: tool.bots!.length,
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 32),
|
||||||
|
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
crossAxisCount: 2,
|
||||||
|
childAspectRatio: 1 / 1,
|
||||||
|
crossAxisSpacing: 18,
|
||||||
|
mainAxisSpacing: 18),
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final bot = tool.bots![index];
|
||||||
|
return InkWell(
|
||||||
|
onTap: () => Navigator.of(context).pushNamed(Routes.aiChat,
|
||||||
|
arguments: AiChatArgs(
|
||||||
|
bot: bot,
|
||||||
|
)),
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.all(12),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: DesignConfig.lowBorderRadius,
|
||||||
|
border: Border.all(color: const Color(0xffbbbbbb))),
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
SkeletonImage(
|
||||||
|
imageUrl: bot.image!,
|
||||||
|
width: 72,
|
||||||
|
height: 72,
|
||||||
|
borderRadius: BorderRadius.circular(360),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 4,
|
||||||
|
),
|
||||||
|
DidvanText(
|
||||||
|
bot.name!,
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: const Color(0xff2A282F),
|
||||||
|
),
|
||||||
|
if (bot.description != null)
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
const SizedBox(
|
||||||
|
height: 4,
|
||||||
|
),
|
||||||
|
DidvanText(
|
||||||
|
bot.description!,
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: const Color(0xffA8A6AC),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,215 @@
|
||||||
|
import 'package:didvan/config/design_config.dart';
|
||||||
|
import 'package:didvan/constants/assets.dart';
|
||||||
|
import 'package:didvan/views/ai/ai_state.dart';
|
||||||
|
import 'package:didvan/views/ai/tools_state.dart';
|
||||||
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||||
|
import 'package:didvan/views/widgets/shimmer_placeholder.dart';
|
||||||
|
import 'package:didvan/views/widgets/state_handlers/empty_state.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class ToolsScreen extends StatefulWidget {
|
||||||
|
const ToolsScreen({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<ToolsScreen> createState() => _ToolsScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ToolsScreenState extends State<ToolsScreen> {
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
context.read<ToolsState>().getTools();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SingleChildScrollView(
|
||||||
|
physics: context.watch<ToolsState>().loading
|
||||||
|
? const NeverScrollableScrollPhysics()
|
||||||
|
: const BouncingScrollPhysics(),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsets.only(top: 46, bottom: 24),
|
||||||
|
child: DidvanText(
|
||||||
|
'انتخاب باتها',
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Color(0xff1B3C59),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Consumer<ToolsState>(
|
||||||
|
builder: (BuildContext context, ToolsState state, Widget? child) {
|
||||||
|
final tools = state.tools;
|
||||||
|
if (tools != null && tools.isEmpty) {
|
||||||
|
return EmptyState(
|
||||||
|
asset: Assets.emptyResult,
|
||||||
|
title: 'لیست خالی است',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (state.loading) {
|
||||||
|
return toolsPlaceHolder();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ListView.builder(
|
||||||
|
itemCount: tools!.length,
|
||||||
|
shrinkWrap: true,
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 24)
|
||||||
|
.copyWith(bottom: 46),
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final tool = tools[index];
|
||||||
|
return InkWell(
|
||||||
|
onTap: () =>
|
||||||
|
context.read<AiState>().goToToolBox(tool: tool),
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: DesignConfig.lowBorderRadius,
|
||||||
|
border: Border.all(
|
||||||
|
color: const Color(0xffB8B8B8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.all(24),
|
||||||
|
margin: const EdgeInsets.symmetric(vertical: 8),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
SvgPicture.network(
|
||||||
|
tool.image!,
|
||||||
|
width: 75,
|
||||||
|
height: 75,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 8,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
DidvanText(
|
||||||
|
tool.name!,
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 8, vertical: 2),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.circular(4),
|
||||||
|
color: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.primary),
|
||||||
|
child: DidvanText(
|
||||||
|
'${tool.bots!.length} مدل',
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
DidvanText(
|
||||||
|
'${tool.bots!.map(
|
||||||
|
(e) => e.name!,
|
||||||
|
)}'
|
||||||
|
.replaceAll('(', '')
|
||||||
|
.replaceAll(')', ''),
|
||||||
|
fontSize: 12,
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
DidvanText(tool.description!,
|
||||||
|
fontSize: 12, color: const Color(0xffA8A6AC))
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView toolsPlaceHolder() {
|
||||||
|
return ListView.builder(
|
||||||
|
itemCount: 10,
|
||||||
|
shrinkWrap: true,
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 24),
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: DesignConfig.lowBorderRadius,
|
||||||
|
border: Border.all(
|
||||||
|
color: const Color(0xffB8B8B8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.all(24),
|
||||||
|
margin: const EdgeInsets.symmetric(vertical: 8),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
ShimmerPlaceholder(
|
||||||
|
width: 75,
|
||||||
|
height: 75,
|
||||||
|
borderRadius: BorderRadius.circular(360),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 8,
|
||||||
|
),
|
||||||
|
const Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
ShimmerPlaceholder(
|
||||||
|
width: 120,
|
||||||
|
height: 24,
|
||||||
|
borderRadius: DesignConfig.mediumBorderRadius,
|
||||||
|
),
|
||||||
|
ShimmerPlaceholder(
|
||||||
|
width: 60,
|
||||||
|
height: 24,
|
||||||
|
borderRadius: DesignConfig.mediumBorderRadius,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 8,
|
||||||
|
),
|
||||||
|
ShimmerPlaceholder(
|
||||||
|
width: 120,
|
||||||
|
height: 24,
|
||||||
|
borderRadius: DesignConfig.mediumBorderRadius,
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 8,
|
||||||
|
),
|
||||||
|
ShimmerPlaceholder(
|
||||||
|
width: 240,
|
||||||
|
height: 46,
|
||||||
|
borderRadius: DesignConfig.mediumBorderRadius,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
import 'package:didvan/models/ai/tools_model.dart';
|
||||||
|
import 'package:didvan/models/enums.dart';
|
||||||
|
import 'package:didvan/providers/core.dart';
|
||||||
|
import 'package:didvan/services/network/request.dart';
|
||||||
|
import 'package:didvan/services/network/request_helper.dart';
|
||||||
|
|
||||||
|
class ToolsState extends CoreProvier {
|
||||||
|
bool loading = true;
|
||||||
|
List<Tools>? tools;
|
||||||
|
|
||||||
|
void getTools() async {
|
||||||
|
final service = RequestService(
|
||||||
|
RequestHelper.tools(),
|
||||||
|
);
|
||||||
|
await service.httpGet();
|
||||||
|
if (service.isSuccess) {
|
||||||
|
final ToolsModel toolsModel = ToolsModel.fromJson(service.result);
|
||||||
|
tools = toolsModel.tools!;
|
||||||
|
tools ??= [];
|
||||||
|
appState = AppState.idle;
|
||||||
|
loading = false;
|
||||||
|
update();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
appState = AppState.failed;
|
||||||
|
loading = false;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,475 @@
|
||||||
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
|
import 'package:didvan/config/theme_data.dart';
|
||||||
|
import 'package:didvan/constants/app_icons.dart';
|
||||||
|
import 'package:didvan/constants/assets.dart';
|
||||||
|
import 'package:didvan/main.dart';
|
||||||
|
import 'package:didvan/models/ai/ai_chat_args.dart';
|
||||||
|
import 'package:didvan/models/ai/chats_model.dart';
|
||||||
|
import 'package:didvan/models/enums.dart';
|
||||||
|
import 'package:didvan/models/view/action_sheet_data.dart';
|
||||||
|
import 'package:didvan/models/view/alert_data.dart';
|
||||||
|
import 'package:didvan/routes/routes.dart';
|
||||||
|
import 'package:didvan/utils/action_sheet.dart';
|
||||||
|
import 'package:didvan/views/ai/history_ai_chat_state.dart';
|
||||||
|
import 'package:didvan/views/home/home.dart';
|
||||||
|
import 'package:didvan/views/widgets/didvan/divider.dart';
|
||||||
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||||
|
import 'package:didvan/views/widgets/shimmer_placeholder.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class HoshanDrawer extends StatefulWidget {
|
||||||
|
const HoshanDrawer({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<HoshanDrawer> createState() => _HoshanDrawerState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _HoshanDrawerState extends State<HoshanDrawer> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Drawer(
|
||||||
|
child: Consumer<HistoryAiChatState>(
|
||||||
|
builder: (context, state, child) {
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
const SizedBox(
|
||||||
|
height: 8,
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 20.0, top: 8),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
InkWell(
|
||||||
|
onTap: () => homeScaffKey.currentState!.closeDrawer(),
|
||||||
|
child: const Icon(
|
||||||
|
DidvanIcons.close_regular,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Icon(
|
||||||
|
DidvanIcons.ai_solid,
|
||||||
|
size: MediaQuery.sizeOf(context).width / 5,
|
||||||
|
color: Theme.of(context).colorScheme.title,
|
||||||
|
),
|
||||||
|
DidvanText(
|
||||||
|
'هوشان',
|
||||||
|
color: Theme.of(context).colorScheme.title,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 24,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
drawerBtn(
|
||||||
|
icon: Icons.handshake_rounded,
|
||||||
|
text: 'ساخت دستیار شخصی',
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
enable: false),
|
||||||
|
const DidvanDivider(),
|
||||||
|
drawerBtn(
|
||||||
|
icon: CupertinoIcons.doc_text_search,
|
||||||
|
text: 'جستجو در مدلها',
|
||||||
|
click: () {
|
||||||
|
ActionSheetUtils(context).botsDialogSelect(
|
||||||
|
context: context, state: state);
|
||||||
|
homeScaffKey.currentState!.closeDrawer();
|
||||||
|
},
|
||||||
|
enable: false),
|
||||||
|
const DidvanDivider(),
|
||||||
|
drawerBtn(
|
||||||
|
icon: DidvanIcons.chats_regular,
|
||||||
|
text: 'تاریخچه همه گفتگوها',
|
||||||
|
label: 'حذف همه',
|
||||||
|
click: () {
|
||||||
|
Navigator.of(context)
|
||||||
|
.pushNamed(Routes.aiHistory);
|
||||||
|
},
|
||||||
|
labelClick: state.chats.isEmpty
|
||||||
|
? null
|
||||||
|
: () async {
|
||||||
|
await ActionSheetUtils(context)
|
||||||
|
.openDialog(
|
||||||
|
data: ActionSheetData(
|
||||||
|
onConfirmed: () async {
|
||||||
|
await state.deleteAllChat(
|
||||||
|
refresh: false);
|
||||||
|
},
|
||||||
|
content: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
crossAxisAlignment:
|
||||||
|
CrossAxisAlignment
|
||||||
|
.center,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
DidvanIcons
|
||||||
|
.trash_solid,
|
||||||
|
color: Theme.of(
|
||||||
|
context)
|
||||||
|
.colorScheme
|
||||||
|
.error,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 8,
|
||||||
|
),
|
||||||
|
DidvanText(
|
||||||
|
'پاک کردن همه گفتوگوها',
|
||||||
|
color: Theme.of(
|
||||||
|
context)
|
||||||
|
.colorScheme
|
||||||
|
.error,
|
||||||
|
fontSize: 20,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 12,
|
||||||
|
),
|
||||||
|
const DidvanText(
|
||||||
|
'آیا از پاک کردن تمامی گفتوگوهای انجام شده با هوشان اطمینان دارید؟'),
|
||||||
|
],
|
||||||
|
)));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 12,
|
||||||
|
),
|
||||||
|
// SearchField(
|
||||||
|
// title: 'title',
|
||||||
|
// onChanged: (value) {},
|
||||||
|
// focusNode: FocusNode()),
|
||||||
|
// SizedBox(
|
||||||
|
// height: 12,
|
||||||
|
// ),
|
||||||
|
Expanded(
|
||||||
|
child: state.loadingdeleteAll ||
|
||||||
|
state.appState == AppState.busy
|
||||||
|
? ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
itemCount: 10,
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 12),
|
||||||
|
physics:
|
||||||
|
const NeverScrollableScrollPhysics(),
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return const Padding(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: 12.0),
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment:
|
||||||
|
CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
ClipOval(
|
||||||
|
child: ShimmerPlaceholder(
|
||||||
|
height: 24,
|
||||||
|
width: 24,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 12),
|
||||||
|
Expanded(
|
||||||
|
child: ShimmerPlaceholder(
|
||||||
|
height: 24,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 12),
|
||||||
|
ShimmerPlaceholder(
|
||||||
|
height: 24,
|
||||||
|
width: 24,
|
||||||
|
),
|
||||||
|
SizedBox(width: 8),
|
||||||
|
ShimmerPlaceholder(
|
||||||
|
height: 24,
|
||||||
|
width: 12,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
: state.chats.isEmpty
|
||||||
|
? Padding(
|
||||||
|
padding: const EdgeInsets.all(12.0),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
SvgPicture.asset(
|
||||||
|
Assets.emptyResult,
|
||||||
|
height:
|
||||||
|
MediaQuery.sizeOf(context)
|
||||||
|
.height /
|
||||||
|
10,
|
||||||
|
),
|
||||||
|
const DidvanText(
|
||||||
|
'لیست خالی است',
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
itemCount: state.chats.length,
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 12),
|
||||||
|
physics:
|
||||||
|
const BouncingScrollPhysics(),
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final chat = state.chats[index];
|
||||||
|
TextEditingController title =
|
||||||
|
TextEditingController(
|
||||||
|
text: chat.title);
|
||||||
|
|
||||||
|
return chatRow(
|
||||||
|
chat, title, state, index);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// SizedBox(
|
||||||
|
// height: 12,
|
||||||
|
// ),
|
||||||
|
// Text('نمایش قدیمیترها')
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
const DidvanDivider(),
|
||||||
|
drawerBtn(
|
||||||
|
icon: Icons.folder_copy_outlined,
|
||||||
|
text: 'گفتوگوهای آرشیو شده',
|
||||||
|
click: () {
|
||||||
|
Navigator.of(context)
|
||||||
|
.pushNamed(Routes.aiHistory, arguments: true);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 12,
|
||||||
|
),
|
||||||
|
drawerBtn(
|
||||||
|
icon: DidvanIcons.support_regular,
|
||||||
|
text: 'پیام به پشتیبانی',
|
||||||
|
click: () {
|
||||||
|
Navigator.of(context).pushNamed(
|
||||||
|
Routes.direct,
|
||||||
|
arguments: {'type': 'پشتیبانی اپلیکیشن'},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 32,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget drawerBtn(
|
||||||
|
{final CrossAxisAlignment? crossAxisAlignment,
|
||||||
|
required final IconData icon,
|
||||||
|
required final String text,
|
||||||
|
final bool enable = true,
|
||||||
|
final String? label,
|
||||||
|
final Function()? labelClick,
|
||||||
|
final Function()? click}) {
|
||||||
|
return InkWell(
|
||||||
|
onTap: enable
|
||||||
|
? click
|
||||||
|
: () {
|
||||||
|
ActionSheetUtils(context).showAlert(
|
||||||
|
AlertData(message: 'درحال توسعه', aLertType: ALertType.info));
|
||||||
|
},
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 12.0),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
crossAxisAlignment:
|
||||||
|
crossAxisAlignment ?? CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
icon,
|
||||||
|
color: enable
|
||||||
|
? Theme.of(context).colorScheme.title
|
||||||
|
: Theme.of(context).colorScheme.disabledText,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 8,
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
DidvanText(text,
|
||||||
|
fontSize: 16,
|
||||||
|
color: enable
|
||||||
|
? Theme.of(context).colorScheme.title
|
||||||
|
: Theme.of(context).colorScheme.disabledText),
|
||||||
|
// if (!enable) Text('در حال توسعه ...')
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (label != null)
|
||||||
|
InkWell(
|
||||||
|
onTap: labelClick,
|
||||||
|
child: DidvanText(
|
||||||
|
label,
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
fontSize: 12,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Padding chatRow(ChatsModel chat, TextEditingController title,
|
||||||
|
HistoryAiChatState state, int index) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
navigatorKey.currentState!.pushNamed(Routes.aiChat,
|
||||||
|
arguments: AiChatArgs(bot: chat.bot!, chat: chat));
|
||||||
|
},
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
ClipOval(
|
||||||
|
child: CachedNetworkImage(
|
||||||
|
imageUrl: chat.bot!.image.toString(),
|
||||||
|
width: 24,
|
||||||
|
height: 24,
|
||||||
|
)),
|
||||||
|
const SizedBox(
|
||||||
|
width: 12,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
chat.title.toString(),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
maxLines: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 24,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
InkWell(
|
||||||
|
onTap: () async {
|
||||||
|
ActionSheetUtils(context).openDialog(
|
||||||
|
data: ActionSheetData(
|
||||||
|
content: Center(
|
||||||
|
child: TextFormField(
|
||||||
|
controller: title,
|
||||||
|
style: const TextStyle(fontSize: 12),
|
||||||
|
textAlignVertical: TextAlignVertical.bottom,
|
||||||
|
maxLines: 3,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
isDense: true,
|
||||||
|
contentPadding: EdgeInsets.symmetric(
|
||||||
|
vertical: 5, horizontal: 10),
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
title: 'تغییر نام',
|
||||||
|
onConfirmed: () async {
|
||||||
|
if (title.text.isNotEmpty) {
|
||||||
|
await state.changeNameChat(
|
||||||
|
chat.id!, index, title.text,
|
||||||
|
refresh: false);
|
||||||
|
title.clear();
|
||||||
|
}
|
||||||
|
if (chat.isEditing != null) {
|
||||||
|
chat.isEditing = !chat.isEditing!;
|
||||||
|
state.update();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
state.update();
|
||||||
|
},
|
||||||
|
));
|
||||||
|
},
|
||||||
|
child: const Padding(
|
||||||
|
padding: EdgeInsets.all(8.0),
|
||||||
|
child: Icon(
|
||||||
|
Icons.edit_outlined,
|
||||||
|
size: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 4,
|
||||||
|
),
|
||||||
|
PopupMenuButton(
|
||||||
|
onSelected: (value) async {
|
||||||
|
switch (value) {
|
||||||
|
case 'حذف پیام':
|
||||||
|
await state.deleteChat(chat.id!, index, refresh: false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'آرشیو':
|
||||||
|
await state.archivedChat(chat.id!, index,
|
||||||
|
refresh: false);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
state.update();
|
||||||
|
},
|
||||||
|
itemBuilder: (BuildContext context) {
|
||||||
|
return <PopupMenuEntry>[
|
||||||
|
ActionSheetUtils.popUpBtns(
|
||||||
|
value: 'حذف پیام',
|
||||||
|
icon: DidvanIcons.trash_regular,
|
||||||
|
color: Theme.of(context).colorScheme.error,
|
||||||
|
height: 32,
|
||||||
|
size: 16),
|
||||||
|
ActionSheetUtils.popUpBtns(
|
||||||
|
value: 'آرشیو',
|
||||||
|
icon: Icons.folder_copy,
|
||||||
|
height: 32,
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
},
|
||||||
|
offset: const Offset(0, 0),
|
||||||
|
position: PopupMenuPosition.under,
|
||||||
|
useRootNavigator: true,
|
||||||
|
child: const Padding(
|
||||||
|
padding: EdgeInsets.all(8.0),
|
||||||
|
child: Icon(
|
||||||
|
Icons.more_vert,
|
||||||
|
size: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,40 +1,33 @@
|
||||||
// ignore_for_file: deprecated_member_use
|
// ignore_for_file: deprecated_member_use
|
||||||
|
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
|
||||||
import 'package:didvan/config/design_config.dart';
|
import 'package:didvan/config/design_config.dart';
|
||||||
import 'package:didvan/config/theme_data.dart';
|
import 'package:didvan/config/theme_data.dart';
|
||||||
import 'package:didvan/constants/app_icons.dart';
|
import 'package:didvan/constants/app_icons.dart';
|
||||||
import 'package:didvan/constants/assets.dart';
|
|
||||||
import 'package:didvan/main.dart';
|
import 'package:didvan/main.dart';
|
||||||
import 'package:didvan/models/ai/ai_chat_args.dart';
|
|
||||||
import 'package:didvan/models/ai/chats_model.dart';
|
|
||||||
import 'package:didvan/models/enums.dart';
|
|
||||||
import 'package:didvan/models/notification_message.dart';
|
import 'package:didvan/models/notification_message.dart';
|
||||||
import 'package:didvan/models/view/action_sheet_data.dart';
|
import 'package:didvan/models/view/action_sheet_data.dart';
|
||||||
import 'package:didvan/models/view/alert_data.dart';
|
|
||||||
import 'package:didvan/providers/theme.dart';
|
import 'package:didvan/providers/theme.dart';
|
||||||
import 'package:didvan/routes/routes.dart';
|
import 'package:didvan/routes/routes.dart';
|
||||||
import 'package:didvan/services/app_initalizer.dart';
|
import 'package:didvan/services/app_initalizer.dart';
|
||||||
import 'package:didvan/services/notification/notification_service.dart';
|
import 'package:didvan/services/notification/notification_service.dart';
|
||||||
import 'package:didvan/utils/action_sheet.dart';
|
import 'package:didvan/utils/action_sheet.dart';
|
||||||
import 'package:didvan/views/ai/ai.dart';
|
import 'package:didvan/views/ai/ai.dart';
|
||||||
|
import 'package:didvan/views/ai/ai_state.dart';
|
||||||
import 'package:didvan/views/ai/history_ai_chat_state.dart';
|
import 'package:didvan/views/ai/history_ai_chat_state.dart';
|
||||||
|
import 'package:didvan/views/ai/widgets/hoshan_drawer.dart';
|
||||||
import 'package:didvan/views/home/categories/categories_page.dart';
|
import 'package:didvan/views/home/categories/categories_page.dart';
|
||||||
import 'package:didvan/views/home/main/main_page.dart';
|
import 'package:didvan/views/home/main/main_page.dart';
|
||||||
import 'package:didvan/views/home/home_state.dart';
|
import 'package:didvan/views/home/home_state.dart';
|
||||||
import 'package:didvan/views/home/new_statistic/new_statistic.dart';
|
import 'package:didvan/views/home/new_statistic/new_statistic.dart';
|
||||||
import 'package:didvan/views/home/search/search.dart';
|
import 'package:didvan/views/home/search/search.dart';
|
||||||
import 'package:didvan/views/widgets/didvan/divider.dart';
|
|
||||||
import 'package:didvan/views/widgets/didvan/text.dart';
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||||
|
import 'package:didvan/views/widgets/hoshan_app_bar.dart';
|
||||||
import 'package:didvan/views/widgets/ink_wrapper.dart';
|
import 'package:didvan/views/widgets/ink_wrapper.dart';
|
||||||
import 'package:didvan/views/widgets/logo_app_bar.dart';
|
import 'package:didvan/views/widgets/logo_app_bar.dart';
|
||||||
import 'package:didvan/views/widgets/didvan/bnb.dart';
|
import 'package:didvan/views/widgets/didvan/bnb.dart';
|
||||||
import 'package:didvan/views/widgets/shimmer_placeholder.dart';
|
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import '../../services/app_home_widget/home_widget_repository.dart';
|
import '../../services/app_home_widget/home_widget_repository.dart';
|
||||||
|
|
||||||
|
|
@ -172,290 +165,32 @@ class _HomeState extends State<Home>
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PreferredSizeWidget getAppBar() {
|
||||||
|
PreferredSizeWidget result = const LogoAppBar();
|
||||||
|
if (context.watch<HomeState>().tabController.index == 2) {
|
||||||
|
result = HoshanAppBar(
|
||||||
|
onBack: () {
|
||||||
|
final state = context.read<AiState>();
|
||||||
|
if (state.page == 1) {
|
||||||
|
state.goToAi();
|
||||||
|
} else {
|
||||||
|
state.goToTools();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
key: homeScaffKey,
|
key: homeScaffKey,
|
||||||
appBar: LogoAppBar(
|
appBar: getAppBar(),
|
||||||
canSearch: context.watch<HomeState>().tabController.index != 2,
|
|
||||||
),
|
|
||||||
resizeToAvoidBottomInset: false,
|
resizeToAvoidBottomInset: false,
|
||||||
drawer: context.watch<HomeState>().tabController.index == 2
|
drawer: context.watch<HomeState>().tabController.index == 2
|
||||||
? Drawer(
|
? const HoshanDrawer()
|
||||||
child: Consumer<HistoryAiChatState>(
|
|
||||||
builder: (context, state, child) {
|
|
||||||
return Column(
|
|
||||||
children: [
|
|
||||||
const SizedBox(
|
|
||||||
height: 8,
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(left: 20.0, top: 8),
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
|
||||||
children: [
|
|
||||||
InkWell(
|
|
||||||
onTap: () =>
|
|
||||||
homeScaffKey.currentState!.closeDrawer(),
|
|
||||||
child: const Icon(
|
|
||||||
DidvanIcons.close_regular,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Icon(
|
|
||||||
DidvanIcons.ai_solid,
|
|
||||||
size: MediaQuery.sizeOf(context).width / 5,
|
|
||||||
color: Theme.of(context).colorScheme.title,
|
|
||||||
),
|
|
||||||
DidvanText(
|
|
||||||
'هوشان',
|
|
||||||
color: Theme.of(context).colorScheme.title,
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 24,
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 20.0),
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
drawerBtn(
|
|
||||||
icon: Icons.handshake_rounded,
|
|
||||||
text: 'ساخت دستیار شخصی',
|
|
||||||
crossAxisAlignment:
|
|
||||||
CrossAxisAlignment.start,
|
|
||||||
enable: false),
|
|
||||||
const DidvanDivider(),
|
|
||||||
drawerBtn(
|
|
||||||
icon: CupertinoIcons.doc_text_search,
|
|
||||||
text: 'جستجو در مدلها',
|
|
||||||
click: () {
|
|
||||||
ActionSheetUtils(context)
|
|
||||||
.botsDialogSelect(
|
|
||||||
context: context,
|
|
||||||
state: state);
|
|
||||||
homeScaffKey.currentState!
|
|
||||||
.closeDrawer();
|
|
||||||
},
|
|
||||||
enable: false),
|
|
||||||
const DidvanDivider(),
|
|
||||||
drawerBtn(
|
|
||||||
icon: DidvanIcons.chats_regular,
|
|
||||||
text: 'تاریخچه همه گفتگوها',
|
|
||||||
label: 'حذف همه',
|
|
||||||
click: () {
|
|
||||||
Navigator.of(context)
|
|
||||||
.pushNamed(Routes.aiHistory);
|
|
||||||
},
|
|
||||||
labelClick: state.chats.isEmpty
|
|
||||||
? null
|
|
||||||
: () async {
|
|
||||||
await ActionSheetUtils(context)
|
|
||||||
.openDialog(
|
|
||||||
data: ActionSheetData(
|
|
||||||
onConfirmed:
|
|
||||||
() async {
|
|
||||||
await state
|
|
||||||
.deleteAllChat(
|
|
||||||
refresh:
|
|
||||||
false);
|
|
||||||
},
|
|
||||||
content: Column(
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
crossAxisAlignment:
|
|
||||||
CrossAxisAlignment
|
|
||||||
.center,
|
|
||||||
children: [
|
|
||||||
Icon(
|
|
||||||
DidvanIcons
|
|
||||||
.trash_solid,
|
|
||||||
color: Theme.of(
|
|
||||||
context)
|
|
||||||
.colorScheme
|
|
||||||
.error,
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
width: 8,
|
|
||||||
),
|
|
||||||
DidvanText(
|
|
||||||
'پاک کردن همه گفتوگوها',
|
|
||||||
color: Theme.of(
|
|
||||||
context)
|
|
||||||
.colorScheme
|
|
||||||
.error,
|
|
||||||
fontSize:
|
|
||||||
20,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 12,
|
|
||||||
),
|
|
||||||
const DidvanText(
|
|
||||||
'آیا از پاک کردن تمامی گفتوگوهای انجام شده با هوشان اطمینان دارید؟'),
|
|
||||||
],
|
|
||||||
)));
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 12,
|
|
||||||
),
|
|
||||||
// SearchField(
|
|
||||||
// title: 'title',
|
|
||||||
// onChanged: (value) {},
|
|
||||||
// focusNode: FocusNode()),
|
|
||||||
// SizedBox(
|
|
||||||
// height: 12,
|
|
||||||
// ),
|
|
||||||
Expanded(
|
|
||||||
child: state.loadingdeleteAll ||
|
|
||||||
state.appState == AppState.busy
|
|
||||||
? ListView.builder(
|
|
||||||
shrinkWrap: true,
|
|
||||||
itemCount: 10,
|
|
||||||
padding:
|
|
||||||
const EdgeInsets.symmetric(
|
|
||||||
horizontal: 12),
|
|
||||||
physics:
|
|
||||||
const NeverScrollableScrollPhysics(),
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
return const Padding(
|
|
||||||
padding: EdgeInsets.symmetric(
|
|
||||||
vertical: 12.0),
|
|
||||||
child: Row(
|
|
||||||
crossAxisAlignment:
|
|
||||||
CrossAxisAlignment
|
|
||||||
.start,
|
|
||||||
children: [
|
|
||||||
ClipOval(
|
|
||||||
child:
|
|
||||||
ShimmerPlaceholder(
|
|
||||||
height: 24,
|
|
||||||
width: 24,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(width: 12),
|
|
||||||
Expanded(
|
|
||||||
child:
|
|
||||||
ShimmerPlaceholder(
|
|
||||||
height: 24,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(width: 12),
|
|
||||||
ShimmerPlaceholder(
|
|
||||||
height: 24,
|
|
||||||
width: 24,
|
|
||||||
),
|
|
||||||
SizedBox(width: 8),
|
|
||||||
ShimmerPlaceholder(
|
|
||||||
height: 24,
|
|
||||||
width: 12,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
)
|
|
||||||
: state.chats.isEmpty
|
|
||||||
? Padding(
|
|
||||||
padding: const EdgeInsets.all(
|
|
||||||
12.0),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
SvgPicture.asset(
|
|
||||||
Assets.emptyResult,
|
|
||||||
height:
|
|
||||||
MediaQuery.sizeOf(
|
|
||||||
context)
|
|
||||||
.height /
|
|
||||||
10,
|
|
||||||
),
|
|
||||||
const DidvanText(
|
|
||||||
'لیست خالی است',
|
|
||||||
fontSize: 14,
|
|
||||||
fontWeight:
|
|
||||||
FontWeight.bold,
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: ListView.builder(
|
|
||||||
shrinkWrap: true,
|
|
||||||
itemCount: state.chats.length,
|
|
||||||
padding: const EdgeInsets
|
|
||||||
.symmetric(
|
|
||||||
horizontal: 12),
|
|
||||||
physics:
|
|
||||||
const BouncingScrollPhysics(),
|
|
||||||
itemBuilder:
|
|
||||||
(context, index) {
|
|
||||||
final chat =
|
|
||||||
state.chats[index];
|
|
||||||
TextEditingController
|
|
||||||
title =
|
|
||||||
TextEditingController(
|
|
||||||
text: chat.title);
|
|
||||||
|
|
||||||
return chatRow(chat, title,
|
|
||||||
state, index);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
// SizedBox(
|
|
||||||
// height: 12,
|
|
||||||
// ),
|
|
||||||
// Text('نمایش قدیمیترها')
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Column(
|
|
||||||
children: [
|
|
||||||
const DidvanDivider(),
|
|
||||||
drawerBtn(
|
|
||||||
icon: Icons.folder_copy_outlined,
|
|
||||||
text: 'گفتوگوهای آرشیو شده',
|
|
||||||
click: () {
|
|
||||||
Navigator.of(context).pushNamed(
|
|
||||||
Routes.aiHistory,
|
|
||||||
arguments: true);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 12,
|
|
||||||
),
|
|
||||||
drawerBtn(
|
|
||||||
icon: DidvanIcons.support_regular,
|
|
||||||
text: 'پیام به پشتیبانی',
|
|
||||||
click: () {
|
|
||||||
Navigator.of(context).pushNamed(
|
|
||||||
Routes.direct,
|
|
||||||
arguments: {
|
|
||||||
'type': 'پشتیبانی اپلیکیشن'
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 32,
|
|
||||||
)
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: null,
|
: null,
|
||||||
body: WillPopScope(
|
body: WillPopScope(
|
||||||
onWillPop: () async {
|
onWillPop: () async {
|
||||||
|
|
@ -519,193 +254,4 @@ class _HomeState extends State<Home>
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Padding chatRow(ChatsModel chat, TextEditingController title,
|
|
||||||
HistoryAiChatState state, int index) {
|
|
||||||
return Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
|
||||||
child: InkWell(
|
|
||||||
onTap: () {
|
|
||||||
navigatorKey.currentState!.pushNamed(Routes.aiChat,
|
|
||||||
arguments: AiChatArgs(bot: chat.bot!, chat: chat));
|
|
||||||
},
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
ClipOval(
|
|
||||||
child: CachedNetworkImage(
|
|
||||||
imageUrl: chat.bot!.image.toString(),
|
|
||||||
width: 24,
|
|
||||||
height: 24,
|
|
||||||
)),
|
|
||||||
const SizedBox(
|
|
||||||
width: 12,
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
chat.title.toString(),
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
maxLines: 1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
width: 24,
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
InkWell(
|
|
||||||
onTap: () async {
|
|
||||||
ActionSheetUtils(context).openDialog(
|
|
||||||
data: ActionSheetData(
|
|
||||||
content: Center(
|
|
||||||
child: TextFormField(
|
|
||||||
controller: title,
|
|
||||||
style: const TextStyle(fontSize: 12),
|
|
||||||
textAlignVertical: TextAlignVertical.bottom,
|
|
||||||
maxLines: 3,
|
|
||||||
decoration: const InputDecoration(
|
|
||||||
isDense: true,
|
|
||||||
contentPadding: EdgeInsets.symmetric(
|
|
||||||
vertical: 5, horizontal: 10),
|
|
||||||
border: OutlineInputBorder(),
|
|
||||||
)),
|
|
||||||
),
|
|
||||||
title: 'تغییر نام',
|
|
||||||
onConfirmed: () async {
|
|
||||||
if (title.text.isNotEmpty) {
|
|
||||||
await state.changeNameChat(
|
|
||||||
chat.id!, index, title.text,
|
|
||||||
refresh: false);
|
|
||||||
title.clear();
|
|
||||||
}
|
|
||||||
if (chat.isEditing != null) {
|
|
||||||
chat.isEditing = !chat.isEditing!;
|
|
||||||
state.update();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
state.update();
|
|
||||||
},
|
|
||||||
));
|
|
||||||
},
|
|
||||||
child: const Padding(
|
|
||||||
padding: EdgeInsets.all(8.0),
|
|
||||||
child: Icon(
|
|
||||||
Icons.edit_outlined,
|
|
||||||
size: 20,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
width: 4,
|
|
||||||
),
|
|
||||||
PopupMenuButton(
|
|
||||||
onSelected: (value) async {
|
|
||||||
switch (value) {
|
|
||||||
case 'حذف پیام':
|
|
||||||
await state.deleteChat(chat.id!, index, refresh: false);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'آرشیو':
|
|
||||||
await state.archivedChat(chat.id!, index,
|
|
||||||
refresh: false);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
|
|
||||||
state.update();
|
|
||||||
},
|
|
||||||
itemBuilder: (BuildContext context) {
|
|
||||||
return <PopupMenuEntry>[
|
|
||||||
ActionSheetUtils.popUpBtns(
|
|
||||||
value: 'حذف پیام',
|
|
||||||
icon: DidvanIcons.trash_regular,
|
|
||||||
color: Theme.of(context).colorScheme.error,
|
|
||||||
height: 32,
|
|
||||||
size: 16),
|
|
||||||
ActionSheetUtils.popUpBtns(
|
|
||||||
value: 'آرشیو',
|
|
||||||
icon: Icons.folder_copy,
|
|
||||||
height: 32,
|
|
||||||
size: 16,
|
|
||||||
),
|
|
||||||
];
|
|
||||||
},
|
|
||||||
offset: const Offset(0, 0),
|
|
||||||
position: PopupMenuPosition.under,
|
|
||||||
useRootNavigator: true,
|
|
||||||
child: const Padding(
|
|
||||||
padding: EdgeInsets.all(8.0),
|
|
||||||
child: Icon(
|
|
||||||
Icons.more_vert,
|
|
||||||
size: 20,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget drawerBtn(
|
|
||||||
{final CrossAxisAlignment? crossAxisAlignment,
|
|
||||||
required final IconData icon,
|
|
||||||
required final String text,
|
|
||||||
final bool enable = true,
|
|
||||||
final String? label,
|
|
||||||
final Function()? labelClick,
|
|
||||||
final Function()? click}) {
|
|
||||||
return InkWell(
|
|
||||||
onTap: enable
|
|
||||||
? click
|
|
||||||
: () {
|
|
||||||
ActionSheetUtils(context).showAlert(
|
|
||||||
AlertData(message: 'درحال توسعه', aLertType: ALertType.info));
|
|
||||||
},
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12.0),
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
crossAxisAlignment:
|
|
||||||
crossAxisAlignment ?? CrossAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Icon(
|
|
||||||
icon,
|
|
||||||
color: enable
|
|
||||||
? Theme.of(context).colorScheme.title
|
|
||||||
: Theme.of(context).colorScheme.disabledText,
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
width: 8,
|
|
||||||
),
|
|
||||||
Column(
|
|
||||||
children: [
|
|
||||||
DidvanText(text,
|
|
||||||
fontSize: 16,
|
|
||||||
color: enable
|
|
||||||
? Theme.of(context).colorScheme.title
|
|
||||||
: Theme.of(context).colorScheme.disabledText),
|
|
||||||
// if (!enable) Text('در حال توسعه ...')
|
|
||||||
],
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
if (label != null)
|
|
||||||
InkWell(
|
|
||||||
onTap: labelClick,
|
|
||||||
child: DidvanText(
|
|
||||||
label,
|
|
||||||
color: Theme.of(context).colorScheme.primary,
|
|
||||||
fontSize: 12,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:didvan/constants/app_icons.dart';
|
||||||
|
import 'package:didvan/constants/assets.dart';
|
||||||
|
import 'package:didvan/views/ai/ai_state.dart';
|
||||||
|
import 'package:didvan/views/widgets/didvan/icon_button.dart';
|
||||||
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class HoshanAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||||
|
final Function()? onBack;
|
||||||
|
const HoshanAppBar({Key? key, this.onBack}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: const BorderRadius.only(
|
||||||
|
bottomLeft: Radius.circular(20),
|
||||||
|
bottomRight: Radius.circular(20)),
|
||||||
|
color: Theme.of(context).colorScheme.surface,
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: const Color(0XFF1B3C59).withOpacity(0.15),
|
||||||
|
blurRadius: 8,
|
||||||
|
spreadRadius: 0,
|
||||||
|
offset: const Offset(0, 8),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
const Row(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
DidvanIcons.ai_solid,
|
||||||
|
size: 40,
|
||||||
|
),
|
||||||
|
DidvanText(
|
||||||
|
'هوشان',
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
DidvanIconButton(
|
||||||
|
icon: DidvanIcons.info_circle_light,
|
||||||
|
size: 32,
|
||||||
|
onPressed: () {}),
|
||||||
|
DidvanIconButton(
|
||||||
|
icon: DidvanIcons.antenna_light,
|
||||||
|
size: 32,
|
||||||
|
onPressed: () {},
|
||||||
|
),
|
||||||
|
context.watch<AiState>().page != 0
|
||||||
|
? Transform.rotate(
|
||||||
|
angle: 180 * pi / 180,
|
||||||
|
child: DidvanIconButton(
|
||||||
|
icon: DidvanIcons.back_light,
|
||||||
|
size: 32,
|
||||||
|
onPressed: () => onBack?.call(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
context.read<AiState>().goToTools();
|
||||||
|
},
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 8.0),
|
||||||
|
child: Image.asset(
|
||||||
|
Assets.boxAnimation,
|
||||||
|
width: 38,
|
||||||
|
height: 38,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Size get preferredSize => const Size(double.infinity, 144);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue