forked from eatvio/eatvio_app
Merge remote-tracking branch 'upstream/main'
This commit is contained in:
27
lib/features/diary/models/nutrition_model.dart
Normal file
27
lib/features/diary/models/nutrition_model.dart
Normal file
@@ -0,0 +1,27 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'nutrition_model.freezed.dart';
|
||||
|
||||
part 'nutrition_model.g.dart';
|
||||
|
||||
@freezed
|
||||
class NutritionDataModel with _$NutritionDataModel {
|
||||
const factory NutritionDataModel({
|
||||
required NutritionModel dailyNutritionIntake,
|
||||
required NutritionModel dailyNutritionRecommendation,
|
||||
}) = _NutritionDataModel;
|
||||
|
||||
factory NutritionDataModel.fromJson(Map<String, Object?> json) => _$NutritionDataModelFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class NutritionModel with _$NutritionModel {
|
||||
const factory NutritionModel({
|
||||
required double energy,
|
||||
required double proteins,
|
||||
required double fats,
|
||||
required double carbohydrates,
|
||||
}) = _NutritionModel;
|
||||
|
||||
factory NutritionModel.fromJson(Map<String, Object?> json) => _$NutritionModelFromJson(json);
|
||||
}
|
||||
437
lib/features/diary/models/nutrition_model.freezed.dart
Normal file
437
lib/features/diary/models/nutrition_model.freezed.dart
Normal file
@@ -0,0 +1,437 @@
|
||||
// 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 'nutrition_model.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');
|
||||
|
||||
NutritionDataModel _$NutritionDataModelFromJson(Map<String, dynamic> json) {
|
||||
return _NutritionDataModel.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$NutritionDataModel {
|
||||
NutritionModel get dailyNutritionIntake => throw _privateConstructorUsedError;
|
||||
NutritionModel get dailyNutritionRecommendation =>
|
||||
throw _privateConstructorUsedError;
|
||||
|
||||
/// Serializes this NutritionDataModel to a JSON map.
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
|
||||
/// Create a copy of NutritionDataModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$NutritionDataModelCopyWith<NutritionDataModel> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $NutritionDataModelCopyWith<$Res> {
|
||||
factory $NutritionDataModelCopyWith(
|
||||
NutritionDataModel value, $Res Function(NutritionDataModel) then) =
|
||||
_$NutritionDataModelCopyWithImpl<$Res, NutritionDataModel>;
|
||||
@useResult
|
||||
$Res call(
|
||||
{NutritionModel dailyNutritionIntake,
|
||||
NutritionModel dailyNutritionRecommendation});
|
||||
|
||||
$NutritionModelCopyWith<$Res> get dailyNutritionIntake;
|
||||
$NutritionModelCopyWith<$Res> get dailyNutritionRecommendation;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$NutritionDataModelCopyWithImpl<$Res, $Val extends NutritionDataModel>
|
||||
implements $NutritionDataModelCopyWith<$Res> {
|
||||
_$NutritionDataModelCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of NutritionDataModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? dailyNutritionIntake = null,
|
||||
Object? dailyNutritionRecommendation = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
dailyNutritionIntake: null == dailyNutritionIntake
|
||||
? _value.dailyNutritionIntake
|
||||
: dailyNutritionIntake // ignore: cast_nullable_to_non_nullable
|
||||
as NutritionModel,
|
||||
dailyNutritionRecommendation: null == dailyNutritionRecommendation
|
||||
? _value.dailyNutritionRecommendation
|
||||
: dailyNutritionRecommendation // ignore: cast_nullable_to_non_nullable
|
||||
as NutritionModel,
|
||||
) as $Val);
|
||||
}
|
||||
|
||||
/// Create a copy of NutritionDataModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$NutritionModelCopyWith<$Res> get dailyNutritionIntake {
|
||||
return $NutritionModelCopyWith<$Res>(_value.dailyNutritionIntake, (value) {
|
||||
return _then(_value.copyWith(dailyNutritionIntake: value) as $Val);
|
||||
});
|
||||
}
|
||||
|
||||
/// Create a copy of NutritionDataModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$NutritionModelCopyWith<$Res> get dailyNutritionRecommendation {
|
||||
return $NutritionModelCopyWith<$Res>(_value.dailyNutritionRecommendation,
|
||||
(value) {
|
||||
return _then(
|
||||
_value.copyWith(dailyNutritionRecommendation: value) as $Val);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$NutritionDataModelImplCopyWith<$Res>
|
||||
implements $NutritionDataModelCopyWith<$Res> {
|
||||
factory _$$NutritionDataModelImplCopyWith(_$NutritionDataModelImpl value,
|
||||
$Res Function(_$NutritionDataModelImpl) then) =
|
||||
__$$NutritionDataModelImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call(
|
||||
{NutritionModel dailyNutritionIntake,
|
||||
NutritionModel dailyNutritionRecommendation});
|
||||
|
||||
@override
|
||||
$NutritionModelCopyWith<$Res> get dailyNutritionIntake;
|
||||
@override
|
||||
$NutritionModelCopyWith<$Res> get dailyNutritionRecommendation;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$NutritionDataModelImplCopyWithImpl<$Res>
|
||||
extends _$NutritionDataModelCopyWithImpl<$Res, _$NutritionDataModelImpl>
|
||||
implements _$$NutritionDataModelImplCopyWith<$Res> {
|
||||
__$$NutritionDataModelImplCopyWithImpl(_$NutritionDataModelImpl _value,
|
||||
$Res Function(_$NutritionDataModelImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of NutritionDataModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? dailyNutritionIntake = null,
|
||||
Object? dailyNutritionRecommendation = null,
|
||||
}) {
|
||||
return _then(_$NutritionDataModelImpl(
|
||||
dailyNutritionIntake: null == dailyNutritionIntake
|
||||
? _value.dailyNutritionIntake
|
||||
: dailyNutritionIntake // ignore: cast_nullable_to_non_nullable
|
||||
as NutritionModel,
|
||||
dailyNutritionRecommendation: null == dailyNutritionRecommendation
|
||||
? _value.dailyNutritionRecommendation
|
||||
: dailyNutritionRecommendation // ignore: cast_nullable_to_non_nullable
|
||||
as NutritionModel,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
class _$NutritionDataModelImpl implements _NutritionDataModel {
|
||||
const _$NutritionDataModelImpl(
|
||||
{required this.dailyNutritionIntake,
|
||||
required this.dailyNutritionRecommendation});
|
||||
|
||||
factory _$NutritionDataModelImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$NutritionDataModelImplFromJson(json);
|
||||
|
||||
@override
|
||||
final NutritionModel dailyNutritionIntake;
|
||||
@override
|
||||
final NutritionModel dailyNutritionRecommendation;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'NutritionDataModel(dailyNutritionIntake: $dailyNutritionIntake, dailyNutritionRecommendation: $dailyNutritionRecommendation)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$NutritionDataModelImpl &&
|
||||
(identical(other.dailyNutritionIntake, dailyNutritionIntake) ||
|
||||
other.dailyNutritionIntake == dailyNutritionIntake) &&
|
||||
(identical(other.dailyNutritionRecommendation,
|
||||
dailyNutritionRecommendation) ||
|
||||
other.dailyNutritionRecommendation ==
|
||||
dailyNutritionRecommendation));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(
|
||||
runtimeType, dailyNutritionIntake, dailyNutritionRecommendation);
|
||||
|
||||
/// Create a copy of NutritionDataModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$NutritionDataModelImplCopyWith<_$NutritionDataModelImpl> get copyWith =>
|
||||
__$$NutritionDataModelImplCopyWithImpl<_$NutritionDataModelImpl>(
|
||||
this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$$NutritionDataModelImplToJson(
|
||||
this,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _NutritionDataModel implements NutritionDataModel {
|
||||
const factory _NutritionDataModel(
|
||||
{required final NutritionModel dailyNutritionIntake,
|
||||
required final NutritionModel dailyNutritionRecommendation}) =
|
||||
_$NutritionDataModelImpl;
|
||||
|
||||
factory _NutritionDataModel.fromJson(Map<String, dynamic> json) =
|
||||
_$NutritionDataModelImpl.fromJson;
|
||||
|
||||
@override
|
||||
NutritionModel get dailyNutritionIntake;
|
||||
@override
|
||||
NutritionModel get dailyNutritionRecommendation;
|
||||
|
||||
/// Create a copy of NutritionDataModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$NutritionDataModelImplCopyWith<_$NutritionDataModelImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
NutritionModel _$NutritionModelFromJson(Map<String, dynamic> json) {
|
||||
return _NutritionModel.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$NutritionModel {
|
||||
double get energy => throw _privateConstructorUsedError;
|
||||
double get proteins => throw _privateConstructorUsedError;
|
||||
double get fats => throw _privateConstructorUsedError;
|
||||
double get carbohydrates => throw _privateConstructorUsedError;
|
||||
|
||||
/// Serializes this NutritionModel to a JSON map.
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
|
||||
/// Create a copy of NutritionModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$NutritionModelCopyWith<NutritionModel> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $NutritionModelCopyWith<$Res> {
|
||||
factory $NutritionModelCopyWith(
|
||||
NutritionModel value, $Res Function(NutritionModel) then) =
|
||||
_$NutritionModelCopyWithImpl<$Res, NutritionModel>;
|
||||
@useResult
|
||||
$Res call(
|
||||
{double energy, double proteins, double fats, double carbohydrates});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$NutritionModelCopyWithImpl<$Res, $Val extends NutritionModel>
|
||||
implements $NutritionModelCopyWith<$Res> {
|
||||
_$NutritionModelCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of NutritionModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? energy = null,
|
||||
Object? proteins = null,
|
||||
Object? fats = null,
|
||||
Object? carbohydrates = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
energy: null == energy
|
||||
? _value.energy
|
||||
: energy // ignore: cast_nullable_to_non_nullable
|
||||
as double,
|
||||
proteins: null == proteins
|
||||
? _value.proteins
|
||||
: proteins // ignore: cast_nullable_to_non_nullable
|
||||
as double,
|
||||
fats: null == fats
|
||||
? _value.fats
|
||||
: fats // ignore: cast_nullable_to_non_nullable
|
||||
as double,
|
||||
carbohydrates: null == carbohydrates
|
||||
? _value.carbohydrates
|
||||
: carbohydrates // ignore: cast_nullable_to_non_nullable
|
||||
as double,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$NutritionModelImplCopyWith<$Res>
|
||||
implements $NutritionModelCopyWith<$Res> {
|
||||
factory _$$NutritionModelImplCopyWith(_$NutritionModelImpl value,
|
||||
$Res Function(_$NutritionModelImpl) then) =
|
||||
__$$NutritionModelImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call(
|
||||
{double energy, double proteins, double fats, double carbohydrates});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$NutritionModelImplCopyWithImpl<$Res>
|
||||
extends _$NutritionModelCopyWithImpl<$Res, _$NutritionModelImpl>
|
||||
implements _$$NutritionModelImplCopyWith<$Res> {
|
||||
__$$NutritionModelImplCopyWithImpl(
|
||||
_$NutritionModelImpl _value, $Res Function(_$NutritionModelImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of NutritionModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? energy = null,
|
||||
Object? proteins = null,
|
||||
Object? fats = null,
|
||||
Object? carbohydrates = null,
|
||||
}) {
|
||||
return _then(_$NutritionModelImpl(
|
||||
energy: null == energy
|
||||
? _value.energy
|
||||
: energy // ignore: cast_nullable_to_non_nullable
|
||||
as double,
|
||||
proteins: null == proteins
|
||||
? _value.proteins
|
||||
: proteins // ignore: cast_nullable_to_non_nullable
|
||||
as double,
|
||||
fats: null == fats
|
||||
? _value.fats
|
||||
: fats // ignore: cast_nullable_to_non_nullable
|
||||
as double,
|
||||
carbohydrates: null == carbohydrates
|
||||
? _value.carbohydrates
|
||||
: carbohydrates // ignore: cast_nullable_to_non_nullable
|
||||
as double,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
class _$NutritionModelImpl implements _NutritionModel {
|
||||
const _$NutritionModelImpl(
|
||||
{required this.energy,
|
||||
required this.proteins,
|
||||
required this.fats,
|
||||
required this.carbohydrates});
|
||||
|
||||
factory _$NutritionModelImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$NutritionModelImplFromJson(json);
|
||||
|
||||
@override
|
||||
final double energy;
|
||||
@override
|
||||
final double proteins;
|
||||
@override
|
||||
final double fats;
|
||||
@override
|
||||
final double carbohydrates;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'NutritionModel(energy: $energy, proteins: $proteins, fats: $fats, carbohydrates: $carbohydrates)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$NutritionModelImpl &&
|
||||
(identical(other.energy, energy) || other.energy == energy) &&
|
||||
(identical(other.proteins, proteins) ||
|
||||
other.proteins == proteins) &&
|
||||
(identical(other.fats, fats) || other.fats == fats) &&
|
||||
(identical(other.carbohydrates, carbohydrates) ||
|
||||
other.carbohydrates == carbohydrates));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode =>
|
||||
Object.hash(runtimeType, energy, proteins, fats, carbohydrates);
|
||||
|
||||
/// Create a copy of NutritionModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$NutritionModelImplCopyWith<_$NutritionModelImpl> get copyWith =>
|
||||
__$$NutritionModelImplCopyWithImpl<_$NutritionModelImpl>(
|
||||
this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$$NutritionModelImplToJson(
|
||||
this,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _NutritionModel implements NutritionModel {
|
||||
const factory _NutritionModel(
|
||||
{required final double energy,
|
||||
required final double proteins,
|
||||
required final double fats,
|
||||
required final double carbohydrates}) = _$NutritionModelImpl;
|
||||
|
||||
factory _NutritionModel.fromJson(Map<String, dynamic> json) =
|
||||
_$NutritionModelImpl.fromJson;
|
||||
|
||||
@override
|
||||
double get energy;
|
||||
@override
|
||||
double get proteins;
|
||||
@override
|
||||
double get fats;
|
||||
@override
|
||||
double get carbohydrates;
|
||||
|
||||
/// Create a copy of NutritionModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$NutritionModelImplCopyWith<_$NutritionModelImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
40
lib/features/diary/models/nutrition_model.g.dart
Normal file
40
lib/features/diary/models/nutrition_model.g.dart
Normal file
@@ -0,0 +1,40 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'nutrition_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_$NutritionDataModelImpl _$$NutritionDataModelImplFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$NutritionDataModelImpl(
|
||||
dailyNutritionIntake: NutritionModel.fromJson(
|
||||
json['dailyNutritionIntake'] as Map<String, dynamic>),
|
||||
dailyNutritionRecommendation: NutritionModel.fromJson(
|
||||
json['dailyNutritionRecommendation'] as Map<String, dynamic>),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$NutritionDataModelImplToJson(
|
||||
_$NutritionDataModelImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'dailyNutritionIntake': instance.dailyNutritionIntake,
|
||||
'dailyNutritionRecommendation': instance.dailyNutritionRecommendation,
|
||||
};
|
||||
|
||||
_$NutritionModelImpl _$$NutritionModelImplFromJson(Map<String, dynamic> json) =>
|
||||
_$NutritionModelImpl(
|
||||
energy: (json['energy'] as num).toDouble(),
|
||||
proteins: (json['proteins'] as num).toDouble(),
|
||||
fats: (json['fats'] as num).toDouble(),
|
||||
carbohydrates: (json['carbohydrates'] as num).toDouble(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$NutritionModelImplToJson(
|
||||
_$NutritionModelImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'energy': instance.energy,
|
||||
'proteins': instance.proteins,
|
||||
'fats': instance.fats,
|
||||
'carbohydrates': instance.carbohydrates,
|
||||
};
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:eatvio_app/features/diary/models/diary_day_model.dart';
|
||||
import 'package:eatvio_app/features/diary/models/nutrition_model.dart';
|
||||
import 'package:eatvio_app/features/diary/presentation/bloc/diary_state.dart';
|
||||
import 'package:eatvio_app/features/diary/repositories/diary_repository.dart';
|
||||
import 'package:eatvio_app/features/glossary/models/glossary_model.dart';
|
||||
@@ -10,6 +11,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
class DiaryCubit extends Cubit<DiaryState> {
|
||||
final DiaryRepository diaryRepository;
|
||||
final GlossaryRepository glossaryRepository;
|
||||
double currentSelectedSatietyRating = 3;
|
||||
|
||||
DiaryCubit({
|
||||
required this.diaryRepository,
|
||||
@@ -19,13 +21,23 @@ class DiaryCubit extends Cubit<DiaryState> {
|
||||
getDiaryDay(String date, [bool needLoading = true]) async {
|
||||
if (needLoading) emit(const DiaryState.loading());
|
||||
try {
|
||||
emit(DiaryState.loaded(diary: await diaryRepository.getDiaryByDate(date)));
|
||||
emit(
|
||||
DiaryState.loaded(
|
||||
diary: await diaryRepository.getDiaryByDate(date),
|
||||
nutrition: await getNutrition(await diaryRepository.getDiaryIndexByDate(date)),
|
||||
currentSelectedSatietyRating: currentSelectedSatietyRating,
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
emit(DiaryState.error(errorMessage: e.toString()));
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
Future<NutritionDataModel> getNutrition(int index) async {
|
||||
return (await diaryRepository.getNutritionData(index));
|
||||
}
|
||||
|
||||
addProductToMeal({
|
||||
required int diaryId,
|
||||
required int mealId,
|
||||
@@ -109,4 +121,9 @@ class DiaryCubit extends Cubit<DiaryState> {
|
||||
);
|
||||
await getDiaryDay(date, false);
|
||||
}
|
||||
|
||||
updateCurrentSelectedSatietyRating(double value) {
|
||||
currentSelectedSatietyRating = value;
|
||||
emit((state as DiaryStateLoaded).copyWith(currentSelectedSatietyRating: currentSelectedSatietyRating));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:eatvio_app/features/diary/models/diary_day_model.dart';
|
||||
import 'package:eatvio_app/features/diary/models/nutrition_model.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'diary_state.freezed.dart';
|
||||
@@ -15,5 +16,7 @@ class DiaryState with _$DiaryState {
|
||||
|
||||
const factory DiaryState.loaded({
|
||||
required DiaryDayModel diary,
|
||||
required NutritionDataModel nutrition,
|
||||
required double currentSelectedSatietyRating,
|
||||
}) = DiaryStateLoaded;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,9 @@ mixin _$DiaryState {
|
||||
TResult Function() $default, {
|
||||
required TResult Function() loading,
|
||||
required TResult Function(String errorMessage) error,
|
||||
required TResult Function(DiaryDayModel diary) loaded,
|
||||
required TResult Function(DiaryDayModel diary, NutritionDataModel nutrition,
|
||||
double currentSelectedSatietyRating)
|
||||
loaded,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
@@ -29,7 +31,9 @@ mixin _$DiaryState {
|
||||
TResult? Function()? $default, {
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(String errorMessage)? error,
|
||||
TResult? Function(DiaryDayModel diary)? loaded,
|
||||
TResult? Function(DiaryDayModel diary, NutritionDataModel nutrition,
|
||||
double currentSelectedSatietyRating)?
|
||||
loaded,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
@@ -37,7 +41,9 @@ mixin _$DiaryState {
|
||||
TResult Function()? $default, {
|
||||
TResult Function()? loading,
|
||||
TResult Function(String errorMessage)? error,
|
||||
TResult Function(DiaryDayModel diary)? loaded,
|
||||
TResult Function(DiaryDayModel diary, NutritionDataModel nutrition,
|
||||
double currentSelectedSatietyRating)?
|
||||
loaded,
|
||||
required TResult orElse(),
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@@ -133,7 +139,9 @@ class _$DiaryStateImpl implements _DiaryState {
|
||||
TResult Function() $default, {
|
||||
required TResult Function() loading,
|
||||
required TResult Function(String errorMessage) error,
|
||||
required TResult Function(DiaryDayModel diary) loaded,
|
||||
required TResult Function(DiaryDayModel diary, NutritionDataModel nutrition,
|
||||
double currentSelectedSatietyRating)
|
||||
loaded,
|
||||
}) {
|
||||
return $default();
|
||||
}
|
||||
@@ -144,7 +152,9 @@ class _$DiaryStateImpl implements _DiaryState {
|
||||
TResult? Function()? $default, {
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(String errorMessage)? error,
|
||||
TResult? Function(DiaryDayModel diary)? loaded,
|
||||
TResult? Function(DiaryDayModel diary, NutritionDataModel nutrition,
|
||||
double currentSelectedSatietyRating)?
|
||||
loaded,
|
||||
}) {
|
||||
return $default?.call();
|
||||
}
|
||||
@@ -155,7 +165,9 @@ class _$DiaryStateImpl implements _DiaryState {
|
||||
TResult Function()? $default, {
|
||||
TResult Function()? loading,
|
||||
TResult Function(String errorMessage)? error,
|
||||
TResult Function(DiaryDayModel diary)? loaded,
|
||||
TResult Function(DiaryDayModel diary, NutritionDataModel nutrition,
|
||||
double currentSelectedSatietyRating)?
|
||||
loaded,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if ($default != null) {
|
||||
@@ -250,7 +262,9 @@ class _$DiaryStateLoadingImpl implements DiaryStateLoading {
|
||||
TResult Function() $default, {
|
||||
required TResult Function() loading,
|
||||
required TResult Function(String errorMessage) error,
|
||||
required TResult Function(DiaryDayModel diary) loaded,
|
||||
required TResult Function(DiaryDayModel diary, NutritionDataModel nutrition,
|
||||
double currentSelectedSatietyRating)
|
||||
loaded,
|
||||
}) {
|
||||
return loading();
|
||||
}
|
||||
@@ -261,7 +275,9 @@ class _$DiaryStateLoadingImpl implements DiaryStateLoading {
|
||||
TResult? Function()? $default, {
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(String errorMessage)? error,
|
||||
TResult? Function(DiaryDayModel diary)? loaded,
|
||||
TResult? Function(DiaryDayModel diary, NutritionDataModel nutrition,
|
||||
double currentSelectedSatietyRating)?
|
||||
loaded,
|
||||
}) {
|
||||
return loading?.call();
|
||||
}
|
||||
@@ -272,7 +288,9 @@ class _$DiaryStateLoadingImpl implements DiaryStateLoading {
|
||||
TResult Function()? $default, {
|
||||
TResult Function()? loading,
|
||||
TResult Function(String errorMessage)? error,
|
||||
TResult Function(DiaryDayModel diary)? loaded,
|
||||
TResult Function(DiaryDayModel diary, NutritionDataModel nutrition,
|
||||
double currentSelectedSatietyRating)?
|
||||
loaded,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (loading != null) {
|
||||
@@ -396,7 +414,9 @@ class _$DiaryStateErrorImpl implements DiaryStateError {
|
||||
TResult Function() $default, {
|
||||
required TResult Function() loading,
|
||||
required TResult Function(String errorMessage) error,
|
||||
required TResult Function(DiaryDayModel diary) loaded,
|
||||
required TResult Function(DiaryDayModel diary, NutritionDataModel nutrition,
|
||||
double currentSelectedSatietyRating)
|
||||
loaded,
|
||||
}) {
|
||||
return error(errorMessage);
|
||||
}
|
||||
@@ -407,7 +427,9 @@ class _$DiaryStateErrorImpl implements DiaryStateError {
|
||||
TResult? Function()? $default, {
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(String errorMessage)? error,
|
||||
TResult? Function(DiaryDayModel diary)? loaded,
|
||||
TResult? Function(DiaryDayModel diary, NutritionDataModel nutrition,
|
||||
double currentSelectedSatietyRating)?
|
||||
loaded,
|
||||
}) {
|
||||
return error?.call(errorMessage);
|
||||
}
|
||||
@@ -418,7 +440,9 @@ class _$DiaryStateErrorImpl implements DiaryStateError {
|
||||
TResult Function()? $default, {
|
||||
TResult Function()? loading,
|
||||
TResult Function(String errorMessage)? error,
|
||||
TResult Function(DiaryDayModel diary)? loaded,
|
||||
TResult Function(DiaryDayModel diary, NutritionDataModel nutrition,
|
||||
double currentSelectedSatietyRating)?
|
||||
loaded,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (error != null) {
|
||||
@@ -484,9 +508,13 @@ abstract class _$$DiaryStateLoadedImplCopyWith<$Res> {
|
||||
$Res Function(_$DiaryStateLoadedImpl) then) =
|
||||
__$$DiaryStateLoadedImplCopyWithImpl<$Res>;
|
||||
@useResult
|
||||
$Res call({DiaryDayModel diary});
|
||||
$Res call(
|
||||
{DiaryDayModel diary,
|
||||
NutritionDataModel nutrition,
|
||||
double currentSelectedSatietyRating});
|
||||
|
||||
$DiaryDayModelCopyWith<$Res> get diary;
|
||||
$NutritionDataModelCopyWith<$Res> get nutrition;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@@ -503,12 +531,22 @@ class __$$DiaryStateLoadedImplCopyWithImpl<$Res>
|
||||
@override
|
||||
$Res call({
|
||||
Object? diary = null,
|
||||
Object? nutrition = null,
|
||||
Object? currentSelectedSatietyRating = null,
|
||||
}) {
|
||||
return _then(_$DiaryStateLoadedImpl(
|
||||
diary: null == diary
|
||||
? _value.diary
|
||||
: diary // ignore: cast_nullable_to_non_nullable
|
||||
as DiaryDayModel,
|
||||
nutrition: null == nutrition
|
||||
? _value.nutrition
|
||||
: nutrition // ignore: cast_nullable_to_non_nullable
|
||||
as NutritionDataModel,
|
||||
currentSelectedSatietyRating: null == currentSelectedSatietyRating
|
||||
? _value.currentSelectedSatietyRating
|
||||
: currentSelectedSatietyRating // ignore: cast_nullable_to_non_nullable
|
||||
as double,
|
||||
));
|
||||
}
|
||||
|
||||
@@ -521,19 +559,36 @@ class __$$DiaryStateLoadedImplCopyWithImpl<$Res>
|
||||
return _then(_value.copyWith(diary: value));
|
||||
});
|
||||
}
|
||||
|
||||
/// Create a copy of DiaryState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$NutritionDataModelCopyWith<$Res> get nutrition {
|
||||
return $NutritionDataModelCopyWith<$Res>(_value.nutrition, (value) {
|
||||
return _then(_value.copyWith(nutrition: value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$DiaryStateLoadedImpl implements DiaryStateLoaded {
|
||||
const _$DiaryStateLoadedImpl({required this.diary});
|
||||
const _$DiaryStateLoadedImpl(
|
||||
{required this.diary,
|
||||
required this.nutrition,
|
||||
required this.currentSelectedSatietyRating});
|
||||
|
||||
@override
|
||||
final DiaryDayModel diary;
|
||||
@override
|
||||
final NutritionDataModel nutrition;
|
||||
@override
|
||||
final double currentSelectedSatietyRating;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DiaryState.loaded(diary: $diary)';
|
||||
return 'DiaryState.loaded(diary: $diary, nutrition: $nutrition, currentSelectedSatietyRating: $currentSelectedSatietyRating)';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -541,11 +596,18 @@ class _$DiaryStateLoadedImpl implements DiaryStateLoaded {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$DiaryStateLoadedImpl &&
|
||||
(identical(other.diary, diary) || other.diary == diary));
|
||||
(identical(other.diary, diary) || other.diary == diary) &&
|
||||
(identical(other.nutrition, nutrition) ||
|
||||
other.nutrition == nutrition) &&
|
||||
(identical(other.currentSelectedSatietyRating,
|
||||
currentSelectedSatietyRating) ||
|
||||
other.currentSelectedSatietyRating ==
|
||||
currentSelectedSatietyRating));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, diary);
|
||||
int get hashCode =>
|
||||
Object.hash(runtimeType, diary, nutrition, currentSelectedSatietyRating);
|
||||
|
||||
/// Create a copy of DiaryState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@@ -562,9 +624,11 @@ class _$DiaryStateLoadedImpl implements DiaryStateLoaded {
|
||||
TResult Function() $default, {
|
||||
required TResult Function() loading,
|
||||
required TResult Function(String errorMessage) error,
|
||||
required TResult Function(DiaryDayModel diary) loaded,
|
||||
required TResult Function(DiaryDayModel diary, NutritionDataModel nutrition,
|
||||
double currentSelectedSatietyRating)
|
||||
loaded,
|
||||
}) {
|
||||
return loaded(diary);
|
||||
return loaded(diary, nutrition, currentSelectedSatietyRating);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -573,9 +637,11 @@ class _$DiaryStateLoadedImpl implements DiaryStateLoaded {
|
||||
TResult? Function()? $default, {
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(String errorMessage)? error,
|
||||
TResult? Function(DiaryDayModel diary)? loaded,
|
||||
TResult? Function(DiaryDayModel diary, NutritionDataModel nutrition,
|
||||
double currentSelectedSatietyRating)?
|
||||
loaded,
|
||||
}) {
|
||||
return loaded?.call(diary);
|
||||
return loaded?.call(diary, nutrition, currentSelectedSatietyRating);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -584,11 +650,13 @@ class _$DiaryStateLoadedImpl implements DiaryStateLoaded {
|
||||
TResult Function()? $default, {
|
||||
TResult Function()? loading,
|
||||
TResult Function(String errorMessage)? error,
|
||||
TResult Function(DiaryDayModel diary)? loaded,
|
||||
TResult Function(DiaryDayModel diary, NutritionDataModel nutrition,
|
||||
double currentSelectedSatietyRating)?
|
||||
loaded,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (loaded != null) {
|
||||
return loaded(diary);
|
||||
return loaded(diary, nutrition, currentSelectedSatietyRating);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
@@ -632,10 +700,15 @@ class _$DiaryStateLoadedImpl implements DiaryStateLoaded {
|
||||
}
|
||||
|
||||
abstract class DiaryStateLoaded implements DiaryState {
|
||||
const factory DiaryStateLoaded({required final DiaryDayModel diary}) =
|
||||
const factory DiaryStateLoaded(
|
||||
{required final DiaryDayModel diary,
|
||||
required final NutritionDataModel nutrition,
|
||||
required final double currentSelectedSatietyRating}) =
|
||||
_$DiaryStateLoadedImpl;
|
||||
|
||||
DiaryDayModel get diary;
|
||||
NutritionDataModel get nutrition;
|
||||
double get currentSelectedSatietyRating;
|
||||
|
||||
/// Create a copy of DiaryState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
|
||||
@@ -2,8 +2,11 @@ import 'dart:io';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:eatvio_app/core/const.dart';
|
||||
import 'package:eatvio_app/features/diary/models/diary_day_model.dart';
|
||||
import 'package:eatvio_app/features/diary/models/nutrition_model.dart';
|
||||
import 'package:eatvio_app/features/diary/presentation/bloc/diary_cubit.dart';
|
||||
import 'package:eatvio_app/features/diary/presentation/bloc/diary_state.dart';
|
||||
import 'package:eatvio_app/features/diary/presentation/widgets/glossary_moderation_request_modal_widget.dart';
|
||||
import 'package:eatvio_app/features/diary/presentation/widgets/satiety_rating_widget.dart';
|
||||
import 'package:eatvio_app/features/glossary/models/glossary_model.dart';
|
||||
import 'package:eatvio_app/locator_service.dart';
|
||||
import 'package:eatvio_app/theme/theme_helper.dart';
|
||||
@@ -15,6 +18,7 @@ import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:flutter_typeahead/flutter_typeahead.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:rive/rive.dart';
|
||||
import 'package:syncfusion_flutter_gauges/gauges.dart';
|
||||
import 'package:table_calendar/table_calendar.dart';
|
||||
|
||||
class DiaryScreen extends StatefulWidget {
|
||||
@@ -34,6 +38,65 @@ class _DiaryScreenState extends State<DiaryScreen> {
|
||||
final productNameController = TextEditingController();
|
||||
final quantityController = TextEditingController();
|
||||
int currentSelectedPhotoIndex = 0;
|
||||
String time = "${DateTime.now().hour.toString().padLeft(2, '0')}:${DateTime.now().minute.toString().padLeft(2, '0')}";
|
||||
DateTime _time = DateTime.now();
|
||||
|
||||
_showDatePicker() {
|
||||
showModalBottomSheet<void>(
|
||||
context: context,
|
||||
useRootNavigator: true,
|
||||
builder: (context) => SizedBox(
|
||||
height: MediaQuery.of(context).copyWith().size.height / 3,
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: CupertinoDatePicker(
|
||||
mode: CupertinoDatePickerMode.time,
|
||||
use24hFormat: true,
|
||||
initialDateTime: DateTime.now(),
|
||||
onDateTimeChanged: (newTime) {
|
||||
setState(() {
|
||||
_time = newTime;
|
||||
time = "${_time.hour.toString().padLeft(2, '0')}:${_time.minute.toString().padLeft(2, '0')}";
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
showModalBottomSheet(
|
||||
useRootNavigator: true,
|
||||
useSafeArea: false,
|
||||
context: context,
|
||||
builder: (context) => GlossaryModerationRequestModalWidget(),
|
||||
);
|
||||
},
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
child: Ink(
|
||||
width: MediaQuery.of(context).size.width - 16,
|
||||
height: 52,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
color: appTheme.blueA400,
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Сохранить',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -59,7 +122,12 @@ class _DiaryScreenState extends State<DiaryScreen> {
|
||||
children: [
|
||||
_calendar(state),
|
||||
if (state is DiaryStateLoading) _loader(),
|
||||
if (state is DiaryStateLoaded) _meals(state.diary),
|
||||
if (state is DiaryStateLoaded)
|
||||
_meals(
|
||||
state.diary,
|
||||
state.currentSelectedSatietyRating,
|
||||
),
|
||||
if (state is DiaryStateLoaded) _chart(state.nutrition),
|
||||
const SizedBox(height: 32),
|
||||
],
|
||||
),
|
||||
@@ -70,13 +138,47 @@ class _DiaryScreenState extends State<DiaryScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
_timeOfMeal(String time) {
|
||||
return InkWell(
|
||||
onTap: () => _showDatePicker(),
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
child: Ink(
|
||||
height: 32,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
color: Color(0xFFF1F2F6),
|
||||
),
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
padding: EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Text(
|
||||
time,
|
||||
style: TextStyle(
|
||||
color: Color(0xFF6D6F71),
|
||||
fontSize: 17,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_arrowDown() {
|
||||
return Container(
|
||||
padding: const EdgeInsets.only(top: 8, bottom: 16),
|
||||
width: double.infinity,
|
||||
child: Icon(
|
||||
_calendarFormat == CalendarFormat.month ? Icons.keyboard_arrow_up_rounded : Icons.keyboard_arrow_down_rounded,
|
||||
color: Colors.grey.shade600,
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.translucent,
|
||||
onVerticalDragStart: (_) {
|
||||
setState(() {
|
||||
_calendarFormat = CalendarFormat.values[(_calendarFormat.index - 1) % CalendarFormat.values.length];
|
||||
});
|
||||
},
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.only(top: 8, bottom: 16),
|
||||
child: Icon(
|
||||
_calendarFormat == CalendarFormat.month ? Icons.keyboard_arrow_up_rounded : Icons.keyboard_arrow_down_rounded,
|
||||
color: Colors.grey.shade600,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -130,7 +232,10 @@ class _DiaryScreenState extends State<DiaryScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
_meals(DiaryDayModel diaryDay) {
|
||||
_meals(
|
||||
DiaryDayModel diaryDay,
|
||||
double currentSelectedSatietyRating,
|
||||
) {
|
||||
return Material(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
color: Colors.white,
|
||||
@@ -161,13 +266,19 @@ class _DiaryScreenState extends State<DiaryScreen> {
|
||||
const SizedBox(height: 12),
|
||||
_divider(context),
|
||||
const SizedBox(height: 12),
|
||||
Text(
|
||||
'Время приема пищи',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF323F4B),
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'Время приема пищи',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF323F4B),
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
_timeOfMeal(time),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
_divider(context),
|
||||
@@ -189,12 +300,254 @@ class _DiaryScreenState extends State<DiaryScreen> {
|
||||
diaryDay.meals[currentSelectedMealNumber - 1].photos,
|
||||
diaryDay,
|
||||
),
|
||||
SatietyRatingWidget(
|
||||
currentSelectedSatietyRating: currentSelectedSatietyRating,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_chart(NutritionDataModel nutrition) {
|
||||
final List<ChartData> chartData = [
|
||||
ChartData(
|
||||
nutrition.dailyNutritionIntake.carbohydrates,
|
||||
nutrition.dailyNutritionRecommendation.carbohydrates,
|
||||
),
|
||||
ChartData(
|
||||
nutrition.dailyNutritionIntake.fats,
|
||||
nutrition.dailyNutritionRecommendation.fats,
|
||||
),
|
||||
ChartData(
|
||||
nutrition.dailyNutritionIntake.proteins,
|
||||
nutrition.dailyNutritionRecommendation.proteins,
|
||||
),
|
||||
ChartData(
|
||||
nutrition.dailyNutritionIntake.energy,
|
||||
nutrition.dailyNutritionRecommendation.energy,
|
||||
),
|
||||
];
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
margin: const EdgeInsets.only(top: 12),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
color: Colors.white,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
'Ваш КБЖУ от дневной\nсуточной нормы',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: Color(0xFF323F4B),
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 18,
|
||||
height: 1,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 48),
|
||||
Stack(
|
||||
alignment: Alignment.bottomCenter,
|
||||
children: [
|
||||
SfRadialGauge(
|
||||
axes: <RadialAxis>[
|
||||
RadialAxis(
|
||||
startAngle: 180,
|
||||
endAngle: 0,
|
||||
minimum: 0,
|
||||
maximum: 100,
|
||||
showLabels: false,
|
||||
showTicks: false,
|
||||
radiusFactor: 0.7,
|
||||
showAxisLine: false,
|
||||
pointers: <GaugePointer>[
|
||||
RangePointer(
|
||||
value: 100,
|
||||
width: 0.16,
|
||||
animationDuration: 2000,
|
||||
color: Color(0xFFF6FAFF),
|
||||
sizeUnit: GaugeSizeUnit.factor,
|
||||
enableAnimation: true,
|
||||
cornerStyle: CornerStyle.bothCurve,
|
||||
),
|
||||
RangePointer(
|
||||
value: (chartData[0].intake / chartData[0].recommendation) * 100,
|
||||
width: 0.16,
|
||||
color: chartData[0].intake < chartData[0].recommendation ? appTheme.blueA400 : Colors.red,
|
||||
sizeUnit: GaugeSizeUnit.factor,
|
||||
enableAnimation: true,
|
||||
cornerStyle: CornerStyle.bothCurve,
|
||||
),
|
||||
RangePointer(
|
||||
value: 100,
|
||||
width: 0.16,
|
||||
animationDuration: 2000,
|
||||
color: Color(0xFFF6FAFF),
|
||||
sizeUnit: GaugeSizeUnit.factor,
|
||||
enableAnimation: true,
|
||||
cornerStyle: CornerStyle.bothCurve,
|
||||
pointerOffset: -0.18,
|
||||
),
|
||||
RangePointer(
|
||||
value: (chartData[1].intake / chartData[1].recommendation) * 100,
|
||||
width: 0.16,
|
||||
color: chartData[1].intake < chartData[1].recommendation ? appTheme.blueA400 : Colors.red,
|
||||
sizeUnit: GaugeSizeUnit.factor,
|
||||
enableAnimation: true,
|
||||
cornerStyle: CornerStyle.bothCurve,
|
||||
pointerOffset: -0.18,
|
||||
),
|
||||
RangePointer(
|
||||
value: 100,
|
||||
width: 0.16,
|
||||
animationDuration: 2000,
|
||||
color: Color(0xFFF6FAFF),
|
||||
sizeUnit: GaugeSizeUnit.factor,
|
||||
enableAnimation: true,
|
||||
cornerStyle: CornerStyle.bothCurve,
|
||||
pointerOffset: -0.36,
|
||||
),
|
||||
RangePointer(
|
||||
value: (chartData[2].intake / chartData[2].recommendation) * 100,
|
||||
width: 0.16,
|
||||
color: chartData[2].intake < chartData[2].recommendation ? appTheme.blueA400 : Colors.red,
|
||||
sizeUnit: GaugeSizeUnit.factor,
|
||||
enableAnimation: true,
|
||||
cornerStyle: CornerStyle.bothCurve,
|
||||
pointerOffset: -0.36,
|
||||
),
|
||||
RangePointer(
|
||||
value: 100,
|
||||
width: 0.16,
|
||||
animationDuration: 2000,
|
||||
color: Color(0xFFF6FAFF),
|
||||
sizeUnit: GaugeSizeUnit.factor,
|
||||
enableAnimation: true,
|
||||
cornerStyle: CornerStyle.bothCurve,
|
||||
pointerOffset: -0.54,
|
||||
),
|
||||
RangePointer(
|
||||
value: (chartData[3].intake / chartData[3].recommendation) * 100,
|
||||
width: 0.16,
|
||||
color: chartData[3].intake < chartData[3].recommendation ? appTheme.blueA400 : Colors.red,
|
||||
sizeUnit: GaugeSizeUnit.factor,
|
||||
enableAnimation: true,
|
||||
cornerStyle: CornerStyle.bothCurve,
|
||||
pointerOffset: -0.54,
|
||||
),
|
||||
],
|
||||
annotations: <GaugeAnnotation>[
|
||||
GaugeAnnotation(
|
||||
widget: Transform.rotate(
|
||||
angle: 30.1,
|
||||
child: Text(
|
||||
'Углеводы',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
angle: 198,
|
||||
positionFactor: 0.92,
|
||||
),
|
||||
GaugeAnnotation(
|
||||
widget: Transform.rotate(
|
||||
angle: 30,
|
||||
child: Text(
|
||||
'Жиры',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
angle: 190,
|
||||
positionFactor: 1.1,
|
||||
),
|
||||
GaugeAnnotation(
|
||||
widget: Transform.rotate(
|
||||
angle: 30,
|
||||
child: Text(
|
||||
'Белки',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
angle: 190,
|
||||
positionFactor: 1.27,
|
||||
),
|
||||
GaugeAnnotation(
|
||||
widget: Transform.rotate(
|
||||
angle: 30,
|
||||
child: Text(
|
||||
'Калории',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
angle: 192,
|
||||
positionFactor: 1.46,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
children: [
|
||||
_chartData('Калории',
|
||||
'${nutrition.dailyNutritionIntake.energy.toStringAsFixed(0)} из ${nutrition.dailyNutritionRecommendation.energy.toStringAsFixed(0)} ккал'),
|
||||
const SizedBox(height: 8),
|
||||
_chartData('Белки',
|
||||
'${nutrition.dailyNutritionIntake.proteins.toStringAsFixed(0)} из ${nutrition.dailyNutritionRecommendation.proteins.toStringAsFixed(0)} грамм'),
|
||||
const SizedBox(height: 8),
|
||||
_chartData('Жиры',
|
||||
'${nutrition.dailyNutritionIntake.fats.toStringAsFixed(0)} из ${nutrition.dailyNutritionRecommendation.fats.toStringAsFixed(0)} грамм'),
|
||||
const SizedBox(height: 8),
|
||||
_chartData('Углеводы',
|
||||
'${nutrition.dailyNutritionIntake.carbohydrates.toStringAsFixed(0)} из ${nutrition.dailyNutritionRecommendation.carbohydrates.toStringAsFixed(0)} грамм'),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_chartData(String title, String value) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF323F4B),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
value,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF323F4B),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
_showImagePicker(DiaryDayModel diaryDay) {
|
||||
showCupertinoModalPopup<void>(
|
||||
context: context,
|
||||
@@ -271,19 +624,20 @@ class _DiaryScreenState extends State<DiaryScreen> {
|
||||
child: IconButton.filled(
|
||||
style: IconButton.styleFrom(
|
||||
backgroundColor: Colors.white,
|
||||
elevation: 0,
|
||||
),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
if (currentSelectedPhotoIndex == photos.length - 1 && currentSelectedPhotoIndex != 0) {
|
||||
currentSelectedPhotoIndex = photos.length - 2;
|
||||
}
|
||||
});
|
||||
diaryCubit.deletePhoto(
|
||||
onPressed: () async {
|
||||
await diaryCubit.deletePhoto(
|
||||
photo: photos[currentSelectedPhotoIndex],
|
||||
diaryId: diaryDay.id,
|
||||
mealId: diaryDay.meals[currentSelectedMealNumber - 1].id,
|
||||
date: _selectedDay.toString(),
|
||||
);
|
||||
setState(() {
|
||||
if (currentSelectedPhotoIndex == photos.length - 1 && currentSelectedPhotoIndex != 0) {
|
||||
currentSelectedPhotoIndex = photos.length - 2;
|
||||
}
|
||||
});
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.close_rounded,
|
||||
@@ -372,7 +726,7 @@ class _DiaryScreenState extends State<DiaryScreen> {
|
||||
child: Text(
|
||||
'$mealNumber',
|
||||
style: TextStyle(
|
||||
color: isActive ? Colors.white : Colors.black,
|
||||
color: isActive ? Colors.white : Color(0xFF6D6F71),
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
@@ -669,3 +1023,13 @@ class _DiaryScreenState extends State<DiaryScreen> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ChartData {
|
||||
final double intake;
|
||||
final double recommendation;
|
||||
|
||||
ChartData(
|
||||
this.intake,
|
||||
this.recommendation,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class GlossaryModerationRequestModalWidget extends StatefulWidget {
|
||||
const GlossaryModerationRequestModalWidget({super.key});
|
||||
|
||||
@override
|
||||
State<GlossaryModerationRequestModalWidget> createState() => _GlossaryModerationRequestModalWidgetState();
|
||||
}
|
||||
|
||||
class _GlossaryModerationRequestModalWidgetState extends State<GlossaryModerationRequestModalWidget> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Dialog(
|
||||
child: Column(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
import 'package:eatvio_app/features/diary/presentation/bloc/diary_cubit.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
|
||||
class SatietyRatingWidget extends StatefulWidget {
|
||||
final double currentSelectedSatietyRating;
|
||||
|
||||
const SatietyRatingWidget({
|
||||
super.key,
|
||||
required this.currentSelectedSatietyRating,
|
||||
});
|
||||
|
||||
@override
|
||||
State<SatietyRatingWidget> createState() => _SatietyRatingWidgetState();
|
||||
}
|
||||
|
||||
class _SatietyRatingWidgetState extends State<SatietyRatingWidget> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(top: 24),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
'Ваша сытость после приёма пищи',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
'assets/icons/satiety_emoji_left.svg',
|
||||
height: 32,
|
||||
width: 32,
|
||||
),
|
||||
RatingBar.builder(
|
||||
initialRating: 3,
|
||||
itemCount: 6,
|
||||
itemSize: MediaQuery.of(context).size.width / 6 - (124 / 6),
|
||||
updateOnDrag: true,
|
||||
itemBuilder: (context, index) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return Container(
|
||||
width: MediaQuery.of(context).size.width / 6,
|
||||
height: 24,
|
||||
margin: widget.currentSelectedSatietyRating == 1 ? EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFFC82222),
|
||||
border: widget.currentSelectedSatietyRating == 1
|
||||
? Border.all(
|
||||
width: 2,
|
||||
color: Color(0xFFAA3333),
|
||||
strokeAlign: BorderSide.strokeAlignOutside,
|
||||
)
|
||||
: null,
|
||||
borderRadius: widget.currentSelectedSatietyRating == 1
|
||||
? BorderRadius.horizontal(
|
||||
left: Radius.circular(8),
|
||||
right: Radius.circular(2),
|
||||
)
|
||||
: BorderRadius.horizontal(
|
||||
left: Radius.circular(8),
|
||||
),
|
||||
),
|
||||
);
|
||||
case 1:
|
||||
return Container(
|
||||
width: MediaQuery.of(context).size.width / 6,
|
||||
height: 24,
|
||||
margin: widget.currentSelectedSatietyRating == 2 ? EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFFFF3E3E),
|
||||
border: widget.currentSelectedSatietyRating == 2
|
||||
? Border.all(
|
||||
width: 2,
|
||||
color: Color(0xFF550000),
|
||||
strokeAlign: BorderSide.strokeAlignOutside,
|
||||
)
|
||||
: null,
|
||||
borderRadius: widget.currentSelectedSatietyRating == 2 ? BorderRadius.circular(2) : null,
|
||||
),
|
||||
);
|
||||
case 2:
|
||||
return Container(
|
||||
width: MediaQuery.of(context).size.width / 6,
|
||||
height: 24,
|
||||
margin: widget.currentSelectedSatietyRating == 3 ? EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFFF8C926),
|
||||
border: widget.currentSelectedSatietyRating == 3
|
||||
? Border.all(
|
||||
width: 2,
|
||||
color: Color(0xFF8C5D00),
|
||||
strokeAlign: BorderSide.strokeAlignOutside,
|
||||
)
|
||||
: null,
|
||||
borderRadius: widget.currentSelectedSatietyRating == 3 ? BorderRadius.circular(2) : null,
|
||||
),
|
||||
);
|
||||
case 3:
|
||||
return Container(
|
||||
width: MediaQuery.of(context).size.width / 6,
|
||||
height: 24,
|
||||
margin: widget.currentSelectedSatietyRating == 4 ? EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFFFFF3BF),
|
||||
border: widget.currentSelectedSatietyRating == 4
|
||||
? Border.all(
|
||||
width: 2,
|
||||
color: Color(0xFFB5911B),
|
||||
strokeAlign: BorderSide.strokeAlignOutside,
|
||||
)
|
||||
: null,
|
||||
borderRadius: widget.currentSelectedSatietyRating == 4 ? BorderRadius.circular(2) : null,
|
||||
),
|
||||
);
|
||||
case 4:
|
||||
return Container(
|
||||
width: MediaQuery.of(context).size.width / 6,
|
||||
height: 24,
|
||||
margin: widget.currentSelectedSatietyRating == 5 ? EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFF62E833),
|
||||
border: widget.currentSelectedSatietyRating == 5
|
||||
? Border.all(
|
||||
width: 2,
|
||||
color: Color(0xFF276918),
|
||||
strokeAlign: BorderSide.strokeAlignOutside,
|
||||
)
|
||||
: null,
|
||||
borderRadius: widget.currentSelectedSatietyRating == 5 ? BorderRadius.circular(2) : null,
|
||||
),
|
||||
);
|
||||
default:
|
||||
return Container(
|
||||
width: MediaQuery.of(context).size.width / 6,
|
||||
height: 24,
|
||||
margin: widget.currentSelectedSatietyRating == 6 ? EdgeInsets.symmetric(horizontal: 2) : null,
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFF4DCE20),
|
||||
border: widget.currentSelectedSatietyRating == 6
|
||||
? Border.all(
|
||||
width: 2,
|
||||
color: Color(0xFF184D12),
|
||||
strokeAlign: BorderSide.strokeAlignOutside,
|
||||
)
|
||||
: null,
|
||||
borderRadius: widget.currentSelectedSatietyRating == 6
|
||||
? BorderRadius.horizontal(
|
||||
left: Radius.circular(2),
|
||||
right: Radius.circular(8),
|
||||
)
|
||||
: BorderRadius.horizontal(
|
||||
right: Radius.circular(8),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
onRatingUpdate: (value) => context.read<DiaryCubit>().updateCurrentSelectedSatietyRating(value),
|
||||
),
|
||||
SvgPicture.asset(
|
||||
'assets/icons/satiety_emoji_right.svg',
|
||||
height: 32,
|
||||
width: 32,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'dart:io';
|
||||
import 'package:eatvio_app/features/diary/models/diary_day_model.dart';
|
||||
import 'package:eatvio_app/features/diary/models/nutrition_model.dart';
|
||||
import 'package:eatvio_app/features/diary/services/diary_service.dart';
|
||||
|
||||
class DiaryRepository {
|
||||
@@ -11,15 +12,19 @@ class DiaryRepository {
|
||||
|
||||
Future<DiaryDayModel> getDiaryByDate(String date) async {
|
||||
return (await diaryService.getDiaryDay(
|
||||
index: await _getDiaryIndexByDate(date),
|
||||
index: await getDiaryIndexByDate(date),
|
||||
))
|
||||
.diary;
|
||||
}
|
||||
|
||||
Future<int> _getDiaryIndexByDate(String date) async {
|
||||
Future<int> getDiaryIndexByDate(String date) async {
|
||||
return (await diaryService.getDiaryIndexByDate(date: date)).id;
|
||||
}
|
||||
|
||||
Future<NutritionDataModel> getNutritionData(int index) async {
|
||||
return await diaryService.getNutrition(index: index);
|
||||
}
|
||||
|
||||
Future<void> addPortionToMeal({
|
||||
required int diaryId,
|
||||
required int mealId,
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'dart:io';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:eatvio_app/features/diary/models/diary_day_model.dart';
|
||||
import 'package:eatvio_app/features/diary/models/diary_index_model.dart';
|
||||
import 'package:eatvio_app/features/diary/models/nutrition_model.dart';
|
||||
import 'package:retrofit/retrofit.dart';
|
||||
|
||||
part 'diary_service.g.dart';
|
||||
@@ -20,6 +21,11 @@ abstract class DiaryService {
|
||||
@Path('diary_id') required int index,
|
||||
});
|
||||
|
||||
@GET('/api/diary/{diary_id}/dailyNutritionData')
|
||||
Future<NutritionDataModel> getNutrition({
|
||||
@Path('diary_id') required int index,
|
||||
});
|
||||
|
||||
@POST('/api/diary/{diary_id}/meal/{meal_id}/photo/upload')
|
||||
@MultiPart()
|
||||
Future<void> uploadPhotoOfMeal({
|
||||
|
||||
@@ -87,6 +87,39 @@ class _DiaryService implements DiaryService {
|
||||
return _value;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<NutritionDataModel> getNutrition({required int index}) async {
|
||||
final _extra = <String, dynamic>{};
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<NutritionDataModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/${index}/dailyNutritionData',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late NutritionDataModel _value;
|
||||
try {
|
||||
_value = NutritionDataModel.fromJson(_result.data!);
|
||||
} on Object catch (e, s) {
|
||||
errorLogger?.logError(e, s, _options);
|
||||
rethrow;
|
||||
}
|
||||
return _value;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> uploadPhotoOfMeal({
|
||||
required int diaryId,
|
||||
|
||||
@@ -8,6 +8,7 @@ import 'package:flutter_svg/svg.dart';
|
||||
|
||||
class TypeBadges extends StatefulWidget {
|
||||
const TypeBadges({super.key, required this.type});
|
||||
|
||||
final DietType type;
|
||||
|
||||
@override
|
||||
@@ -16,6 +17,7 @@ class TypeBadges extends StatefulWidget {
|
||||
|
||||
class _TypeBadgesState extends State<TypeBadges> {
|
||||
final List<bool> overlaysVisibilityState = [false, false, false, false];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final s = S.of(context);
|
||||
@@ -117,11 +119,18 @@ class _TypeBadgesState extends State<TypeBadges> {
|
||||
}
|
||||
|
||||
class _InfoOverlayEntry extends StatelessWidget {
|
||||
const _InfoOverlayEntry({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;
|
||||
final void Function() onClose;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MainBackgroundBouble(
|
||||
|
||||
Reference in New Issue
Block a user