// ignore_for_file: library_private_types_in_public_api 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/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/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 { const HistoryAiChatPage({Key? key}) : super(key: key); @override _HistoryAiChatPageState createState() => _HistoryAiChatPageState(); } class _HistoryAiChatPageState extends State { ScrollController scrollController = ScrollController(); @override void initState() { final state = context.read(); Future.delayed( Duration.zero, () => state.getChats(), ); super.initState(); } @override Widget build(BuildContext context) { return DidvanScaffold( hidePlayer: true, physics: const BouncingScrollPhysics(), padding: const EdgeInsets.only(left: 16, right: 16, bottom: 92), floatingActionButton: openAiListBtn(context), scrollController: scrollController, slivers: [ Consumer( builder: (context, state, child) { return SliverStateHandler( state: state, emptyState: EmptyState( asset: Assets.emptyResult, title: 'لیست خالی است', ), enableEmptyState: state.chats.isEmpty, placeholder: const _HistoryPlaceholder(), placeholderCount: 8, // builder: (context, state, index) => _HistoryPlaceholder(), builder: (context, state, index) { final chat = state.chats[index]; return InkWell( onTap: () { if (state.chatsToDelete.isEmpty) { navigatorKey.currentState!.pushNamed(Routes.aiChat, arguments: AiChatArgs(bot: chat.bot!, chatId: chat.id!)); } else { if (state.chatsToDelete.contains(chat.id)) { state.chatsToDelete.remove(chat.id!); } else { state.chatsToDelete.add(chat.id!); } } state.update(); }, onLongPress: () { if (state.chatsToDelete.isEmpty) { state.chatsToDelete.add(chat.id!); } state.update(); }, child: Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( border: Border( bottom: BorderSide( color: Theme.of(context).colorScheme.border))), child: Stack( children: [ Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ const SizedBox( width: 46, height: 46, ), const SizedBox( width: 18, ), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ DidvanText( chat.bot!.name.toString(), fontWeight: FontWeight.bold, ), DidvanText( DateTimeUtils.momentGenerator( chat.updatedAt.toString()), style: const TextStyle(fontSize: 12)), ], ), SizedBox( child: DidvanText( chat.prompts![0].text.toString(), maxLines: 1, overflow: TextOverflow.ellipsis, ), ), ], ), ), ], ), Positioned( bottom: 0, right: 0, top: 0, child: Padding( padding: const EdgeInsets.all(4.0), child: ClipOval( child: CachedNetworkImage( imageUrl: chat.bot!.image.toString(), ), ), ), ), if (state.chatsToDelete.contains(chat.id)) Positioned( right: 32, bottom: 0, child: Container( // ignore: prefer_const_constructors decoration: BoxDecoration( color: Theme.of(context) .scaffoldBackgroundColor, shape: BoxShape.circle), child: Icon(DidvanIcons.check_circle_solid, size: 20, color: Theme.of(context).colorScheme.success), ), ) ], ), ), ); }, childCount: state.chats.length, onRetry: state.getChats); }, ) ], appBarData: null, ); } 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), ); } void _botsDialogSelect(BuildContext context) { final state = context.read(); ActionSheetUtils.context = context; ActionSheetUtils.openDialog( data: ActionSheetData( hasConfirmButton: false, hasDismissButton: false, content: Column( children: [ // Row( // mainAxisAlignment: MainAxisAlignment.end, // children: [ // Padding( // padding: const EdgeInsets.symmetric(vertical: 8.0), // child: InkWell( // onTap: () { // ActionSheetUtils.pop(); // }, // child: const Icon(DidvanIcons.close_solid)), // ) // ], // ), // SearchField( // title: 'هوش مصنوعی', // value: state.search, // onChanged: (value) { // state.search = value; // if (value.isEmpty) { // state.getBots(); // return; // } // state.timer?.cancel(); // state.timer = Timer(const Duration(seconds: 1), () { // state.getSearchBots(value); // }); // }, // focusNode: FocusNode()), // const SizedBox( // height: 12, // ), SizedBox( width: double.infinity, height: MediaQuery.sizeOf(context).height / 3, child: ValueListenableBuilder( valueListenable: state.loadingBots, builder: (context, value, child) => value ? Center( child: Image.asset( Assets.loadingAnimation, width: 60, height: 60, ), ) : state.bots.isEmpty ? Padding( padding: const EdgeInsets.symmetric( horizontal: 12.0), child: EmptyState( asset: Assets.emptyResult, title: 'نتیجه‌ای پیدا نشد', height: 120, ), ) : ListView.builder( padding: const EdgeInsets.symmetric(vertical: 12), itemCount: state.bots.length, physics: const BouncingScrollPhysics(), shrinkWrap: true, itemBuilder: (context, index) { final bot = state.bots[index]; return InkWell( onTap: () { ActionSheetUtils.pop(); navigatorKey.currentState!.pushNamed( Routes.aiChat, arguments: AiChatArgs(bot: bot)); }, child: Container( alignment: Alignment.center, padding: const EdgeInsets.symmetric( vertical: 8), decoration: BoxDecoration( border: Border( bottom: BorderSide( color: Theme.of(context) .colorScheme .border, width: 1))), child: Row( children: [ ClipOval( child: CachedNetworkImage( imageUrl: bot.image.toString(), width: 42, height: 42, ), ), const SizedBox(width: 12), Text(bot.name.toString()) ], ), ), ); }), ), ) ], ))); } } class _HistoryPlaceholder extends StatelessWidget { const _HistoryPlaceholder({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return const Padding( padding: EdgeInsets.symmetric(vertical: 12.0), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ ClipOval( child: ShimmerPlaceholder( height: 42, width: 42, ), ), 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), ], ), ), ], ), ); } }