didvan-app/lib/views/ai/widgets/hoshan_drawer.dart

463 lines
20 KiB
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:didvan/views/widgets/skeleton_image.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: [
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,
assistantsName: chat.assistantsName));
},
child: Row(
children: [
SkeletonImage(
imageUrl: chat.bot!.image.toString(),
width: 24,
height: 24,
borderRadius: BorderRadius.circular(360),
),
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,
),
),
),
],
)
],
),
),
);
}
}