forked from eatvio/eatvio_app
feat(plans): hide for ios
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
String baseUrl = 'https://eatvio.ru';
|
||||
bool hidePlans = true;
|
||||
|
||||
const List<int> durationValues = [7, 14, 21];
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:easy_debounce/easy_debounce.dart';
|
||||
import 'package:eatvio_app/core/const.dart';
|
||||
import 'package:eatvio_app/core/widgets/add_item_button.dart';
|
||||
import 'package:eatvio_app/core/widgets/custom_search_bar.dart';
|
||||
import 'package:eatvio_app/features/create_diet/presentation/create_diet_screen.dart';
|
||||
@@ -32,24 +33,12 @@ class FeedScreen extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider<RecipesCubit>(
|
||||
create: (context) => sl<RecipesCubit>()..loadRecipesList(),
|
||||
),
|
||||
BlocProvider<FeedProfileCubit>(
|
||||
create: (context) => sl<FeedProfileCubit>()..getProfile(),
|
||||
),
|
||||
BlocProvider<FeedCubit>(
|
||||
create: (context) => sl<FeedCubit>()..loadFeedBlogPostList(),
|
||||
),
|
||||
BlocProvider<DietsCubit>(
|
||||
create: (context) => sl<DietsCubit>()..loadDiets(),
|
||||
),
|
||||
BlocProvider<PlansCubit>(
|
||||
create: (context) => sl<PlansCubit>()..loadPlans(),
|
||||
),
|
||||
BlocProvider<ConsultantsCubit>(
|
||||
create: (context) => sl<ConsultantsCubit>()..getConsultants(),
|
||||
),
|
||||
BlocProvider<RecipesCubit>(create: (context) => sl<RecipesCubit>()..loadRecipesList()),
|
||||
BlocProvider<FeedProfileCubit>(create: (context) => sl<FeedProfileCubit>()..getProfile()),
|
||||
BlocProvider<FeedCubit>(create: (context) => sl<FeedCubit>()..loadFeedBlogPostList()),
|
||||
BlocProvider<DietsCubit>(create: (context) => sl<DietsCubit>()..loadDiets()),
|
||||
if (!hidePlans) BlocProvider<PlansCubit>(create: (context) => sl<PlansCubit>()..loadPlans()),
|
||||
BlocProvider<ConsultantsCubit>(create: (context) => sl<ConsultantsCubit>()..getConsultants()),
|
||||
],
|
||||
child: const FeedScreenContent(),
|
||||
);
|
||||
@@ -69,7 +58,8 @@ class _FeedScreenContentState extends State<FeedScreenContent> {
|
||||
final dietsController = TextEditingController();
|
||||
final plansController = TextEditingController();
|
||||
final consultantsController = TextEditingController();
|
||||
final List<String> chipsLabelList = ['Все', 'Рецепты', 'Диеты', 'Планы питания', 'Консультанты'];
|
||||
|
||||
late final List<String> chipsLabelList;
|
||||
int _selectedChipIndex = 0;
|
||||
final blogPostsScrollController = ScrollController();
|
||||
final recipesScrollController = ScrollController();
|
||||
@@ -78,12 +68,13 @@ class _FeedScreenContentState extends State<FeedScreenContent> {
|
||||
final consultantsScrollController = ScrollController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
void initState() {
|
||||
// Initialize chipsLabelList based on hidePlans setting
|
||||
chipsLabelList = hidePlans ? ['Все', 'Рецепты', 'Диеты', 'Консультанты'] : ['Все', 'Рецепты', 'Диеты', 'Планы питания', 'Консультанты'];
|
||||
|
||||
consultantsScrollController.addListener(_onScrollConsultants);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void _onScrollConsultants() {
|
||||
if (consultantsScrollController.offset >= consultantsScrollController.position.maxScrollExtent && !consultantsScrollController.position.outOfRange) {}
|
||||
@@ -108,45 +99,36 @@ class _FeedScreenContentState extends State<FeedScreenContent> {
|
||||
heroTag: 'recipesTagsFilter',
|
||||
backgroundColor: appTheme.blueA400,
|
||||
shape: const CircleBorder(),
|
||||
child: const Icon(
|
||||
Icons.filter_list_rounded,
|
||||
color: Colors.white,
|
||||
),
|
||||
child: const Icon(Icons.filter_list_rounded, color: Colors.white),
|
||||
onPressed: () async {
|
||||
final recipesCubit = context.read<RecipesCubit>();
|
||||
await showModalBottomSheet(
|
||||
useRootNavigator: true,
|
||||
context: context,
|
||||
builder: (context) => TagsModalWidget(
|
||||
recipesCubit: recipesCubit,
|
||||
),
|
||||
builder: (context) => TagsModalWidget(recipesCubit: recipesCubit),
|
||||
);
|
||||
recipesCubit.loadRecipesList();
|
||||
},
|
||||
)
|
||||
: null,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.white,
|
||||
toolbarHeight: 0,
|
||||
),
|
||||
appBar: AppBar(backgroundColor: Colors.white, toolbarHeight: 0),
|
||||
backgroundColor: Colors.grey.shade200,
|
||||
body: NestedScrollView(
|
||||
controller: switch (_selectedChipIndex) {
|
||||
0 => blogPostsScrollController,
|
||||
1 => recipesScrollController,
|
||||
2 => dietsScrollController,
|
||||
3 => plansScrollController,
|
||||
4 => consultantsScrollController,
|
||||
_ => blogPostsScrollController
|
||||
3 when !hidePlans => plansScrollController,
|
||||
3 when hidePlans => consultantsScrollController,
|
||||
4 when !hidePlans => consultantsScrollController,
|
||||
_ => blogPostsScrollController,
|
||||
},
|
||||
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
|
||||
return [
|
||||
BlocBuilder<FeedProfileCubit, ProfileState>(
|
||||
builder: (context, state) {
|
||||
return SliverAppBar(
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.vertical(bottom: Radius.circular(12)),
|
||||
),
|
||||
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.vertical(bottom: Radius.circular(12))),
|
||||
backgroundColor: Colors.white,
|
||||
foregroundColor: Colors.white,
|
||||
automaticallyImplyLeading: false,
|
||||
@@ -172,78 +154,71 @@ class _FeedScreenContentState extends State<FeedScreenContent> {
|
||||
searchController: switch (_selectedChipIndex) {
|
||||
1 => recipesController,
|
||||
2 => dietsController,
|
||||
3 => plansController,
|
||||
4 => consultantsController,
|
||||
3 when !hidePlans => plansController,
|
||||
3 when hidePlans => consultantsController,
|
||||
4 when !hidePlans => consultantsController,
|
||||
_ => postsController,
|
||||
},
|
||||
onChanged: (query) {
|
||||
if (query.length > 2) {
|
||||
EasyDebounce.debounce(
|
||||
'searchFeed',
|
||||
const Duration(milliseconds: 500),
|
||||
() {
|
||||
switch (_selectedChipIndex) {
|
||||
case 0:
|
||||
context.read<FeedCubit>().loadFeedBlogPostList(query: query);
|
||||
break;
|
||||
case 1:
|
||||
context.read<RecipesCubit>().loadRecipesList(query: query);
|
||||
break;
|
||||
case 2:
|
||||
context.read<DietsCubit>().loadDiets(query: query);
|
||||
break;
|
||||
case 3:
|
||||
context.read<PlansCubit>().loadPlans(query: query);
|
||||
break;
|
||||
case 4:
|
||||
context.read<ConsultantsCubit>().getConsultants();
|
||||
break;
|
||||
}
|
||||
},
|
||||
);
|
||||
EasyDebounce.debounce('searchFeed', const Duration(milliseconds: 500), () {
|
||||
switch (_selectedChipIndex) {
|
||||
case 0:
|
||||
context.read<FeedCubit>().loadFeedBlogPostList(query: query);
|
||||
break;
|
||||
case 1:
|
||||
context.read<RecipesCubit>().loadRecipesList(query: query);
|
||||
break;
|
||||
case 2:
|
||||
context.read<DietsCubit>().loadDiets(query: query);
|
||||
break;
|
||||
case 3 when !hidePlans:
|
||||
context.read<PlansCubit>().loadPlans(query: query);
|
||||
break;
|
||||
case 3 when hidePlans:
|
||||
case 4 when !hidePlans:
|
||||
context.read<ConsultantsCubit>().getConsultants();
|
||||
break;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
EasyDebounce.debounce(
|
||||
'searchFeed',
|
||||
const Duration(milliseconds: 500),
|
||||
() {
|
||||
switch (_selectedChipIndex) {
|
||||
case 0:
|
||||
context.read<FeedCubit>().loadFeedBlogPostList();
|
||||
break;
|
||||
case 1:
|
||||
context.read<RecipesCubit>().loadRecipesList();
|
||||
break;
|
||||
case 2:
|
||||
context.read<DietsCubit>().loadDiets();
|
||||
break;
|
||||
case 3:
|
||||
context.read<PlansCubit>().loadPlans();
|
||||
break;
|
||||
case 4:
|
||||
context.read<ConsultantsCubit>().getConsultants();
|
||||
break;
|
||||
}
|
||||
},
|
||||
);
|
||||
EasyDebounce.debounce('searchFeed', const Duration(milliseconds: 500), () {
|
||||
switch (_selectedChipIndex) {
|
||||
case 0:
|
||||
context.read<FeedCubit>().loadFeedBlogPostList();
|
||||
break;
|
||||
case 1:
|
||||
context.read<RecipesCubit>().loadRecipesList();
|
||||
break;
|
||||
case 2:
|
||||
context.read<DietsCubit>().loadDiets();
|
||||
break;
|
||||
case 3 when !hidePlans:
|
||||
context.read<PlansCubit>().loadPlans();
|
||||
break;
|
||||
case 3 when hidePlans:
|
||||
case 4 when !hidePlans:
|
||||
context.read<ConsultantsCubit>().getConsultants();
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
switch (_selectedChipIndex) {
|
||||
1 => AddItemButton(
|
||||
onTap: () => GoRouter.of(context).pushNamed(RecipeCreateScreen.name),
|
||||
),
|
||||
1 => AddItemButton(onTap: () => GoRouter.of(context).pushNamed(RecipeCreateScreen.name)),
|
||||
2 => AddItemButton(
|
||||
onTap: state.profile?.roles.contains('consultant') ?? false
|
||||
? () async {
|
||||
await GoRouter.of(context).pushNamed(CreateDietScreen.name);
|
||||
}
|
||||
: null,
|
||||
),
|
||||
3 => AddItemButton(
|
||||
onTap: state.profile?.roles.contains('consultant') ?? false ? () => GoRouter.of(context).pushNamed(CreatePlanScreen.name) : null,
|
||||
),
|
||||
_ => const AddItemButton()
|
||||
onTap: state.profile?.roles.contains('consultant') ?? false
|
||||
? () async {
|
||||
await GoRouter.of(context).pushNamed(CreateDietScreen.name);
|
||||
}
|
||||
: null,
|
||||
),
|
||||
3 when !hidePlans => AddItemButton(
|
||||
onTap: state.profile?.roles.contains('consultant') ?? false ? () => GoRouter.of(context).pushNamed(CreatePlanScreen.name) : null,
|
||||
),
|
||||
_ => const AddItemButton(),
|
||||
},
|
||||
],
|
||||
),
|
||||
@@ -256,8 +231,9 @@ class _FeedScreenContentState extends State<FeedScreenContent> {
|
||||
0 => const BlogPosts(),
|
||||
1 => const Recipes(),
|
||||
2 => const Diets(),
|
||||
3 => const Plans(),
|
||||
4 => const Consultants(),
|
||||
3 when !hidePlans => const Plans(),
|
||||
3 when hidePlans => const Consultants(),
|
||||
4 when !hidePlans => const Consultants(),
|
||||
_ => Center(child: Text(chipsLabelList[_selectedChipIndex])),
|
||||
},
|
||||
),
|
||||
|
||||
@@ -2,12 +2,7 @@ import 'package:eatvio_app/features/feed/presentation/widgets/choice_chip_widget
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
class ChipGroup extends StatelessWidget {
|
||||
const ChipGroup({
|
||||
super.key,
|
||||
required this.selectedChipIndex,
|
||||
required this.chipsLabelList,
|
||||
required this.setSelectedChipIndex,
|
||||
});
|
||||
const ChipGroup({super.key, required this.selectedChipIndex, required this.chipsLabelList, required this.setSelectedChipIndex});
|
||||
final int selectedChipIndex;
|
||||
final List<String> chipsLabelList;
|
||||
final void Function(int) setSelectedChipIndex;
|
||||
@@ -22,7 +17,7 @@ class ChipGroup extends StatelessWidget {
|
||||
child: Row(
|
||||
children: [
|
||||
...List.generate(
|
||||
5,
|
||||
chipsLabelList.length,
|
||||
(index) => Padding(
|
||||
padding: const EdgeInsets.only(right: 8.0),
|
||||
child: ChoiceChipWidget(
|
||||
|
||||
@@ -45,10 +45,7 @@ import 'package:url_launcher/url_launcher.dart';
|
||||
class ProfileScreen extends StatefulWidget {
|
||||
final Author? author;
|
||||
|
||||
const ProfileScreen({
|
||||
super.key,
|
||||
this.author,
|
||||
});
|
||||
const ProfileScreen({super.key, this.author});
|
||||
|
||||
@override
|
||||
State<ProfileScreen> createState() => _ProfileScreenState();
|
||||
@@ -91,7 +88,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
}
|
||||
if (isFirstFetch) {
|
||||
canSub = !state.profile.isEntitySubscribedByMe;
|
||||
if (state.profile.roles.contains('consultant')) {
|
||||
if (state.profile.roles.contains('consultant') && !hidePlans) {
|
||||
plansCubit.getPlans(state.profile.slug);
|
||||
}
|
||||
isFirstFetch = false;
|
||||
@@ -109,10 +106,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Scaffold(
|
||||
appBar: AppBar(),
|
||||
body: const Loader(),
|
||||
);
|
||||
return Scaffold(appBar: AppBar(), body: const Loader());
|
||||
}
|
||||
},
|
||||
),
|
||||
@@ -130,9 +124,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.vertical(
|
||||
bottom: Radius.circular(16),
|
||||
),
|
||||
borderRadius: BorderRadius.vertical(bottom: Radius.circular(16)),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
@@ -147,28 +139,15 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
const SizedBox(width: 16),
|
||||
const Text(
|
||||
'Консультант',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(
|
||||
0xFF323F4B,
|
||||
),
|
||||
),
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xFF323F4B)),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF6FAFF),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
decoration: BoxDecoration(color: const Color(0xFFF6FAFF), borderRadius: BorderRadius.circular(12)),
|
||||
child: Text(
|
||||
'${state.consultantInfo!.ratingPlace}-й в рейтинге',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: appTheme.blueA400,
|
||||
),
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: appTheme.blueA400),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -177,17 +156,10 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
const Row(
|
||||
children: [
|
||||
SizedBox(width: 16),
|
||||
Icon(
|
||||
Icons.done_rounded,
|
||||
color: Colors.green,
|
||||
),
|
||||
Icon(Icons.done_rounded, color: Colors.green),
|
||||
Text(
|
||||
'Медицинское образование',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF323F4B),
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
style: TextStyle(color: Color(0xFF323F4B), fontSize: 14, fontWeight: FontWeight.w600),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -205,7 +177,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
if (state.profile.roles.contains('consultant') && state.consultantInfo != null) _socialLinks(state),
|
||||
if (state.profile.roles.contains('consultant') && state.consultantInfo != null) _education(state),
|
||||
if (state.profile.roles.contains('consultant') && state.consultantInfo != null) _diplomasAndCertificates(state),
|
||||
if (state.profile.roles.contains('consultant') && state.consultantInfo != null) _activePlans(state),
|
||||
if (state.profile.roles.contains('consultant') && state.consultantInfo != null && !hidePlans) _activePlans(state),
|
||||
_blogPosts(state),
|
||||
],
|
||||
),
|
||||
@@ -216,9 +188,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
Scaffold _myProfileScreen(ProfileStateLoaded state) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.grey.shade200,
|
||||
appBar: AppBar(
|
||||
toolbarHeight: widget.author == null ? 0 : null,
|
||||
),
|
||||
appBar: AppBar(toolbarHeight: widget.author == null ? 0 : null),
|
||||
body: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -226,9 +196,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.vertical(
|
||||
bottom: Radius.circular(16),
|
||||
),
|
||||
borderRadius: BorderRadius.vertical(bottom: Radius.circular(16)),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
@@ -243,28 +211,15 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
const SizedBox(width: 16),
|
||||
const Text(
|
||||
'Консультант',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(
|
||||
0xFF323F4B,
|
||||
),
|
||||
),
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xFF323F4B)),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF6FAFF),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
decoration: BoxDecoration(color: const Color(0xFFF6FAFF), borderRadius: BorderRadius.circular(12)),
|
||||
child: Text(
|
||||
'${state.consultantInfo!.ratingPlace}-й в рейтинге',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: appTheme.blueA400,
|
||||
),
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: appTheme.blueA400),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -273,17 +228,10 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
const Row(
|
||||
children: [
|
||||
SizedBox(width: 16),
|
||||
Icon(
|
||||
Icons.done_rounded,
|
||||
color: Colors.green,
|
||||
),
|
||||
Icon(Icons.done_rounded, color: Colors.green),
|
||||
Text(
|
||||
'Медицинское образование',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF323F4B),
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
style: TextStyle(color: Color(0xFF323F4B), fontSize: 14, fontWeight: FontWeight.w600),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -299,7 +247,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
if (state.profile.roles.contains('consultant')) _education(state),
|
||||
if (state.profile.roles.contains('consultant')) _diplomasAndCertificates(state),
|
||||
Padding(padding: const EdgeInsets.only(bottom: 16), child: _charts()),
|
||||
if (state.profile.roles.contains('consultant')) _activePlans(state),
|
||||
if (state.profile.roles.contains('consultant') && !hidePlans) _activePlans(state),
|
||||
_newBlogPostButton(),
|
||||
_blogPosts(state),
|
||||
],
|
||||
@@ -309,7 +257,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
}
|
||||
|
||||
Widget _activePlans(ProfileStateLoaded state) {
|
||||
if (!state.profile.roles.contains('consultant')) {
|
||||
if (!state.profile.roles.contains('consultant') || hidePlans) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return BlocBuilder<PlansCubit, PlansState>(
|
||||
@@ -328,12 +276,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
children: [
|
||||
Text(
|
||||
'Активные планы',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF323F4B),
|
||||
fontSize: 24,
|
||||
height: 1,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
style: TextStyle(color: Color(0xFF323F4B), fontSize: 24, height: 1, fontWeight: FontWeight.w600),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -343,10 +286,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
height: 781,
|
||||
child: PageView.builder(
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return PlanWidget(
|
||||
plan: state.plansList[index],
|
||||
index: index,
|
||||
);
|
||||
return PlanWidget(plan: state.plansList[index], index: index);
|
||||
},
|
||||
onPageChanged: (bullet) {
|
||||
setState(() {
|
||||
@@ -370,17 +310,11 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
Container _bullets(int currentBullet, int bulletCount) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(20)),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
for (int i = 0; i < bulletCount; i++) ...[
|
||||
_bullet(i == currentBullet),
|
||||
i < bulletCount - 1 ? const SizedBox(width: 4) : const SizedBox.shrink(),
|
||||
],
|
||||
for (int i = 0; i < bulletCount; i++) ...[_bullet(i == currentBullet), i < bulletCount - 1 ? const SizedBox(width: 4) : const SizedBox.shrink()],
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -391,10 +325,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
width: isActive ? 10 : 8,
|
||||
height: isActive ? 10 : 8,
|
||||
duration: const Duration(milliseconds: 150),
|
||||
decoration: BoxDecoration(
|
||||
color: isActive ? appTheme.blueA400 : const Color(0xFFD7D9DC),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
decoration: BoxDecoration(color: isActive ? appTheme.blueA400 : const Color(0xFFD7D9DC), shape: BoxShape.circle),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -411,25 +342,15 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: Ink(
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF6FAFF),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
decoration: BoxDecoration(color: const Color(0xFFF6FAFF), borderRadius: BorderRadius.circular(8)),
|
||||
child: const Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.add_circle_outline_rounded,
|
||||
color: Color(0xFF2F80ED),
|
||||
),
|
||||
Icon(Icons.add_circle_outline_rounded, color: Color(0xFF2F80ED)),
|
||||
SizedBox(width: 12),
|
||||
Text(
|
||||
'Новая запись',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF2F80ED),
|
||||
),
|
||||
style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600, color: Color(0xFF2F80ED)),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -454,12 +375,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
children: [
|
||||
const Text(
|
||||
'Дипломы\nи сертификаты',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF323F4B),
|
||||
fontSize: 24,
|
||||
height: 1,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
style: TextStyle(color: Color(0xFF323F4B), fontSize: 24, height: 1, fontWeight: FontWeight.w600),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
@@ -467,11 +383,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
},
|
||||
child: Text(
|
||||
widget.author == null || widget.author!.authorIsMe ? 'Редактировать' : '',
|
||||
style: const TextStyle(
|
||||
color: Color(0xFF2F80ED),
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
style: const TextStyle(color: Color(0xFF2F80ED), fontSize: 16, fontWeight: FontWeight.w500),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -491,17 +403,14 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
child: Row(
|
||||
children: [
|
||||
if (state.consultantInfo!.photos.isNotEmpty)
|
||||
...List.generate(
|
||||
state.consultantInfo!.photos.length * 2 - 1,
|
||||
(index) {
|
||||
if (index.isEven) {
|
||||
final photo = state.consultantInfo!.photos[index ~/ 2];
|
||||
return _diplomaImage(photo.url);
|
||||
} else {
|
||||
return const SizedBox(width: 8);
|
||||
}
|
||||
},
|
||||
),
|
||||
...List.generate(state.consultantInfo!.photos.length * 2 - 1, (index) {
|
||||
if (index.isEven) {
|
||||
final photo = state.consultantInfo!.photos[index ~/ 2];
|
||||
return _diplomaImage(photo.url);
|
||||
} else {
|
||||
return const SizedBox(width: 8);
|
||||
}
|
||||
}),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -515,24 +424,13 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
GestureDetector _diplomaImage(String url) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
context.pushTransparentRoute(
|
||||
rootNavigator: true,
|
||||
PhotoViewScreen(
|
||||
imageUrls: [url],
|
||||
index: 0,
|
||||
),
|
||||
);
|
||||
context.pushTransparentRoute(rootNavigator: true, PhotoViewScreen(imageUrls: [url], index: 0));
|
||||
},
|
||||
child: Hero(
|
||||
tag: url,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: CachedNetworkImage(
|
||||
imageUrl: url,
|
||||
fit: BoxFit.fitHeight,
|
||||
width: MediaQuery.of(context).size.width / 3 - (60 / 3),
|
||||
height: 160,
|
||||
),
|
||||
child: CachedNetworkImage(imageUrl: url, fit: BoxFit.fitHeight, width: MediaQuery.of(context).size.width / 3 - (60 / 3), height: 160),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -555,11 +453,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
children: [
|
||||
const Text(
|
||||
'Образование',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF323F4B),
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
style: TextStyle(color: Color(0xFF323F4B), fontSize: 24, fontWeight: FontWeight.w600),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
@@ -567,11 +461,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
},
|
||||
child: Text(
|
||||
widget.author == null || widget.author!.authorIsMe ? 'Редактировать' : '',
|
||||
style: const TextStyle(
|
||||
color: Color(0xFF2F80ED),
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
style: const TextStyle(color: Color(0xFF2F80ED), fontSize: 16, fontWeight: FontWeight.w500),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -590,8 +480,10 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
ListView.separated(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemBuilder: (context, index) => _educationBlock(state.consultantInfo!.educationModel.completedCourses![index].values.first.title,
|
||||
state.consultantInfo!.educationModel.completedCourses![index].values.first.date),
|
||||
itemBuilder: (context, index) => _educationBlock(
|
||||
state.consultantInfo!.educationModel.completedCourses![index].values.first.title,
|
||||
state.consultantInfo!.educationModel.completedCourses![index].values.first.date,
|
||||
),
|
||||
separatorBuilder: (context, index) => const SizedBox(height: 8),
|
||||
itemCount: state.consultantInfo!.educationModel.completedCourses!.length,
|
||||
),
|
||||
@@ -621,22 +513,12 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: const TextStyle(
|
||||
height: 1,
|
||||
color: Color(0xFF323F4B),
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 16,
|
||||
),
|
||||
style: const TextStyle(height: 1, color: Color(0xFF323F4B), fontWeight: FontWeight.w500, fontSize: 16),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
formattedDate,
|
||||
style: const TextStyle(
|
||||
height: 1,
|
||||
color: Color(0xFF6D6F71),
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 14,
|
||||
),
|
||||
style: const TextStyle(height: 1, color: Color(0xFF6D6F71), fontWeight: FontWeight.w500, fontSize: 14),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -660,12 +542,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
children: [
|
||||
_socialLinkButton(
|
||||
() {
|
||||
launchUrl(
|
||||
Uri.parse(
|
||||
state.consultantInfo!.educationModel.vkLink ?? '',
|
||||
),
|
||||
mode: LaunchMode.externalApplication,
|
||||
);
|
||||
launchUrl(Uri.parse(state.consultantInfo!.educationModel.vkLink ?? ''), mode: LaunchMode.externalApplication);
|
||||
},
|
||||
'assets/icons/vk.svg',
|
||||
state.consultantInfo!.educationModel.vkLink!.isEmpty ? true : false,
|
||||
@@ -673,12 +550,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
const SizedBox(width: 12),
|
||||
_socialLinkButton(
|
||||
() {
|
||||
launchUrl(
|
||||
Uri.parse(
|
||||
state.consultantInfo!.educationModel.tgLink ?? '',
|
||||
),
|
||||
mode: LaunchMode.externalApplication,
|
||||
);
|
||||
launchUrl(Uri.parse(state.consultantInfo!.educationModel.tgLink ?? ''), mode: LaunchMode.externalApplication);
|
||||
},
|
||||
'assets/icons/telegram.svg',
|
||||
state.consultantInfo!.educationModel.tgLink!.isEmpty ? true : false,
|
||||
@@ -686,12 +558,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
const SizedBox(width: 12),
|
||||
_socialLinkButton(
|
||||
() {
|
||||
launchUrl(
|
||||
Uri.parse(
|
||||
state.consultantInfo!.educationModel.personalSiteLink ?? '',
|
||||
),
|
||||
mode: LaunchMode.externalApplication,
|
||||
);
|
||||
launchUrl(Uri.parse(state.consultantInfo!.educationModel.personalSiteLink ?? ''), mode: LaunchMode.externalApplication);
|
||||
},
|
||||
'assets/icons/web.svg',
|
||||
state.consultantInfo!.educationModel.personalSiteLink!.isEmpty ? true : false,
|
||||
@@ -709,10 +576,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
child: Ink(
|
||||
width: MediaQuery.of(context).size.width / 3 - (56 / 3),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
color: const Color(0xFFF6F6F6),
|
||||
),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(20), color: const Color(0xFFF6F6F6)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 16),
|
||||
child: SvgPicture.asset(
|
||||
@@ -734,20 +598,13 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
child: Ink(
|
||||
padding: const EdgeInsets.all(8),
|
||||
width: MediaQuery.of(context).size.width,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: Colors.white,
|
||||
),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
'Достижения',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF6D6F71),
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
style: TextStyle(color: Color(0xFF6D6F71), fontSize: 14, fontWeight: FontWeight.w600),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
SingleChildScrollView(
|
||||
@@ -759,51 +616,25 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
? Tooltip(
|
||||
message: state.profile.badges[i].description,
|
||||
triggerMode: TooltipTriggerMode.tap,
|
||||
textStyle: const TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
textStyle: const TextStyle(color: Colors.black, fontSize: 16, fontWeight: FontWeight.w500),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withAlpha((255 * 0.2).toInt()),
|
||||
blurRadius: 32,
|
||||
)
|
||||
],
|
||||
),
|
||||
child: SvgPicture.network(
|
||||
'$baseUrl/storage/${state.profile.badges[i].image}',
|
||||
width: 40,
|
||||
height: 40,
|
||||
boxShadow: [BoxShadow(color: Colors.black.withAlpha((255 * 0.2).toInt()), blurRadius: 32)],
|
||||
),
|
||||
child: SvgPicture.network('$baseUrl/storage/${state.profile.badges[i].image}', width: 40, height: 40),
|
||||
)
|
||||
: Tooltip(
|
||||
message: state.profile.badges[i].description,
|
||||
margin: const EdgeInsets.symmetric(horizontal: 32),
|
||||
triggerMode: TooltipTriggerMode.tap,
|
||||
textStyle: const TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
textStyle: const TextStyle(color: Colors.black, fontSize: 16, fontWeight: FontWeight.w500),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withAlpha((255 * 0.2).toInt()),
|
||||
blurRadius: 32,
|
||||
)
|
||||
],
|
||||
),
|
||||
child: CachedNetworkImage(
|
||||
imageUrl: '$baseUrl/storage/${state.profile.badges[i].image}',
|
||||
width: 40,
|
||||
height: 40,
|
||||
boxShadow: [BoxShadow(color: Colors.black.withAlpha((255 * 0.2).toInt()), blurRadius: 32)],
|
||||
),
|
||||
child: CachedNetworkImage(imageUrl: '$baseUrl/storage/${state.profile.badges[i].image}', width: 40, height: 40),
|
||||
),
|
||||
i < state.profile.badges.length - 1 ? const SizedBox(width: 8) : const SizedBox.shrink(),
|
||||
],
|
||||
@@ -823,21 +654,12 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
child: Row(
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () => GoRouter.of(context).pushNamed(
|
||||
'subsScreen',
|
||||
extra: SubType.subscriptions,
|
||||
pathParameters: {
|
||||
'slug': state.profile.slug,
|
||||
},
|
||||
),
|
||||
onTap: () => GoRouter.of(context).pushNamed('subsScreen', extra: SubType.subscriptions, pathParameters: {'slug': state.profile.slug}),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: Ink(
|
||||
padding: const EdgeInsets.all(8),
|
||||
width: MediaQuery.of(context).size.width / 2 - 6,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: Colors.white,
|
||||
),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
@@ -847,47 +669,27 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
children: [
|
||||
const Text(
|
||||
'Подписки',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF6D6F71),
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
style: TextStyle(color: Color(0xFF6D6F71), fontSize: 14, fontWeight: FontWeight.w600),
|
||||
),
|
||||
Text(
|
||||
'${state.profile.subscriptions.length}',
|
||||
style: const TextStyle(
|
||||
color: Color(0xFF323F4B),
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
style: const TextStyle(color: Color(0xFF323F4B), fontSize: 22, fontWeight: FontWeight.w700),
|
||||
),
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 8),
|
||||
child: _miniAvatars(state.profile.subscriptions),
|
||||
),
|
||||
Padding(padding: const EdgeInsets.only(right: 8), child: _miniAvatars(state.profile.subscriptions)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
InkWell(
|
||||
onTap: () => GoRouter.of(context).pushNamed(
|
||||
'subsScreen',
|
||||
extra: SubType.subscribers,
|
||||
pathParameters: {
|
||||
'slug': state.profile.slug,
|
||||
},
|
||||
),
|
||||
onTap: () => GoRouter.of(context).pushNamed('subsScreen', extra: SubType.subscribers, pathParameters: {'slug': state.profile.slug}),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: Ink(
|
||||
padding: const EdgeInsets.all(8),
|
||||
width: MediaQuery.of(context).size.width / 2 - 6,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: Colors.white,
|
||||
),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
@@ -897,26 +699,15 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
children: [
|
||||
const Text(
|
||||
'Подписчики',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF6D6F71),
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
style: TextStyle(color: Color(0xFF6D6F71), fontSize: 14, fontWeight: FontWeight.w600),
|
||||
),
|
||||
Text(
|
||||
'${state.profile.subscribers.length}',
|
||||
style: const TextStyle(
|
||||
color: Color(0xFF323F4B),
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
style: const TextStyle(color: Color(0xFF323F4B), fontSize: 22, fontWeight: FontWeight.w700),
|
||||
),
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 8),
|
||||
child: _miniAvatars(state.profile.subscribers),
|
||||
),
|
||||
Padding(padding: const EdgeInsets.only(right: 8), child: _miniAvatars(state.profile.subscribers)),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -934,13 +725,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
for (int i = 0; i < maxLength; i++)
|
||||
Align(
|
||||
widthFactor: 0.8,
|
||||
child: CircleAvatar(
|
||||
radius: 14,
|
||||
foregroundImage: NetworkImage(
|
||||
urls[i],
|
||||
),
|
||||
backgroundImage: const AssetImage('assets/images/no_avatar.png'),
|
||||
),
|
||||
child: CircleAvatar(radius: 14, foregroundImage: NetworkImage(urls[i]), backgroundImage: const AssetImage('assets/images/no_avatar.png')),
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -951,10 +736,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemBuilder: (context, index) => ProfileBlogPostWidget(
|
||||
index: index,
|
||||
profileCubit: profileCubit,
|
||||
),
|
||||
itemBuilder: (context, index) => ProfileBlogPostWidget(index: index, profileCubit: profileCubit),
|
||||
separatorBuilder: (context, index) => const SizedBox(height: 8),
|
||||
itemCount: state.blogPosts.length,
|
||||
);
|
||||
@@ -968,13 +750,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
return Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Text(
|
||||
text,
|
||||
style: TextStyle(
|
||||
color: Colors.black.withValues(alpha: 0.4),
|
||||
height: 1,
|
||||
),
|
||||
),
|
||||
child: Text(text, style: TextStyle(color: Colors.black.withValues(alpha: 0.4), height: 1)),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -986,13 +762,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
PopupMenuButton(
|
||||
onSelected: (value) async {
|
||||
if (value == 'view') {
|
||||
context.pushTransparentRoute(
|
||||
rootNavigator: true,
|
||||
PhotoViewScreen(
|
||||
imageUrls: [baseUrl + state.profile.profilePhotoUrl],
|
||||
index: 0,
|
||||
),
|
||||
);
|
||||
context.pushTransparentRoute(rootNavigator: true, PhotoViewScreen(imageUrls: [baseUrl + state.profile.profilePhotoUrl], index: 0));
|
||||
}
|
||||
if (value == 'replace') {
|
||||
showCupertinoModalPopup<void>(
|
||||
@@ -1019,13 +789,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
context: context,
|
||||
);
|
||||
},
|
||||
child: const Row(
|
||||
children: [
|
||||
Icon(Icons.photo_camera),
|
||||
SizedBox(width: 8),
|
||||
Text('Фото'),
|
||||
],
|
||||
),
|
||||
child: const Row(children: [Icon(Icons.photo_camera), SizedBox(width: 8), Text('Фото')]),
|
||||
),
|
||||
CupertinoActionSheetAction(
|
||||
onPressed: () async {
|
||||
@@ -1045,13 +809,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
context: context,
|
||||
);
|
||||
},
|
||||
child: const Row(
|
||||
children: [
|
||||
Icon(Icons.photo),
|
||||
SizedBox(width: 8),
|
||||
Text('Галерея'),
|
||||
],
|
||||
),
|
||||
child: const Row(children: [Icon(Icons.photo), SizedBox(width: 8), Text('Галерея')]),
|
||||
),
|
||||
],
|
||||
cancelButton: CupertinoActionSheetAction(
|
||||
@@ -1069,20 +827,9 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
}
|
||||
},
|
||||
itemBuilder: (context) => [
|
||||
const PopupMenuItem(
|
||||
value: 'view',
|
||||
child: Text('Посмотреть'),
|
||||
),
|
||||
if (widget.author == null || widget.author!.authorIsMe)
|
||||
const PopupMenuItem(
|
||||
value: 'replace',
|
||||
child: Text('Заменить'),
|
||||
),
|
||||
if (widget.author == null || widget.author!.authorIsMe)
|
||||
const PopupMenuItem(
|
||||
value: 'delete',
|
||||
child: Text('Удалить'),
|
||||
),
|
||||
const PopupMenuItem(value: 'view', child: Text('Посмотреть')),
|
||||
if (widget.author == null || widget.author!.authorIsMe) const PopupMenuItem(value: 'replace', child: Text('Заменить')),
|
||||
if (widget.author == null || widget.author!.authorIsMe) const PopupMenuItem(value: 'delete', child: Text('Удалить')),
|
||||
],
|
||||
child: Hero(
|
||||
tag: state.profile.profilePhotoUrl,
|
||||
@@ -1101,12 +848,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
children: [
|
||||
Text(
|
||||
'${state.profileDetails.firstName} ${state.profileDetails.lastName}',
|
||||
style: const TextStyle(
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 16,
|
||||
height: 1,
|
||||
),
|
||||
style: const TextStyle(color: Colors.black, fontWeight: FontWeight.w600, fontSize: 16, height: 1),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
GestureDetector(
|
||||
@@ -1124,11 +866,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
children: [
|
||||
const Text(
|
||||
'Подробнее',
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: Color(0xFF323F4B),
|
||||
),
|
||||
style: TextStyle(fontSize: 20, fontWeight: FontWeight.w700, color: Color(0xFF323F4B)),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
_additional('Дата рожденя: ', state.profileDetails.birthdate),
|
||||
@@ -1148,19 +886,11 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
},
|
||||
child: const Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.info_outline,
|
||||
size: 20,
|
||||
color: Color(0xFF6D6F71),
|
||||
),
|
||||
Icon(Icons.info_outline, size: 20, color: Color(0xFF6D6F71)),
|
||||
SizedBox(width: 4),
|
||||
Text(
|
||||
'Дополнительно',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF6D6F71),
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
style: TextStyle(color: Color(0xFF6D6F71), fontSize: 14, fontWeight: FontWeight.w500),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -1173,10 +903,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
if (value == 'share') {
|
||||
final box = context.findRenderObject() as RenderBox?;
|
||||
SharePlus.instance.share(
|
||||
ShareParams(
|
||||
uri: Uri.parse('$baseUrl/ru/profile/${state.profile.slug}'),
|
||||
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
|
||||
),
|
||||
ShareParams(uri: Uri.parse('$baseUrl/ru/profile/${state.profile.slug}'), sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size),
|
||||
);
|
||||
} else if (value == 'block') {
|
||||
isFirstFetch = true;
|
||||
@@ -1198,33 +925,15 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
builder: (context) => ComplainingBottomSheet(
|
||||
complainedContentType: ComplainedContent.profile,
|
||||
slug: widget.author?.authorSlug,
|
||||
),
|
||||
builder: (context) => ComplainingBottomSheet(complainedContentType: ComplainedContent.profile, slug: widget.author?.authorSlug),
|
||||
);
|
||||
}
|
||||
},
|
||||
itemBuilder: (context) => [
|
||||
const PopupMenuItem(
|
||||
value: 'share',
|
||||
child: Text('Поделиться'),
|
||||
),
|
||||
if (widget.author != null)
|
||||
const PopupMenuItem(
|
||||
value: 'complain',
|
||||
child: Text('Пожаловаться'),
|
||||
),
|
||||
if (widget.author != null && !state.profile.isBlockedByMe)
|
||||
const PopupMenuItem(
|
||||
value: 'block',
|
||||
child: Text('Заблокировать'),
|
||||
),
|
||||
if (widget.author != null && state.profile.isBlockedByMe)
|
||||
const PopupMenuItem(
|
||||
value: 'unblock',
|
||||
child: Text('Разблокировать'),
|
||||
),
|
||||
const PopupMenuItem(value: 'share', child: Text('Поделиться')),
|
||||
if (widget.author != null) const PopupMenuItem(value: 'complain', child: Text('Пожаловаться')),
|
||||
if (widget.author != null && !state.profile.isBlockedByMe) const PopupMenuItem(value: 'block', child: Text('Заблокировать')),
|
||||
if (widget.author != null && state.profile.isBlockedByMe) const PopupMenuItem(value: 'unblock', child: Text('Разблокировать')),
|
||||
],
|
||||
child: const Icon(Icons.more_horiz_rounded),
|
||||
),
|
||||
@@ -1238,19 +947,11 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF6D6F71),
|
||||
),
|
||||
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500, color: Color(0xFF6D6F71)),
|
||||
),
|
||||
Text(
|
||||
value,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF323F4B),
|
||||
),
|
||||
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500, color: Color(0xFF323F4B)),
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -1266,16 +967,8 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
alignment: Alignment.center,
|
||||
padding: const EdgeInsets.all(8),
|
||||
width: (MediaQuery.of(context).size.width - 40) / 2,
|
||||
decoration: BoxDecoration(
|
||||
color: appTheme.blueA400.withValues(alpha: 0.1),
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
child: Text(
|
||||
'Сообщение',
|
||||
style: TextStyle(
|
||||
color: appTheme.blueA400,
|
||||
),
|
||||
),
|
||||
decoration: BoxDecoration(color: appTheme.blueA400.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(16)),
|
||||
child: Text('Сообщение', style: TextStyle(color: appTheme.blueA400)),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
@@ -1290,16 +983,8 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
alignment: Alignment.center,
|
||||
padding: const EdgeInsets.all(8),
|
||||
width: (MediaQuery.of(context).size.width - 40) / 2,
|
||||
decoration: BoxDecoration(
|
||||
color: !canSub ? Colors.grey.shade200 : appTheme.blueA400,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
child: Text(
|
||||
!canSub ? 'Отписаться' : 'Подписаться',
|
||||
style: TextStyle(
|
||||
color: !canSub ? Colors.black : Colors.white,
|
||||
),
|
||||
),
|
||||
decoration: BoxDecoration(color: !canSub ? Colors.grey.shade200 : appTheme.blueA400, borderRadius: BorderRadius.circular(16)),
|
||||
child: Text(!canSub ? 'Отписаться' : 'Подписаться', style: TextStyle(color: !canSub ? Colors.black : Colors.white)),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
@@ -1318,33 +1003,17 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
SingleChildScrollView(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
children: [
|
||||
_choiceChipWidget(0),
|
||||
const SizedBox(width: 8),
|
||||
_choiceChipWidget(1),
|
||||
const SizedBox(width: 8),
|
||||
_choiceChipWidget(2),
|
||||
],
|
||||
),
|
||||
child: Row(children: [_choiceChipWidget(0), const SizedBox(width: 8), _choiceChipWidget(1), const SizedBox(width: 8), _choiceChipWidget(2)]),
|
||||
),
|
||||
Builder(
|
||||
builder: (context) {
|
||||
switch (_selectedChipIndex) {
|
||||
case 0:
|
||||
return WeightChartWidget(
|
||||
weightPoints: weightPoints,
|
||||
profileCubit: profileCubit,
|
||||
);
|
||||
return WeightChartWidget(weightPoints: weightPoints, profileCubit: profileCubit);
|
||||
case 1:
|
||||
return CircumferenceChartWidget(
|
||||
circumferencePoints: circumferencePoints,
|
||||
profileCubit: profileCubit,
|
||||
);
|
||||
return CircumferenceChartWidget(circumferencePoints: circumferencePoints, profileCubit: profileCubit);
|
||||
case 2:
|
||||
return ImtChartWidget(
|
||||
weightPoints: weightPoints,
|
||||
);
|
||||
return ImtChartWidget(weightPoints: weightPoints);
|
||||
default:
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
@@ -1377,16 +1046,10 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
pressElevation: 0,
|
||||
showCheckmark: false,
|
||||
side: BorderSide.none,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
label: Text(chipsIntervalLabelList[index]),
|
||||
labelStyle: TextStyle(
|
||||
color: appTheme.gray600,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 12,
|
||||
),
|
||||
labelStyle: TextStyle(color: appTheme.gray600, fontWeight: FontWeight.w500, fontSize: 12),
|
||||
selected: _selectedIntervalChipIndex == index,
|
||||
onSelected: (bool selected) {
|
||||
profileCubit.getMyProfile(period: chipsIntervalList[index]);
|
||||
@@ -1403,16 +1066,10 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
pressElevation: 0,
|
||||
showCheckmark: false,
|
||||
side: BorderSide.none,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
label: Text(chipsLabelList[index]),
|
||||
labelStyle: TextStyle(
|
||||
color: index == _selectedChipIndex ? Colors.white : appTheme.gray600,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 12,
|
||||
),
|
||||
labelStyle: TextStyle(color: index == _selectedChipIndex ? Colors.white : appTheme.gray600, fontWeight: FontWeight.w500, fontSize: 12),
|
||||
selected: _selectedChipIndex == index,
|
||||
backgroundColor: appTheme.gray100,
|
||||
onSelected: (bool selected) {
|
||||
|
||||
Reference in New Issue
Block a user