trailing comma rule added

This commit is contained in:
Username1548
2024-11-12 19:05:30 +07:00
parent c5e1c5d9b8
commit 4d8f6464d7
43 changed files with 1923 additions and 459 deletions

View File

@@ -1,4 +1,11 @@
linter:
rules:
- require_trailing_commas
analyzer:
exclude:
- '**/*.g.dart'
errors:
invalid_annotation_target: ignore
plugins:

View File

@@ -89,11 +89,11 @@ class InitializationCubit extends Cubit<InitializationState> {
emit(InitializationState.success(
client: client,
));
),);
} catch (e) {
emit(InitializationState.error(
errorMessage: e.toString(),
));
),);
rethrow;
}
}

View File

@@ -11,5 +11,5 @@ void showInfoToast(String message) {
timeInSecForIosWeb: _toastDuration,
backgroundColor: appTheme.blueA400,
textColor: appTheme.whiteA700,
fontSize: 16.0);
fontSize: 16.0,);
}

View File

@@ -0,0 +1,10 @@
import 'package:flutter/material.dart';
class BaseButton extends StatelessWidget {
const BaseButton({super.key});
@override
Widget build(BuildContext context) {
return FilledButton(onPressed: () {}, child: Text('qweqwe'));
}
}

View File

@@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
class CustomDivider extends StatelessWidget {
const CustomDivider({super.key});
@override
Widget build(BuildContext context) {
return Divider(

View File

@@ -13,7 +13,7 @@ class ProfileAvatarCubit extends Cubit<ProfileAvatarState> {
try {
emit(ProfileAvatarState.loaded(
profile: await profileRepository.getMyProfile(),
));
),);
} catch (e) {
emit(ProfileAvatarState.error(errorMessage: e.toString()));
}

View File

@@ -89,7 +89,7 @@ class CalendarScreen extends StatelessWidget {
),
),
),
]);
],);
}
_buildCalendarBody(BuildContext context, CalendarStateLoaded state) {
@@ -225,7 +225,7 @@ class CalendarScreen extends StatelessWidget {
style: CustomTextStyles.titleSmallBold, // Предполагается, что текст белый
),
),
]),
],),
],
),
),

View File

@@ -38,7 +38,7 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
chatMessages: (state as ChatRoomStateLoaded).chatMessages,
isTyping: (state as ChatRoomStateLoaded).isTyping,
isLoading: isLoading,
));
),);
try {
final chatMessages = await chatRepository.getChatMessages(chatId, currentPage + 1);
@@ -49,7 +49,7 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
chatMessages: [...(state as ChatRoomStateLoaded).chatMessages, ...chatMessages.messagesList],
isTyping: (state as ChatRoomStateLoaded).isTyping,
isLoading: isLoading,
));
),);
currentPage++;
} catch (e) {
@@ -72,7 +72,7 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
chatMessages: chatMessages.messagesList,
isTyping: false,
isLoading: isLoading,
));
),);
} catch (e) {
emit(ChatRoomState.error(errorMessage: 'Ошибка получеия данных'));
}

View File

