// ignore_for_file: deprecated_member_use import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; import 'package:flutter_svg/svg.dart'; import 'package:go_router/go_router.dart'; import 'package:hoshan/core/gen/assets.gen.dart'; import 'package:hoshan/core/services/api/dio_service.dart'; import 'package:hoshan/data/model/ai/bots_model.dart'; import 'package:hoshan/data/storage/shared_preferences_helper.dart'; import 'package:hoshan/ui/screens/library/bloc/chats_history_bloc.dart'; import 'package:hoshan/ui/screens/library/library_screen.dart'; import 'package:hoshan/ui/screens/gmedia/cubit/media_g_response_cubit.dart'; import 'package:hoshan/ui/screens/gmedia/cubit/single_media_cubit.dart'; import 'package:hoshan/ui/screens/gmedia/chats/audio_chat_page.dart'; import 'package:hoshan/ui/theme/colors.dart'; import 'package:hoshan/ui/theme/cubit/theme_mode_cubit.dart'; import 'package:hoshan/ui/theme/responsive.dart'; import 'package:hoshan/ui/theme/text.dart'; import 'package:hoshan/ui/widgets/components/dialog/dialog_handler.dart'; import 'package:hoshan/ui/widgets/components/image/network_image.dart'; import 'package:hoshan/ui/widgets/components/snackbar/snackbar_manager.dart'; class GenerateAudioPage extends StatefulWidget { final int? id; const GenerateAudioPage({super.key, this.id}); @override State createState() => _GenerateAudioPageState(); } class _GenerateAudioPageState extends State with TickerProviderStateMixin { Bots? selectedBot; int? chatId; @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { context.read().add(RestartChatsHistory()); context.read().add(const GetAllChats(type: 'audio')); if (!GuidsStorage.isSeenAudio()) { DialogHandler(context: context).onMusicCreate(); GuidsStorage.setSeenAudio(true); } if (widget.id != null) { context.read().getMediaById(widget.id!); } }); } @override void dispose() { tabController.dispose(); super.dispose(); } late final TabController tabController = TabController(length: 3, vsync: this); @override Widget build(BuildContext context) { return BlocConsumer( listener: (context, state) { if (state is SingleMediaFail) { context.pop(); SnackBarManager(context).show( message: 'خطا در برقراری ارتباط با سرور لطفا لحظاتی دیگر امتحان کنید', status: SnackBarStatus.error); } }, builder: (context, state) { if (state is SingleMediaFail) { return const SizedBox.shrink(); } if (state is SingleMediaSuccess) { return SizedBox( child: DefaultTabController( length: state.medias.categories?.length ?? 0, child: Scaffold( body: Responsive(context).maxWidthInDesktop( child: (contxet, mw) => Scaffold( drawer: Drawer( shape: const BeveledRectangleBorder( borderRadius: BorderRadius.zero), child: LibraryScreen( type: 'audio', onTap: (chat) { final id = chat.bot?.category?.id; if (id != null) { final index = state.medias.categories! .indexOf(state.medias.categories!.firstWhere( (element) { return element.id == id; }, )); tabController.animateTo(index); Navigator.of(context).pop(); // Close the drawer setState(() { chatId = chat.id; selectedBot = chat.bot; }); } }, ), ), appBar: AppBar( toolbarHeight: 28, backgroundColor: context.read().isDark() ? null : AppColors.primaryColor[50], bottom: TabBar( controller: tabController, dividerColor: Colors.transparent, onTap: (value) { setState(() { selectedBot = null; chatId = null; }); }, tabs: List.generate( state.medias.categories?.length ?? 0, (index) { return Tab( height: 80, child: AnimatedBuilder( animation: tabController, builder: (context, _) { return Column( children: [ if (state.medias.categories?[index] .icon != null) Expanded( child: SvgPicture.network( DioService.baseURL + state.medias .categories![index].icon!, color: tabController.index == index ? Theme.of(context) .colorScheme .primary : AppColors.gray[context .read< ThemeModeCubit>() .isDark() ? 400 : 800], ), ), Text( state.medias.categories?[index] .name ?? '', style: AppTextStyles.body4.copyWith( fontWeight: tabController.index == index ? FontWeight.bold : FontWeight.normal, color: tabController.index == index ? Theme.of(context) .colorScheme .primary : AppColors.gray[context .read< ThemeModeCubit>() .isDark() ? 400 : 800]), ), const SizedBox( height: 8, ), ], ); }), ); }, ), ), ), body: TabBarView( key: ValueKey(chatId), // Change key to force rebuild physics: const NeverScrollableScrollPhysics(), controller: tabController, children: List.generate( state.medias.categories!.length, (index) { switch (index) { case 0: return MultiBlocProvider( providers: [ BlocProvider( create: (context) { return MediaGResponseCubit(); }, ), ], child: AudioChatPage( type: 'text', chatId: chatId, bot: selectedBot ?? state.medias.categories![index].bots! .first, maxWidth: mw, ), ); case 1: return MultiBlocProvider( providers: [ BlocProvider( create: (context) { return MediaGResponseCubit(); }, ), ], child: AudioChatPage( type: 'file', chatId: chatId, bot: selectedBot ?? state.medias.categories![index].bots! .first, maxWidth: mw, ), ); case 2: if (selectedBot != null) { return MultiBlocProvider( providers: [ BlocProvider( create: (context) { return MediaGResponseCubit(); }, ), ], child: AudioChatPage( type: 'music', chatId: chatId, bot: selectedBot!, maxWidth: mw, ), ); } final category = state.medias.categories![index]; return MasonryGridView.builder( itemCount: category.bots?.length, physics: const BouncingScrollPhysics(), padding: const EdgeInsets.symmetric( vertical: 16, horizontal: 16), gridDelegate: const SliverSimpleGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2), itemBuilder: (context, index) { final bot = category.bots?[index]; return Padding( // color: Colors.amberAccent, padding: const EdgeInsets.all(8), child: InkWell( onTap: () { setState(() { selectedBot = bot; }); }, child: Container( constraints: BoxConstraints( maxHeight: MediaQuery.sizeOf(context) .height * 0.3), decoration: BoxDecoration( color: Theme.of(context) .colorScheme .surface, borderRadius: BorderRadius.circular(16)), child: Stack( children: [ ConstrainedBox( constraints: BoxConstraints( minHeight: mw * 0.3, minWidth: mw * 0.3), child: ImageNetwork( radius: 16, url: bot?.image ?? '', fit: BoxFit.cover, ), ), Positioned.fill( child: Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( borderRadius: BorderRadius.circular(16), gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment .bottomCenter, colors: [ Theme.of(context) .colorScheme .surface .withAlpha(40), AppColors .primaryColor[600] .withAlpha(180) ])), child: Column( crossAxisAlignment: CrossAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end, children: [ Text( bot?.name ?? '', style: AppTextStyles.body4 .copyWith( color: Colors.white, fontWeight: FontWeight .bold), textDirection: TextDirection.rtl, maxLines: 2, overflow: TextOverflow.ellipsis, ), Row( mainAxisAlignment: MainAxisAlignment.end, children: [ Padding( padding: const EdgeInsets .only(top: 4.0), child: Text( bot?.cost ?.toString() ?? '', style: AppTextStyles .body4 .copyWith( color: Colors .white), ), ), const SizedBox( width: 4, ), Assets.icon.outline.coin .svg( color: Colors.white, width: 18, height: 18) ], ) ], ), )) ], ), ), ), ); }, ); default: return const SizedBox.shrink(); } }, ), ), ), ), ), ), ); } return const Scaffold( body: Center( child: CircularProgressIndicator(), ), ); }, ); } }