366 lines
14 KiB
Dart
366 lines
14 KiB
Dart
// ignore_for_file: deprecated_member_use_from_same_package
|
|
|
|
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/data/model/ai/bots_model.dart';
|
|
import 'package:hoshan/data/model/empty_states_enum.dart';
|
|
import 'package:hoshan/data/model/tools_categories_model.dart';
|
|
import 'package:hoshan/ui/screens/main/assistant/bloc/global_assistants_bloc.dart';
|
|
import 'package:hoshan/ui/screens/main/forum/cubit/category_cubit.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/bot/bot_grid_card.dart';
|
|
import 'package:hoshan/ui/widgets/components/bot/bot_grid_card_placeholder.dart';
|
|
import 'package:hoshan/ui/widgets/sections/empty/empty_states.dart';
|
|
import 'package:hoshan/ui/widgets/sections/loading/default_placeholder.dart';
|
|
|
|
class GlobalAssistantsScreen extends StatefulWidget {
|
|
const GlobalAssistantsScreen({super.key});
|
|
|
|
@override
|
|
State<GlobalAssistantsScreen> createState() => _GlobalAssistantsScreenState();
|
|
}
|
|
|
|
ValueNotifier<Categories> initiaGlobalCatItem =
|
|
ValueNotifier(Categories(id: -1, name: 'برگزیدهها'));
|
|
|
|
class _GlobalAssistantsScreenState extends State<GlobalAssistantsScreen> {
|
|
void onSelect(BuildContext contxet, Bots bot) {
|
|
context.go(Routes.assistant, extra: bot.id);
|
|
}
|
|
|
|
void onMark(bool marked, Bots bot, int index) {
|
|
final newBot = bot;
|
|
// if (initialItem.value.id == -2) {
|
|
// context.read<GlobalAssistantsBloc>().add(RemoveGlobalAssistantBot(
|
|
// oldAssistantsIndex: index,
|
|
// oldBot: newBot,
|
|
// ));
|
|
// return;
|
|
// }
|
|
newBot.marked = marked;
|
|
context.read<GlobalAssistantsBloc>().add(ChangeGlobalAssistantBot(
|
|
oldAssistantsIndex: index, oldBot: bot, newBot: newBot));
|
|
}
|
|
|
|
final ScrollController scrollController = ScrollController();
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return RefreshIndicator(
|
|
backgroundColor: Theme.of(context).colorScheme.surface,
|
|
color: Theme.of(context).colorScheme.primary,
|
|
onRefresh: () async {
|
|
context
|
|
.read<GlobalAssistantsBloc>()
|
|
.add(GetGlobalAssistants(category: initiaGlobalCatItem.value.id));
|
|
scrollController.jumpTo(0);
|
|
},
|
|
child: Column(
|
|
children: [
|
|
BlocBuilder<CategoryCubit, CategoryState>(
|
|
builder: (context, state) {
|
|
if (state is CategoryLoading) {
|
|
return SizedBox(
|
|
height: 36,
|
|
child: ListView.builder(
|
|
padding:
|
|
const EdgeInsetsDirectional.symmetric(horizontal: 16),
|
|
itemCount: 10,
|
|
physics: const NeverScrollableScrollPhysics(),
|
|
scrollDirection: Axis.horizontal,
|
|
itemBuilder: (context, index) {
|
|
return categoryPlaceholder();
|
|
},
|
|
),
|
|
);
|
|
}
|
|
if (state is CategorySuccess) {
|
|
final categories = [
|
|
Categories(id: -1, name: 'برگزیدهها'),
|
|
Categories(id: -2, name: 'علاقهمندیها'),
|
|
...state.categories
|
|
];
|
|
return Padding(
|
|
padding: const EdgeInsets.symmetric(vertical: 12),
|
|
child: Directionality(
|
|
textDirection: TextDirection.rtl,
|
|
child: SizedBox(
|
|
height: 36,
|
|
width: MediaQuery.sizeOf(context).width,
|
|
child: ListView.builder(
|
|
padding: const EdgeInsetsDirectional.symmetric(
|
|
horizontal: 16),
|
|
scrollDirection: Axis.horizontal,
|
|
physics: const BouncingScrollPhysics(),
|
|
itemCount: categories.length,
|
|
itemBuilder: (context, index) {
|
|
final cat = categories[index];
|
|
return GestureDetector(
|
|
onTap: () {
|
|
if (context.read<GlobalAssistantsBloc>().state
|
|
is GlobalAssistantsLoading) {
|
|
return;
|
|
}
|
|
if (initiaGlobalCatItem.value.id == cat.id) {
|
|
return;
|
|
}
|
|
context.read<GlobalAssistantsBloc>().add(
|
|
GetGlobalAssistants(category: cat.id));
|
|
initiaGlobalCatItem.value = cat;
|
|
},
|
|
child: categoryContainer(cat));
|
|
},
|
|
)),
|
|
),
|
|
);
|
|
}
|
|
return const SizedBox.shrink();
|
|
},
|
|
),
|
|
Expanded(
|
|
child: BlocBuilder<GlobalAssistantsBloc, GlobalAssistantsState>(
|
|
builder: (context, state) {
|
|
if (state is GlobalAssistantsFail) {
|
|
return EmptyStates.getEmptyState(
|
|
status: EmptyStatesEnum.server, scale: 0.8);
|
|
}
|
|
if (state is GlobalAssistantsSuccess) {
|
|
final assistants = state.assistants;
|
|
if (assistants.isEmpty) {
|
|
if (initiaGlobalCatItem.value.id == -2) {
|
|
return Center(
|
|
child: Column(
|
|
children: [
|
|
const SizedBox(
|
|
height: 32,
|
|
),
|
|
Assets.icon.gif.emptyBookmarks.image(),
|
|
Padding(
|
|
padding:
|
|
const EdgeInsets.symmetric(horizontal: 16.0),
|
|
child: Text(
|
|
'اینجا دستیارهای نشاندار شده شما نمایش داده میشوند. هنوز موردی اضافه نکردهاید. برای دسترسی سریعتر، دستیارهای دلخواهتان را بوکمارک کنید!',
|
|
style: AppTextStyles.body4.copyWith(
|
|
color:
|
|
Theme.of(context).colorScheme.onSurface),
|
|
textDirection: TextDirection.rtl,
|
|
textAlign: TextAlign.center,
|
|
),
|
|
)
|
|
],
|
|
));
|
|
}
|
|
|
|
return EmptyStates.getEmptyState(
|
|
status: EmptyStatesEnum.assistant,
|
|
title: 'دستیاری وجود ندارد',
|
|
height: MediaQuery.sizeOf(context).height * 0.4,
|
|
);
|
|
}
|
|
return Directionality(
|
|
textDirection: TextDirection.rtl,
|
|
child: ListView.builder(
|
|
itemCount: assistants.length,
|
|
shrinkWrap: true,
|
|
padding: EdgeInsets.only(bottom: 90),
|
|
physics: const BouncingScrollPhysics(),
|
|
itemBuilder: (context, index) {
|
|
final assistant = assistants[index];
|
|
return state.category == null ||
|
|
state.category == -1 ||
|
|
state.category == -2
|
|
? Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Builder(builder: (context) {
|
|
return ListTile(
|
|
title: Text(
|
|
assistant.categoryName ?? '',
|
|
style: AppTextStyles.body4.copyWith(
|
|
color: Theme.of(context)
|
|
.colorScheme
|
|
.onSurface),
|
|
),
|
|
);
|
|
}),
|
|
rowsList(assistant.bots!)
|
|
],
|
|
)
|
|
: gridsList(assistant.bots!);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
return Directionality(
|
|
textDirection: TextDirection.rtl,
|
|
child: ListView.builder(
|
|
itemCount: 10,
|
|
shrinkWrap: true,
|
|
physics: const NeverScrollableScrollPhysics(),
|
|
itemBuilder: (context, index) {
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(
|
|
horizontal: 16, vertical: 8),
|
|
child: DefaultPlaceHolder(
|
|
child: Container(
|
|
decoration: BoxDecoration(
|
|
color: Colors.white,
|
|
borderRadius: BorderRadius.circular(16)),
|
|
child: Text(
|
|
'عمومی',
|
|
style: AppTextStyles.body4
|
|
.copyWith(color: AppColors.black[900]),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
rowsListPlaceHolder()
|
|
],
|
|
);
|
|
},
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget gridsList(List<Bots> bots) {
|
|
return GridView.builder(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
|
crossAxisCount: Responsive(context).isMobile()
|
|
? 2
|
|
: Responsive(context).isTablet()
|
|
? 3
|
|
: 5,
|
|
crossAxisSpacing: 16,
|
|
mainAxisSpacing: 16,
|
|
mainAxisExtent: 150),
|
|
itemCount: bots.length,
|
|
physics: const NeverScrollableScrollPhysics(),
|
|
shrinkWrap: true,
|
|
itemBuilder: (context, index) {
|
|
return GestureDetector(
|
|
onTap: () => onSelect(context, bots[index]),
|
|
child: BotGridCard(
|
|
onMark: (marked) => onMark(marked, bots[index], index),
|
|
bot: bots[index],
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
Widget rowsList(List<Bots> bots) {
|
|
return SizedBox(
|
|
height: 170,
|
|
child: ListView.builder(
|
|
shrinkWrap: true,
|
|
scrollDirection: Axis.horizontal,
|
|
physics: const BouncingScrollPhysics(),
|
|
padding: const EdgeInsets.symmetric(horizontal: 8),
|
|
itemCount: bots.length,
|
|
itemBuilder: (context, index) {
|
|
return SizedBox(
|
|
width: 180,
|
|
child: Padding(
|
|
padding:
|
|
const EdgeInsets.symmetric(horizontal: 8.0, vertical: 8),
|
|
child: GestureDetector(
|
|
onTap: () => onSelect(context, bots[index]),
|
|
child: BotGridCard(
|
|
onMark: (marked) => onMark(marked, bots[index], index),
|
|
bot: bots[index],
|
|
),
|
|
),
|
|
));
|
|
},
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget rowsListPlaceHolder() {
|
|
return SizedBox(
|
|
height: 170,
|
|
child: ListView.builder(
|
|
shrinkWrap: true,
|
|
scrollDirection: Axis.horizontal,
|
|
physics: const NeverScrollableScrollPhysics(),
|
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
|
itemCount: 10,
|
|
itemBuilder: (context, index) {
|
|
return SizedBox(
|
|
width: 180,
|
|
child: Padding(
|
|
padding:
|
|
const EdgeInsets.symmetric(horizontal: 8.0, vertical: 8),
|
|
child: BotGridCardPlaceholder(
|
|
index: index,
|
|
),
|
|
));
|
|
},
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget categoryContainer(Categories cat) {
|
|
return ValueListenableBuilder(
|
|
valueListenable: initiaGlobalCatItem,
|
|
builder: (context, item, child) {
|
|
final active = item.id == cat.id;
|
|
return Container(
|
|
padding: const EdgeInsets.all(0),
|
|
margin: const EdgeInsets.symmetric(horizontal: 4),
|
|
constraints: const BoxConstraints(minWidth: 100),
|
|
alignment: Alignment.center,
|
|
decoration: BoxDecoration(
|
|
color: active
|
|
? AppColors.primaryColor[
|
|
context.read<ThemeModeCubit>().isDark() ? 500 : 50]
|
|
: AppColors.gray[
|
|
context.read<ThemeModeCubit>().isDark() ? 900 : 400],
|
|
borderRadius: BorderRadius.circular(360)),
|
|
child: Text(
|
|
cat.name ?? '',
|
|
style: AppTextStyles.body4.copyWith(
|
|
color: context.read<ThemeModeCubit>().isDark()
|
|
? Colors.white
|
|
: active
|
|
? AppColors.primaryColor.defaultShade
|
|
: AppColors.black[300]),
|
|
),
|
|
);
|
|
});
|
|
}
|
|
|
|
Widget categoryPlaceholder() {
|
|
return DefaultPlaceHolder(
|
|
child: Container(
|
|
padding: const EdgeInsets.all(8),
|
|
margin: const EdgeInsets.symmetric(horizontal: 4),
|
|
constraints: const BoxConstraints(minWidth: 100),
|
|
alignment: Alignment.center,
|
|
decoration: BoxDecoration(
|
|
color: Colors.white, borderRadius: BorderRadius.circular(360)),
|
|
child: Text(
|
|
'for placeholder',
|
|
style: AppTextStyles.body4,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|