@@ -14,7 +14,7 @@ class ChatSelectCubit extends Cubit<ChatSelectState> {
try {
emit(ChatSelectState.loaded(
chatRooms: (await chatRepository.getChatRoomPreviews(query: query)),
));
),);
} catch (e) {
emit(
ChatSelectState.error(errorMessage: e.toString()),

View File

@@ -0,0 +1,115 @@
import 'dart:async';
import 'dart:developer';
import 'package:easy_debounce/easy_debounce.dart';
import 'package:eatvio_app/features/diets/presentation/bloc/about_diet_state.dart';
import 'package:eatvio_app/features/diets/repositories/diets_repository.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class AboutDietCubit extends Cubit<AboutDietState> {
AboutDietCubit({required this.dietsRepository}) : super(AboutDietState.initial());
final DietsRepository dietsRepository;
Future<void> getDiet(int id) async {
try {
final diet = await dietsRepository.getDiet(id);
emit(AboutDietState.loaded(diet));
} catch (e) {
log(e.toString());
}
}
Future<void> getDietWithLoading(int id) async{
try {
emit(AboutDietState.loading());
final diet = await dietsRepository.getDiet(id);
emit(AboutDietState.loaded(diet));
} catch (e) {
log(e.toString());
}
}
Future<void> likeDiet(int id) async {
if (state is! DietStateLoaded) return;
final currentDiet = (state as DietStateLoaded).diet;
if (currentDiet.wasLikedByMe) {
final updatedDiet = currentDiet.copyWith(
totalLikes: currentDiet.totalLikes - 1,
wasLikedByMe: false,
);
emit(AboutDietState.loaded(updatedDiet));
} else {
final updatedDiet = currentDiet.copyWith(
totalLikes: currentDiet.totalLikes + 1,
wasLikedByMe: true,
);
emit(AboutDietState.loaded(updatedDiet));
}
EasyDebounce.debounce(
'like_diet',
Duration(seconds: 1),
() async {
try {
await dietsRepository.likeDiet(id);
await getDiet(id);
} catch (e) {
log(e.toString());
emit(AboutDietState.loaded(currentDiet));
}
},
);
}
Future<void> addToFavorite(int id) async {
if (state is! DietStateLoaded) return;
final currentDiet = (state as DietStateLoaded).diet;
final updatedDiet = currentDiet.copyWith(
isFavorite: true,
);
emit(AboutDietState.loaded(updatedDiet));
EasyDebounce.debounce(
'add_diet_to_favorites',
Duration(seconds: 1),
() async {
try {
await dietsRepository.addToFavorite(id);
await getDiet(id);
} catch (e) {
log(e.toString());
emit(AboutDietState.loaded(currentDiet));
}
},
);
}
Future<void> removeFromFavorite(int id) async {
if (state is! DietStateLoaded) return;
final currentDiet = (state as DietStateLoaded).diet;
final updatedDiet = currentDiet.copyWith(
isFavorite: false,
);
emit(AboutDietState.loaded(updatedDiet));
EasyDebounce.debounce(
'remove_diet_from_favorites',
Duration(seconds: 1),
() async {
try {
await dietsRepository.removeFromFavorite(id);
await getDiet(id);
} catch (e) {
log(e.toString());
emit(AboutDietState.loaded(currentDiet));
}
},
);
}
}

View File

@@ -0,0 +1,14 @@
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'about_diet_state.freezed.dart';
@freezed
class AboutDietState with _$AboutDietState {
const factory AboutDietState() = _AboutDietState;
const factory AboutDietState.initial() = DietStateInitial;
const factory AboutDietState.loading() = DietStateLoading;
const factory AboutDietState.loaded(Diet diet) = DietStateLoaded;
const factory AboutDietState.error({required String message}) = DietStateError;
}

View File

@@ -0,0 +1,796 @@
// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of 'about_diet_state.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
/// @nodoc
mixin _$AboutDietState {
@optionalTypeArgs
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(Diet diet) loaded,
required TResult Function(String message) error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(Diet diet)? loaded,
TResult? Function(String message)? error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function()? initial,
TResult Function()? loading,
TResult Function(Diet diet)? loaded,
TResult Function(String message)? error,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>(
TResult Function(_AboutDietState value) $default, {
required TResult Function(DietStateInitial value) initial,
required TResult Function(DietStateLoading value) loading,
required TResult Function(DietStateLoaded value) loaded,
required TResult Function(DietStateError value) error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>(
TResult? Function(_AboutDietState value)? $default, {
TResult? Function(DietStateInitial value)? initial,
TResult? Function(DietStateLoading value)? loading,
TResult? Function(DietStateLoaded value)? loaded,
TResult? Function(DietStateError value)? error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>(
TResult Function(_AboutDietState value)? $default, {
TResult Function(DietStateInitial value)? initial,
TResult Function(DietStateLoading value)? loading,
TResult Function(DietStateLoaded value)? loaded,
TResult Function(DietStateError value)? error,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $AboutDietStateCopyWith<$Res> {
factory $AboutDietStateCopyWith(
AboutDietState value, $Res Function(AboutDietState) then) =
_$AboutDietStateCopyWithImpl<$Res, AboutDietState>;
}
/// @nodoc
class _$AboutDietStateCopyWithImpl<$Res, $Val extends AboutDietState>
implements $AboutDietStateCopyWith<$Res> {
_$AboutDietStateCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of AboutDietState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
abstract class _$$AboutDietStateImplCopyWith<$Res> {
factory _$$AboutDietStateImplCopyWith(_$AboutDietStateImpl value,
$Res Function(_$AboutDietStateImpl) then) =
__$$AboutDietStateImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$AboutDietStateImplCopyWithImpl<$Res>
extends _$AboutDietStateCopyWithImpl<$Res, _$AboutDietStateImpl>
implements _$$AboutDietStateImplCopyWith<$Res> {
__$$AboutDietStateImplCopyWithImpl(
_$AboutDietStateImpl _value, $Res Function(_$AboutDietStateImpl) _then)
: super(_value, _then);
/// Create a copy of AboutDietState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$AboutDietStateImpl implements _AboutDietState {
const _$AboutDietStateImpl();
@override
String toString() {
return 'AboutDietState()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$AboutDietStateImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(Diet diet) loaded,
required TResult Function(String message) error,
}) {
return $default();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(Diet diet)? loaded,
TResult? Function(String message)? error,
}) {
return $default?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function()? initial,
TResult Function()? loading,
TResult Function(Diet diet)? loaded,
TResult Function(String message)? error,
required TResult orElse(),
}) {
if ($default != null) {
return $default();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>(
TResult Function(_AboutDietState value) $default, {
required TResult Function(DietStateInitial value) initial,
required TResult Function(DietStateLoading value) loading,
required TResult Function(DietStateLoaded value) loaded,
required TResult Function(DietStateError value) error,
}) {
return $default(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>(
TResult? Function(_AboutDietState value)? $default, {
TResult? Function(DietStateInitial value)? initial,
TResult? Function(DietStateLoading value)? loading,
TResult? Function(DietStateLoaded value)? loaded,
TResult? Function(DietStateError value)? error,
}) {
return $default?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>(
TResult Function(_AboutDietState value)? $default, {
TResult Function(DietStateInitial value)? initial,
TResult Function(DietStateLoading value)? loading,
TResult Function(DietStateLoaded value)? loaded,
TResult Function(DietStateError value)? error,
required TResult orElse(),
}) {
if ($default != null) {
return $default(this);
}
return orElse();
}
}
abstract class _AboutDietState implements AboutDietState {
const factory _AboutDietState() = _$AboutDietStateImpl;
}
/// @nodoc
abstract class _$$DietStateInitialImplCopyWith<$Res> {
factory _$$DietStateInitialImplCopyWith(_$DietStateInitialImpl value,
$Res Function(_$DietStateInitialImpl) then) =
__$$DietStateInitialImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$DietStateInitialImplCopyWithImpl<$Res>
extends _$AboutDietStateCopyWithImpl<$Res, _$DietStateInitialImpl>
implements _$$DietStateInitialImplCopyWith<$Res> {
__$$DietStateInitialImplCopyWithImpl(_$DietStateInitialImpl _value,
$Res Function(_$DietStateInitialImpl) _then)
: super(_value, _then);
/// Create a copy of AboutDietState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$DietStateInitialImpl implements DietStateInitial {
const _$DietStateInitialImpl();
@override
String toString() {
return 'AboutDietState.initial()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$DietStateInitialImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(Diet diet) loaded,
required TResult Function(String message) error,
}) {
return initial();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(Diet diet)? loaded,
TResult? Function(String message)? error,
}) {
return initial?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function()? initial,
TResult Function()? loading,
TResult Function(Diet diet)? loaded,
TResult Function(String message)? error,
required TResult orElse(),
}) {
if (initial != null) {
return initial();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>(
TResult Function(_AboutDietState value) $default, {
required TResult Function(DietStateInitial value) initial,
required TResult Function(DietStateLoading value) loading,
required TResult Function(DietStateLoaded value) loaded,
required TResult Function(DietStateError value) error,
}) {
return initial(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>(
TResult? Function(_AboutDietState value)? $default, {
TResult? Function(DietStateInitial value)? initial,
TResult? Function(DietStateLoading value)? loading,
TResult? Function(DietStateLoaded value)? loaded,
TResult? Function(DietStateError value)? error,
}) {
return initial?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>(
TResult Function(_AboutDietState value)? $default, {
TResult Function(DietStateInitial value)? initial,
TResult Function(DietStateLoading value)? loading,
TResult Function(DietStateLoaded value)? loaded,
TResult Function(DietStateError value)? error,
required TResult orElse(),
}) {
if (initial != null) {
return initial(this);
}
return orElse();
}
}
abstract class DietStateInitial implements AboutDietState {
const factory DietStateInitial() = _$DietStateInitialImpl;
}
/// @nodoc
abstract class _$$DietStateLoadingImplCopyWith<$Res> {
factory _$$DietStateLoadingImplCopyWith(_$DietStateLoadingImpl value,
$Res Function(_$DietStateLoadingImpl) then) =
__$$DietStateLoadingImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$DietStateLoadingImplCopyWithImpl<$Res>
extends _$AboutDietStateCopyWithImpl<$Res, _$DietStateLoadingImpl>
implements _$$DietStateLoadingImplCopyWith<$Res> {
__$$DietStateLoadingImplCopyWithImpl(_$DietStateLoadingImpl _value,
$Res Function(_$DietStateLoadingImpl) _then)
: super(_value, _then);
/// Create a copy of AboutDietState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$DietStateLoadingImpl implements DietStateLoading {
const _$DietStateLoadingImpl();
@override
String toString() {
return 'AboutDietState.loading()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$DietStateLoadingImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(Diet diet) loaded,
required TResult Function(String message) error,
}) {
return loading();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(Diet diet)? loaded,
TResult? Function(String message)? error,
}) {
return loading?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function()? initial,
TResult Function()? loading,
TResult Function(Diet diet)? loaded,
TResult Function(String message)? error,
required TResult orElse(),
}) {
if (loading != null) {
return loading();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>(
TResult Function(_AboutDietState value) $default, {
required TResult Function(DietStateInitial value) initial,
required TResult Function(DietStateLoading value) loading,
required TResult Function(DietStateLoaded value) loaded,
required TResult Function(DietStateError value) error,
}) {
return loading(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>(
TResult? Function(_AboutDietState value)? $default, {
TResult? Function(DietStateInitial value)? initial,
TResult? Function(DietStateLoading value)? loading,
TResult? Function(DietStateLoaded value)? loaded,
TResult? Function(DietStateError value)? error,
}) {
return loading?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>(
TResult Function(_AboutDietState value)? $default, {
TResult Function(DietStateInitial value)? initial,
TResult Function(DietStateLoading value)? loading,
TResult Function(DietStateLoaded value)? loaded,
TResult Function(DietStateError value)? error,
required TResult orElse(),
}) {
if (loading != null) {
return loading(this);
}
return orElse();
}
}
abstract class DietStateLoading implements AboutDietState {
const factory DietStateLoading() = _$DietStateLoadingImpl;
}
/// @nodoc
abstract class _$$DietStateLoadedImplCopyWith<$Res> {
factory _$$DietStateLoadedImplCopyWith(_$DietStateLoadedImpl value,
$Res Function(_$DietStateLoadedImpl) then) =
__$$DietStateLoadedImplCopyWithImpl<$Res>;
@useResult
$Res call({Diet diet});
$DietCopyWith<$Res> get diet;
}
/// @nodoc
class __$$DietStateLoadedImplCopyWithImpl<$Res>
extends _$AboutDietStateCopyWithImpl<$Res, _$DietStateLoadedImpl>
implements _$$DietStateLoadedImplCopyWith<$Res> {
__$$DietStateLoadedImplCopyWithImpl(
_$DietStateLoadedImpl _value, $Res Function(_$DietStateLoadedImpl) _then)
: super(_value, _then);
/// Create a copy of AboutDietState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? diet = null,
}) {
return _then(_$DietStateLoadedImpl(
null == diet
? _value.diet
: diet // ignore: cast_nullable_to_non_nullable
as Diet,
));
}
/// Create a copy of AboutDietState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$DietCopyWith<$Res> get diet {
return $DietCopyWith<$Res>(_value.diet, (value) {
return _then(_value.copyWith(diet: value));
});
}
}
/// @nodoc
class _$DietStateLoadedImpl implements DietStateLoaded {
const _$DietStateLoadedImpl(this.diet);
@override
final Diet diet;
@override
String toString() {
return 'AboutDietState.loaded(diet: $diet)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$DietStateLoadedImpl &&
(identical(other.diet, diet) || other.diet == diet));
}
@override
int get hashCode => Object.hash(runtimeType, diet);
/// Create a copy of AboutDietState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$DietStateLoadedImplCopyWith<_$DietStateLoadedImpl> get copyWith =>
__$$DietStateLoadedImplCopyWithImpl<_$DietStateLoadedImpl>(
this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(Diet diet) loaded,
required TResult Function(String message) error,
}) {
return loaded(diet);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(Diet diet)? loaded,
TResult? Function(String message)? error,
}) {
return loaded?.call(diet);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function()? initial,
TResult Function()? loading,
TResult Function(Diet diet)? loaded,
TResult Function(String message)? error,
required TResult orElse(),
}) {
if (loaded != null) {
return loaded(diet);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>(
TResult Function(_AboutDietState value) $default, {
required TResult Function(DietStateInitial value) initial,
required TResult Function(DietStateLoading value) loading,
required TResult Function(DietStateLoaded value) loaded,
required TResult Function(DietStateError value) error,
}) {
return loaded(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>(
TResult? Function(_AboutDietState value)? $default, {
TResult? Function(DietStateInitial value)? initial,
TResult? Function(DietStateLoading value)? loading,
TResult? Function(DietStateLoaded value)? loaded,
TResult? Function(DietStateError value)? error,
}) {
return loaded?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>(
TResult Function(_AboutDietState value)? $default, {
TResult Function(DietStateInitial value)? initial,
TResult Function(DietStateLoading value)? loading,
TResult Function(DietStateLoaded value)? loaded,
TResult Function(DietStateError value)? error,
required TResult orElse(),
}) {
if (loaded != null) {
return loaded(this);
}
return orElse();
}
}
abstract class DietStateLoaded implements AboutDietState {
const factory DietStateLoaded(final Diet diet) = _$DietStateLoadedImpl;
Diet get diet;
/// Create a copy of AboutDietState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$DietStateLoadedImplCopyWith<_$DietStateLoadedImpl> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class _$$DietStateErrorImplCopyWith<$Res> {
factory _$$DietStateErrorImplCopyWith(_$DietStateErrorImpl value,
$Res Function(_$DietStateErrorImpl) then) =
__$$DietStateErrorImplCopyWithImpl<$Res>;
@useResult
$Res call({String message});
}
/// @nodoc
class __$$DietStateErrorImplCopyWithImpl<$Res>
extends _$AboutDietStateCopyWithImpl<$Res, _$DietStateErrorImpl>
implements _$$DietStateErrorImplCopyWith<$Res> {
__$$DietStateErrorImplCopyWithImpl(
_$DietStateErrorImpl _value, $Res Function(_$DietStateErrorImpl) _then)
: super(_value, _then);
/// Create a copy of AboutDietState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? message = null,
}) {
return _then(_$DietStateErrorImpl(
message: null == message
? _value.message
: message // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
/// @nodoc
class _$DietStateErrorImpl implements DietStateError {
const _$DietStateErrorImpl({required this.message});
@override
final String message;
@override
String toString() {
return 'AboutDietState.error(message: $message)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$DietStateErrorImpl &&
(identical(other.message, message) || other.message == message));
}
@override
int get hashCode => Object.hash(runtimeType, message);
/// Create a copy of AboutDietState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$DietStateErrorImplCopyWith<_$DietStateErrorImpl> get copyWith =>
__$$DietStateErrorImplCopyWithImpl<_$DietStateErrorImpl>(
this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(Diet diet) loaded,
required TResult Function(String message) error,
}) {
return error(message);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(Diet diet)? loaded,
TResult? Function(String message)? error,
}) {
return error?.call(message);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function()? initial,
TResult Function()? loading,
TResult Function(Diet diet)? loaded,
TResult Function(String message)? error,
required TResult orElse(),
}) {
if (error != null) {
return error(message);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>(
TResult Function(_AboutDietState value) $default, {
required TResult Function(DietStateInitial value) initial,
required TResult Function(DietStateLoading value) loading,
required TResult Function(DietStateLoaded value) loaded,
required TResult Function(DietStateError value) error,
}) {
return error(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>(
TResult? Function(_AboutDietState value)? $default, {
TResult? Function(DietStateInitial value)? initial,
TResult? Function(DietStateLoading value)? loading,
TResult? Function(DietStateLoaded value)? loaded,
TResult? Function(DietStateError value)? error,
}) {
return error?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>(
TResult Function(_AboutDietState value)? $default, {
TResult Function(DietStateInitial value)? initial,
TResult Function(DietStateLoading value)? loading,
TResult Function(DietStateLoaded value)? loaded,
TResult Function(DietStateError value)? error,
required TResult orElse(),
}) {
if (error != null) {
return error(this);
}
return orElse();
}
}
abstract class DietStateError implements AboutDietState {
const factory DietStateError({required final String message}) =
_$DietStateErrorImpl;
String get message;
/// Create a copy of AboutDietState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$DietStateErrorImplCopyWith<_$DietStateErrorImpl> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@@ -5,12 +5,15 @@ import 'package:eatvio_app/core/const.dart';
import 'package:eatvio_app/core/utils/localization_utils.dart';
import 'package:eatvio_app/core/utils/string_extentions.dart';
import 'package:eatvio_app/core/widgets/custom_divider.dart';
import 'package:eatvio_app/features/diets/presentation/bloc/about_diet_cubit.dart';
import 'package:eatvio_app/features/diets/presentation/bloc/about_diet_state.dart';
import 'package:eatvio_app/features/diets/presentation/widgets/author_card.dart';
import 'package:eatvio_app/features/diets/presentation/widgets/cpfc_container.dart';
import 'package:eatvio_app/features/diets/presentation/widgets/expandable_text.dart';
import 'package:eatvio_app/features/diets/presentation/widgets/info_bouble.dart';
import 'package:eatvio_app/features/diets/presentation/widgets/main_background_bouble.dart';
import 'package:eatvio_app/features/diets/presentation/widgets/more_options.dart';
import 'package:eatvio_app/features/diets/presentation/widgets/start_diet_bottom_sheet.dart';
import 'package:eatvio_app/features/diets/presentation/widgets/type_badges.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/comments_cubit/comments_cubit.dart';
@@ -39,6 +42,7 @@ class AboutDietScreen extends StatefulWidget {
class _AboutDietScreenState extends State<AboutDietScreen> {
final CommentsCubit commentsCubit = sl<CommentsCubit>();
final AboutDietCubit dietsCubit = sl<AboutDietCubit>();
int? replyId;
final ScrollController scrollController = ScrollController();
final textEditingController = TextEditingController();
@@ -59,365 +63,451 @@ class _AboutDietScreenState extends State<AboutDietScreen> {
@override
Widget build(BuildContext context) {
final s = S.of(context);
return BlocProvider<CommentsCubit>(
create: (BuildContext context) => commentsCubit
..getComments(
widget.diet.id.toString(),
CommentSourceType.diet,
true,
),
child: BlocConsumer<CommentsCubit, CommentsState>(
listener: (BuildContext context, CommentsState state) {
if (state is CommentsStateLoaded) {
setState(() {
replyId = state.replyId;
});
}
},
builder: (BuildContext context, CommentsState state) {
return Scaffold(
backgroundColor: appTheme.gray100,
resizeToAvoidBottomInset: true,
bottomSheet: Container(
padding: EdgeInsets.symmetric(vertical: 12) + (Platform.isIOS ? const EdgeInsets.only(bottom: 16) : EdgeInsets.zero),
decoration: BoxDecoration(
color: Colors.white,
border: Border(
top: BorderSide(
color: Colors.black.withOpacity(0.1),
),
),
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
Expanded(
child: SizedBox(
child: FloatingActionButton.extended(
heroTag: 'nextButtonRegistration',
highlightElevation: 0,
elevation: 0,
focusElevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
backgroundColor: appTheme.greenA700,
onPressed: () {},
label: Text(
s.startDiet,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: appTheme.whiteA700,
),
return BlocProvider(
create: (context) => dietsCubit..getDietWithLoading(widget.diet.id),
child: BlocProvider<CommentsCubit>(
create: (BuildContext context) => commentsCubit
..getComments(
widget.diet.id.toString(),
CommentSourceType.diet,
true,
),
child: BlocConsumer<CommentsCubit, CommentsState>(
listener: (BuildContext context, CommentsState commentsState) {
if (commentsState is CommentsStateLoaded) {
setState(() {
replyId = commentsState.replyId;
});
}
},
builder: (BuildContext context, CommentsState state) {
return BlocBuilder<AboutDietCubit, AboutDietState>(
builder: (context, dietState) {
return dietState is DietStateLoaded
? Scaffold(
backgroundColor: appTheme.gray100,
resizeToAvoidBottomInset: true,
bottomSheet: Container(
padding: EdgeInsets.symmetric(vertical: 12) + (Platform.isIOS ? const EdgeInsets.only(bottom: 16) : EdgeInsets.zero),
decoration: BoxDecoration(
color: Colors.white,
border: Border(
top: BorderSide(
color: Colors.black.withOpacity(0.1),
),
),
),
),
SizedBox(width: 8),
Container(
width: 52,
height: 52,
decoration: BoxDecoration(color: appTheme.gray50, shape: BoxShape.circle),
child: Icon(
Icons.bookmark_border_rounded,
color: appTheme.blueGray800,
size: 24,
),
)
],
),
SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (replyId != null)
GestureDetector(
onTap: () {
context.read<CommentsCubit>().setReplyId(null);
setState(() {
replyId = null;
textEditingController.clear();
});
FocusManager.instance.primaryFocus?.unfocus();
},
child: Container(
decoration: BoxDecoration(
color: appTheme.blueA400,
shape: BoxShape.circle,
),
height: 32,
width: 32,
child: Icon(
Icons.close_rounded,
size: 18,
color: Colors.white,
),
),
),
if (replyId != null) SizedBox(width: 8),
Expanded(
child: SizedBox(
child: TextFormField(
onChanged: (_) {
setState(() {});
},
controller: textEditingController,
maxLines: 5,
minLines: 1,
keyboardType: TextInputType.multiline,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
color: Colors.black,
height: 1,
),
decoration: InputDecoration(
isDense: true,
contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
hintText: s.comment.capitalize(),
hintStyle: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
height: 1,
color: Color(0xFFAEAEB2),
),
filled: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(16),
borderSide: BorderSide(
color: Color(0xFFD1D1D6),
width: 1,
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(16),
borderSide: BorderSide(
color: Color(0xFFD1D1D6),
width: 1,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(16),
borderSide: BorderSide(
color: Color(0xFFD1D1D6),
width: 1,
),
),
),
),
),
),
SizedBox(width: 8),
GestureDetector(
onTap: () {
if (textEditingController.text.length > 2) {
commentsCubit.sendComment(
id: widget.diet.id.toString(),
commentText: textEditingController.text,
parentCommentId: replyId,
commentSourceType: CommentSourceType.diet,
);
context.read<CommentsCubit>().setReplyId(null);
setState(() {
textEditingController.clear();
replyId = null;
});
FocusManager.instance.primaryFocus?.unfocus();
}
},
child: Container(
decoration: BoxDecoration(
color: textEditingController.text.length > 2 ? appTheme.blueA400 : appTheme.gray50,
shape: BoxShape.circle,
),
height: 32,
width: 32,
child: Icon(
Icons.send_rounded,
size: 18,
color: textEditingController.text.length > 2 ? appTheme.whiteA700 : appTheme.blueGray800,
),
),
),
],
),
],
),
),
),
appBar: AppBar(
centerTitle: true,
title: Text(
widget.diet.name,
maxLines: 2,
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
softWrap: true,
style: TextStyle(
color: Colors.black,
fontSize: 24,
fontWeight: FontWeight.w500,
height: 1,
),
),
actions: [
PortalTarget(
visible: isMoreOptionsVisible,
portalFollower: MoreOptions(id: widget.diet.id),
anchor: Aligned(
shiftToWithinBound: AxisFlag(x: true, y: true),
follower: Alignment.topRight,
target: Alignment.bottomRight,
),
child: IconButton(
onPressed: () {
setState(() {
isMoreOptionsVisible = !isMoreOptionsVisible;
});
},
icon: SvgPicture.asset(
'assets/icons/more_button.svg',
width: 20,
height: 20,
)),
),
],
),
body: SingleChildScrollView(
controller: scrollController,
padding: EdgeInsets.only(bottom: 160),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 8),
MainBackgroundBouble(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Stack(children: [
CachedNetworkImage(
imageUrl: baseUrl + '/storage/' + widget.diet.image,
),
Positioned(
child: Row(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
InfoBouble(children: [
], backgroundColor: appTheme.whiteA700,)
Row(
children: [
Expanded(
child: SizedBox(
child: FloatingActionButton.extended(
heroTag: 'nextButtonRegistration',
highlightElevation: 0,
elevation: 0,
focusElevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
backgroundColor: appTheme.greenA700,
onPressed: () {
showModalBottomSheet(context: context, builder: (context) => StartDietBottomSheet());
},
label: Text(
s.startDiet,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: appTheme.whiteA700,
),
),
),
),
),
SizedBox(width: 8),
GestureDetector(
onTap: () {
if (dietState.diet.isFavorite) {
dietsCubit.removeFromFavorite(widget.diet.id);
} else {
dietsCubit.addToFavorite(widget.diet.id);
}
},
child: Container(
width: 52,
height: 52,
decoration: BoxDecoration(color: appTheme.gray50, shape: BoxShape.circle),
child: Icon(
dietState.diet.isFavorite ? Icons.bookmark : Icons.bookmark_border_rounded,
color: appTheme.blueGray800,
size: 24,
),
),
),
],
),
SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (replyId != null)
GestureDetector(
onTap: () {
context.read<CommentsCubit>().setReplyId(null);
setState(() {
replyId = null;
textEditingController.clear();
});
FocusManager.instance.primaryFocus?.unfocus();
},
child: Container(
decoration: BoxDecoration(
color: appTheme.blueA400,
shape: BoxShape.circle,
),
height: 32,
width: 32,
child: Icon(
Icons.close_rounded,
size: 18,
color: Colors.white,
),
),
),
if (replyId != null) SizedBox(width: 8),
Expanded(
child: SizedBox(
child: TextFormField(
onChanged: (_) {
setState(() {});
},
controller: textEditingController,
maxLines: 5,
minLines: 1,
keyboardType: TextInputType.multiline,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
color: Colors.black,
height: 1,
),
decoration: InputDecoration(
isDense: true,
contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
hintText: s.comment.capitalize(),
hintStyle: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
height: 1,
color: Color(0xFFAEAEB2),
),
filled: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(16),
borderSide: BorderSide(
color: Color(0xFFD1D1D6),
width: 1,
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(16),
borderSide: BorderSide(
color: Color(0xFFD1D1D6),
width: 1,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(16),
borderSide: BorderSide(
color: Color(0xFFD1D1D6),
width: 1,
),
),
),
),
),
),
SizedBox(width: 8),
GestureDetector(
onTap: () {
if (textEditingController.text.length > 2) {
commentsCubit.sendComment(
id: widget.diet.id.toString(),
commentText: textEditingController.text,
parentCommentId: replyId,
commentSourceType: CommentSourceType.diet,
);
context.read<CommentsCubit>().setReplyId(null);
setState(() {
textEditingController.clear();
replyId = null;
});
dietsCubit.getDiet(widget.diet.id);
FocusManager.instance.primaryFocus?.unfocus();
}
},
child: Container(
decoration: BoxDecoration(
color: textEditingController.text.length > 2 ? appTheme.blueA400 : appTheme.gray50,
shape: BoxShape.circle,
),
height: 32,
width: 32,
child: Icon(
Icons.send_rounded,
size: 18,
color: textEditingController.text.length > 2 ? appTheme.whiteA700 : appTheme.blueGray800,
),
),
),
],
),
],
),
)
]),
SizedBox(height: 16),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Text(
s.about_diet,
style: TextStyle(color: appTheme.blueGray800, fontSize: 20, fontWeight: FontWeight.w600),
),
),
SizedBox(height: 12),
SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 16),
scrollDirection: Axis.horizontal,
child: Row(
appBar: AppBar(
centerTitle: true,
title: Text(
widget.diet.name,
maxLines: 2,
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
softWrap: true,
style: TextStyle(
color: Colors.black,
fontSize: 24,
fontWeight: FontWeight.w500,
height: 1,
),
),
actions: [
PortalTarget(
visible: isMoreOptionsVisible,
portalFollower: MoreOptions(id: widget.diet.id),
anchor: Aligned(
shiftToWithinBound: AxisFlag(x: true, y: true),
follower: Alignment.topRight,
target: Alignment.bottomRight,
),
child: IconButton(
onPressed: () {
setState(() {
isMoreOptionsVisible = !isMoreOptionsVisible;
});
},
icon: SvgPicture.asset(
'assets/icons/more_button.svg',
width: 20,
height: 20,
),),
),
],
),
body: SingleChildScrollView(
controller: scrollController,
padding: EdgeInsets.only(bottom: 160),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
InfoBouble(
children: [
SvgPicture.asset(
'assets/icons/time2.svg',
width: 13.3,
height: 13.3,
),
SizedBox(width: 4),
Text(widget.diet.duration.toString() + ' ' + getDayForm(widget.diet.duration, s),
style: TextStyle(color: appTheme.blueGray800, fontSize: 12, fontWeight: FontWeight.w500)),
],
SizedBox(height: 8),
MainBackgroundBouble(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Stack(children: [
CachedNetworkImage(
imageUrl: baseUrl + '/storage/' + widget.diet.image,
),
Positioned(
bottom: 16,
left: 0,
right: 0,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
InfoBouble(
children: [
SvgPicture.asset('assets/icons/eye.svg', width: 18, height: 12),
SizedBox(width: 8),
Text(
dietState.diet.totalViews.toString(),
style: TextStyle(color: appTheme.blueGray800, fontSize: 12, fontWeight: FontWeight.w500),
),
],
backgroundColor: appTheme.whiteA700,
),
SizedBox(width: 12),
GestureDetector(
onTap: () {
dietsCubit.likeDiet(widget.diet.id);
},
child: InfoBouble(
children: [
SvgPicture.asset(
'assets/icons/heart.svg',
width: 14,
height: 12,
colorFilter: dietState.diet.wasLikedByMe ? ColorFilter.mode(appTheme.blueA400, BlendMode.srcIn) : null,
),
SizedBox(width: 8),
Text(
dietState.diet.totalLikes.toString(),
style: TextStyle(color: appTheme.blueGray800, fontSize: 12, fontWeight: FontWeight.w500),
),
],
backgroundColor: appTheme.whiteA700,
),
),
SizedBox(width: 12),
InfoBouble(
children: [
SvgPicture.asset('assets/icons/comment2.svg', width: 13, height: 12),
SizedBox(width: 8),
Text(
dietState.diet.totalComments.toString(),
style: TextStyle(color: appTheme.blueGray800, fontSize: 12, fontWeight: FontWeight.w500),
),
],
backgroundColor: appTheme.whiteA700,
),
],
),
),
],),
SizedBox(height: 16),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Text(
s.about_diet,
style: TextStyle(color: appTheme.blueGray800, fontSize: 20, fontWeight: FontWeight.w600),
),
),
SizedBox(height: 12),
SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 16),
scrollDirection: Axis.horizontal,
child: Row(
children: [
InfoBouble(
children: [
SvgPicture.asset(
'assets/icons/time2.svg',
width: 13.3,
height: 13.3,
),
SizedBox(width: 4),
Text(widget.diet.duration.toString() + ' ' + getDayForm(widget.diet.duration, s),
style: TextStyle(color: appTheme.blueGray800, fontSize: 12, fontWeight: FontWeight.w500),),
],
),
SizedBox(width: 12),
InfoBouble(
children: [
SvgPicture.asset(
'assets/icons/people.svg',
width: 13.3,
height: 13.3,
),
SizedBox(width: 4),
Text('80 человек прошли(статика, ещё нет бека)',
style: TextStyle(color: appTheme.blueGray800, fontSize: 12, fontWeight: FontWeight.w500),),
],
),
SizedBox(width: 12),
InfoBouble(
children: [
TypeBadges(type: widget.diet.type),
],
),
],
),
),
ExpandableText(
text: widget.diet.details,
),
SizedBox(height: 20),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: AuthorCard(
author: widget.diet.author,
),
),
SizedBox(height: 16),
],
),
),
SizedBox(width: 12),
InfoBouble(
children: [
SvgPicture.asset(
'assets/icons/people.svg',
width: 13.3,
height: 13.3,
SizedBox(height: 16),
MainBackgroundBouble(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: Center(
child: Text(
s.diet_plan + '(${widget.diet.duration.toString()} ' + getDayForm(widget.diet.duration, s) + ')',
style: TextStyle(
color: appTheme.blueGray800,
fontSize: 20,
fontWeight: FontWeight.w600,
),
),
SizedBox(width: 4),
Text('80 человек прошли(статика, ещё нет бека)',
style: TextStyle(color: appTheme.blueGray800, fontSize: 12, fontWeight: FontWeight.w500)),
],
),
),),
SizedBox(height: 8),
ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (context, index) {
return _dayOfPlan(widget.diet.dailySchedule[index], index, s);
},
itemCount: widget.diet.dailySchedule.length,
),
MainBackgroundBouble(
padding: EdgeInsets.symmetric(vertical: 16),
child: Column(children: [
Container(
padding: EdgeInsets.symmetric(horizontal: 16),
alignment: Alignment.centerLeft,
child: Text(
dietState.diet.totalComments.toString() + ' ' + getCommentForm(widget.diet.totalComments, s),
style: TextStyle(
fontSize: 12,
color: appTheme.gray500,
fontWeight: FontWeight.w400,
),
),
),
SizedBox(height: 16),
if (state is CommentsStateLoading)
Padding(
padding: const EdgeInsets.all(32),
child: SizedBox(
height: 32,
width: 32,
child: RiveAnimation.asset(
'assets/rive_animations/loading.riv',
),
),
),
if (state is CommentsStateLoaded)
CommentsWidget(
id: widget.diet.id.toString(),
commentSourceType: CommentSourceType.diet,
comment: state.comment,
replyId: replyId,
),
],),
),
SizedBox(width: 12),
InfoBouble(
children: [
TypeBadges(type: widget.diet.type),
],
)
],
),
),
ExpandableText(
text: widget.diet.details,
),
SizedBox(height: 20),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: AuthorCard(
author: widget.diet.author,
),
),
SizedBox(height: 16),
],
),
),
SizedBox(height: 16),
MainBackgroundBouble(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: Center(
child: Text(
s.diet_plan + '(${widget.diet.duration.toString()} ' + getDayForm(widget.diet.duration, s) + ')',
style: TextStyle(
color: appTheme.blueGray800,
fontSize: 20,
fontWeight: FontWeight.w600,
),
),
),
)),
SizedBox(height: 8),
ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (context, index) {
return _dayOfPlan(widget.diet.dailySchedule[index], index, s);
},
itemCount: widget.diet.dailySchedule.length,
),
MainBackgroundBouble(
padding: EdgeInsets.symmetric(vertical: 16),
child: Column(children: [
Container(
padding: EdgeInsets.symmetric(horizontal: 16),
alignment: Alignment.centerLeft,
child: Text(
widget.diet.totalComments.toString() + ' ' + getCommentForm(widget.diet.totalComments, s),
style: TextStyle(
fontSize: 12,
color: appTheme.gray500,
fontWeight: FontWeight.w400,
),
),
),
SizedBox(height: 16),
if (state is CommentsStateLoading)
Padding(
padding: const EdgeInsets.all(32),
)
: Scaffold(
body: Center(
child: SizedBox(
height: 32,
width: 32,
@@ -426,20 +516,11 @@ class _AboutDietScreenState extends State<AboutDietScreen> {
),
),
),
if (state is CommentsStateLoaded)
CommentsWidget(
id: widget.diet.id.toString(),
commentSourceType: CommentSourceType.diet,
comment: state.comment,
replyId: replyId,
),
]),
),
],
),
),
);
},
);
},
);
},
),
),
);
}
@@ -525,7 +606,7 @@ class _AboutDietScreenState extends State<AboutDietScreen> {
],
),
),
CpfcContainer(calories: 0, protein: 0, fat: 0, carbohydrates: 0)
CpfcContainer(calories: 0, protein: 0, fat: 0, carbohydrates: 0),
],
),
),

