Houshan-Basa/lib/ui/screens/main/persons/persons_screen.dart

482 lines
23 KiB
Dart

// ignore_for_file: deprecated_member_use
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.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/routes/route_generator.dart';
import 'package:hoshan/core/services/api/dio_service.dart';
import 'package:hoshan/data/model/chat_args.dart';
import 'package:hoshan/data/model/photo_gen_model.dart';
import 'package:hoshan/ui/screens/main/persons/cubit/persons_cubit.dart';
import 'package:hoshan/ui/theme/colors.dart';
import 'package:hoshan/ui/theme/responsive.dart';
import 'package:hoshan/ui/theme/text.dart';
import 'package:hoshan/ui/widgets/components/button/loading_button.dart';
import 'package:hoshan/ui/widgets/components/image/network_image.dart';
class PersonsScreen extends StatefulWidget {
const PersonsScreen({super.key});
@override
State<PersonsScreen> createState() => _PersonsScreenState();
}
class _PersonsScreenState extends State<PersonsScreen> {
@override
Widget build(BuildContext context) {
return Directionality(
textDirection: TextDirection.rtl,
child: BlocBuilder<PersonsCubit, PersonsState>(
builder: (context, state) {
if (state is PersonsSuccess) {
if (state.chars.categories?.isEmpty ?? true) {
return SizedBox.shrink();
}
return SingleChildScrollView(
physics: const BouncingScrollPhysics(),
child: Responsive(context).maxWidthInDesktop(
maxWidth: 1200,
child: (contxet, mw) => Column(
children: [
Responsive(context).isMobile()
? ListView.builder(
itemCount: state.chars.categories?.length ?? 0,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.only(bottom: 32.0),
child: personsCat(context,
state.chars.categories![index], mw),
);
})
: GridView.builder(
itemCount: state.chars.categories?.length ?? 0,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2),
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.only(bottom: 32.0),
child: personsCat(context,
state.chars.categories![index], mw / 2),
);
},
),
Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
children: [
Assets.icon.outline.messageQuestion.svg(
color: Theme.of(context).colorScheme.onSurface),
const SizedBox(
width: 8,
),
Text.rich(
TextSpan(
children: [
const TextSpan(
text: 'جای کدوم شخصیت اینجا خالیه؟ '),
TextSpan(
text: 'بهمون بگو.',
recognizer: TapGestureRecognizer()
..onTap = () {
// DialogHandler(context: context)
// .showPersonsAlert();
context.go(Routes.ticket);
},
style: TextStyle(
fontWeight: FontWeight.bold,
color: Theme.of(context)
.colorScheme
.primary)),
],
),
style: AppTextStyles.body4.copyWith(
color: Theme.of(context).colorScheme.onSurface),
)
],
),
),
],
),
),
);
}
if (state is PersonsFail) {
return SizedBox.shrink();
}
return const Center(
child: CircularProgressIndicator(),
);
},
),
);
}
Column personsCat(BuildContext context, GenModel item, double maxWidth) {
final PageController pageController = PageController(initialPage: 0);
final ValueNotifier<int> currentPageNotifier = ValueNotifier<int>(0);
final ValueNotifier<int> currentSliderNotifier = ValueNotifier<int>(0);
return Column(
children: [
ListTile(
leading: SvgPicture.network(
DioService.baseURL + item.icon!,
color: Theme.of(context).colorScheme.onSurface,
),
title: Text(
item.name ?? '',
style: AppTextStyles.headline6
.copyWith(color: Theme.of(context).colorScheme.onSurface),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
trailing: ValueListenableBuilder<int>(
valueListenable: currentPageNotifier,
builder: (context, currentPage, child) {
return InkWell(
onTap: () {
if (currentPage == 0) {
pageController.animateToPage(1,
duration: const Duration(milliseconds: 500),
curve: Curves.easeInOut);
} else {
pageController.animateToPage(0,
duration: const Duration(milliseconds: 500),
curve: Curves.easeInOut);
}
},
child: Text(
currentPage != 0 ? 'بازگشت' : 'همه',
style: AppTextStyles.body5
.copyWith(color: Theme.of(context).colorScheme.primary),
),
);
},
),
),
const SizedBox(
height: 8,
),
SizedBox(
width: maxWidth,
height: maxWidth * 0.8,
child: PageView(
controller: pageController,
onPageChanged: (value) {
currentPageNotifier.value = value;
},
physics:
const NeverScrollableScrollPhysics(), // Disable swipe, use button
children: [
// Second Widget
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Flexible(
child: CarouselSlider.builder(
itemCount: item.bots?.length ?? 0,
itemBuilder: (context, index, realIndex) {
if (item.bots == null || item.bots!.isEmpty) {
return SizedBox();
}
final bot = item.bots![index];
return Padding(
padding: const EdgeInsets.all(8.0),
child: InkWell(
onTap: () {
context.go(Routes.chat,
extra: ChatArgs(bot: bot, isPerson: true));
},
child: Stack(
children: [
ImageNetwork(
width: double.infinity,
height: double.infinity,
radius: 16,
url: bot.image ?? ''),
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.start,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
bot.name ?? '',
style: AppTextStyles.body6.copyWith(
color: Colors.white,
fontWeight: FontWeight.bold),
),
Row(
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(
top: 4.0),
child: Text(
bot.cost == 0 ||
bot.cost == null
? 'رایگان'
: bot.cost.toString(),
style: AppTextStyles.body6
.copyWith(
color: Colors.white),
),
),
const SizedBox(
width: 4,
),
Assets.icon.outline.coin.svg(
color: Colors.white,
width: 14,
height: 14)
],
)
],
),
))
],
),
),
);
},
options: CarouselOptions(
scrollPhysics: const NeverScrollableScrollPhysics(),
height: double.infinity,
autoPlay: true,
aspectRatio: 1 / 1,
viewportFraction: 1 / 3,
autoPlayInterval: const Duration(seconds: 3),
autoPlayAnimationDuration:
const Duration(milliseconds: 800),
scrollDirection: Axis.vertical,
enableInfiniteScroll: true,
onPageChanged: (index, reason) {
currentSliderNotifier.value = index;
},
),
),
),
SizedBox(
width: maxWidth * 0.6,
child: ValueListenableBuilder(
valueListenable: currentSliderNotifier,
builder: (context, index, child) {
final bot = item.bots![index];
return AnimatedSwitcher(
duration: const Duration(milliseconds: 500),
transitionBuilder:
(Widget child, Animation<double> animation) {
return FadeTransition(
opacity: animation, child: child);
},
child: Column(
key: ValueKey<int>(index),
children: [
Expanded(
child: Stack(
children: [
ImageNetwork(
width: double.infinity,
height: double.infinity,
radius: 16,
url: bot.image ?? ''),
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.start,
mainAxisAlignment:
MainAxisAlignment.end,
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.end,
children: [
Padding(
padding:
const EdgeInsets.only(
top: 4.0),
child: Text(
bot.cost == 0 ||
bot.cost == null
? 'رایگان'
: bot.cost.toString(),
style: AppTextStyles.body3
.copyWith(
color:
Colors.white),
),
),
const SizedBox(
width: 4,
),
Assets.icon.outline.coin.svg(
color: Colors.white,
width: 18,
height: 18)
],
)
],
),
))
],
)),
const SizedBox(
height: 12,
),
Row(
children: [
Expanded(
child: LoadingButton(
onPressed: () {
context.go(Routes.chat,
extra: ChatArgs(
bot: bot, isPerson: true));
},
width: double.infinity,
child: Text(
'گپ با ${bot.name ?? ''}',
style: AppTextStyles.body4
.copyWith(color: Colors.white),
),
),
),
],
)
],
),
);
}),
),
],
),
),
SizedBox(
height: maxWidth,
child: GridView.builder(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
childAspectRatio: 1 / 1,
crossAxisSpacing: 8,
mainAxisSpacing: 8,
maxCrossAxisExtent: maxWidth / 2),
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: item.bots?.length ?? 0,
physics: const BouncingScrollPhysics(),
padding: const EdgeInsets.symmetric(horizontal: 8),
itemBuilder: (context, index) {
final bot = item.bots![index];
return InkWell(
onTap: () {
context.go(Routes.chat,
extra: ChatArgs(bot: bot, isPerson: true));
},
child: Stack(
children: [
ImageNetwork(radius: 16, url: bot.image ?? ''),
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.start,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
bot.name ?? '',
style: AppTextStyles.body6.copyWith(
color: Colors.white,
fontWeight: FontWeight.bold),
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(top: 4.0),
child: Text(
bot.cost == 0 || bot.cost == null
? 'رایگان'
: bot.cost.toString(),
style: AppTextStyles.body6
.copyWith(color: Colors.white),
),
),
const SizedBox(
width: 4,
),
Assets.icon.outline.coin.svg(
color: Colors.white,
width: 14,
height: 14)
],
)
],
),
))
],
),
);
},
),
),
],
),
)
],
);
}
}