// ignore_for_file: library_private_types_in_public_api, deprecated_member_use import 'dart:async'; 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/view/action_sheet_data.dart'; import 'package:didvan/models/view/app_bar_data.dart'; import 'package:didvan/routes/routes.dart'; import 'package:didvan/utils/action_sheet.dart'; import 'package:didvan/utils/date_time.dart'; import 'package:didvan/views/ai/history_ai_chat_state.dart'; import 'package:didvan/views/widgets/didvan/scaffold.dart'; import 'package:didvan/views/widgets/didvan/text.dart'; import 'package:didvan/views/widgets/search_field.dart'; import 'package:didvan/views/widgets/shimmer_placeholder.dart'; import 'package:didvan/views/widgets/state_handlers/empty_state.dart'; import 'package:didvan/views/widgets/state_handlers/sliver_state_handler.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; class HistoryAiChatPage extends StatefulWidget { final bool? archived; const HistoryAiChatPage({Key? key, required this.archived}) : super(key: key); @override _HistoryAiChatPageState createState() => _HistoryAiChatPageState(); } class _HistoryAiChatPageState extends State { final ScrollController scrollController = ScrollController(); Timer? _timer; late bool archived = widget.archived ?? false; @override void initState() { final state = context.read(); Future.delayed( Duration.zero, () => state.getChats(archived: archived), ); super.initState(); } @override Widget build(BuildContext context) { return WillPopScope( onWillPop: () async { if (context.read().refresh) { context.read().getChats(); context.read().refresh = false; } return true; }, child: DidvanScaffold( hidePlayer: true, physics: const BouncingScrollPhysics(), // floatingActionButton: openAiListBtn(context), padding: EdgeInsets.zero, scrollController: scrollController, showSliversFirst: false, slivers: [ SliverAppBar( backgroundColor: Theme.of(context).colorScheme.surface, scrolledUnderElevation: 0, automaticallyImplyLeading: false, pinned: true, flexibleSpace: Container( color: Theme.of(context).colorScheme.surface, padding: const EdgeInsets.only(right: 20, left: 20, bottom: 24), child: SearchField( title: 'گفت‌و‌گو‌ها', onChanged: (value) { final state = context.read(); if (value.isEmpty) { state.getChats(archived: archived); return; } _timer?.cancel(); _timer = Timer(const Duration(seconds: 1), () { state.search = value; state.getSearchChats(q: value, archived: archived); }); }, focusNode: FocusNode()), ), ), Consumer( builder: (context, state, child) { return SliverStateHandler( state: state, emptyState: EmptyState( asset: Assets.emptyResult, title: 'لیست خالی است', ), enableEmptyState: archived ? state.archivedChats.isEmpty : state.chats.isEmpty, placeholder: const _HistoryPlaceholder(), placeholderCount: 8, // builder: (context, state, index) => _HistoryPlaceholder(), builder: (context, state, index) { final chat = archived ? state.archivedChats[index] : state.chats[index]; TextEditingController title = TextEditingController(text: chat.title); return Dismissible( key: UniqueKey(), background: Container( color: Theme.of(context).colorScheme.error, alignment: Alignment.centerRight, padding: const EdgeInsets.symmetric(horizontal: 20.0), child: Icon( DidvanIcons.trash_solid, color: Theme.of(context).colorScheme.white, ), ), secondaryBackground: Container( color: Theme.of(context).colorScheme.primary, alignment: Alignment.centerLeft, padding: const EdgeInsets.symmetric(horizontal: 20.0), child: Icon( archived ? Icons.folder_delete : Icons.create_new_folder_rounded, color: Theme.of(context).colorScheme.white), ), movementDuration: const Duration(milliseconds: 600), confirmDismiss: (direction) async { bool result = false; if (direction == DismissDirection.startToEnd) { await ActionSheetUtils(context).openDialog( data: ActionSheetData( onConfirmed: () async { final state = context.read(); await state.deleteChat(chat.id!, index, archived: archived); result = true; }, content: Column( children: [ Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Icon( DidvanIcons.trash_solid, color: Theme.of(context) .colorScheme .error, ), const SizedBox( width: 8, ), SizedBox( child: DidvanText( 'پاک کردن گفت‌و‌گو', color: Theme.of(context) .colorScheme .error, fontSize: 20, ), ), ], ), const SizedBox( height: 12, ), SizedBox( child: RichText( text: TextSpan( text: 'آیا از پاک کردن گفت‌و‌گوی ', style: TextStyle( color: Theme.of(context) .colorScheme .text), children: [ TextSpan( text: "\"${chat.title}\"", style: const TextStyle( fontWeight: FontWeight.bold)), const TextSpan( text: ' با هوشان اطمینان دارید؟ '), ]), ), ), ], ))); } else { result = await state.archivedChat(chat.id!, index, archived: archived); } return result; }, child: InkWell( onTap: () { // if (state.chatsToDelete.isEmpty) { navigatorKey.currentState!.pushNamed(Routes.aiChat, arguments: AiChatArgs(bot: chat.bot!, chat: chat)); // } else { // if (state.chatsToDelete.contains(chat.id)) { // state.chatsToDelete.remove(chat.id!); // } else { // state.chatsToDelete.add(chat.id!); // } // } // state.update(); }, onLongPress: () { if (archived) { state.archivedChats[index] = state .archivedChats[index] .copyWith(isEditing: true); } else { state.chats[index] = state.chats[index].copyWith(isEditing: true); } state.update(); // if (state.chatsToDelete.isEmpty) { // state.chatsToDelete.add(chat.id!); // } // state.update(); }, child: Container( padding: const EdgeInsets.symmetric( vertical: 12, horizontal: 20), decoration: BoxDecoration( border: Border( bottom: BorderSide( color: Theme.of(context) .colorScheme .border))), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ SizedBox( width: 46, height: 46, child: ClipOval( child: CachedNetworkImage( imageUrl: chat.bot!.image.toString(), ), ), ), const SizedBox( width: 18, ), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ DidvanText( chat.bot!.name.toString(), fontWeight: FontWeight.bold, // fontSize: 18, ), DidvanText( DateTimeUtils.momentGenerator( chat.updatedAt.toString()), style: const TextStyle(fontSize: 12)), ], ), SizedBox( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ chat.isEditing != null && chat.isEditing! ? Row( children: [ Expanded( child: TextFormField( controller: title, style: const TextStyle( fontSize: 12), textAlignVertical: TextAlignVertical .bottom, maxLines: 1, decoration: const InputDecoration( isDense: true, contentPadding: EdgeInsets .symmetric( vertical: 5, horizontal: 10), border: OutlineInputBorder(), )), ), const SizedBox( width: 12, ), state.loadingchangeTitle ? const SizedBox( width: 12, height: 12, child: CircularProgressIndicator()) : InkWell( onTap: () async { if (title.text .toString() == chat.title .toString()) { chat.isEditing = false; state.update(); return; } if (title.text .isNotEmpty) { await state .changeNameChat( chat .id!, index, title .text); title.clear(); } if (chat.isEditing != null) { chat.isEditing = !chat .isEditing!; state.update(); return; } chat.isEditing = true; state.update(); }, child: const Icon( DidvanIcons .check_circle_solid), ) ], ) : DidvanText( chat.title.toString(), maxLines: 1, overflow: TextOverflow.ellipsis, // fontWeight: FontWeight.bold, // fontSize: 16, ), DidvanText( chat.prompts![0].text.toString(), maxLines: 1, overflow: TextOverflow.ellipsis, fontSize: 12, ), ], ), ), ], ), ), ], ), ), ), ); }, childCount: archived ? state.archivedChats.length : state.chats.length, onRetry: () => state.getChats(archived: archived)); }, ) ], appBarData: AppBarData( title: archived ? 'آرشیو‌ها' : 'تاریخچه گفت‌وگوها', hasBack: true, hasElevation: true, backClick: () { if (context.read().refresh) { context.read().getChats(); context.read().refresh = false; } }, isSmall: false, trailing: archived ? null : Padding( padding: const EdgeInsets.symmetric(horizontal: 20.0), child: InkWell( onTap: () async { await ActionSheetUtils(context).openDialog( data: ActionSheetData( onConfirmed: () async { final state = context.read(); archived ? null : await state.deleteAllChat(); }, content: Column( children: [ Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Icon( DidvanIcons.trash_solid, color: Theme.of(context) .colorScheme .error, ), const SizedBox( width: 8, ), DidvanText( archived ? 'خارج کردن همه آرشیو ها' : 'پاک کردن همه گفت‌وگوها', color: Theme.of(context) .colorScheme .error, fontSize: 20, ), ], ), const SizedBox( height: 12, ), const DidvanText( 'آیا از پاک کردن تمامی گفت‌وگوهای انجام شده با هوشان اطمینان دارید؟'), ], ))); }, child: DidvanText( archived ? 'خارج کردن همه' : 'حذف همه', color: Theme.of(context).colorScheme.error, ), ), )), ), ); } // Widget openAiListBtn(BuildContext context) { // final watch = context.watch(); // final state = context.read(); // return FloatingActionButton( // backgroundColor: watch.chatsToDelete.isEmpty // ? Theme.of(context).colorScheme.primary // : Theme.of(context).colorScheme.error, // shape: const OvalBorder(), // mini: true, // onPressed: () { // if (watch.chatsToDelete.isEmpty) { // state.getBots(); // state.search = ''; // _botsDialogSelect(context); // } else { // state.addChatToDelete(); // } // }, // child: watch.chatsToDelete.isEmpty // ? const Icon(DidvanIcons.add_regular) // : const Icon(DidvanIcons.trash_regular), // ); // } } class _HistoryPlaceholder extends StatelessWidget { const _HistoryPlaceholder({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return const Padding( padding: EdgeInsets.symmetric(vertical: 18.0, horizontal: 20), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ ClipOval( child: ShimmerPlaceholder( height: 46, width: 46, ), ), SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ ShimmerPlaceholder( height: 20, width: 100, ), ShimmerPlaceholder( height: 14, width: 100, ), ], ), SizedBox(height: 12), ShimmerPlaceholder( height: 16, width: double.infinity, ), SizedBox(height: 8), ShimmerPlaceholder( height: 16, width: double.infinity, ), ], ), ), ], ), ); } }