View File

@@ -70,10 +70,10 @@ class AuthorCard extends StatelessWidget {
fontSize: 16,
fontWeight: FontWeight.w500,
),
)
])
),
],),
],
)
),
],
),
),
@@ -99,7 +99,7 @@ class AuthorCard extends StatelessWidget {
),
),
),
)
),
],
),
);

View File

@@ -0,0 +1,90 @@
import 'package:eatvio_app/theme/theme_helper.dart';
import 'package:flutter/material.dart';
import 'package:table_calendar/table_calendar.dart';
class CalendarWidget extends StatefulWidget {
const CalendarWidget({super.key});
@override
State<CalendarWidget> createState() => _CalendarWidgetState();
}
class _CalendarWidgetState extends State<CalendarWidget> {
CalendarFormat _calendarFormat = CalendarFormat.month;
DateTime _focusedDay = DateTime.now();
DateTime? _selectedDay = DateTime.now();
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.only(top: 5),
child: TableCalendar(
firstDay: DateTime.utc(2010, 10, 16),
lastDay: DateTime.utc(2030, 3, 14),
locale: 'ru_RU',
startingDayOfWeek: StartingDayOfWeek.monday,
focusedDay: _focusedDay,
rangeStartDay: _selectedDay,
rangeEndDay: _selectedDay?.add(const Duration(days: 6)),
calendarFormat: _calendarFormat,
headerStyle: HeaderStyle(
titleCentered: true,
formatButtonVisible: false,
leftChevronVisible: false,
rightChevronVisible: false,
),
rowHeight: 40,
selectedDayPredicate: (day) {
return isSameDay(_selectedDay, day);
},
onDaySelected: (selectedDay, focusedDay) {
if (!isSameDay(_selectedDay, selectedDay)) {
setState(() {
_selectedDay = selectedDay;
_focusedDay = focusedDay;
});
}
},
onFormatChanged: (format) {
if (_calendarFormat != format) {
setState(() {
_calendarFormat = format;
});
}
},
onPageChanged: (focusedDay) {
_focusedDay = focusedDay;
},
calendarStyle: CalendarStyle(
weekendDecoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
defaultDecoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
selectedDecoration: BoxDecoration(
color: appTheme.blueA400,
shape: BoxShape.circle,
),
todayTextStyle: TextStyle(
color: Colors.black,
),
todayDecoration: BoxDecoration(
border: Border.all(
color: appTheme.blueA400,
width: 2,
),
color: Colors.white,
shape: BoxShape.circle,
),
),
),
),
],
);
}
}

