Merge pull request 'mso7nueh' (#156) from mso7nueh/eatvio_app:main into main

Reviewed-on: eatvio/eatvio_app#156
This commit is contained in:
mso7nueh
2024-11-15 13:29:25 +00:00
6 changed files with 125 additions and 78 deletions

View File

@@ -159,7 +159,7 @@ class AppRouter {
GoRoute(
path: '/blog-post-create-screen',
name: 'blogPostCreateScreen',
builder: (context, state) => BlogPostCreateScreen.builder(context),
builder: (context, state) => BlogPostCreateScreen(),
),
GoRoute(
path: '/blog-post-screen',

View File

@@ -1,10 +1,10 @@
import 'dart:async';
import 'dart:io';
import 'package:eatvio_app/old/feed/blog_post_create_screen/bloc/blog_post_create_bloc.dart';
import 'package:eatvio_app/old/feed/blog_post_create_screen/models/blog_post_create_model.dart';
import 'package:eatvio_app/theme/app_decoration.dart';
import 'package:eatvio_app/theme/theme_helper.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
@@ -13,22 +13,13 @@ import 'package:image_picker/image_picker.dart';
class BlogPostCreateScreen extends StatefulWidget {
const BlogPostCreateScreen({Key? key}) : super(key: key);
static Widget builder(BuildContext context) {
final blog_postID = ModalRoute.of(context)!.settings.arguments;
return BlocProvider<BlogPostCreateBloc>(
create: (context) => BlogPostCreateBloc(BlogPostCreateState(blog_postModelObj: BlogPostCreateModel(blog_postID: blog_postID.toString())))
..add(BlogPostCreateInitialEvent()),
child: BlogPostCreateScreen(),
);
}
@override
State<BlogPostCreateScreen> createState() => _BlogPostCreateScreenState();
}
class _BlogPostCreateScreenState extends State<BlogPostCreateScreen> {
final blogPostCreateBloc = BlogPostCreateBloc(BlogPostCreateState())..add(BlogPostCreateInitialEvent());
bool shrinkImage = false;
late StreamSubscription<bool> keyboardSubscription;
@override
@@ -49,24 +40,72 @@ class _BlogPostCreateScreenState extends State<BlogPostCreateScreen> {
}
Widget build(BuildContext context) {
return BlocBuilder<BlogPostCreateBloc, BlogPostCreateState>(
builder: (context, state) {
if (state is BlogPostCreateInitialState) {
// Это начальное состояние, данные ещё не загружены.
return Container(
color: Colors.white,
);
} else if (state is BlogPostCreateLoadedState) {
// Данные загружены, можно строить экран.
return _buildBlogPostCreate(context, state);
} else if (state is BlogPostCreateErrorState) {
// Произошла ошибка при загрузке данных.
return Center(child: Text(state.errorMessage));
} else {
// Другие состояния, если они есть.
return Container(); // Пустой контейнер для необработанных состояний.
}
},
return BlocProvider<BlogPostCreateBloc>(
create: (BuildContext context) => blogPostCreateBloc,
child: BlocBuilder<BlogPostCreateBloc, BlogPostCreateState>(
builder: (context, state) {
if (state is BlogPostCreateInitialState) {
// Это начальное состояние, данные ещё не загружены.
return Container(
color: Colors.white,
);
} else if (state is BlogPostCreateLoadedState) {
// Данные загружены, можно строить экран.
return _buildBlogPostCreate(context, state);
} else if (state is BlogPostCreateErrorState) {
// Произошла ошибка при загрузке данных.
return Center(child: Text(state.errorMessage));
} else {
// Другие состояния, если они есть.
return Container(); // Пустой контейнер для необработанных состояний.
}
},
),
);
}
_showImagePicker() {
showCupertinoModalPopup<void>(
context: context,
builder: (context) => CupertinoActionSheet(
actions: [
CupertinoActionSheetAction(
onPressed: () async {
final picker = ImagePicker();
XFile? image = await picker.pickImage(source: ImageSource.camera);
if (image != null) blogPostCreateBloc.add(UploadImages(image));
Navigator.of(context).pop();
},
child: const Row(
children: const [
Icon(Icons.photo_camera),
SizedBox(width: 8),
Text('Фото'),
],
),
),
CupertinoActionSheetAction(
onPressed: () async {
final picker = ImagePicker();
XFile? image = await picker.pickImage(source: ImageSource.gallery);
if (image != null) blogPostCreateBloc.add(UploadImages(image));
Navigator.of(context).pop();
},
child: const Row(
children: const [
Icon(Icons.photo),
SizedBox(width: 8),
Text('Галерея'),
],
),
),
],
cancelButton: CupertinoActionSheetAction(
onPressed: () => Navigator.of(context).pop(),
isDestructiveAction: true,
child: const Text('Отмена'),
),
),
);
}
@@ -164,15 +203,15 @@ class _BlogPostCreateScreenState extends State<BlogPostCreateScreen> {
),
),
if (state.image != null)
AnimatedContainer(
Container(
width: shrinkImage ? 52 : MediaQuery.of(context).size.width - 32,
curve: Curves.easeIn,
duration: Duration(milliseconds: 150),
child: ClipRRect(
borderRadius: BorderRadius.circular(16),
child: Image(
image: FileImage(
File(state.image!.path),
File(
state.image!.path,
),
),
),
),
@@ -181,6 +220,14 @@ class _BlogPostCreateScreenState extends State<BlogPostCreateScreen> {
),
);
}
addImage(BuildContext context, bool isLoading) {
if (!isLoading) {
return () {
_showImagePicker();
};
}
}
}
_submitForm(
@@ -191,15 +238,3 @@ _submitForm(
) async {
context.read<BlogPostCreateBloc>().add(CreateBlogPost());
}
addImage(BuildContext context, bool isLoading) {
if (!isLoading) {
return () async {
final picker = ImagePicker();
XFile? image = await picker.pickImage(source: ImageSource.gallery);
if (image != null) {
context.read<BlogPostCreateBloc>().add(UploadImages(image));
}
};
}
}

View File

@@ -63,7 +63,7 @@ class _BottomNavigationBarWidgetState extends State<BottomNavigationBarWidget> {
return Scaffold(
body: widget.child,
bottomNavigationBar: SizedBox(
height: 58,
height: 80,
child: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
onTap: _onItemTapped,

View File

@@ -130,7 +130,7 @@ class _DiaryScreenState extends State<DiaryScreen> {
state.diary,
state.currentSelectedSatietyRating,
),
if (state is DiaryStateLoaded) _chart(state.nutrition),
if (state is DiaryStateLoaded && _selectedDay!.compareTo(today!) != 1) _chart(state.nutrition),
if (state is DiaryStateLoaded && state.diary.closed == 0 && _selectedDay == today)
Padding(
padding: const EdgeInsets.only(top: 12),
@@ -278,23 +278,25 @@ class _DiaryScreenState extends State<DiaryScreen> {
_mealButton(5),
],
),
const SizedBox(height: 12),
_divider(context),
const SizedBox(height: 12),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Время приема пищи',
style: TextStyle(
color: Color(0xFF323F4B),
fontSize: 16,
fontWeight: FontWeight.w500,
_selectedDay!.compareTo(today!) == 1 ? const SizedBox.shrink() : const SizedBox(height: 12),
_selectedDay!.compareTo(today!) == 1 ? const SizedBox.shrink() : _divider(context),
_selectedDay!.compareTo(today!) == 1 ? const SizedBox.shrink() : const SizedBox(height: 12),
_selectedDay!.compareTo(today!) == 1
? const SizedBox.shrink()
: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Время приема пищи',
style: TextStyle(
color: Color(0xFF323F4B),
fontSize: 16,
fontWeight: FontWeight.w500,
),
),
_timeOfMeal(time),
],
),
),
_timeOfMeal(time),
],
),
const SizedBox(height: 12),
_divider(context),
const SizedBox(height: 12),
@@ -303,21 +305,25 @@ class _DiaryScreenState extends State<DiaryScreen> {
_addProductButton(diaryDay),
const SizedBox(height: 24),
if (diaryDay.meals[currentSelectedMealNumber - 1].photos.isEmpty)
GestureDetector(
onTap: () => _showImagePicker(diaryDay),
child: SvgPicture.asset(
width: MediaQuery.of(context).size.width - 32,
'assets/no_one_image_was_added.svg',
),
),
_selectedDay!.compareTo(today!) == 1
? const SizedBox.shrink()
: GestureDetector(
onTap: () => _showImagePicker(diaryDay),
child: SvgPicture.asset(
width: MediaQuery.of(context).size.width - 32,
'assets/no_one_image_was_added.svg',
),
),
if (diaryDay.meals[currentSelectedMealNumber - 1].photos.isNotEmpty)
_photoGallery(
diaryDay.meals[currentSelectedMealNumber - 1].photos,
diaryDay,
),
SatietyRatingWidget(
currentSelectedSatietyRating: currentSelectedSatietyRating,
),
_selectedDay!.compareTo(today!) == 1
? const SizedBox.shrink()
: SatietyRatingWidget(
currentSelectedSatietyRating: currentSelectedSatietyRating,
),
],
),
),
@@ -1057,6 +1063,7 @@ class _DiaryScreenState extends State<DiaryScreen> {
}
_addProductButton(DiaryDayModel diaryDay) {
if (_selectedDay!.compareTo(today!) == 1) return const SizedBox.shrink();
return InkWell(
onTap: () {
setState(() {

View File

@@ -4,7 +4,6 @@ import 'package:eatvio_app/generated/l10n.dart';
import 'package:eatvio_app/theme/theme_helper.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:go_router/go_router.dart';
class OtherInfoScreen extends StatefulWidget {
@@ -60,6 +59,7 @@ class _OtherInfoScreenState extends State<OtherInfoScreen> {
autofocus: true,
minLines: 2,
maxLines: 8,
maxLength: 250,
onChanged: (newValue) {},
),
SizedBox(height: 16),
@@ -70,6 +70,7 @@ class _OtherInfoScreenState extends State<OtherInfoScreen> {
hintText: s.enter_information,
autofocus: true,
minLines: 2,
maxLength: 250,
maxLines: 8,
onChanged: (newValue) {},
),
@@ -82,6 +83,7 @@ class _OtherInfoScreenState extends State<OtherInfoScreen> {
"Я занимаюсь плаванием , почти каждый вечер прогулки на свежем воздухе, пару раз в месяц играю в волейбол. Стараюсь не сидеть на месте!",
autofocus: true,
maxLines: 8,
maxLength: 250,
onChanged: (newValue) {},
),
SizedBox(height: 16),
@@ -92,6 +94,7 @@ class _OtherInfoScreenState extends State<OtherInfoScreen> {
hintText: s.enter_information,
maxLines: 7,
minLines: 2,
maxLength: 250,
onChanged: (newValue) {},
),
SizedBox(height: 16),
@@ -102,6 +105,7 @@ class _OtherInfoScreenState extends State<OtherInfoScreen> {
hintText: s.enter_information,
maxLines: 7,
minLines: 2,
maxLength: 250,
onChanged: (newValue) {},
),
SizedBox(height: 16),
@@ -114,9 +118,7 @@ class _OtherInfoScreenState extends State<OtherInfoScreen> {
SizedBox(height: 4),
CustomTextFormField(
controller: additionalInfoController,
inputFormatters: [
new LengthLimitingTextInputFormatter(250),
],
maxLength: 250,
hintText: "У меня крепкое здоровье, но последнее время часто утомляюсь, однако, это мне не мешает радоваться жизни",
maxLines: 8,
onChanged: (newValue) {},

View File

@@ -34,6 +34,7 @@ class CustomTextFormField extends StatelessWidget {
this.onChanged,
this.onEditingComplete,
this.minLines = 1,
this.maxLength,
super.key,
});
@@ -67,6 +68,7 @@ class CustomTextFormField extends StatelessWidget {
final Function()? onEditingComplete;
final void Function(String?)? onSaved;
final void Function(String)? onChanged;
final int? maxLength;
@override
Widget build(BuildContext context) {
@@ -74,6 +76,7 @@ class CustomTextFormField extends StatelessWidget {
alignment: alignment ?? Alignment.center,
child: TextFormField(
minLines: minLines,
maxLength: maxLength,
onChanged: onChanged,
controller: controller,
focusNode: focusNode ?? null,