// ignore_for_file: deprecated_member_use_from_same_package import 'dart:math'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; import 'package:hoshan/core/gen/assets.gen.dart'; import 'package:hoshan/core/routes/route_generator.dart'; import 'package:hoshan/core/utils/strings.dart'; import 'package:hoshan/data/model/ai/bots_model.dart'; import 'package:hoshan/data/model/banner_model.dart'; import 'package:hoshan/data/model/chat_args.dart'; import 'package:hoshan/data/model/courses_model.dart'; import 'package:hoshan/data/model/posts_model.dart'; import 'package:hoshan/data/model/tools_categories_model.dart'; import 'package:hoshan/ui/screens/gmedia/cubit/medias_cubit.dart'; import 'package:hoshan/ui/screens/main/assistant/bloc/global_assistants_bloc.dart'; import 'package:hoshan/ui/screens/main/assistant/global_assistants_screen.dart'; import 'package:hoshan/ui/screens/main/home/bloc/bots_bloc.dart'; import 'package:hoshan/ui/screens/main/home/bloc/courses_bloc.dart'; import 'package:hoshan/ui/screens/main/home/bloc/cubit/posts_cubit.dart'; import 'package:hoshan/ui/screens/main/home/cubit/banners_cubit.dart'; import 'package:hoshan/ui/screens/main/home/cubit/best_assistants_cubit.dart'; import 'package:hoshan/ui/screens/main/home/cubit/main_chat_bot_cubit.dart'; import 'package:hoshan/ui/screens/main/home_page.dart'; import 'package:hoshan/ui/screens/main/persons/cubit/persons_cubit.dart'; import 'package:hoshan/ui/screens/splash/cubit/user_info_cubit.dart'; import 'package:hoshan/ui/screens/tools/bloc/tools_bloc.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/ai_Banner.dart'; import 'package:hoshan/ui/widgets/components/bot/bot_grid_card.dart'; import 'package:hoshan/ui/widgets/components/bot/bot_grid_card_placeholder.dart'; import 'package:hoshan/ui/widgets/components/bot/tool_card.dart'; import 'package:hoshan/ui/widgets/components/bot/tool_card_placeholder.dart'; import 'package:hoshan/ui/widgets/components/button/circle_icon_btn.dart'; import 'package:hoshan/ui/widgets/components/button/loading_button.dart'; import 'package:hoshan/ui/widgets/components/image/network_image.dart'; import 'package:hoshan/ui/widgets/components/slider/carousle_slider_banners.dart'; import 'package:hoshan/ui/widgets/family_banner.dart'; import 'package:hoshan/ui/widgets/sections/loading/default_placeholder.dart'; import 'package:string_validator/string_validator.dart'; import 'package:url_launcher/url_launcher.dart'; class HomeScreen extends StatefulWidget { const HomeScreen({super.key}); @override State createState() => _HomeScreenState(); } class _HomeScreenState extends State with AutomaticKeepAliveClientMixin { @override bool get wantKeepAlive => true; final ScrollController scrollController = ScrollController(); @override Widget build(BuildContext context) { super.build(context); return RefreshIndicator( backgroundColor: Theme.of(context).colorScheme.surface, color: Theme.of(context).colorScheme.primary, onRefresh: () async { context.read().getUserInfo(); context.read().getAssistants(); context.read().add(GetAllBots()); context.read().add(GetAllTools()); context.read().getBanners(); context.read().getMedias(); context.read().add(GetAllCourses()); context.read().getLastPosts(); context.read().getBot(1); scrollController.jumpTo(0); }, child: SingleChildScrollView( controller: scrollController, physics: const BouncingScrollPhysics( parent: AlwaysScrollableScrollPhysics()), child: Directionality( textDirection: TextDirection.rtl, child: Column( children: [ FamilyBanner(), // carousleSliders(), SizedBox( height: 15, ), Row( children: [ Expanded( child: Divider( color: context.read().isDark() ? Theme.of(context).colorScheme.onSurface : AppColors.primaryColor[100])), Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( shape: BoxShape.circle, color: context.read().isDark() ? Theme.of(context).colorScheme.onSurface : AppColors.primaryColor[100]), child: Assets.icon.gif.chatMain.image( width: 46, ), ), Expanded( child: Divider( color: context.read().isDark() ? Theme.of(context).colorScheme.onSurface : AppColors.primaryColor[100])), ], ), SizedBox( height: 16, ), startChatSection(context), Responsive(context).builder( tabletAndMobileSame: true, desktop: Padding( padding: const EdgeInsets.symmetric(horizontal: 32.0), child: Column( children: [ const SizedBox( height: 32, ), Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ Flexible(flex: 2, child: toolsList()), Flexible( child: Padding( padding: const EdgeInsets.only(top: 32.0), child: BlocBuilder( builder: (context, state) { if (state is BannersSuccess) { if (state.banners.length < 3) { return const SizedBox.shrink(); } Banners banner = state.banners[state.banners.length - 2]; return bannerCard(context, banner); } if (state is BannersFail) { return const SizedBox.shrink(); } return DefaultPlaceHolder( child: Container( height: Responsive(context).isMobile() ? 80 : 160, width: double.infinity, padding: const EdgeInsets.all(8), margin: const EdgeInsets.symmetric( horizontal: 16.0) .copyWith(bottom: 16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), ), ), ); }, ), ), ) ], ), const SizedBox( height: 16, ), Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ Flexible( flex: 2, child: BlocBuilder( builder: (context, state) { if (state is BestAssistantsFail) { return const SizedBox.shrink(); } if (state is BestAssistantsSuccess) { final List allBots = state.assistants; allBots.shuffle(); return Column( children: [ ListTile( leading: Assets.icon.outline.assistant .svg( color: Theme.of(context) .colorScheme .onSurface, width: 24, height: 24), title: Padding( padding: const EdgeInsets.only(top: 8.0), child: Text( 'دستیارهای برگزیده', style: AppTextStyles.headline6 .copyWith( color: Theme.of(context) .colorScheme .onSurface), ), ), trailing: InkWell( onTap: () { screenIndex.value = 2; initiaGlobalCatItem.value = Categories( id: -1, name: 'برگزیده‌ها'); context .read() .add( const GetGlobalAssistants()); }, child: Text( 'مشاهده همه', style: AppTextStyles.body6 .copyWith( color: Theme.of(context) .colorScheme .primary, fontWeight: FontWeight.bold), )), ), SizedBox( width: double.infinity, height: 170, child: ListView.builder( scrollDirection: Axis.horizontal, physics: const BouncingScrollPhysics(), shrinkWrap: true, itemCount: min(10, allBots.length), padding: const EdgeInsets.symmetric( horizontal: 8), itemBuilder: (context, index) { return SizedBox( width: 160, child: Padding( padding: const EdgeInsets.symmetric( horizontal: 4.0, vertical: 8), child: InkWell( onTap: () { context.go( Routes.assistant, extra: allBots[index] .id); }, child: BotGridCard( showCat: true, bot: allBots[index], )), ), ); }, ), ), const SizedBox( height: 16, ), ], ); } return Column( children: [ DefaultPlaceHolder( child: ListTile( leading: Assets.icon.outline.assistant .svg( color: Theme.of(context) .colorScheme .onSurface, width: 24, height: 24), title: Padding( padding: const EdgeInsets.only(top: 8.0), child: Text( 'دستیارهای برگزیده', style: AppTextStyles.headline6 .copyWith( color: Theme.of(context) .colorScheme .onSurface), ), ), trailing: Text( 'مشاهده همه', style: AppTextStyles.body6.copyWith( color: Theme.of(context) .colorScheme .primary, fontWeight: FontWeight.bold), ), ), ), SizedBox( width: double.infinity, height: 170, child: ListView.builder( scrollDirection: Axis.horizontal, physics: const NeverScrollableScrollPhysics(), shrinkWrap: true, itemCount: 10, padding: const EdgeInsets.symmetric( horizontal: 8), itemBuilder: (context, index) { return const SizedBox( width: 160, child: Padding( padding: EdgeInsets.symmetric( horizontal: 4.0, vertical: 8), child: BotGridCardPlaceholder(), ), ); }, ), ), const SizedBox( height: 16, ), ], ); }, ), ), Flexible( child: Padding( padding: const EdgeInsets.only(top: 32.0), child: BlocBuilder( builder: (context, state) { if (state is BannersSuccess) { if (state.banners.length < 3) { return const SizedBox.shrink(); } Banners banner = state.banners.last; return bannerCard(context, banner); } if (state is BannersFail) { return const SizedBox.shrink(); } return DefaultPlaceHolder( child: Container( height: Responsive(context).isMobile() ? 80 : 160, width: double.infinity, padding: const EdgeInsets.all(8), margin: const EdgeInsets.symmetric( horizontal: 16.0) .copyWith(bottom: 16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), ), ), ); }, ), ), ) ], ), BlocBuilder( builder: (context, state) { if (state is PersonsFail) { return const SizedBox(); } if (state is PersonsSuccess) { if (state.chars.categories?.isEmpty ?? true) { return const SizedBox.shrink(); } final List bots = state.chars.categories! .expand( (genModel) => genModel.bots!.take(2)) .toList() ..shuffle(); return Column( children: [ ListTile( leading: Assets.icon.outline.mageScanUser.svg( color: Theme.of(context) .colorScheme .onSurface, width: 24, height: 24), title: Padding( padding: const EdgeInsets.only(top: 8.0), child: Text( 'گفتگو با شخصیت‌ها', style: AppTextStyles.headline6.copyWith( color: Theme.of(context) .colorScheme .onSurface), ), ), trailing: InkWell( onTap: () { screenIndex.value = 3; }, child: Text( 'مشاهده همه', style: AppTextStyles.body6.copyWith( color: Theme.of(context) .colorScheme .primary, fontWeight: FontWeight.bold), )), ), SizedBox( width: double.infinity, height: 160, child: ListView.builder( scrollDirection: Axis.horizontal, shrinkWrap: true, itemCount: bots.length, physics: const BouncingScrollPhysics(), padding: const EdgeInsets.symmetric( horizontal: 8), itemBuilder: (context, index) { final person = bots[index]; return InkWell( onTap: () { context.go(Routes.chat, extra: ChatArgs( bot: person, isPerson: true)); }, child: Container( margin: const EdgeInsets.all(8), constraints: BoxConstraints( maxWidth: MediaQuery.sizeOf(context) .width * 0.2), decoration: BoxDecoration( boxShadow: const [ BoxShadow( color: Color(0x664D4D4D), blurRadius: 6, offset: Offset(0, 1), spreadRadius: 0, ) ], color: Theme.of(context) .colorScheme .surface, borderRadius: BorderRadius.circular(16)), child: ClipRRect( borderRadius: BorderRadius.circular(16), child: Row( mainAxisSize: MainAxisSize.min, children: [ AspectRatio( aspectRatio: 1 / 1, child: ImageNetwork( url: person.image ?? '', fit: BoxFit.cover, radius: 0, height: double.infinity, ), ), Expanded( child: Padding( padding: const EdgeInsets.all( 16.0), child: Column( crossAxisAlignment: CrossAxisAlignment .start, mainAxisAlignment: MainAxisAlignment .center, children: [ Text( person.name ?? '', style: AppTextStyles .body3 .copyWith( color: Theme.of( context) .colorScheme .onSurface, fontWeight: FontWeight .bold), maxLines: 1, overflow: TextOverflow .ellipsis, ), Row( children: [ Assets.icon.outline.coin.svg( width: 16, height: 16, color: Theme.of( context) .colorScheme .secondary), const SizedBox( width: 4, ), Text( person.cost == 0 || person.cost == null ? 'رایگان' : person.cost .toString(), style: AppTextStyles.body5.copyWith( color: Theme.of( context) .colorScheme .secondary), maxLines: 1, overflow: TextOverflow .ellipsis, ) ], ), Row( children: [ Container( width: 8, height: 8, decoration: BoxDecoration( shape: BoxShape .circle, color: Theme.of( context) .colorScheme .secondary, ), ), const SizedBox( width: 8, ), Expanded( child: Text( person.category ?.name ?? '', maxLines: 1, overflow: TextOverflow .ellipsis, style: AppTextStyles .body5 .copyWith( color: Theme.of( context) .colorScheme .onSurface, )), ) ], ) ], ), ), ), ], ), ), ), ); }, ), ), ], ); } return Column( children: [ ListTile( leading: DefaultPlaceHolder( child: Assets.icon.outline.mageScanUser.svg( color: Theme.of(context) .colorScheme .onSurface, width: 24, height: 24), ), title: Padding( padding: const EdgeInsets.only(top: 8.0), child: DefaultPlaceHolder( child: Text( 'گفتگو با شخصیت‌ها', style: AppTextStyles.headline6.copyWith( color: Theme.of(context) .colorScheme .onSurface), ), ), ), ), SizedBox( width: double.infinity, height: 160, child: ListView.builder( scrollDirection: Axis.horizontal, shrinkWrap: true, itemCount: 10, physics: const NeverScrollableScrollPhysics(), padding: const EdgeInsets.symmetric(horizontal: 8), itemBuilder: (context, index) { return Container( margin: const EdgeInsets.all(8), constraints: BoxConstraints( maxWidth: MediaQuery.sizeOf(context).width * 0.2), decoration: BoxDecoration( boxShadow: const [ BoxShadow( color: Color(0x664D4D4D), blurRadius: 6, offset: Offset(0, 1), spreadRadius: 0, ) ], color: Theme.of(context) .colorScheme .surface, borderRadius: BorderRadius.circular(16)), child: ClipRRect( borderRadius: BorderRadius.circular(16), child: Row( mainAxisSize: MainAxisSize.min, children: [ DefaultPlaceHolder( child: AspectRatio( aspectRatio: 1 / 1, child: Container( color: Colors.white, height: double.infinity, ), ), ), Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ DefaultPlaceHolder( child: Container( height: 12, width: 120, decoration: BoxDecoration( borderRadius: BorderRadius .circular(16), color: Colors.white), ), ), const SizedBox( height: 8, ), Row( children: [ DefaultPlaceHolder( child: Assets .icon.outline.coin .svg( width: 16, height: 16, color: Theme.of( context) .colorScheme .secondary), ), const SizedBox( width: 4, ), DefaultPlaceHolder( child: Container( width: 24, height: 12, decoration: BoxDecoration( borderRadius: BorderRadius .circular( 16), color: Colors.white), ), ) ], ), const SizedBox( height: 8, ), Row( children: [ DefaultPlaceHolder( child: Container( width: 8, height: 8, decoration: BoxDecoration( shape: BoxShape.circle, color: Theme.of( context) .colorScheme .secondary, ), ), ), const SizedBox( width: 8, ), DefaultPlaceHolder( child: Container( width: 46, height: 12, decoration: BoxDecoration( borderRadius: BorderRadius .circular( 16), color: Colors.white), )) ], ) ], ), ), ], ), ), ); }, ), ), ], ); }, ), // BlocBuilder( // builder: (context, state) { // if (state is CoursesFail) { // return const SizedBox.shrink(); // } // if (state is CoursesSuccess) { // if (state.courses.isEmpty) { // return const SizedBox.shrink(); // } // return coursesList(state); // } // return coursesListPlaceholder(); // }, // ), BlocBuilder( builder: (context, state) { if (state is PostsFail) { return const SizedBox.shrink(); } if (state is PostsSuccess) { if (kDebugMode) { print('✅ Posts: ${state.posts.length}'); } if (state.posts.isEmpty) { return const SizedBox.shrink(); } return postsList(state); } return postsListPlaceholder(); }, ), const SizedBox( height: 24, ) // publicBotsList(), // BlocBuilder( // builder: (context, state) { // if (state is BannersSuccess) { // if (state.banners.length < 3) { // return const SizedBox.shrink(); // } // Banners banner = state.banners[state.banners.length - 2]; // return bannerCard(context, banner); // } // if (state is BannersFail) { // return const SizedBox.shrink(); // } // return DefaultPlaceHolder( // child: Container( // height: Responsive(context).isMobile() ? 80 : 160, // width: double.infinity, // padding: const EdgeInsets.all(8), // margin: const EdgeInsets.symmetric(horizontal: 16.0) // .copyWith(bottom: 16), // decoration: BoxDecoration( // color: Colors.white, // borderRadius: BorderRadius.circular(16), // ), // ), // ); // }, // ), // toolsList(), // BlocBuilder( // builder: (context, state) { // if (state is BannersSuccess) { // if (state.banners.length < 3) { // return const SizedBox.shrink(); // } // Banners banner = state.banners.last; // return bannerCard(context, banner); // } // if (state is BannersFail) { // return const SizedBox.shrink(); // } // return DefaultPlaceHolder( // child: Container( // height: Responsive(context).isMobile() ? 80 : 160, // width: double.infinity, // padding: const EdgeInsets.all(8), // margin: const EdgeInsets.symmetric(horizontal: 16.0) // .copyWith(bottom: 16), // decoration: BoxDecoration( // color: Colors.white, // borderRadius: BorderRadius.circular(16), // ), // ), // ); // }, // ), // privateBotsList(), ], ), ), mobile: Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ const SizedBox( height: 16, ), toolsList(), const SizedBox( height: 16, ), BlocBuilder( builder: (context, state) { if (state is BannersSuccess) { if (state.banners.length < 3) { return const SizedBox.shrink(); } Banners banner = state.banners[state.banners.length - 2]; return bannerCard(context, banner); } if (state is BannersFail) { return const SizedBox.shrink(); } return DefaultPlaceHolder( child: Container( height: Responsive(context).isMobile() ? 80 : 160, width: double.infinity, padding: const EdgeInsets.all(8), margin: const EdgeInsets.symmetric(horizontal: 16.0) .copyWith(bottom: 16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), ), ), ); }, ), BlocBuilder( builder: (context, state) { if (state is BestAssistantsFail) { return const SizedBox.shrink(); } if (state is BestAssistantsSuccess) { final List allBots = state.assistants; return Column( children: [ ListTile( leading: Assets.icon.outline.assistant.svg( color: Theme.of(context).colorScheme.onSurface, width: 24, height: 24), title: Padding( padding: const EdgeInsets.only(top: 8.0), child: Text( 'دستیارهای برگزیده', style: AppTextStyles.headline6.copyWith( color: Theme.of(context) .colorScheme .onSurface), ), ), trailing: InkWell( onTap: () { screenIndex.value = 1; initiaGlobalCatItem.value = Categories( id: -1, name: 'برگزیده‌ها'); context .read() .add(const GetGlobalAssistants()); }, child: Text( 'مشاهده همه', style: AppTextStyles.body6.copyWith( color: Theme.of(context) .colorScheme .primary, fontWeight: FontWeight.bold), )), ), SizedBox( width: double.infinity, height: 170, child: ListView.builder( scrollDirection: Axis.horizontal, physics: const BouncingScrollPhysics(), shrinkWrap: true, itemCount: min(10, allBots.length), padding: const EdgeInsets.symmetric(horizontal: 8), itemBuilder: (context, index) { return SizedBox( width: 160, child: Padding( padding: const EdgeInsets.symmetric( horizontal: 4.0, vertical: 8), child: InkWell( onTap: () { context.go(Routes.assistant, extra: allBots[index].id); }, child: BotGridCard( showCat: true, bot: allBots[index], )), ), ); }, ), ), const SizedBox( height: 16, ), ], ); } return Column( children: [ DefaultPlaceHolder( child: ListTile( leading: Assets.icon.outline.assistant.svg( color: Theme.of(context).colorScheme.onSurface, width: 24, height: 24), title: Padding( padding: const EdgeInsets.only(top: 8.0), child: Text( 'دستیارهای برگزیده', style: AppTextStyles.headline6.copyWith( color: Theme.of(context) .colorScheme .onSurface), ), ), trailing: Text( 'مشاهده همه', style: AppTextStyles.body6.copyWith( color: Theme.of(context).colorScheme.primary, fontWeight: FontWeight.bold), ), ), ), SizedBox( width: double.infinity, height: 170, child: ListView.builder( scrollDirection: Axis.horizontal, physics: const NeverScrollableScrollPhysics(), shrinkWrap: true, itemCount: 10, padding: const EdgeInsets.symmetric(horizontal: 8), itemBuilder: (context, index) { return const SizedBox( width: 160, child: Padding( padding: EdgeInsets.symmetric( horizontal: 4.0, vertical: 8), child: BotGridCardPlaceholder(), ), ); }, ), ), const SizedBox( height: 16, ), ], ); }, ), BlocBuilder( builder: (context, state) { if (state is BannersSuccess) { if (state.banners.length < 3) { return const SizedBox.shrink(); } Banners banner = state.banners.last; return bannerCard(context, banner); } if (state is BannersFail) { return const SizedBox.shrink(); } return DefaultPlaceHolder( child: Container( height: Responsive(context).isMobile() ? 80 : 160, width: double.infinity, padding: const EdgeInsets.all(8), margin: const EdgeInsets.symmetric(horizontal: 16.0) .copyWith(bottom: 16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), ), ), ); }, ), BlocBuilder( builder: (context, state) { if (state is PersonsFail) { return const SizedBox(); } if (state is PersonsSuccess) { if (state.chars.categories?.isEmpty ?? true) { return const SizedBox.shrink(); } final List bots = state.chars.categories! .expand( (genModel) => genModel.bots!.take(2)) .toList() ..shuffle(); return Column( children: [ ListTile( leading: Assets.icon.outline.mageScanUser.svg( color: Theme.of(context).colorScheme.onSurface, width: 24, height: 24), title: Padding( padding: const EdgeInsets.only(top: 8.0), child: Text( 'گفتگو با شخصیت‌ها', style: AppTextStyles.headline6.copyWith( color: Theme.of(context) .colorScheme .onSurface), ), ), trailing: InkWell( onTap: () { screenIndex.value = 3; }, child: Text( 'مشاهده همه', style: AppTextStyles.body6.copyWith( color: Theme.of(context) .colorScheme .primary, fontWeight: FontWeight.bold), )), ), SizedBox( width: double.infinity, height: 160, child: ListView.builder( scrollDirection: Axis.horizontal, shrinkWrap: true, itemCount: bots.length, physics: const BouncingScrollPhysics(), padding: const EdgeInsets.symmetric(horizontal: 8), itemBuilder: (context, index) { final person = bots[index]; return InkWell( onTap: () { context.go(Routes.chat, extra: ChatArgs( bot: person, isPerson: true)); }, child: Container( margin: const EdgeInsets.all(8), constraints: BoxConstraints( maxWidth: MediaQuery.sizeOf(context) .width * 0.8), decoration: BoxDecoration( boxShadow: const [ BoxShadow( color: Color(0x664D4D4D), blurRadius: 6, offset: Offset(0, 1), spreadRadius: 0, ) ], color: Theme.of(context) .colorScheme .surface, borderRadius: BorderRadius.circular(16)), child: ClipRRect( borderRadius: BorderRadius.circular(16), child: Row( mainAxisSize: MainAxisSize.min, children: [ AspectRatio( aspectRatio: 1 / 1, child: ImageNetwork( url: person.image ?? '', fit: BoxFit.cover, radius: 0, height: double.infinity, ), ), Expanded( child: Padding( padding: const EdgeInsets.all( 16.0), child: Column( crossAxisAlignment: CrossAxisAlignment .start, mainAxisAlignment: MainAxisAlignment .center, children: [ Text( person.name ?? '', style: AppTextStyles .body3 .copyWith( color: Theme.of( context) .colorScheme .onSurface, fontWeight: FontWeight .bold), maxLines: 1, overflow: TextOverflow .ellipsis, ), Row( children: [ Assets.icon.outline.coin.svg( width: 16, height: 16, color: Theme.of( context) .colorScheme .secondary), const SizedBox( width: 4, ), Text( person.cost == 0 || person.cost == null ? 'رایگان' : person.cost .toString(), style: AppTextStyles.body5.copyWith( color: Theme.of( context) .colorScheme .secondary), maxLines: 1, overflow: TextOverflow .ellipsis, ) ], ), Row( children: [ Container( width: 8, height: 8, decoration: BoxDecoration( shape: BoxShape .circle, color: Theme.of( context) .colorScheme .secondary, ), ), const SizedBox( width: 8, ), Expanded( child: Text( person.category ?.name ?? '', maxLines: 1, overflow: TextOverflow .ellipsis, style: AppTextStyles .body5 .copyWith( color: Theme.of( context) .colorScheme .onSurface, )), ) ], ) ], ), ), ), ], ), ), ), ); }, ), ), ], ); } return Column( children: [ ListTile( leading: DefaultPlaceHolder( child: Assets.icon.outline.mageScanUser.svg( color: Theme.of(context).colorScheme.onSurface, width: 24, height: 24), ), title: Padding( padding: const EdgeInsets.only(top: 8.0), child: DefaultPlaceHolder( child: Text( 'گفتگو با شخصیت‌ها', style: AppTextStyles.headline6.copyWith( color: Theme.of(context) .colorScheme .onSurface), ), ), ), ), SizedBox( width: double.infinity, height: 160, child: ListView.builder( scrollDirection: Axis.horizontal, shrinkWrap: true, itemCount: 10, physics: const NeverScrollableScrollPhysics(), padding: const EdgeInsets.symmetric(horizontal: 8), itemBuilder: (context, index) { return Container( margin: const EdgeInsets.all(8), constraints: BoxConstraints( maxWidth: MediaQuery.sizeOf(context).width * 0.8), decoration: BoxDecoration( boxShadow: const [ BoxShadow( color: Color(0x664D4D4D), blurRadius: 6, offset: Offset(0, 1), spreadRadius: 0, ) ], color: Theme.of(context) .colorScheme .surface, borderRadius: BorderRadius.circular(16)), child: ClipRRect( borderRadius: BorderRadius.circular(16), child: Row( mainAxisSize: MainAxisSize.min, children: [ DefaultPlaceHolder( child: AspectRatio( aspectRatio: 1 / 1, child: Container( color: Colors.white, height: double.infinity, ), ), ), Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ DefaultPlaceHolder( child: Container( height: 12, width: 120, decoration: BoxDecoration( borderRadius: BorderRadius .circular(16), color: Colors.white), ), ), const SizedBox( height: 8, ), Row( children: [ DefaultPlaceHolder( child: Assets .icon.outline.coin .svg( width: 16, height: 16, color: Theme.of( context) .colorScheme .secondary), ), const SizedBox( width: 4, ), DefaultPlaceHolder( child: Container( width: 24, height: 12, decoration: BoxDecoration( borderRadius: BorderRadius .circular( 16), color: Colors.white), ), ) ], ), const SizedBox( height: 8, ), Row( children: [ DefaultPlaceHolder( child: Container( width: 8, height: 8, decoration: BoxDecoration( shape: BoxShape.circle, color: Theme.of(context) .colorScheme .secondary, ), ), ), const SizedBox( width: 8, ), DefaultPlaceHolder( child: Container( width: 46, height: 12, decoration: BoxDecoration( borderRadius: BorderRadius .circular(16), color: Colors.white), )) ], ) ], ), ), ], ), ), ); }, ), ), ], ); }, ), // BlocBuilder( // builder: (context, state) { // if (state is CoursesFail) { // return const SizedBox.shrink(); // } // if (state is CoursesSuccess) { // if (state.courses.isEmpty) { // return const SizedBox.shrink(); // } // return coursesList(state); // } // return coursesListPlaceholder(); // }, // ), BlocBuilder( builder: (context, state) { if (state is PostsFail) { return const SizedBox.shrink(); } if (state is PostsSuccess) { if (state.posts.isEmpty) { return const SizedBox.shrink(); } return postsList(state); } return postsListPlaceholder(); }, ), const SizedBox( height: 24, ) // publicBotsList(), // BlocBuilder( // builder: (context, state) { // if (state is BannersSuccess) { // if (state.banners.length < 3) { // return const SizedBox.shrink(); // } // Banners banner = state.banners[state.banners.length - 2]; // return bannerCard(context, banner); // } // if (state is BannersFail) { // return const SizedBox.shrink(); // } // return DefaultPlaceHolder( // child: Container( // height: Responsive(context).isMobile() ? 80 : 160, // width: double.infinity, // padding: const EdgeInsets.all(8), // margin: const EdgeInsets.symmetric(horizontal: 16.0) // .copyWith(bottom: 16), // decoration: BoxDecoration( // color: Colors.white, // borderRadius: BorderRadius.circular(16), // ), // ), // ); // }, // ), // toolsList(), // BlocBuilder( // builder: (context, state) { // if (state is BannersSuccess) { // if (state.banners.length < 3) { // return const SizedBox.shrink(); // } // Banners banner = state.banners.last; // return bannerCard(context, banner); // } // if (state is BannersFail) { // return const SizedBox.shrink(); // } // return DefaultPlaceHolder( // child: Container( // height: Responsive(context).isMobile() ? 80 : 160, // width: double.infinity, // padding: const EdgeInsets.all(8), // margin: const EdgeInsets.symmetric(horizontal: 16.0) // .copyWith(bottom: 16), // decoration: BoxDecoration( // color: Colors.white, // borderRadius: BorderRadius.circular(16), // ), // ), // ); // }, // ), // privateBotsList(), ], ), ), ], ), ), ), ); } SizedBox startChatSection(BuildContext context) { return SizedBox( child: Responsive(context).isMobile() ? Column( children: [ BlocBuilder( builder: (context, state) { if (state is MainChatBotFail) { return const SizedBox.shrink(); } return InkWell( onTap: state is MainChatBotSuccess ? () => context.go(Routes.chat, extra: ChatArgs(bot: state.bot)) : null, child: DefaultPlaceHolder( enabled: state is! MainChatBotSuccess, child: Container( width: double.infinity, decoration: BoxDecoration( borderRadius: BorderRadius.circular(360), color: Theme.of(context).colorScheme.surface), padding: const EdgeInsets.all(16), margin: const EdgeInsets.symmetric( horizontal: 16, vertical: 8), child: Row( children: [ Expanded( child: FittedBox( child: Text( 'سوالت رو همینجا بپرس تا باهم صحبت کنیم!', textDirection: TextDirection.rtl, style: AppTextStyles.body5.copyWith( color: Theme.of(context) .colorScheme .onSurface), ), ), ), const SizedBox( width: 24, ), Transform.rotate( angle: pi, child: CircleIconBtn( iconColor: Colors.white, color: Theme.of(context) .colorScheme .secondary, icon: Assets.icon.bold.send)), ], ), ), ), ); }, ), ListTile( title: Text( 'مدیا', style: AppTextStyles.body4.copyWith( fontWeight: FontWeight.bold, color: Theme.of(context).colorScheme.onSurface), ), leading: Assets.icon.outline.media .svg(color: Theme.of(context).colorScheme.onSurface), // trailing: GestureDetector( // onTap: () { // screenIndex.value = 3; // }, // child: Text( // 'مشاهده همه', // style: AppTextStyles.body6.copyWith( // color: Theme.of(context).colorScheme.primary, // fontWeight: FontWeight.bold), // ), // ), ), const SizedBox( height: 8, ), BlocBuilder( builder: (context, state) { if (state is MediasFail) { return const SizedBox.shrink(); } if (state is MediasSuccess) { final medias = state.medias.categories!; if (medias.isEmpty) return const SizedBox.shrink(); return Padding( padding: const EdgeInsets.symmetric(horizontal: 8.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: List.generate( medias.length, (index) { final media = medias[index]; return Row(children: [ mediaCard(context, title: media.name!.replaceAll('ساخت ', ''), icon: media.icon!, onClick: () { String? route; if (media.icon!.contains('image')) { route = Routes.generatPhoto; } else if (media.icon!.contains('audio')) { route = Routes.generatAudio; } else if (media.icon!.contains('video')) { route = Routes.generatVideo; } if (route != null) { context.go(route, extra: media.id); } }), if (index != medias.length - 1) const SizedBox( width: 16, ) ]); }, )), ); } return Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: List.generate( 3, (index) => Row( children: [ DefaultPlaceHolder( child: Container( width: 95, height: 95, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(36), ), )), if (index != 2) const SizedBox( width: 16, ) ], ), ), ); }, ), ], ) : Column( mainAxisAlignment: MainAxisAlignment.center, children: [ BlocBuilder( builder: (context, state) { if (state is MainChatBotFail) { return const SizedBox.shrink(); } return InkWell( onTap: state is MainChatBotSuccess ? () => context.go(Routes.chat, extra: ChatArgs(bot: state.bot)) : null, child: DefaultPlaceHolder( enabled: state is! MainChatBotSuccess, child: Container( width: MediaQuery.sizeOf(context).width * 0.4, decoration: BoxDecoration( borderRadius: BorderRadius.circular(360), color: Theme.of(context).colorScheme.surface), padding: const EdgeInsets.all(16), margin: const EdgeInsets.symmetric( horizontal: 16, vertical: 8), child: Row( children: [ Expanded( child: Text( 'سوالت رو همینجا بپرس تا باهم صحبت کنیم!', textDirection: TextDirection.rtl, style: AppTextStyles.body2.copyWith( color: Theme.of(context) .colorScheme .onSurface), ), ), const SizedBox( width: 24, ), Transform.rotate( angle: pi, child: CircleIconBtn( iconColor: Colors.white, size: 64, color: Theme.of(context) .colorScheme .secondary, icon: Assets.icon.bold.send)), ], ), ), ), ); }, ), const SizedBox( height: 8, ), BlocBuilder( builder: (context, state) { if (state is MediasFail) { return const SizedBox.shrink(); } if (state is MediasSuccess) { final medias = state.medias.categories!; if (medias.isEmpty) return const SizedBox.shrink(); return Padding( padding: const EdgeInsets.symmetric(horizontal: 8.0), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: List.generate( medias.length, (index) { final media = medias[index]; return Row(children: [ mediaCard(context, title: media.name!.replaceAll('ساخت ', ''), icon: media.icon!, onClick: () { String? route; if (media.icon!.contains('image')) { route = Routes.generatPhoto; } else if (media.icon!.contains('audio')) { route = Routes.generatAudio; } else if (media.icon!.contains('video')) { route = Routes.generatVideo; } if (route != null) { context.go(route, extra: media.id); } }), if (index != medias.length - 1) const SizedBox( width: 16, ) ]); }, )), ); } return Row( mainAxisAlignment: MainAxisAlignment.center, children: List.generate( 3, (index) => Row( children: [ DefaultPlaceHolder( child: Container( width: 95, height: 95, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(36), ), )), if (index != 2) const SizedBox( width: 16, ) ], ), ), ); }, ), ], ), ); } Column mediaCard(BuildContext context, {required final String title, required final String icon, final Function()? onClick}) { return Column( children: [ InkWell( onTap: onClick, child: Stack( children: [ Container( width: 95, height: 95, padding: const EdgeInsets.only(left: 4, bottom: 4), decoration: BoxDecoration( boxShadow: const [ BoxShadow( color: Color(0x664D4D4D), blurRadius: 6, offset: Offset(0, 1), spreadRadius: 0, ) ], borderRadius: BorderRadius.circular(36), color: context.read().isDark() ? Theme.of(context).colorScheme.surface : AppColors.primaryColor[50], border: Border( top: BorderSide( width: 12, color: context.read().isDark() ? AppColors.black[900] : AppColors.primaryColor[100], ), right: BorderSide( width: 12, color: context.read().isDark() ? AppColors.black[900] : AppColors.primaryColor[100], ))), child: Center( child: SizedBox( width: 48, height: 48, child: ImageNetwork( url: icon, fit: BoxFit.cover, )), ), ), Positioned( top: 10, right: 16, child: Container( width: 4, height: 4, decoration: const BoxDecoration( color: Colors.white, shape: BoxShape.circle), )), Positioned( top: 14, right: 22, child: Container( width: 8, height: 8, decoration: const BoxDecoration( color: Colors.white, shape: BoxShape.circle), )), Positioned( top: 24, right: 12, child: Container( width: 10, height: 10, decoration: const BoxDecoration( color: Colors.white, shape: BoxShape.circle), )), ], ), ), const SizedBox( height: 8, ), Text( title, style: AppTextStyles.body4.copyWith( fontWeight: FontWeight.bold, color: Theme.of(context).colorScheme.onSurface), ) ], ); } Widget bannerCard(BuildContext context, Banners banner) { return Padding( padding: const EdgeInsets.symmetric(horizontal: 16.0).copyWith(bottom: 16), child: GestureDetector( onTap: () async { if (banner.bot != null) { if (banner.bot?.tool ?? false) { context.go(Routes.assistant, extra: banner.bot!.id); } else { context.go(Routes.chat, extra: ChatArgs(bot: banner.bot!)); } } else if (banner.link != null) { if (banner.link!.isURL()) { await launchUrl(Uri.parse(banner.link!), mode: LaunchMode.externalApplication) .onError( (error, stackTrace) { if (kDebugMode) { print('error open Link is: $error'); } return false; }, ); } else { try { if (banner.link!.contains('navigate')) { int? index; if (banner.link!.contains('home')) { index = 0; } else if (banner.link!.contains('assisstant')) { index = 1; } else if (banner.link!.contains('media')) { index = 2; } else if (banner.link!.contains('characters')) { index = 3; } else if (banner.link!.contains('setting')) { index = 4; } screenIndex.value = index!; } else { context.go(banner.link!); } } catch (e) { if (kDebugMode) { print('Error is: $e'); } } } } }, child: Builder( builder: (context) { if (banner.image != null) { return Center( child: ClipRRect( borderRadius: BorderRadius.circular(16), child: ImageNetwork( width: Responsive(context).isMobile() ? double.infinity : 600, height: Responsive(context).isMobile() ? null : 180, url: banner.image, fit: BoxFit.contain, placeholder: DefaultPlaceHolder( child: Container( height: Responsive(context).isMobile() ? 80 : 160, width: double.infinity, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), ), ), ), ), ), ); } return Container( height: Responsive(context).isMobile() ? 80 : 160, padding: const EdgeInsets.all(8), decoration: BoxDecoration( image: DecorationImage( opacity: 0.5, colorFilter: ColorFilter.mode( AppColors.green.defaultShade, BlendMode.multiply), image: const NetworkImage( 'https://s3-alpha-sig.figma.com/img/6353/8887/9fc27292d7cdaf98ca1632ffe66cab33?Expires=1739145600&Key-Pair-Id=APKAQ4GOSFWCW27IBOMQ&Signature=OOoLrh4qH2H~6-6Z2pMM1LnElA1c04FSNMJTJifksA~RSCjQw2H7D-QMwWUcn38BmdUFWDxN1pk6U~WL4lwy36dpHlTq9KyAeFTl-XHhO5wQT8z~xhoRqKpaizAkoiU1bb-G2BD0rQUU~CfbkdpMy8k8iBa6HfXxXiBDxhWYLluUTtCtJHpt1-cQhE2ryYY1sYCgzGZp2uM8hbAFznCwgQxNVt4gNofnLHGRCw8dZ7e2QUzv2CohTRCaV-O1IM2SU2xd44UmciD5z~3DqnxD4bLe9IPtJ22HqiDRL8pMIeNpcrqiUPPQslO9GtMXdXAe4wb8WDU3byegROvbrZ4KbA__'), fit: BoxFit.cover), borderRadius: BorderRadius.circular(16), ), ); }, ), ), ); } Widget carousleSliders() { return BlocBuilder( builder: (context, state) { if (state is BannersSuccess) { final banners = [...state.banners]; if (banners.length >= 3) { banners.removeLast(); banners.removeLast(); } return CarousleSliderBanners( banners: banners, autoPlay: true, enableInfiniteScroll: banners.length > 1, ); } if (state is BannersFail) { return const SizedBox.shrink(); } return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ if (Responsive(context).isDesktop()) Expanded( child: DefaultPlaceHolder( child: Container( height: MediaQuery.sizeOf(context).height * 0.15, margin: const EdgeInsets.all(16).copyWith(right: 0), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(16), bottomLeft: Radius.circular(16))), ), ), ), if (Responsive(context).isDesktop() || Responsive(context).isTablet()) Expanded( child: DefaultPlaceHolder( child: Container( height: MediaQuery.sizeOf(context).height * 0.15, margin: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16)), ), ), ), Expanded( child: DefaultPlaceHolder( child: AspectRatio( aspectRatio: 16 / 9, child: Container( width: double.infinity, height: MediaQuery.sizeOf(context).height * (Responsive(context).isDesktop() ? 0.15 : 0.3), margin: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16)), ), ), ), ), if (Responsive(context).isDesktop() || Responsive(context).isTablet()) Expanded( child: DefaultPlaceHolder( child: Container( height: MediaQuery.sizeOf(context).height * 0.15, margin: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16)), ), ), ), if (Responsive(context).isDesktop()) Expanded( child: DefaultPlaceHolder( child: Container( height: MediaQuery.sizeOf(context).height * 0.15, margin: const EdgeInsets.all(16).copyWith(left: 0), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topRight: Radius.circular(16), bottomRight: Radius.circular(16))), ), ), ), ], ); }, ); } Widget publicBotsList() { return Directionality( textDirection: TextDirection.rtl, child: BlocBuilder( builder: (context, state) { if (state is BotsFail) { return const SizedBox.shrink(); } if (state is BotsSuccess) { final publicBots = state.publicBots; if (publicBots.isEmpty) return const SizedBox.shrink(); return Column( children: [ ListTile( title: Text( 'مدل‌های هوش مصنوعی رایگان', style: AppTextStyles.body4.copyWith( fontWeight: FontWeight.bold, color: Theme.of(context).colorScheme.onSurface), ), leading: Assets.icon.outline.gift .svg(color: Theme.of(context).colorScheme.onSurface), ), SizedBox( width: MediaQuery.sizeOf(context).width, height: 154, child: ListView.builder( itemCount: publicBots.length, physics: const BouncingScrollPhysics(), shrinkWrap: true, scrollDirection: Axis.horizontal, padding: const EdgeInsets.symmetric(horizontal: 8), itemBuilder: (context, index) { final bot = publicBots[index]; return GestureDetector( onTap: () { context.go(Routes.chat, extra: ChatArgs(bot: bot)); }, child: publicBotCard(context, bot)); }, ), ), const SizedBox( height: 16, ) ], ); } return Column( children: [ DefaultPlaceHolder( child: ListTile( title: Text( 'مدل‌های هوش مصنوعی رایگان', style: AppTextStyles.body4 .copyWith(fontWeight: FontWeight.bold), ), leading: Assets.icon.outline.gift.svg(), ), ), SizedBox( width: MediaQuery.sizeOf(context).width, height: 154, child: ListView.builder( itemCount: 10, physics: const NeverScrollableScrollPhysics(), shrinkWrap: true, scrollDirection: Axis.horizontal, padding: const EdgeInsets.symmetric(horizontal: 8), itemBuilder: (context, index) { return publicBotCardPlaceholder(context); }, ), ), const SizedBox( height: 16, ) ], ); }, ), ); } Widget publicBotCard(BuildContext context, Bots bot) { return Container( margin: const EdgeInsets.all(8), decoration: BoxDecoration( boxShadow: const [ BoxShadow( color: Color(0x664D4D4D), blurRadius: 6, offset: Offset(0, 1), spreadRadius: 0, ) ], color: Theme.of(context).colorScheme.surface, borderRadius: BorderRadius.circular(16)), child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.all(12), child: Row( children: [ Container( padding: const EdgeInsets.all(8), width: 60, height: 60, decoration: BoxDecoration( borderRadius: BorderRadius.circular(16), color: context.read().isDark() ? AppColors.black[900] : AppColors.primaryColor[50] // boxShadow: const [ // BoxShadow( // color: Color(0x664D4D4D), // blurRadius: 30, // offset: Offset(0, 1), // spreadRadius: 0, // ) // ], ), child: ImageNetwork( radius: 16, color: Theme.of(context).colorScheme.onSurface, url: bot.image), ), const SizedBox( width: 8, ), Text( bot.name ?? '', style: AppTextStyles.headline6 .copyWith(color: Theme.of(context).colorScheme.onSurface), ) ], ), ), Padding( padding: const EdgeInsets.symmetric(horizontal: 12) .copyWith(bottom: 12), child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: Theme.of(context) .colorScheme .secondary .withAlpha(50), borderRadius: BorderRadius.circular(8)), child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Container( width: 8, height: 8, margin: const EdgeInsets.only(bottom: 4), decoration: BoxDecoration( shape: BoxShape.circle, color: Theme.of(context).colorScheme.secondary), ), const SizedBox( width: 8, ), Text( 'رایگان', style: AppTextStyles.body5.copyWith( color: Theme.of(context).colorScheme.onSurface, fontWeight: FontWeight.bold), ) ], ), ), const SizedBox( width: 8, ), Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: Theme.of(context) .colorScheme .secondary .withAlpha(50), borderRadius: BorderRadius.circular(8)), child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Container( width: 8, height: 8, margin: const EdgeInsets.only(bottom: 4), decoration: BoxDecoration( shape: BoxShape.circle, color: Theme.of(context).colorScheme.secondary), ), const SizedBox( width: 8, ), Text( 'بدون محدودیت', style: AppTextStyles.body5.copyWith( color: Theme.of(context).colorScheme.onSurface, fontWeight: FontWeight.bold), ) ], ), ), ], )), ], ), ); } Widget publicBotCardPlaceholder( BuildContext context, ) { return Container( margin: const EdgeInsets.all(8), decoration: BoxDecoration( boxShadow: const [ BoxShadow( color: Color(0x664D4D4D), blurRadius: 6, offset: Offset(0, 1), spreadRadius: 0, ) ], color: Theme.of(context).colorScheme.surface, borderRadius: BorderRadius.circular(16)), child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.all(12), child: Row( children: [ DefaultPlaceHolder( child: Container( width: 54, height: 54, decoration: BoxDecoration( borderRadius: BorderRadius.circular(16), color: Colors.white, // boxShadow: const [ // BoxShadow( // color: Color(0x664D4D4D), // blurRadius: 30, // offset: Offset(0, 1), // spreadRadius: 0, // ) // ], ), ), ), const SizedBox( width: 8, ), DefaultPlaceHolder( child: Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8)), child: Text( 'bot.name ', style: AppTextStyles.headline6.copyWith( color: Theme.of(context).colorScheme.onSurface), ), ), ) ], ), ), Padding( padding: const EdgeInsets.symmetric(horizontal: 12) .copyWith(bottom: 12), child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ DefaultPlaceHolder( child: Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8)), child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Container( width: 8, height: 8, margin: const EdgeInsets.only(bottom: 4), decoration: BoxDecoration( shape: BoxShape.circle, color: Theme.of(context).colorScheme.secondary), ), const SizedBox( width: 8, ), Text( 'رایگان', style: AppTextStyles.body5.copyWith( color: Theme.of(context).colorScheme.onSurface, fontWeight: FontWeight.bold), ) ], ), ), ), const SizedBox( width: 8, ), DefaultPlaceHolder( child: Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8)), child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Container( width: 8, height: 8, margin: const EdgeInsets.only(bottom: 4), decoration: BoxDecoration( shape: BoxShape.circle, color: Theme.of(context).colorScheme.secondary), ), const SizedBox( width: 8, ), Text( 'بدون محدودیت', style: AppTextStyles.body5.copyWith( color: Theme.of(context).colorScheme.onSurface, fontWeight: FontWeight.bold), ) ], ), ), ), ], )), ], ), ); } Widget toolsList() { return Directionality( textDirection: TextDirection.rtl, child: BlocBuilder( builder: (context, state) { if (state is ToolsFail || state is ToolsEmpty) { return const SizedBox.shrink(); } if (state is ToolsSuccess) { final privateBots = state.categories; return Column( children: [ ListTile( title: Text( 'حرفه‌ای‌ترین ابزارها', style: AppTextStyles.body4.copyWith( fontWeight: FontWeight.bold, color: Theme.of(context).colorScheme.onSurface), ), leading: Assets.icon.outline.toolBox .svg(color: Theme.of(context).colorScheme.onSurface), trailing: GestureDetector( onTap: () => context.go(Routes.tools), child: Text( 'مشاهده همه', style: AppTextStyles.body6.copyWith( color: Theme.of(context).colorScheme.primary, fontWeight: FontWeight.bold), ), ), ), SizedBox( width: double.infinity, height: 158, child: ListView.builder( scrollDirection: Axis.horizontal, itemCount: privateBots.length, shrinkWrap: true, padding: const EdgeInsets.symmetric(horizontal: 8), physics: const BouncingScrollPhysics(), itemBuilder: (context, index) { final cat = privateBots[index]; return ToolCard(cat: cat); }, ), ), const SizedBox( height: 16, ) ], ); } return Column( children: [ DefaultPlaceHolder( child: ListTile( title: Text( 'حرفه‌ای‌ترین ابزارها', style: AppTextStyles.body4.copyWith( fontWeight: FontWeight.bold, color: Theme.of(context).colorScheme.onSurface), ), leading: Assets.icon.outline.crown .svg(color: Theme.of(context).colorScheme.onSurface), ), ), SizedBox( width: MediaQuery.sizeOf(context).width, height: 168, child: ListView.builder( padding: const EdgeInsets.symmetric(horizontal: 16), itemCount: 10, physics: const NeverScrollableScrollPhysics(), scrollDirection: Axis.horizontal, shrinkWrap: true, itemBuilder: (context, index) { return const ToolCardPlaceholder(); }, ), ), ], ); }, ), ); } Widget privateBotsList() { return Directionality( textDirection: TextDirection.rtl, child: BlocBuilder( builder: (context, state) { if (state is BotsFail) { return const SizedBox.shrink(); } if (state is BotsSuccess) { final privateBots = state.privateBots; if (privateBots.isEmpty) return const SizedBox.shrink(); return Column( children: [ ListTile( title: Text( 'مدل‌های هوش مصنوعی حرفه‌ای', style: AppTextStyles.body4 .copyWith(fontWeight: FontWeight.bold), ), leading: Assets.icon.outline.crown .svg(color: Theme.of(context).colorScheme.onSurface), ), SingleChildScrollView( scrollDirection: Axis.horizontal, physics: const BouncingScrollPhysics(), padding: const EdgeInsets.symmetric(horizontal: 8), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: List.generate( (privateBots.length / 2).ceil(), (index) { final bot = privateBots[index]; return GestureDetector( onTap: () { context.go(Routes.chat, extra: ChatArgs(bot: bot)); }, child: privateBotCard(context, bot)); }, ), ), Row( children: List.generate( (privateBots.length / 2).floor(), (i) { final index = (((privateBots.length) / 2).ceil() + i); final bot = privateBots[index]; return GestureDetector( onTap: () { context.go(Routes.chat, extra: ChatArgs(bot: bot)); }, child: privateBotCard(context, bot)); }, ), ), ], ), ), // SizedBox( // width: MediaQuery.sizeOf(context).width, // height: 108 * 2, // child: GridView.count( // padding: const EdgeInsets.symmetric(horizontal: 8), // crossAxisCount: 2, // physics: const BouncingScrollPhysics(), // scrollDirection: Axis.horizontal, // shrinkWrap: true, // childAspectRatio: 0.4, // children: List.generate( // privateBots.length, // (index) { // final bot = privateBots[index]; // return GestureDetector( // onTap: () { // context.go(Routes.chat, // extra: ChatArgs(bot: bot)); // }, // child: privateBotCard(context, bot)); // }, // ), // ), // ), const SizedBox( height: 16, ) ], ); } return Column( children: [ DefaultPlaceHolder( child: ListTile( title: Text( 'مدل‌های هوش مصنوعی حرفه‌ای', style: AppTextStyles.body4.copyWith( fontWeight: FontWeight.bold, color: Theme.of(context).colorScheme.onSurface), ), leading: Assets.icon.outline.crown .svg(color: Theme.of(context).colorScheme.onSurface), ), ), SizedBox( width: MediaQuery.sizeOf(context).width, height: 108, child: ListView.builder( padding: const EdgeInsets.symmetric(horizontal: 16), itemCount: 10, physics: const NeverScrollableScrollPhysics(), scrollDirection: Axis.horizontal, shrinkWrap: true, itemBuilder: (context, index) { return privateBotCardPlaceholder(context); }, ), ), const SizedBox( height: 16, ) ], ); }, ), ); } Widget privateBotCard(BuildContext context, Bots bot) { return Container( margin: const EdgeInsets.all(8), padding: const EdgeInsets.all(12), decoration: BoxDecoration( boxShadow: const [ BoxShadow( color: Color(0x664D4D4D), blurRadius: 6, offset: Offset(0, 1), spreadRadius: 0, ) ], color: Theme.of(context).colorScheme.surface, borderRadius: BorderRadius.circular(16)), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Row( children: [ Container( padding: const EdgeInsets.all(8), width: 60, height: 60, decoration: BoxDecoration( borderRadius: BorderRadius.circular(16), color: context.read().isDark() ? AppColors.black[900] : AppColors.primaryColor[50] // boxShadow: const [ // BoxShadow( // color: Color(0x664D4D4D), // blurRadius: 30, // offset: Offset(0, 1), // spreadRadius: 0, // ) // ], ), child: ImageNetwork( radius: 16, color: Theme.of(context).colorScheme.onSurface, url: bot.image), ), const SizedBox( width: 8, ), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( bot.name ?? '', style: AppTextStyles.headline6.copyWith( color: Theme.of(context).colorScheme.onSurface), ), const SizedBox( height: 4, ), Row( children: [ Assets.icon.outline.coin.svg( color: Theme.of(context).colorScheme.primary, width: 18, height: 18), Text( bot.cost == 0 ? 'رایگان' : 'هر پیام ${bot.cost} سکه', style: AppTextStyles.body5.copyWith( color: AppColors.gray[ context.read().isDark() ? 600 : 900]), ), ], ), ], ) ], ), ], ), ); } Widget privateBotCardPlaceholder(BuildContext context) { return Container( margin: const EdgeInsets.all(8), padding: const EdgeInsets.all(12), decoration: BoxDecoration( boxShadow: const [ BoxShadow( color: Color(0x664D4D4D), blurRadius: 6, offset: Offset(0, 1), spreadRadius: 0, ) ], color: Theme.of(context).colorScheme.surface, borderRadius: BorderRadius.circular(16)), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Row( children: [ DefaultPlaceHolder( child: Container( width: 54, height: 54, decoration: BoxDecoration( borderRadius: BorderRadius.circular(16), color: Colors.white, // boxShadow: const [ // BoxShadow( // color: Color(0x664D4D4D), // blurRadius: 30, // offset: Offset(0, 1), // spreadRadius: 0, // ) // ], ), ), ), const SizedBox( width: 8, ), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ DefaultPlaceHolder( child: Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8)), child: Text( "bot.name ", style: AppTextStyles.headline6.copyWith( color: Theme.of(context).colorScheme.onSurface), ), ), ), const SizedBox( height: 8, ), Row( children: [ DefaultPlaceHolder( child: Assets.icon.outline.coin.svg( color: Theme.of(context).colorScheme.primary, width: 18, height: 18), ), DefaultPlaceHolder( child: Text( 'هر پیام ...', style: AppTextStyles.body5.copyWith( color: AppColors.gray[ context.read().isDark() ? 600 : 900]), ), ), ], ), ], ) ], ), ], ), ); } Widget coursesList(CoursesSuccess state) { return Directionality( textDirection: TextDirection.rtl, child: Column( children: [ ListTile( title: Text( 'رسانه هوشان', style: AppTextStyles.body4.copyWith(fontWeight: FontWeight.bold), ), leading: Assets.icon.outline.hat .svg(color: Theme.of(context).colorScheme.onSurface), trailing: GestureDetector( onTap: () async { await launchUrl( Uri.parse( 'https://houshan.ai/%d8%a8%d9%84%d8%a7%da%af/'), mode: LaunchMode.externalApplication) .onError( (error, stackTrace) { if (kDebugMode) { print('error open Link is: $error'); } return false; }, ); }, child: Text( 'مشاهده همه', style: AppTextStyles.body6.copyWith( color: Theme.of(context).colorScheme.primary, fontWeight: FontWeight.bold), ), ), ), SizedBox( width: double.infinity, height: 280, child: ListView.builder( itemCount: state.courses.length, shrinkWrap: true, physics: const BouncingScrollPhysics(), padding: const EdgeInsets.symmetric(horizontal: 8), scrollDirection: Axis.horizontal, itemBuilder: (context, index) { final course = state.courses[index]; return GestureDetector( onTap: () async { await launchUrl(Uri.parse(course.permalink ?? ''), mode: LaunchMode.externalApplication) .onError( (error, stackTrace) { if (kDebugMode) { print('error open Link is: $error'); } return false; }, ); }, child: courseCard(context, course)); }, ), ), ], ), ); } Widget postsList(PostsSuccess state) { return Directionality( textDirection: TextDirection.rtl, child: Column( children: [ ListTile( title: Text( 'رسانه هوشان', style: AppTextStyles.body4.copyWith(fontWeight: FontWeight.bold), ), leading: Assets.icon.outline.documentText .svg(color: Theme.of(context).colorScheme.onSurface), trailing: GestureDetector( onTap: () async { await launchUrl( Uri.parse( 'https://houshan.ai/%d8%a8%d9%84%d8%a7%da%af/'), mode: LaunchMode.externalApplication) .onError( (error, stackTrace) { if (kDebugMode) { print('error open Link is: $error'); } return false; }, ); }, child: Text( 'مشاهده همه', style: AppTextStyles.body6.copyWith( color: Theme.of(context).colorScheme.primary, fontWeight: FontWeight.bold), ), ), ), SizedBox( width: double.infinity, height: 280, child: ListView.builder( itemCount: state.posts.length, shrinkWrap: true, physics: const BouncingScrollPhysics(), padding: const EdgeInsets.symmetric(horizontal: 8), scrollDirection: Axis.horizontal, itemBuilder: (context, index) { final post = state.posts[index]; return GestureDetector( onTap: () async { await launchUrl(Uri.parse(post.link ?? ''), mode: LaunchMode.externalApplication) .onError( (error, stackTrace) { if (kDebugMode) { print('error open Link is: $error'); } return false; }, ); }, child: postsCard(context, post)); }, ), ), ], ), ); } Widget postsListPlaceholder() { return Directionality( textDirection: TextDirection.rtl, child: Column( children: [ ListTile( title: DefaultPlaceHolder( child: Text( 'رسانه هوشان', style: AppTextStyles.body4.copyWith(fontWeight: FontWeight.bold), ), ), leading: DefaultPlaceHolder( child: Assets.icon.outline.documentText .svg(color: Theme.of(context).colorScheme.onSurface), ), ), SizedBox( width: double.infinity, height: 280, child: ListView.builder( itemCount: 10, shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), padding: const EdgeInsets.symmetric(horizontal: 8), scrollDirection: Axis.horizontal, itemBuilder: (context, index) { return courseCardPlaceholder(context); }, ), ), ], ), ); } Widget courseCardPlaceholder(BuildContext context) { return Container( width: 250, padding: const EdgeInsets.all(8), margin: const EdgeInsets.all(8), decoration: BoxDecoration( boxShadow: const [ BoxShadow( color: Color(0x664D4D4D), blurRadius: 6, offset: Offset(0, 1), spreadRadius: 0, ) ], borderRadius: BorderRadius.circular(16), color: Theme.of(context).colorScheme.surface, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ DefaultPlaceHolder( child: AspectRatio( aspectRatio: 16 / 9, child: Container( width: double.infinity, height: double.infinity, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8)), )), ), const SizedBox(height: 8), DefaultPlaceHolder( child: Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8)), child: Text( "course.name", style: AppTextStyles.body4.copyWith( color: Theme.of(context).colorScheme.onSurface, fontWeight: FontWeight.bold), maxLines: 1, overflow: TextOverflow.ellipsis, ), ), ), const SizedBox(height: 4), DefaultPlaceHolder( child: Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8)), child: Text( "course.name dsadsasd sad ds asd as dasd sd ", style: AppTextStyles.body4.copyWith( color: Theme.of(context).colorScheme.onSurface, fontWeight: FontWeight.bold), maxLines: 1, overflow: TextOverflow.ellipsis, ), ), ), ], ), IgnorePointer( ignoring: true, child: LoadingButton( onPressed: () {}, width: double.infinity, loading: true, color: AppColors.gray[800], child: Text( 'مشاهده دوره', style: AppTextStyles.body4.copyWith(color: Colors.white), )), ) ], ), ); } Widget coursesListPlaceholder() { return Directionality( textDirection: TextDirection.rtl, child: Column( children: [ ListTile( title: DefaultPlaceHolder( child: Text( 'دوره‌های هوش مصنوعی', style: AppTextStyles.body4.copyWith(fontWeight: FontWeight.bold), ), ), leading: DefaultPlaceHolder( child: Assets.icon.outline.hat .svg(color: Theme.of(context).colorScheme.onSurface), ), ), SizedBox( width: double.infinity, height: 280, child: ListView.builder( itemCount: 10, shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), padding: const EdgeInsets.symmetric(horizontal: 8), scrollDirection: Axis.horizontal, itemBuilder: (context, index) { return courseCardPlaceholder(context); }, ), ), ], ), ); } Widget courseCard(BuildContext context, Courses course) { return Container( width: 250, padding: const EdgeInsets.all(8), margin: const EdgeInsets.all(8), decoration: BoxDecoration( boxShadow: const [ BoxShadow( color: Color(0x664D4D4D), blurRadius: 6, offset: Offset(0, 1), spreadRadius: 0, ) ], borderRadius: BorderRadius.circular(16), color: Theme.of(context).colorScheme.surface, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Center( child: AspectRatio( aspectRatio: 16 / 9, child: ImageNetwork( radius: 12, url: course.images != null && course.images!.isNotEmpty ? course.images?.single.src : null)), ), const SizedBox(height: 8), Text( course.name ?? '', style: AppTextStyles.body4.copyWith( color: Theme.of(context).colorScheme.onSurface, fontWeight: FontWeight.bold), maxLines: 2, overflow: TextOverflow.ellipsis, ), ], ), IgnorePointer( ignoring: true, child: LoadingButton( onPressed: () {}, width: double.infinity, child: Text( 'مشاهده دوره', style: AppTextStyles.body4.copyWith(color: Colors.white), )), ) ], ), ); } Widget postsCard(BuildContext context, PostsModel post) { return Container( width: 250, padding: const EdgeInsets.all(8), margin: const EdgeInsets.all(8), decoration: BoxDecoration( boxShadow: const [ BoxShadow( color: Color(0x664D4D4D), blurRadius: 6, offset: Offset(0, 1), spreadRadius: 0, ) ], borderRadius: BorderRadius.circular(16), color: Theme.of(context).colorScheme.surface, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Center( child: AspectRatio( aspectRatio: 16 / 9, child: ImageNetwork( radius: 12, url: post.featuredImageSrc ?? post.content?.rendered?.getFirstmageTag())), ), const SizedBox(height: 8), Text( post.title?.rendered ?? '', style: AppTextStyles.body4.copyWith( color: Theme.of(context).colorScheme.onSurface, fontWeight: FontWeight.bold), maxLines: 2, overflow: TextOverflow.ellipsis, ), ], ), IgnorePointer( ignoring: true, child: LoadingButton( onPressed: () {}, width: double.infinity, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Assets.icon.outline.library.svg(color: Colors.white), const SizedBox( width: 4, ), Text( 'ادامه مطلب', style: AppTextStyles.body4.copyWith(color: Colors.white), ), ], )), ) ], ), ); } }