View File

@@ -39,8 +39,8 @@ class CpfcContainer extends StatelessWidget {
Text('$carbohydrates', style: TextStyle(color: appTheme.blueGray800, fontSize: 16, fontWeight: FontWeight.w600)),
Text(s.carbohydrates, style: TextStyle(color: appTheme.blueGray800, fontSize: 12, fontWeight: FontWeight.w500)),
],
)
]),
),
],),
);
}
}

View File

@@ -14,7 +14,7 @@ class InfoBouble extends StatelessWidget {
color: backgroundColor ?? appTheme.gray50,
borderRadius: BorderRadius.circular(radius),
),
child: Row(children: children),
child: Row(mainAxisSize: MainAxisSize.min, children: children),
);
}
}

View File

@@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
class MainBackgroundBouble extends StatelessWidget {
const MainBackgroundBouble(
{super.key, required this.child, this.width, this.padding, this.enableShadow = false});
{super.key, required this.child, this.width, this.padding, this.enableShadow = false,});
final double? width;
final Widget child;
final bool enableShadow;
@@ -21,7 +21,7 @@ class MainBackgroundBouble extends StatelessWidget {
offset: Offset(0, 0),
),
]
: null),
: null,),
child: ClipRRect(
borderRadius: BorderRadius.circular(12),
child: Container(

View File

@@ -7,6 +7,7 @@ import 'package:eatvio_app/theme/theme_helper.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:go_router/go_router.dart';
import 'package:share_plus/share_plus.dart';
class MoreOptions extends StatelessWidget {
@@ -72,7 +73,9 @@ class MoreOptions extends StatelessWidget {
child: CustomDivider(),
),
GestureDetector(
onTap: () {},
onTap: () {
context.push('complainingScreen');
},
child: Row(
children: [
Text(
@@ -87,10 +90,10 @@ class MoreOptions extends StatelessWidget {
SvgPicture.asset('assets/icons/complain.svg', width: 16, height: 20),
],
),
)
),
],
),
),
width: 272);
width: 272,);
}
}

View File

@@ -0,0 +1,56 @@
import 'package:eatvio_app/features/diets/presentation/widgets/calendar_widget.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:eatvio_app/theme/theme_helper.dart';
import 'package:eatvio_app/widgets/custom_outlined_button.dart';
import 'package:flutter/material.dart';
class StartDietBottomSheet extends StatelessWidget {
const StartDietBottomSheet({super.key});
@override
Widget build(BuildContext context) {
final s = S.of(context);
return Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(height: 5),
Container(
height: 4,
width: 40,
decoration: BoxDecoration(color: appTheme.lightGrey, borderRadius: BorderRadius.circular(20)),
),
SizedBox(height: 22),
Text(s.startDiet,
style: TextStyle(
color: appTheme.blueGray800,
fontSize: 20,
fontWeight: FontWeight.w600,
),),
SizedBox(height: 12),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 25.0),
child: Text(s.choose_start_diet_date,
textAlign: TextAlign.center,
style: TextStyle(
color: appTheme.blueGray800,
fontSize: 16,
fontWeight: FontWeight.w500,
),),
),
CalendarWidget(),
Padding(
padding: EdgeInsets.only(left: 16, right: 16, top: 20, bottom: 25),
child: CustomOutlinedButton(
height: 52,
text: s.continue_,
buttonStyle: ButtonStyle(
textStyle: WidgetStatePropertyAll(TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w600)),
backgroundColor: WidgetStatePropertyAll(appTheme.blueA400),
side: WidgetStatePropertyAll(BorderSide.none),
),
),
),
],
);
}
}

View File

@@ -29,7 +29,7 @@ class _TypeBadgesState extends State<TypeBadges> {
title: s.alko_type,
description: s.alko_type_desc,
)
));
),);
}
if (widget.type.veg == true) {
badgeSource.add((
@@ -40,7 +40,7 @@ class _TypeBadgesState extends State<TypeBadges> {
title: s.vegan_type,
description: s.vegan_type_desc,
)
));
),);
}
if (widget.type.corb == true) {
badgeSource.add((
@@ -51,7 +51,7 @@ class _TypeBadgesState extends State<TypeBadges> {
title: s.corb_type,
description: s.corb_type_desc,
)
));
),);
}
if (widget.type.meat == true) {
badgeSource.add((
@@ -62,7 +62,7 @@ class _TypeBadgesState extends State<TypeBadges> {
title: s.meat_type,
description: s.meat_type_desc,
)
));
),);
}
return Row(
children: List.generate(
@@ -117,7 +117,7 @@ class _TypeBadgesState extends State<TypeBadges> {
}
class _InfoOverlayEntry extends StatelessWidget {
const _InfoOverlayEntry({super.key, required this.title, required this.description, required this.assetPath, required this.onClose});
const _InfoOverlayEntry({required this.title, required this.description, required this.assetPath, required this.onClose});
final String title;
final String description;
final assetPath;

View File

@@ -0,0 +1,48 @@
import 'package:eatvio_app/features/diets/services/diets_service.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
class DietsRepository {
DietsRepository({required this.dietsService});
final DietsService dietsService;
Future<void> likeDiet(int id) async {
try {
await dietsService.likeDiet(id: id);
} catch (e) {
rethrow;
}
}
Future<void> unlikeDiet(int id) async {
try {
await dietsService.unlikeDiet(id: id);
} catch (e) {
rethrow;
}
}
Future<Diet> getDiet(int id) async {
try {
final diet = await dietsService.getDiet(id: id);
return diet;
} catch (e) {
rethrow;
}
}
Future<void> addToFavorite(int id) async {
try {
await dietsService.addToFavorite(id: id);
} catch (e) {
rethrow;
}
}
Future<void> removeFromFavorite(int id) async {
try {
await dietsService.removeFromFavorite(id: id);
} catch (e) {
rethrow;
}
}
}

View File

@@ -1,12 +1,36 @@
import 'package:dio/dio.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:retrofit/retrofit.dart';
part 'diets_service.g.dart';
@RestApi()
abstract class DietsService {
factory DietsService(Dio dio, {String baseUrl}) = _DietsService;
@POST('/api/diets/{id}/like')
Future<void> likeDiet({
@Path() required int id,
});
}
@POST('/api/diets/{id}/add_to_favorite')
Future<void> addToFavorite({
@Path() required int id,
});
@POST('/api/diets/{id}/remove_from_favorite')
Future<void> removeFromFavorite({
@Path() required int id,
});
@POST('/api/diets/{id}/unliked')
Future<void> unlikeDiet({
@Path() required int id,
});
@GET('/api/diets/show/{id}')
Future<Diet> getDiet({
@Path() required int id,
});
}

View File

@@ -21,6 +21,139 @@ class _DietsService implements DietsService {
final ParseErrorLogger? errorLogger;
@override
Future<void> likeDiet({required int id}) async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _headers = <String, dynamic>{};
const Map<String, dynamic>? _data = null;
final _options = _setStreamType<void>(Options(
method: 'POST',
headers: _headers,
extra: _extra,
)
.compose(
_dio.options,
'/api/diets/${id}/like',
queryParameters: queryParameters,
data: _data,
)
.copyWith(
baseUrl: _combineBaseUrls(
_dio.options.baseUrl,
baseUrl,
)));
await _dio.fetch<void>(_options);
}
@override
Future<void> addToFavorite({required int id}) async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _headers = <String, dynamic>{};
const Map<String, dynamic>? _data = null;
final _options = _setStreamType<void>(Options(
method: 'POST',
headers: _headers,
extra: _extra,
)
.compose(
_dio.options,
'/api/diets/${id}/add_to_favorite',
queryParameters: queryParameters,
data: _data,
)
.copyWith(
baseUrl: _combineBaseUrls(
_dio.options.baseUrl,
baseUrl,
)));
await _dio.fetch<void>(_options);
}
@override
Future<void> removeFromFavorite({required int id}) async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _headers = <String, dynamic>{};
const Map<String, dynamic>? _data = null;
final _options = _setStreamType<void>(Options(
method: 'POST',
headers: _headers,
extra: _extra,
)
.compose(
_dio.options,
'/api/diets/${id}/remove_from_favorite',
queryParameters: queryParameters,
data: _data,
)
.copyWith(
baseUrl: _combineBaseUrls(
_dio.options.baseUrl,
baseUrl,
)));
await _dio.fetch<void>(_options);
}
@override
Future<void> unlikeDiet({required int id}) async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _headers = <String, dynamic>{};
const Map<String, dynamic>? _data = null;
final _options = _setStreamType<void>(Options(
method: 'POST',
headers: _headers,
extra: _extra,
)
.compose(
_dio.options,
'/api/diets/${id}/unliked',
queryParameters: queryParameters,
data: _data,
)
.copyWith(
baseUrl: _combineBaseUrls(
_dio.options.baseUrl,
baseUrl,
)));
await _dio.fetch<void>(_options);
}
@override
Future<Diet> getDiet({required int id}) async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _headers = <String, dynamic>{};
const Map<String, dynamic>? _data = null;
final _options = _setStreamType<Diet>(Options(
method: 'GET',
headers: _headers,
extra: _extra,
)
.compose(
_dio.options,
'/api/diets/show/${id}',
queryParameters: queryParameters,
data: _data,
)
.copyWith(
baseUrl: _combineBaseUrls(
_dio.options.baseUrl,
baseUrl,
)));
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
late Diet _value;
try {
_value = Diet.fromJson(_result.data!);
} on Object catch (e, s) {
errorLogger?.logError(e, s, _options);
rethrow;
}
return _value;
}
RequestOptions _setStreamType<T>(RequestOptions requestOptions) {
if (T != dynamic &&
!(requestOptions.responseType == ResponseType.bytes ||

View File

@@ -31,6 +31,8 @@ class Diet with _$Diet {
@JsonKey(name: "total_likes") required int totalLikes,
@JsonKey(name: "total_views") required int totalViews,
@JsonKey(name: "total_comments") required int totalComments,
@JsonKey(name: "was_liked_by_me") required bool wasLikedByMe,
@JsonKey(name: "is_favorite") required bool isFavorite,
}) = _Diet;
factory Diet.fromJson(Map<String, dynamic> json) => _$DietFromJson(json);

View File

@@ -284,6 +284,10 @@ mixin _$Diet {
int get totalViews => throw _privateConstructorUsedError;
@JsonKey(name: "total_comments")
int get totalComments => throw _privateConstructorUsedError;
@JsonKey(name: "was_liked_by_me")
bool get wasLikedByMe => throw _privateConstructorUsedError;
@JsonKey(name: "is_favorite")
bool get isFavorite => throw _privateConstructorUsedError;
/// Serializes this Diet to a JSON map.
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@@ -312,7 +316,9 @@ abstract class $DietCopyWith<$Res> {
@JsonKey(name: "author") Author author,
@JsonKey(name: "total_likes") int totalLikes,
@JsonKey(name: "total_views") int totalViews,
@JsonKey(name: "total_comments") int totalComments});
@JsonKey(name: "total_comments") int totalComments,
@JsonKey(name: "was_liked_by_me") bool wasLikedByMe,
@JsonKey(name: "is_favorite") bool isFavorite});
$DietTypeCopyWith<$Res> get type;
$AuthorCopyWith<$Res> get author;
@@ -345,6 +351,8 @@ class _$DietCopyWithImpl<$Res, $Val extends Diet>
Object? totalLikes = null,
Object? totalViews = null,
Object? totalComments = null,
Object? wasLikedByMe = null,
Object? isFavorite = null,
}) {
return _then(_value.copyWith(
id: null == id
@@ -395,6 +403,14 @@ class _$DietCopyWithImpl<$Res, $Val extends Diet>
? _value.totalComments
: totalComments // ignore: cast_nullable_to_non_nullable
as int,
wasLikedByMe: null == wasLikedByMe
? _value.wasLikedByMe
: wasLikedByMe // ignore: cast_nullable_to_non_nullable
as bool,
isFavorite: null == isFavorite
? _value.isFavorite
: isFavorite // ignore: cast_nullable_to_non_nullable
as bool,
) as $Val);
}
@@ -439,7 +455,9 @@ abstract class _$$DietImplCopyWith<$Res> implements $DietCopyWith<$Res> {
@JsonKey(name: "author") Author author,
@JsonKey(name: "total_likes") int totalLikes,
@JsonKey(name: "total_views") int totalViews,
@JsonKey(name: "total_comments") int totalComments});
@JsonKey(name: "total_comments") int totalComments,
@JsonKey(name: "was_liked_by_me") bool wasLikedByMe,
@JsonKey(name: "is_favorite") bool isFavorite});
@override
$DietTypeCopyWith<$Res> get type;
@@ -471,6 +489,8 @@ class __$$DietImplCopyWithImpl<$Res>
Object? totalLikes = null,
Object? totalViews = null,
Object? totalComments = null,
Object? wasLikedByMe = null,
Object? isFavorite = null,
}) {
return _then(_$DietImpl(
id: null == id
@@ -521,6 +541,14 @@ class __$$DietImplCopyWithImpl<$Res>
? _value.totalComments
: totalComments // ignore: cast_nullable_to_non_nullable
as int,
wasLikedByMe: null == wasLikedByMe
? _value.wasLikedByMe
: wasLikedByMe // ignore: cast_nullable_to_non_nullable
as bool,
isFavorite: null == isFavorite
? _value.isFavorite
: isFavorite // ignore: cast_nullable_to_non_nullable
as bool,
));
}
}
@@ -541,7 +569,9 @@ class _$DietImpl implements _Diet {
@JsonKey(name: "author") required this.author,
@JsonKey(name: "total_likes") required this.totalLikes,
@JsonKey(name: "total_views") required this.totalViews,
@JsonKey(name: "total_comments") required this.totalComments})
@JsonKey(name: "total_comments") required this.totalComments,
@JsonKey(name: "was_liked_by_me") required this.wasLikedByMe,
@JsonKey(name: "is_favorite") required this.isFavorite})
: _dailySchedule = dailySchedule;
factory _$DietImpl.fromJson(Map<String, dynamic> json) =>
@@ -589,10 +619,16 @@ class _$DietImpl implements _Diet {
@override
@JsonKey(name: "total_comments")
final int totalComments;
@override
@JsonKey(name: "was_liked_by_me")
final bool wasLikedByMe;
@override
@JsonKey(name: "is_favorite")
final bool isFavorite;
@override
String toString() {
return 'Diet(id: $id, name: $name, image: $image, duration: $duration, state: $state, type: $type, details: $details, dailySchedule: $dailySchedule, author: $author, totalLikes: $totalLikes, totalViews: $totalViews, totalComments: $totalComments)';
return 'Diet(id: $id, name: $name, image: $image, duration: $duration, state: $state, type: $type, details: $details, dailySchedule: $dailySchedule, author: $author, totalLikes: $totalLikes, totalViews: $totalViews, totalComments: $totalComments, wasLikedByMe: $wasLikedByMe, isFavorite: $isFavorite)';
}
@override
@@ -616,7 +652,11 @@ class _$DietImpl implements _Diet {
(identical(other.totalViews, totalViews) ||
other.totalViews == totalViews) &&
(identical(other.totalComments, totalComments) ||
other.totalComments == totalComments));
other.totalComments == totalComments) &&
(identical(other.wasLikedByMe, wasLikedByMe) ||
other.wasLikedByMe == wasLikedByMe) &&
(identical(other.isFavorite, isFavorite) ||
other.isFavorite == isFavorite));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -634,7 +674,9 @@ class _$DietImpl implements _Diet {
author,
totalLikes,
totalViews,
totalComments);
totalComments,
wasLikedByMe,
isFavorite);
/// Create a copy of Diet
/// with the given fields replaced by the non-null parameter values.
@@ -666,7 +708,9 @@ abstract class _Diet implements Diet {
@JsonKey(name: "author") required final Author author,
@JsonKey(name: "total_likes") required final int totalLikes,
@JsonKey(name: "total_views") required final int totalViews,
@JsonKey(name: "total_comments") required final int totalComments}) =
@JsonKey(name: "total_comments") required final int totalComments,
@JsonKey(name: "was_liked_by_me") required final bool wasLikedByMe,
@JsonKey(name: "is_favorite") required final bool isFavorite}) =
_$DietImpl;
factory _Diet.fromJson(Map<String, dynamic> json) = _$DietImpl.fromJson;
@@ -707,6 +751,12 @@ abstract class _Diet implements Diet {
@override
@JsonKey(name: "total_comments")
int get totalComments;
@override
@JsonKey(name: "was_liked_by_me")
bool get wasLikedByMe;
@override
@JsonKey(name: "is_favorite")
bool get isFavorite;
/// Create a copy of Diet
/// with the given fields replaced by the non-null parameter values.

View File

@@ -43,6 +43,8 @@ _$DietImpl _$$DietImplFromJson(Map<String, dynamic> json) => _$DietImpl(
totalLikes: (json['total_likes'] as num).toInt(),
totalViews: (json['total_views'] as num).toInt(),
totalComments: (json['total_comments'] as num).toInt(),
wasLikedByMe: json['was_liked_by_me'] as bool,
isFavorite: json['is_favorite'] as bool,
);
Map<String, dynamic> _$$DietImplToJson(_$DietImpl instance) =>
@@ -59,6 +61,8 @@ Map<String, dynamic> _$$DietImplToJson(_$DietImpl instance) =>
'total_likes': instance.totalLikes,
'total_views': instance.totalViews,
'total_comments': instance.totalComments,
'was_liked_by_me': instance.wasLikedByMe,
'is_favorite': instance.isFavorite,
};
_$AuthorImpl _$$AuthorImplFromJson(Map<String, dynamic> json) => _$AuthorImpl(

View File

@@ -23,11 +23,11 @@ class DietsCubit extends Cubit<DietsState> {
emit(DietsState.loaded(
dietsList: dietsPagination.data,
isLoading: isLoading,
));
),);
} catch (e) {
emit(DietsState.error(
errorMessage: e.toString(),
));
),);
}
}

View File

@@ -34,7 +34,7 @@ class RecipesCubit extends Cubit<RecipesState> {
selectedTags: _selectedTags,
selectedTagsCounter: _selectedTags.length,
isLoading: isLoading,
));
),);
} catch (e) {
emit(RecipesState.error(errorMessage: e.toString()));
}
@@ -61,7 +61,7 @@ class RecipesCubit extends Cubit<RecipesState> {
...recipesList,
],
isLoading: isLoading,
));
),);
}
} catch (e) {
emit(RecipesState.error(errorMessage: e.toString()));
@@ -74,6 +74,6 @@ class RecipesCubit extends Cubit<RecipesState> {
emit((state as RecipesStateLoaded).copyWith(
selectedTags: _selectedTags,
selectedTagsCounter: _selectedTags.length,
));
),);
}
}

View File

@@ -19,7 +19,7 @@ class ProfileCubit extends Cubit<ProfileState> {
profile: await profileRepository.getProfileBySlug(slug),
profileDetails: await profileRepository.getMyProfileDetails(),
blogPosts: await profileRepository.getBlogPostsByAuthorSlug(slug: slug),
));
),);
} catch (e) {
emit(ProfileState.error(errorMessage: e.toString()));
}
@@ -37,7 +37,7 @@ class ProfileCubit extends Cubit<ProfileState> {
blogPosts: await profileRepository.getBlogPostsByAuthorSlug(slug: profile.slug),
weightPoints: await profileRepository.getWeight(period: period),
circumferencePoints: await profileRepository.getCircumferences(period: period),
));
),);
} catch (e) {
emit(ProfileState.error(errorMessage: e.toString()));
}

View File

@@ -88,7 +88,7 @@ class RecipeCreateCubit extends Cubit<RecipeCreateState> {
statuses: statuses,
selectedType: selectedType,
selectedCookingTime: selectedCookingTime,
selectedStatus: selectedStatus));
selectedStatus: selectedStatus,),);
} catch (e) {
emit(RecipeCreateState.error(errorMessage: e.toString()));
}
@@ -136,7 +136,7 @@ class RecipeCreateCubit extends Cubit<RecipeCreateState> {
statuses: statuses,
selectedType: types[0],
selectedCookingTime: cookingTimes[0],
selectedStatus: statuses[0]));
selectedStatus: statuses[0],),);
} catch (e) {
emit(RecipeCreateState.error(errorMessage: e.toString()));
}

View File

@@ -238,7 +238,7 @@ class RecipeCreateScreen extends StatelessWidget {
inactiveTrackColor: Colors.grey.shade300,
),
Text('шт'),
]),
],),
SizedBox(height: 8),
Container(
height: 48,
@@ -340,7 +340,7 @@ class RecipeCreateScreen extends StatelessWidget {
),
),
],
)),
),),
],
),
),
@@ -381,7 +381,7 @@ class RecipeCreateScreen extends StatelessWidget {
],
),
)
: Image.file(File(state.stepImages[stepNumber]!.path), height: 150, fit: BoxFit.cover)),
: Image.file(File(state.stepImages[stepNumber]!.path), height: 150, fit: BoxFit.cover),),
SizedBox(height: 16),
CustomTextFormField(
hintText: 'Введите описание шага',
@@ -495,7 +495,7 @@ class RecipeCreateScreen extends StatelessWidget {
steps.add(step.Step(
description: state.stepControllers[i].text,
image: state.stepImages[i]?.path,
));
),);
}
}

View File

@@ -247,7 +247,7 @@ class RecipeEditScreen extends StatelessWidget {
inactiveTrackColor: Colors.grey.shade300,
),
Text('шт'),
]),
],),
SizedBox(height: 8),
Container(
height: 48,
@@ -267,7 +267,7 @@ class RecipeEditScreen extends StatelessWidget {
onPressed: () => context.read<RecipeCreateCubit>().addIngredient(new Ingredient(
name: state.productNameController.text,
portion: state.ingredientController.text,
unit: state.ingredientAsItems ? 'pcs' : 'gr'))),
unit: state.ingredientAsItems ? 'pcs' : 'gr',),),),
),
SizedBox(height: 24),
Text('Описание рецепта'),
@@ -345,7 +345,7 @@ class RecipeEditScreen extends StatelessWidget {
),
),
],
)),
),),
],
),
),
@@ -390,7 +390,7 @@ class RecipeEditScreen extends StatelessWidget {
baseUrl + '/storage/' + state.stepImages[stepNumber]!.path,
height: 150,
fit: BoxFit.cover,
)),
),),
SizedBox(height: 16),
CustomTextFormField(
hintText: 'Введите описание шага',
@@ -504,7 +504,7 @@ class RecipeEditScreen extends StatelessWidget {
steps.add(step.Step(
description: state.stepControllers[i].text,
image: state.stepImages[i]?.path,
));
),);
}
}

View File

@@ -88,7 +88,7 @@ class _CityOfLivingScreenState extends State<CityOfLivingScreen> {
textStyle: TextStyle(
fontSize: 16,
color: Colors.black,
)),
),),
itemBuilder: (BuildContext context, String item) {
return Padding(
padding: const EdgeInsets.all(8.0),
@@ -111,8 +111,7 @@ class _CityOfLivingScreenState extends State<CityOfLivingScreen> {
suggestionsCallback: (query) async {
if (query.length >= 3) {
final registrationCubit = context.read<RegistrationCubit>();
final qwe = (await registrationCubit.getLocationsByQuery(query));
return qwe;
return (await registrationCubit.getLocationsByQuery(query));
}
return null;
},
@@ -130,11 +129,9 @@ class _CityOfLivingScreenState extends State<CityOfLivingScreen> {
if (locationData != null) {
final List<String> locations = await context
.read<RegistrationCubit>()
.getLocationsByCoordinates(
locationData.latitude.toString(), locationData.longitude.toString());
.getLocationsByCoordinates(locationData.latitude.toString(), locationData.longitude.toString());
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit
.updateSheet(registrationCubit.state.sheet.copyWith(location: locations.first));
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(location: locations.first));
setState(() {
cityController.text = locations.first;
suggestionsController.suggestions = locations;

View File

@@ -20,7 +20,7 @@ class SettingsCubit extends Cubit<SettingsState> {
profileSettings: await settingsRepository.getProfileSettings(),
profileDetails: await profileRepository.getMyProfileDetails(),
profile: await profileRepository.getMyProfile(),
));
),);
} catch (e) {
emit(SettingsState.error(errorMessage: e.toString()));
}

View File

@@ -36,7 +36,7 @@ MessageLookupByLibrary? _findExact(String localeName) {
Future<bool> initializeMessages(String localeName) {
var availableLocale = Intl.verifiedLocale(
localeName, (locale) => _deferredLibraries[locale] != null,
onFailure: (_) => null);
onFailure: (_) => null,);
if (availableLocale == null) {
return new SynchronousFuture(false);
}

View File

@@ -32,7 +32,7 @@ class MessageLookup extends MessageLookupByLibrary {
"admin": MessageLookupByLibrary.simpleMessage("Админ"),
"alko_type": MessageLookupByLibrary.simpleMessage("Алкоголь"),
"alko_type_desc": MessageLookupByLibrary.simpleMessage(
"С некоторыми видами диет можно употреблять алкоголь в умеренных количествах. Рекомендуется совмещать вместе с низкокалорийными закусками."),
"С некоторыми видами диет можно употреблять алкоголь в умеренных количествах. Рекомендуется совмещать вместе с низкокалорийными закусками.",),
"allergies_presence":
MessageLookupByLibrary.simpleMessage("Наличие аллергии"),
"another_form_of_comment":
@@ -42,7 +42,7 @@ class MessageLookup extends MessageLookupByLibrary {
"archived": MessageLookupByLibrary.simpleMessage("В архиве"),
"authentificate": MessageLookupByLibrary.simpleMessage("Войти"),
"average_pressure": MessageLookupByLibrary.simpleMessage(
"Средние показатели давления:"),
"Средние показатели давления:",),
"bodymass_chart": MessageLookupByLibrary.simpleMessage("График ИМТ"),
"calories": MessageLookupByLibrary.simpleMessage("Калории"),
"carbohydrates": MessageLookupByLibrary.simpleMessage("Углеводы"),
@@ -50,10 +50,12 @@ class MessageLookup extends MessageLookupByLibrary {
"chest": MessageLookupByLibrary.simpleMessage("Грудь"),
"chest_circumference":
MessageLookupByLibrary.simpleMessage("Обхват груди"),
"choose_start_diet_date": MessageLookupByLibrary.simpleMessage(
"Выберите дату старты диеты. Она отобразиться у Вас в дневнике",),
"circumference_empty": MessageLookupByLibrary.simpleMessage(
"Все замеры обязательны к заполнению"),
"Все замеры обязательны к заполнению",),
"circumference_is_not_a_number": MessageLookupByLibrary.simpleMessage(
"Все замеры должны быть числами"),
"Все замеры должны быть числами",),
"circumferences_chart":
MessageLookupByLibrary.simpleMessage("График обхватов"),
"city": MessageLookupByLibrary.simpleMessage("Город"),
@@ -64,10 +66,11 @@ class MessageLookup extends MessageLookupByLibrary {
"comments_plural": MessageLookupByLibrary.simpleMessage("комментариев"),
"complain": MessageLookupByLibrary.simpleMessage("Пожаловаться"),
"continueButton": MessageLookupByLibrary.simpleMessage("Продолжить"),
"continue_": MessageLookupByLibrary.simpleMessage("Продолжить"),
"copy_link": MessageLookupByLibrary.simpleMessage("Скопировать ссылку"),
"corb_type": MessageLookupByLibrary.simpleMessage("Мучное"),
"corb_type_desc": MessageLookupByLibrary.simpleMessage(
"Если вы любите мучные продукты, но хотите придерживаться диеты, вам подходит диета с добавленим мучных блюд на основе цельнозерновых вариантов. В них больше сложных углеводов и клетчатки, что способствует длительному чувству сытости и поддерживает здоровье пищеварительной системы."),
"Если вы любите мучные продукты, но хотите придерживаться диеты, вам подходит диета с добавленим мучных блюд на основе цельнозерновых вариантов. В них больше сложных углеводов и клетчатки, что способствует длительному чувству сытости и поддерживает здоровье пищеварительной системы.",),
"country": MessageLookupByLibrary.simpleMessage("Страна"),
"date_of_birth": MessageLookupByLibrary.simpleMessage("Дата рождения"),
"day": MessageLookupByLibrary.simpleMessage("День"),
@@ -80,17 +83,17 @@ class MessageLookup extends MessageLookupByLibrary {
"do_you_have_hypotension_tendency":
MessageLookupByLibrary.simpleMessage("Есть ли у вас гипотония?"),
"do_you_take_pills": MessageLookupByLibrary.simpleMessage(
"Принимаете ли вы лекарства или бады?"),
"Принимаете ли вы лекарства или бады?",),
"down_pressure":
MessageLookupByLibrary.simpleMessage("Нижние показатели давления:"),
"draft": MessageLookupByLibrary.simpleMessage("Черновик"),
"email": MessageLookupByLibrary.simpleMessage("Элетронная почта"),
"email_empty": MessageLookupByLibrary.simpleMessage(
"Необходимо ввести адрес электронной почты"),
"Необходимо ввести адрес электронной почты",),
"email_invalid": MessageLookupByLibrary.simpleMessage(
"Некорректный адрес электронной почты"),
"Некорректный адрес электронной почты",),
"enter_additional_information": MessageLookupByLibrary.simpleMessage(
"Введите любую дополнительную информацию на своё усмотрение:"),
"Введите любую дополнительную информацию на своё усмотрение:",),
"enter_information":
MessageLookupByLibrary.simpleMessage("Введите информацию..."),
"exit": MessageLookupByLibrary.simpleMessage("Выйти"),
@@ -99,16 +102,16 @@ class MessageLookup extends MessageLookupByLibrary {
"favorite_foods":
MessageLookupByLibrary.simpleMessage("Любимые продукты"),
"favorite_unfavorite_foods": MessageLookupByLibrary.simpleMessage(
"Ваши любимые/нелюбимые продукты питания?"),
"Ваши любимые/нелюбимые продукты питания?",),
"female": MessageLookupByLibrary.simpleMessage("Женский"),
"fill_in_information":
MessageLookupByLibrary.simpleMessage("Заполните информацию:"),
"finish": MessageLookupByLibrary.simpleMessage("Завершить"),
"first_name": MessageLookupByLibrary.simpleMessage("Имя"),
"first_name_empty": MessageLookupByLibrary.simpleMessage(
"Имя обязательно для заполнения"),
"Имя обязательно для заполнения",),
"first_name_short": MessageLookupByLibrary.simpleMessage(
"В имени должен быть минимум 1 символ"),
"В имени должен быть минимум 1 символ",),
"gr": MessageLookupByLibrary.simpleMessage("гр"),
"grams": MessageLookupByLibrary.simpleMessage("гр"),
"height_measurements":
@@ -123,9 +126,9 @@ class MessageLookup extends MessageLookupByLibrary {
"language": MessageLookupByLibrary.simpleMessage("Язык"),
"last_name": MessageLookupByLibrary.simpleMessage("Фамилия"),
"last_name_empty": MessageLookupByLibrary.simpleMessage(
"Фамилия обязательна для заполнения"),
"Фамилия обязательна для заполнения",),
"last_name_short": MessageLookupByLibrary.simpleMessage(
"В фамилии должен быть минимум 6 символов"),
"В фамилии должен быть минимум 6 символов",),
"lbl_english": MessageLookupByLibrary.simpleMessage("English"),
"link_was_copied":
MessageLookupByLibrary.simpleMessage("Ссылка успешно скопирована"),
@@ -134,7 +137,7 @@ class MessageLookup extends MessageLookupByLibrary {
"meal": MessageLookupByLibrary.simpleMessage("Приём пищи"),
"meat_type": MessageLookupByLibrary.simpleMessage("С мясом"),
"meat_type_desc": MessageLookupByLibrary.simpleMessage(
"Диета с мясом полезная и сбалансированная. Включает в себя нежирное мясо: курицу, индейку, кролика или говядину. В сочетании с овощами получаете все необходимые витамины и минералы. Не забывайте о порциях и старайтесь есть медленно, прислушиваясь к своему организму."),
"Диета с мясом полезная и сбалансированная. Включает в себя нежирное мясо: курицу, индейку, кролика или говядину. В сочетании с овощами получаете все необходимые витамины и минералы. Не забывайте о порциях и старайтесь есть медленно, прислушиваясь к своему организму.",),
"milliliter": MessageLookupByLibrary.simpleMessage("мл"),
"msg_network_err":
MessageLookupByLibrary.simpleMessage("Сетевая ошибка!"),
@@ -143,9 +146,9 @@ class MessageLookup extends MessageLookupByLibrary {
"my_blog": MessageLookupByLibrary.simpleMessage("Мой блог"),
"my_settings": MessageLookupByLibrary.simpleMessage("Мои настройки"),
"name_empty": MessageLookupByLibrary.simpleMessage(
"Имя пользователя обязательно для заполнения"),
"Имя пользователя обязательно для заполнения",),
"name_short": MessageLookupByLibrary.simpleMessage(
"В имени пользователя должно быть минимум 6 символов"),
"В имени пользователя должно быть минимум 6 символов",),
"no": MessageLookupByLibrary.simpleMessage("Нет"),
"no_account":
MessageLookupByLibrary.simpleMessage("У меня нет аккаунта"),
@@ -155,9 +158,9 @@ class MessageLookup extends MessageLookupByLibrary {
"password_confirmation_mismatch":
MessageLookupByLibrary.simpleMessage("Пароли не совпадают"),
"password_empty": MessageLookupByLibrary.simpleMessage(
"Пароль обязателен для заполнения"),
"Пароль обязателен для заполнения",),
"password_short": MessageLookupByLibrary.simpleMessage(
"В пароле должно быть минимум 6 символов"),
"В пароле должно быть минимум 6 символов",),
"pcs": MessageLookupByLibrary.simpleMessage("шт"),
"place_of_living":
MessageLookupByLibrary.simpleMessage("Место проживания"),
@@ -166,9 +169,9 @@ class MessageLookup extends MessageLookupByLibrary {
"preferred_language":
MessageLookupByLibrary.simpleMessage("Предпочитаемый язык общения"),
"pressure_empty": MessageLookupByLibrary.simpleMessage(
"Все показатели давления обязательны к заполнению"),
"Все показатели давления обязательны к заполнению",),
"pressure_is_not_a_number": MessageLookupByLibrary.simpleMessage(
"Все показатели давления должны быть числами"),
"Все показатели давления должны быть числами",),
"profile": MessageLookupByLibrary.simpleMessage("Профиль"),
"proteins": MessageLookupByLibrary.simpleMessage("Белки"),
"save": MessageLookupByLibrary.simpleMessage("Сохранить"),
@@ -177,11 +180,11 @@ class MessageLookup extends MessageLookupByLibrary {
"skip": MessageLookupByLibrary.simpleMessage("Пропустить"),
"startDiet": MessageLookupByLibrary.simpleMessage("Начать диету"),
"tell_your_schedule": MessageLookupByLibrary.simpleMessage(
"Расскажите в свободной форме о том как просыпаетесь, когда едите, когда ложитесь спать:"),
"Расскажите в свободной форме о том как просыпаетесь, когда едите, когда ложитесь спать:",),
"unfavorite_foods":
MessageLookupByLibrary.simpleMessage("Нелюбимые продукты"),
"up_pressure": MessageLookupByLibrary.simpleMessage(
"Верхние показатели давления:"),
"Верхние показатели давления:",),
"user_authorization":
MessageLookupByLibrary.simpleMessage("Аутентификация"),
"user_registration":
@@ -189,7 +192,7 @@ class MessageLookup extends MessageLookupByLibrary {
"username": MessageLookupByLibrary.simpleMessage("Имя пользователя"),
"vegan_type": MessageLookupByLibrary.simpleMessage("Вегетарианская"),
"vegan_type_desc": MessageLookupByLibrary.simpleMessage(
"Диета основана на потреблении растительной пищи и отказе от продуктов животного происхождения. Такой тип питания может быть разнообразным и вкусным, а также полезным для здоровья."),
"Диета основана на потреблении растительной пищи и отказе от продуктов животного происхождения. Такой тип питания может быть разнообразным и вкусным, а также полезным для здоровья.",),
"waist": MessageLookupByLibrary.simpleMessage("Талия"),
"waist_circumference":
MessageLookupByLibrary.simpleMessage("Обхват талии"),
@@ -200,7 +203,7 @@ class MessageLookup extends MessageLookupByLibrary {
"what_is_your_name":
MessageLookupByLibrary.simpleMessage("Как вас зовут?"),
"wrong_credentials": MessageLookupByLibrary.simpleMessage(
"Неверные данные пользователя"),
"Неверные данные пользователя",),
"your_blood_pressure":
MessageLookupByLibrary.simpleMessage("Ваше артериальное давление?"),
"your_favorite_sports":
@@ -208,6 +211,6 @@ class MessageLookup extends MessageLookupByLibrary {
"your_gender": MessageLookupByLibrary.simpleMessage("Ваш пол?"),
"your_height": MessageLookupByLibrary.simpleMessage("Ваш рост:"),
"your_schedule": MessageLookupByLibrary.simpleMessage("Ваш режим дня?"),
"your_weight": MessageLookupByLibrary.simpleMessage("Ваш вес:")
"your_weight": MessageLookupByLibrary.simpleMessage("Ваш вес:"),
};
}

View File

@@ -19,7 +19,7 @@ class S {
static S get current {
assert(_current != null,
'No instance of S was loaded. Try to initialize the S delegate before accessing S.current.');
'No instance of S was loaded. Try to initialize the S delegate before accessing S.current.',);
return _current!;
}
@@ -42,7 +42,7 @@ class S {
static S of(BuildContext context) {
final instance = S.maybeOf(context);
assert(instance != null,
'No instance of S present in the widget tree. Did you add S.delegate in localizationsDelegates?');
'No instance of S present in the widget tree. Did you add S.delegate in localizationsDelegates?',);
return instance!;
}
@@ -1349,6 +1349,26 @@ class S {
args: [],
);
}
/// `Выберите дату старты диеты. Она отобразиться у Вас в дневнике`
String get choose_start_diet_date {
return Intl.message(
'Выберите дату старты диеты. Она отобразиться у Вас в дневнике',
name: 'choose_start_diet_date',
desc: '',
args: [],
);
}
/// `Продолжить`
String get continue_ {
return Intl.message(
'Продолжить',
name: 'continue_',
desc: '',
args: [],
);
}
}
class AppLocalizationDelegate extends LocalizationsDelegate<S> {

View File

@@ -128,5 +128,7 @@
"fats": "Жиры",
"carbohydrates": "Углеводы",
"answer": "Ответить",
"link_was_copied": "Ссылка успешно скопирована"
"link_was_copied": "Ссылка успешно скопирована",
"choose_start_diet_date": "Выберите дату старты диеты. Она отобразиться у Вас в дневнике",
"continue_": "Продолжить"
}

View File

@@ -17,6 +17,9 @@ import 'package:eatvio_app/features/consultant/become_consultant/services/consul
import 'package:eatvio_app/features/diary/presentation/bloc/diary_cubit.dart';
import 'package:eatvio_app/features/diary/repositories/diary_repository.dart';
import 'package:eatvio_app/features/diary/services/diary_service.dart';
import 'package:eatvio_app/features/diets/presentation/bloc/about_diet_cubit.dart';
import 'package:eatvio_app/features/diets/repositories/diets_repository.dart';
import 'package:eatvio_app/features/diets/services/diets_service.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/comments_cubit/comments_cubit.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart';
@@ -66,6 +69,7 @@ Future<void> init() async {
sl.registerFactory<SettingsCubit>(() => SettingsCubit(profileRepository: sl(), settingsRepository: sl()));
sl.registerFactory<RegisterConsultantCubit>(() => RegisterConsultantCubit(consultantRepository: sl()));
sl.registerFactory<DiaryCubit>(() => DiaryCubit(diaryRepository: sl(), glossaryRepository: sl()));
sl.registerFactory<AboutDietCubit>(() => AboutDietCubit(dietsRepository: sl()));
// Repository
sl.registerLazySingleton<ChatRepository>(() => ChatRepository(chatService: sl()));
@@ -79,6 +83,7 @@ Future<void> init() async {
sl.registerLazySingleton<ConsultantRepository>(() => ConsultantRepository(consultantService: sl()));
sl.registerLazySingleton<DiaryRepository>(() => DiaryRepository(diaryService: sl()));
sl.registerLazySingleton<GlossaryRepository>(() => GlossaryRepository(glossaryService: sl()));
sl.registerLazySingleton<DietsRepository>(() => DietsRepository(dietsService: sl()));
// Services
sl.registerLazySingleton<ChatService>(() => ChatService(sl()));
@@ -92,7 +97,9 @@ Future<void> init() async {
sl.registerLazySingleton<ConsultantService>(() => ConsultantService(sl()));
sl.registerLazySingleton<DiaryService>(() => DiaryService(sl()));
sl.registerLazySingleton<GlossaryService>(() => GlossaryService(sl()));
sl.registerLazySingleton<DietsService>(() => DietsService(sl()));
// External
sl.registerLazySingleton(
() => Dio(

View File

@@ -44,11 +44,11 @@ class SubscribersBloc extends Bloc<SubscribersEvent, SubscribersState> {
emit((currentState).copyWith(
subscribers: data,
myProfileModelObj: currentState.myProfileModelObj,
));
),);
} else {
emit(SubscribersLoadedState(
subscribers: data,
));
),);
}
} else {
// Один или несколько ключевых полей отсутствуют, обрабатываем ошибку

View File

@@ -20,7 +20,7 @@ class SubscribersScreen extends StatelessWidget {
static Widget builder(BuildContext context) {
return BlocProvider<SubscribersBloc>(
create: (context) => SubscribersBloc(SubscribersState(myProfileModelObj: SubscribersModel()))..add(SubscribersInitialEvent()),
child: SubscribersScreen());
child: SubscribersScreen(),);
}
Widget build(BuildContext context) {
@@ -93,7 +93,7 @@ class SubscribersScreen extends StatelessWidget {
Padding(
padding: const EdgeInsets.only(right: 20.0),
child: GestureDetector(child: Icon(Icons.create_outlined)),
)
),
],
),
),
@@ -149,7 +149,7 @@ class SubscribersScreen extends StatelessWidget {
),
),
],
)
),
],
),
),
@@ -212,6 +212,6 @@ class SubscribersScreen extends StatelessWidget {
),
subtitle: Text(subscriber?['description'] ?? ''),
trailing: GestureDetector(child: Icon(Icons.edit)),
));
),);
}
}

View File

@@ -170,6 +170,8 @@ class PrimaryColors {
Color get dividerColor => Color(0xFFF1F2F6);
Color get grey => Color(0xFF6D6F71);
Color get lightGrey => Color(0xFFCECECE);
}
PrimaryColors get appTheme => ThemeHelper().themeColor();