forked from eatvio/eatvio_app
Merge pull request 'main' (#43) from main into mso7nueh-feat(chat)
Reviewed-on: maxxkim/eatvio_app#43
This commit is contained in:
116
lib/features/diary/models/diary_model.dart
Normal file
116
lib/features/diary/models/diary_model.dart
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
|
part 'diary_model.freezed.dart';
|
||||||
|
part 'diary_model.g.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class DiaryModel with _$DiaryModel {
|
||||||
|
const factory DiaryModel(
|
||||||
|
{required int id,
|
||||||
|
required DateTime date,
|
||||||
|
required DateTime wakeup,
|
||||||
|
required DateTime retire,
|
||||||
|
required int closed,
|
||||||
|
required String comment,
|
||||||
|
required List<Meals> meals}) = _DiaryModel;
|
||||||
|
|
||||||
|
factory DiaryModel.fromJson(Map<String, Object?> json) => _$DiaryModelFromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Meals {
|
||||||
|
int? id;
|
||||||
|
String? time;
|
||||||
|
int? type;
|
||||||
|
int? satiety;
|
||||||
|
int? mood;
|
||||||
|
List<Portions>? portions;
|
||||||
|
List<Photos>? photos;
|
||||||
|
|
||||||
|
Meals({this.id, this.time, this.type, this.satiety, this.mood, this.portions, this.photos});
|
||||||
|
|
||||||
|
Meals.fromJson(Map<String, dynamic> json) {
|
||||||
|
List<Portions> portions = [];
|
||||||
|
List<Photos> photos = [];
|
||||||
|
id = json['id'];
|
||||||
|
time = json['time'];
|
||||||
|
type = json['type'];
|
||||||
|
satiety = json['satiety'];
|
||||||
|
mood = json['mood'];
|
||||||
|
if (json['portions'] != null) {
|
||||||
|
json['portions'].forEach((v) {
|
||||||
|
portions.add(new Portions.fromJson(v));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (json['photos'] != null) {
|
||||||
|
json['photos'].forEach((v) {
|
||||||
|
photos.add(new Photos.fromJson(v));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
|
data['id'] = this.id;
|
||||||
|
data['time'] = this.time;
|
||||||
|
data['type'] = this.type;
|
||||||
|
data['satiety'] = this.satiety;
|
||||||
|
data['mood'] = this.mood;
|
||||||
|
if (this.portions != null) {
|
||||||
|
data['portions'] = this.portions?.map((v) => v.toJson()).toList();
|
||||||
|
}
|
||||||
|
if (this.photos != null) {
|
||||||
|
data['photos'] = this.photos?.map((v) => v.toJson()).toList();
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Portions {
|
||||||
|
int? id;
|
||||||
|
String? productName;
|
||||||
|
int? quantity;
|
||||||
|
String? portion;
|
||||||
|
|
||||||
|
Portions({this.id, this.productName, this.quantity, this.portion});
|
||||||
|
|
||||||
|
Portions.fromJson(Map<String, dynamic> json) {
|
||||||
|
id = json['id'];
|
||||||
|
productName = json['product_name'];
|
||||||
|
quantity = json['quantity'];
|
||||||
|
portion = json['portion'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
|
data['id'] = this.id;
|
||||||
|
data['product_name'] = this.productName;
|
||||||
|
data['quantity'] = this.quantity;
|
||||||
|
data['portion'] = this.portion;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Photos {
|
||||||
|
int? id;
|
||||||
|
String? originalName;
|
||||||
|
String? path;
|
||||||
|
int? size;
|
||||||
|
|
||||||
|
Photos({this.id, this.originalName, this.path, this.size});
|
||||||
|
|
||||||
|
Photos.fromJson(Map<String, dynamic> json) {
|
||||||
|
id = json['id'];
|
||||||
|
originalName = json['original_name'];
|
||||||
|
path = json['path'];
|
||||||
|
size = json['size'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
|
data['id'] = this.id;
|
||||||
|
data['original_name'] = this.originalName;
|
||||||
|
data['path'] = this.path;
|
||||||
|
data['size'] = this.size;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
282
lib/features/diary/models/diary_model.freezed.dart
Normal file
282
lib/features/diary/models/diary_model.freezed.dart
Normal file
@@ -0,0 +1,282 @@
|
|||||||
|
// 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 'diary_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');
|
||||||
|
|
||||||
|
DiaryModel _$DiaryModelFromJson(Map<String, dynamic> json) {
|
||||||
|
return _DiaryModel.fromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$DiaryModel {
|
||||||
|
int get id => throw _privateConstructorUsedError;
|
||||||
|
DateTime get date => throw _privateConstructorUsedError;
|
||||||
|
DateTime get wakeup => throw _privateConstructorUsedError;
|
||||||
|
DateTime get retire => throw _privateConstructorUsedError;
|
||||||
|
int get closed => throw _privateConstructorUsedError;
|
||||||
|
String get comment => throw _privateConstructorUsedError;
|
||||||
|
List<Meals> get meals => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
$DiaryModelCopyWith<DiaryModel> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $DiaryModelCopyWith<$Res> {
|
||||||
|
factory $DiaryModelCopyWith(
|
||||||
|
DiaryModel value, $Res Function(DiaryModel) then) =
|
||||||
|
_$DiaryModelCopyWithImpl<$Res, DiaryModel>;
|
||||||
|
@useResult
|
||||||
|
$Res call(
|
||||||
|
{int id,
|
||||||
|
DateTime date,
|
||||||
|
DateTime wakeup,
|
||||||
|
DateTime retire,
|
||||||
|
int closed,
|
||||||
|
String comment,
|
||||||
|
List<Meals> meals});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$DiaryModelCopyWithImpl<$Res, $Val extends DiaryModel>
|
||||||
|
implements $DiaryModelCopyWith<$Res> {
|
||||||
|
_$DiaryModelCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? id = null,
|
||||||
|
Object? date = null,
|
||||||
|
Object? wakeup = null,
|
||||||
|
Object? retire = null,
|
||||||
|
Object? closed = null,
|
||||||
|
Object? comment = null,
|
||||||
|
Object? meals = null,
|
||||||
|
}) {
|
||||||
|
return _then(_value.copyWith(
|
||||||
|
id: null == id
|
||||||
|
? _value.id
|
||||||
|
: id // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
date: null == date
|
||||||
|
? _value.date
|
||||||
|
: date // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,
|
||||||
|
wakeup: null == wakeup
|
||||||
|
? _value.wakeup
|
||||||
|
: wakeup // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,
|
||||||
|
retire: null == retire
|
||||||
|
? _value.retire
|
||||||
|
: retire // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,
|
||||||
|
closed: null == closed
|
||||||
|
? _value.closed
|
||||||
|
: closed // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
comment: null == comment
|
||||||
|
? _value.comment
|
||||||
|
: comment // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
meals: null == meals
|
||||||
|
? _value.meals
|
||||||
|
: meals // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<Meals>,
|
||||||
|
) as $Val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$DiaryModelImplCopyWith<$Res>
|
||||||
|
implements $DiaryModelCopyWith<$Res> {
|
||||||
|
factory _$$DiaryModelImplCopyWith(
|
||||||
|
_$DiaryModelImpl value, $Res Function(_$DiaryModelImpl) then) =
|
||||||
|
__$$DiaryModelImplCopyWithImpl<$Res>;
|
||||||
|
@override
|
||||||
|
@useResult
|
||||||
|
$Res call(
|
||||||
|
{int id,
|
||||||
|
DateTime date,
|
||||||
|
DateTime wakeup,
|
||||||
|
DateTime retire,
|
||||||
|
int closed,
|
||||||
|
String comment,
|
||||||
|
List<Meals> meals});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$DiaryModelImplCopyWithImpl<$Res>
|
||||||
|
extends _$DiaryModelCopyWithImpl<$Res, _$DiaryModelImpl>
|
||||||
|
implements _$$DiaryModelImplCopyWith<$Res> {
|
||||||
|
__$$DiaryModelImplCopyWithImpl(
|
||||||
|
_$DiaryModelImpl _value, $Res Function(_$DiaryModelImpl) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? id = null,
|
||||||
|
Object? date = null,
|
||||||
|
Object? wakeup = null,
|
||||||
|
Object? retire = null,
|
||||||
|
Object? closed = null,
|
||||||
|
Object? comment = null,
|
||||||
|
Object? meals = null,
|
||||||
|
}) {
|
||||||
|
return _then(_$DiaryModelImpl(
|
||||||
|
id: null == id
|
||||||
|
? _value.id
|
||||||
|
: id // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
date: null == date
|
||||||
|
? _value.date
|
||||||
|
: date // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,
|
||||||
|
wakeup: null == wakeup
|
||||||
|
? _value.wakeup
|
||||||
|
: wakeup // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,
|
||||||
|
retire: null == retire
|
||||||
|
? _value.retire
|
||||||
|
: retire // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,
|
||||||
|
closed: null == closed
|
||||||
|
? _value.closed
|
||||||
|
: closed // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
comment: null == comment
|
||||||
|
? _value.comment
|
||||||
|
: comment // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
meals: null == meals
|
||||||
|
? _value._meals
|
||||||
|
: meals // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<Meals>,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
class _$DiaryModelImpl implements _DiaryModel {
|
||||||
|
const _$DiaryModelImpl(
|
||||||
|
{required this.id,
|
||||||
|
required this.date,
|
||||||
|
required this.wakeup,
|
||||||
|
required this.retire,
|
||||||
|
required this.closed,
|
||||||
|
required this.comment,
|
||||||
|
required final List<Meals> meals})
|
||||||
|
: _meals = meals;
|
||||||
|
|
||||||
|
factory _$DiaryModelImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$$DiaryModelImplFromJson(json);
|
||||||
|
|
||||||
|
@override
|
||||||
|
final int id;
|
||||||
|
@override
|
||||||
|
final DateTime date;
|
||||||
|
@override
|
||||||
|
final DateTime wakeup;
|
||||||
|
@override
|
||||||
|
final DateTime retire;
|
||||||
|
@override
|
||||||
|
final int closed;
|
||||||
|
@override
|
||||||
|
final String comment;
|
||||||
|
final List<Meals> _meals;
|
||||||
|
@override
|
||||||
|
List<Meals> get meals {
|
||||||
|
if (_meals is EqualUnmodifiableListView) return _meals;
|
||||||
|
// ignore: implicit_dynamic_type
|
||||||
|
return EqualUnmodifiableListView(_meals);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'DiaryModel(id: $id, date: $date, wakeup: $wakeup, retire: $retire, closed: $closed, comment: $comment, meals: $meals)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$DiaryModelImpl &&
|
||||||
|
(identical(other.id, id) || other.id == id) &&
|
||||||
|
(identical(other.date, date) || other.date == date) &&
|
||||||
|
(identical(other.wakeup, wakeup) || other.wakeup == wakeup) &&
|
||||||
|
(identical(other.retire, retire) || other.retire == retire) &&
|
||||||
|
(identical(other.closed, closed) || other.closed == closed) &&
|
||||||
|
(identical(other.comment, comment) || other.comment == comment) &&
|
||||||
|
const DeepCollectionEquality().equals(other._meals, _meals));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType, id, date, wakeup, retire, closed,
|
||||||
|
comment, const DeepCollectionEquality().hash(_meals));
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$DiaryModelImplCopyWith<_$DiaryModelImpl> get copyWith =>
|
||||||
|
__$$DiaryModelImplCopyWithImpl<_$DiaryModelImpl>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$$DiaryModelImplToJson(
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _DiaryModel implements DiaryModel {
|
||||||
|
const factory _DiaryModel(
|
||||||
|
{required final int id,
|
||||||
|
required final DateTime date,
|
||||||
|
required final DateTime wakeup,
|
||||||
|
required final DateTime retire,
|
||||||
|
required final int closed,
|
||||||
|
required final String comment,
|
||||||
|
required final List<Meals> meals}) = _$DiaryModelImpl;
|
||||||
|
|
||||||
|
factory _DiaryModel.fromJson(Map<String, dynamic> json) =
|
||||||
|
_$DiaryModelImpl.fromJson;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get id;
|
||||||
|
@override
|
||||||
|
DateTime get date;
|
||||||
|
@override
|
||||||
|
DateTime get wakeup;
|
||||||
|
@override
|
||||||
|
DateTime get retire;
|
||||||
|
@override
|
||||||
|
int get closed;
|
||||||
|
@override
|
||||||
|
String get comment;
|
||||||
|
@override
|
||||||
|
List<Meals> get meals;
|
||||||
|
@override
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
_$$DiaryModelImplCopyWith<_$DiaryModelImpl> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
31
lib/features/diary/models/diary_model.g.dart
Normal file
31
lib/features/diary/models/diary_model.g.dart
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'diary_model.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
_$DiaryModelImpl _$$DiaryModelImplFromJson(Map<String, dynamic> json) =>
|
||||||
|
_$DiaryModelImpl(
|
||||||
|
id: (json['id'] as num).toInt(),
|
||||||
|
date: DateTime.parse(json['date'] as String),
|
||||||
|
wakeup: DateTime.parse(json['wakeup'] as String),
|
||||||
|
retire: DateTime.parse(json['retire'] as String),
|
||||||
|
closed: (json['closed'] as num).toInt(),
|
||||||
|
comment: json['comment'] as String,
|
||||||
|
meals: (json['meals'] as List<dynamic>)
|
||||||
|
.map((e) => Meals.fromJson(e as Map<String, dynamic>))
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$DiaryModelImplToJson(_$DiaryModelImpl instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'id': instance.id,
|
||||||
|
'date': instance.date.toIso8601String(),
|
||||||
|
'wakeup': instance.wakeup.toIso8601String(),
|
||||||
|
'retire': instance.retire.toIso8601String(),
|
||||||
|
'closed': instance.closed,
|
||||||
|
'comment': instance.comment,
|
||||||
|
'meals': instance.meals,
|
||||||
|
};
|
||||||
22
lib/features/diary/presentation/bloc/diary_cubit.dart
Normal file
22
lib/features/diary/presentation/bloc/diary_cubit.dart
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
/*import 'package:eatvio_app/core/app_export.dart';
|
||||||
|
import 'package:eatvio_app/features/diary/presentation/bloc/diary_state.dart';
|
||||||
|
import 'package:eatvio_app/features/diary/repositories/diary_repository.dart';
|
||||||
|
|
||||||
|
class DiaryCubit extends Cubit<DiaryState> {
|
||||||
|
final DiaryRepository blogPostRepository;
|
||||||
|
|
||||||
|
DiaryCubit({required this.blogPostRepository})
|
||||||
|
: super(const DiaryState.loading());
|
||||||
|
|
||||||
|
loadDiary(String blogPostID) async {
|
||||||
|
emit(const DiaryState.loading());
|
||||||
|
try {
|
||||||
|
final blogPost = await blogPostRepository.getDiary(blogPostID);
|
||||||
|
emit(DiaryState.loaded(blogPost: blogPost));
|
||||||
|
} catch (e) {
|
||||||
|
emit(DiaryState.error(errorMessage: e.toString()));
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
20
lib/features/diary/presentation/bloc/diary_state.dart
Normal file
20
lib/features/diary/presentation/bloc/diary_state.dart
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
/*import 'package:eatvio_app/features/diary/models/diary_model.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
|
part 'diary_state.freezed.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class DiaryState with _$DiaryState {
|
||||||
|
const factory DiaryState() = _DiaryState;
|
||||||
|
|
||||||
|
const factory DiaryState.loading() = DiaryStateLoading;
|
||||||
|
|
||||||
|
const factory DiaryState.loaded({
|
||||||
|
required DiaryModel blogPost,
|
||||||
|
}) = DiaryStateLoaded;
|
||||||
|
|
||||||
|
const factory DiaryState.error({
|
||||||
|
required String errorMessage,
|
||||||
|
}) = DiaryStateError;
|
||||||
|
}
|
||||||
|
*/
|
||||||
1299
lib/features/diary/presentation/pages/diary_screen.dart
Normal file
1299
lib/features/diary/presentation/pages/diary_screen.dart
Normal file
File diff suppressed because it is too large
Load Diff
17
lib/features/diary/repositories/diary_repository.dart
Normal file
17
lib/features/diary/repositories/diary_repository.dart
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/*import 'package:eatvio_app/features/diary/models/diary_model.dart';
|
||||||
|
import 'package:eatvio_app/features/diary/services/diary_service.dart';
|
||||||
|
|
||||||
|
class DiaryRepository {
|
||||||
|
final DiaryService blogPostService;
|
||||||
|
|
||||||
|
DiaryRepository({required this.blogPostService});
|
||||||
|
|
||||||
|
Future<DiaryModel> getDiary(String blogPostID) async {
|
||||||
|
try {
|
||||||
|
return await blogPostService.getDiary(blogPostID);
|
||||||
|
} catch (e) {
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
14
lib/features/diary/services/diary_service.dart
Normal file
14
lib/features/diary/services/diary_service.dart
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
/*import 'package:dio/dio.dart';
|
||||||
|
import 'package:eatvio_app/features/diary/models/diary_model.dart';
|
||||||
|
import 'package:retrofit/retrofit.dart';
|
||||||
|
|
||||||
|
part 'diary_service.g.dart';
|
||||||
|
|
||||||
|
@RestApi()
|
||||||
|
abstract class DiaryService {
|
||||||
|
factory DiaryService(Dio dio, {String baseUrl}) = _DiaryService;
|
||||||
|
|
||||||
|
@GET('/feed/show/{id}')
|
||||||
|
Future<DiaryModel> getDiary(@Path() String id);
|
||||||
|
}
|
||||||
|
*/
|
||||||
@@ -29,15 +29,18 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
on<AddPortionEvent>(_addPortion); //пользователь нажимает "Добавить продукт"
|
on<AddPortionEvent>(_addPortion); //пользователь нажимает "Добавить продукт"
|
||||||
on<RemovePortionEvent>(_removePortion);
|
on<RemovePortionEvent>(_removePortion);
|
||||||
on<RemoveImageEvent>(
|
on<RemoveImageEvent>(
|
||||||
_removeImage,); // пользователь нажимает на крестик около продукта
|
_removeImage,
|
||||||
|
); // пользователь нажимает на крестик около продукта
|
||||||
on<UploadImages>(_uploadImages); //пользователь нажимает "Добавить фото"
|
on<UploadImages>(_uploadImages); //пользователь нажимает "Добавить фото"
|
||||||
on<AddComment>(_addComment); //пользователь нажимает "Добавить комментарий"
|
on<AddComment>(_addComment); //пользователь нажимает "Добавить комментарий"
|
||||||
on<ProductInput>(
|
on<ProductInput>(
|
||||||
_inputProduct,); //пользователь нажимает "Добавить комментарий"
|
_inputProduct,
|
||||||
|
); //пользователь нажимает "Добавить комментарий"
|
||||||
on<FinishDay>(_finishDay); //пользователь нажимает "Добавить комментарий"
|
on<FinishDay>(_finishDay); //пользователь нажимает "Добавить комментарий"
|
||||||
on<SendModeration>(_sendModeration);
|
on<SendModeration>(_sendModeration);
|
||||||
on<RefreshEvent>(
|
on<RefreshEvent>(
|
||||||
reloadScreen,); //пользователь нажимает "Добавить комментарий"
|
reloadScreen,
|
||||||
|
); //пользователь нажимает "Добавить комментарий"
|
||||||
on<ClearInput>(_clearInput);
|
on<ClearInput>(_clearInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,12 +60,14 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
final diary = await fetchDiaryData(token, diaryId);
|
final diary = await fetchDiaryData(token, diaryId);
|
||||||
print("Screen load success");
|
print("Screen load success");
|
||||||
if (diary is Map<String, dynamic>) {
|
if (diary is Map<String, dynamic>) {
|
||||||
|
print(diary);
|
||||||
final String diaryDate = diary['date'] ?? DateTime.now().toString();
|
final String diaryDate = diary['date'] ?? DateTime.now().toString();
|
||||||
final chartValues = await fetchChartValues(token, diaryId, emit);
|
final chartValues = await fetchChartValues(token, diaryId, emit);
|
||||||
if (state is DiaryEditLoadedState) {
|
if (state is DiaryEditLoadedState) {
|
||||||
// Если текущее состояние уже загружено, обновляем его
|
// Если текущее состояние уже загружено, обновляем его
|
||||||
var currentState = state as DiaryEditLoadedState;
|
var currentState = state as DiaryEditLoadedState;
|
||||||
emit((currentState).copyWith(
|
emit(
|
||||||
|
(currentState).copyWith(
|
||||||
currentMeal: currentState.currentMeal,
|
currentMeal: currentState.currentMeal,
|
||||||
wakeupExpanded: currentState.wakeupExpanded,
|
wakeupExpanded: currentState.wakeupExpanded,
|
||||||
moodExpanded: currentState.moodExpanded,
|
moodExpanded: currentState.moodExpanded,
|
||||||
@@ -84,20 +89,24 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
selectedMood: currentState.selectedMood,
|
selectedMood: currentState.selectedMood,
|
||||||
diaryDate: currentState.diaryDate,
|
diaryDate: currentState.diaryDate,
|
||||||
diaryId: currentState.diaryId,
|
diaryId: currentState.diaryId,
|
||||||
productQuantityController:
|
productQuantityController: currentState.productQuantityController,
|
||||||
currentState.productQuantityController,
|
|
||||||
recommendedChartValues: currentState.recommendedChartValues,
|
recommendedChartValues: currentState.recommendedChartValues,
|
||||||
consumedChartValues: currentState.consumedChartValues,
|
consumedChartValues: currentState.consumedChartValues,
|
||||||
autocompleteList: currentState.autocompleteList,
|
autocompleteList: currentState.autocompleteList,
|
||||||
diaryEditModelObj: currentState.diaryEditModelObj,),);
|
diaryEditModelObj: currentState.diaryEditModelObj,
|
||||||
|
),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
// Если текущее состояние - начальное, создаем новое загруженное состояние
|
// Если текущее состояние - начальное, создаем новое загруженное состояние
|
||||||
final List<SelectionPopupModel> meals =
|
final List<SelectionPopupModel> meals = fillMealList(diary['meals']);
|
||||||
fillMealList(diary['meals']);
|
emit(
|
||||||
emit(DiaryEditLoadedState(
|
DiaryEditLoadedState(
|
||||||
currentMeal: meals[0],
|
currentMeal: meals[0],
|
||||||
portionController: SelectionPopupModel(
|
portionController: SelectionPopupModel(
|
||||||
id: 0, title: "порций", isSelected: true,),
|
id: 0,
|
||||||
|
title: "порций",
|
||||||
|
isSelected: true,
|
||||||
|
),
|
||||||
wakeupExpanded: true,
|
wakeupExpanded: true,
|
||||||
moodExpanded: true,
|
moodExpanded: true,
|
||||||
moderationExpanded: false,
|
moderationExpanded: false,
|
||||||
@@ -109,12 +118,10 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
photos: diary['meals'][0]['photos'],
|
photos: diary['meals'][0]['photos'],
|
||||||
wakeupController: toTime(diary['wakeup'] ?? "09:00"),
|
wakeupController: toTime(diary['wakeup'] ?? "09:00"),
|
||||||
retireController: toTime(diary['retire'] ?? "23:00"),
|
retireController: toTime(diary['retire'] ?? "23:00"),
|
||||||
mealTimeController:
|
mealTimeController: toTime(diary['meals'][0]['time'] ?? "10:00"),
|
||||||
toTime(diary['meals'][0]['time'] ?? "10:00"),
|
|
||||||
selectedSatiety: diary['meals'][0]['satiety'],
|
selectedSatiety: diary['meals'][0]['satiety'],
|
||||||
selectedMood: diary['meals'][0]['mood'],
|
selectedMood: diary['meals'][0]['mood'],
|
||||||
commentController:
|
commentController: TextEditingController(text: diary['comment']),
|
||||||
TextEditingController(text: diary['comment']),
|
|
||||||
productNameController: TextEditingController(),
|
productNameController: TextEditingController(),
|
||||||
productQuantityController: TextEditingController(),
|
productQuantityController: TextEditingController(),
|
||||||
caloriesController: TextEditingController(),
|
caloriesController: TextEditingController(),
|
||||||
@@ -124,8 +131,9 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
diaryId: diaryId,
|
diaryId: diaryId,
|
||||||
diaryDate: diaryDate,
|
diaryDate: diaryDate,
|
||||||
autocompleteList: [],
|
autocompleteList: [],
|
||||||
diaryEditModelObj: state.diaryEditModelObj
|
diaryEditModelObj: state.diaryEditModelObj?.copyWith(mealList: meals, portionList: fillPortions()),
|
||||||
?.copyWith(mealList: meals, portionList: fillPortions()),),);
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -177,31 +185,33 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fetchChartValues(
|
fetchChartValues(
|
||||||
String token, int diaryID, Emitter<DiaryEditState> emit,) async {
|
String token,
|
||||||
|
int diaryID,
|
||||||
|
Emitter<DiaryEditState> emit,
|
||||||
|
) async {
|
||||||
final responseChart = await http.get(
|
final responseChart = await http.get(
|
||||||
Uri.parse(
|
Uri.parse(
|
||||||
dotenv.env['SERVER_ROOT']! + '/diary/$diaryID/dailyNutritionData/',),
|
dotenv.env['SERVER_ROOT']! + '/diary/$diaryID/dailyNutritionData/',
|
||||||
|
),
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'Authorization': 'Bearer $token',
|
'Authorization': 'Bearer $token',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (responseChart.statusCode == 200) {
|
if (responseChart.statusCode == 200) {
|
||||||
final recommendedChartValues =
|
final responseBody = jsonDecode(responseChart.body);
|
||||||
jsonDecode(responseChart.body)['dailyNutritionRecommendation']
|
|
||||||
.values
|
final recommendedChartValues = responseBody['dailyNutritionRecommendation'].values.map<int>((value) => convertToInt(value)).toList();
|
||||||
.map<double>((value) => value as double)
|
|
||||||
.toList();
|
final consumedChartValues = responseBody['dailyNutritionIntake'].values.map<int>((value) => convertToInt(value)).toList();
|
||||||
final consumedChartValues =
|
|
||||||
jsonDecode(responseChart.body)['dailyNutritionIntake']
|
print([recommendedChartValues, consumedChartValues]);
|
||||||
.values
|
|
||||||
.map<double>((value) => value as double)
|
|
||||||
.toList();
|
|
||||||
return [recommendedChartValues, consumedChartValues];
|
return [recommendedChartValues, consumedChartValues];
|
||||||
} else {
|
} else {
|
||||||
emit(DiaryEditErrorState('Ошибка при декодировании данных КБЖУ'));
|
emit(DiaryEditErrorState('Ошибка при декодировании данных КБЖУ'));
|
||||||
print('fail');
|
print('fail');
|
||||||
return -1;
|
return [[], []]; // Return empty lists instead of -1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,8 +259,9 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
if (diary is Map<String, dynamic>) {
|
if (diary is Map<String, dynamic>) {
|
||||||
final String diaryDate = diary['date'] ?? DateTime.now().toString();
|
final String diaryDate = diary['date'] ?? DateTime.now().toString();
|
||||||
final responseChart = await http.get(
|
final responseChart = await http.get(
|
||||||
Uri.parse(dotenv.env['SERVER_ROOT']! +
|
Uri.parse(
|
||||||
'/diary/$diaryId/dailyNutritionData/',),
|
dotenv.env['SERVER_ROOT']! + '/diary/$diaryId/dailyNutritionData/',
|
||||||
|
),
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'Authorization': 'Bearer $token',
|
'Authorization': 'Bearer $token',
|
||||||
@@ -258,39 +269,38 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
);
|
);
|
||||||
if (responseChart.statusCode == 200) {
|
if (responseChart.statusCode == 200) {
|
||||||
final recommendedChartValues = jsonDecode(
|
final recommendedChartValues = jsonDecode(
|
||||||
responseChart.body,)['dailyNutritionRecommendation'];
|
responseChart.body,
|
||||||
final consumedChartValues =
|
)['dailyNutritionRecommendation'];
|
||||||
jsonDecode(responseChart.body)['dailyNutritionIntake'];
|
final consumedChartValues = jsonDecode(responseChart.body)['dailyNutritionIntake'];
|
||||||
final List<SelectionPopupModel> meals =
|
final List<SelectionPopupModel> meals = fillMealList(diary['meals']);
|
||||||
fillMealList(diary['meals']);
|
|
||||||
try {
|
try {
|
||||||
await Future(() => emit(DiaryEditLoadedState(
|
await Future(
|
||||||
|
() => emit(
|
||||||
|
DiaryEditLoadedState(
|
||||||
diaryEditModelObj: state.diaryEditModelObj?.copyWith(
|
diaryEditModelObj: state.diaryEditModelObj?.copyWith(
|
||||||
mealList: meals, portionList: fillPortions(),),
|
mealList: meals,
|
||||||
|
portionList: fillPortions(),
|
||||||
|
),
|
||||||
currentMeal: meals[0],
|
currentMeal: meals[0],
|
||||||
portionController: SelectionPopupModel(
|
portionController: SelectionPopupModel(
|
||||||
id: 0, title: "порций", isSelected: true,),
|
id: 0,
|
||||||
|
title: "порций",
|
||||||
|
isSelected: true,
|
||||||
|
),
|
||||||
wakeupExpanded: true,
|
wakeupExpanded: true,
|
||||||
moodExpanded: true,
|
moodExpanded: true,
|
||||||
moderationExpanded: false,
|
moderationExpanded: false,
|
||||||
token: token,
|
token: token,
|
||||||
recommendedChartValues: recommendedChartValues.values
|
recommendedChartValues: recommendedChartValues.values.map<int>((value) => convertToInt(value)).toList(),
|
||||||
.map<double>((value) => value as double)
|
consumedChartValues: consumedChartValues.values.map<int>((value) => convertToInt(value)).toList(),
|
||||||
.toList(),
|
|
||||||
consumedChartValues: consumedChartValues.values
|
|
||||||
.map<double>((value) => value as double)
|
|
||||||
.toList(),
|
|
||||||
meals: diary['meals'],
|
|
||||||
portions: diary['meals'][0]['portions'],
|
portions: diary['meals'][0]['portions'],
|
||||||
photos: diary['meals'][0]['photos'],
|
photos: diary['meals'][0]['photos'],
|
||||||
wakeupController: toTime(diary['wakeup'] ?? "09:00"),
|
wakeupController: toTime(diary['wakeup'] ?? "09:00"),
|
||||||
retireController: toTime(diary['retire'] ?? "23:00"),
|
retireController: toTime(diary['retire'] ?? "23:00"),
|
||||||
mealTimeController:
|
mealTimeController: toTime(diary['meals'][0]['time'] ?? "10:00"),
|
||||||
toTime(diary['meals'][0]['time'] ?? "10:00"),
|
|
||||||
selectedSatiety: diary['meals'][0]['satiety'],
|
selectedSatiety: diary['meals'][0]['satiety'],
|
||||||
selectedMood: diary['meals'][0]['mood'],
|
selectedMood: diary['meals'][0]['mood'],
|
||||||
commentController:
|
commentController: TextEditingController(text: diary['comment']),
|
||||||
TextEditingController(text: diary['comment']),
|
|
||||||
productNameController: TextEditingController(),
|
productNameController: TextEditingController(),
|
||||||
productQuantityController: TextEditingController(),
|
productQuantityController: TextEditingController(),
|
||||||
caloriesController: TextEditingController(),
|
caloriesController: TextEditingController(),
|
||||||
@@ -301,7 +311,9 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
diaryDate: diaryDate,
|
diaryDate: diaryDate,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
autocompleteList: [],
|
autocompleteList: [],
|
||||||
),),);
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
print("Updated");
|
print("Updated");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -311,12 +323,16 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
emit(DiaryEditErrorState('Ошибка при декодировании данных КБЖУ'));
|
emit(DiaryEditErrorState('Ошибка при декодировании данных КБЖУ'));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
emit(DiaryEditErrorState(
|
emit(
|
||||||
'Ошибка при декодировании данных дневника',),);
|
DiaryEditErrorState(
|
||||||
|
'Ошибка при декодировании данных дневника',
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
emit(
|
emit(
|
||||||
DiaryEditErrorState('Некоторые необходимые данные отсутствуют.'),);
|
DiaryEditErrorState('Некоторые необходимые данные отсутствуют.'),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
emit(DiaryEditErrorState('Ошибка сервера: ${response.statusCode}'));
|
emit(DiaryEditErrorState('Ошибка сервера: ${response.statusCode}'));
|
||||||
@@ -327,18 +343,20 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _changeSatiety(
|
Future<void> _changeSatiety(
|
||||||
ChangeSatiety event, Emitter<DiaryEditState> emit,) async {
|
ChangeSatiety event,
|
||||||
|
Emitter<DiaryEditState> emit,
|
||||||
|
) async {
|
||||||
if (state is DiaryEditLoadedState) {
|
if (state is DiaryEditLoadedState) {
|
||||||
var currentState = state as DiaryEditLoadedState;
|
var currentState = state as DiaryEditLoadedState;
|
||||||
var updatedState =
|
var updatedState = currentState.copyWith(selectedSatiety: event.selectedElement);
|
||||||
currentState.copyWith(selectedSatiety: event.selectedElement);
|
|
||||||
|
|
||||||
// Отправляем данные по HTTP маршруту и ждем ответ
|
// Отправляем данные по HTTP маршруту и ждем ответ
|
||||||
var response = await sendSatietyData(
|
var response = await sendSatietyData(
|
||||||
currentState.token,
|
currentState.token,
|
||||||
event.selectedElement,
|
event.selectedElement,
|
||||||
currentState.currentMeal?.id,
|
currentState.currentMeal?.id,
|
||||||
currentState.diaryId,);
|
currentState.diaryId,
|
||||||
|
);
|
||||||
|
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
updatedState.selectedSatiety = event.selectedElement;
|
updatedState.selectedSatiety = event.selectedElement;
|
||||||
@@ -353,38 +371,42 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
int? mealID,
|
int? mealID,
|
||||||
int diaryID,
|
int diaryID,
|
||||||
) async {
|
) async {
|
||||||
String url = dotenv.env['SERVER_ROOT']! +
|
String url = dotenv.env['SERVER_ROOT']! + '/diary/$diaryID/meal/$mealID/satiety/fill';
|
||||||
'/diary/$diaryID/meal/$mealID/satiety/fill';
|
|
||||||
final Map<String, dynamic> credentials = {
|
final Map<String, dynamic> credentials = {
|
||||||
'satiety': selectedSatiety,
|
'satiety': selectedSatiety,
|
||||||
};
|
};
|
||||||
var response = await http.post(Uri.parse(url),
|
var response = await http.post(
|
||||||
headers: {
|
Uri.parse(url),
|
||||||
'Content-Type': 'application/json',
|
headers: {
|
||||||
'Authorization': 'Bearer $token',
|
'Content-Type': 'application/json',
|
||||||
},
|
'Authorization': 'Bearer $token',
|
||||||
body: json.encode(credentials),
|
},
|
||||||
encoding: utf8,);
|
body: json.encode(credentials),
|
||||||
|
encoding: utf8,
|
||||||
|
);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _changeMood(
|
Future<void> _changeMood(
|
||||||
ChangeMood event, Emitter<DiaryEditState> emit,) async {
|
ChangeMood event,
|
||||||
|
Emitter<DiaryEditState> emit,
|
||||||
|
) async {
|
||||||
if (state is DiaryEditLoadedState) {
|
if (state is DiaryEditLoadedState) {
|
||||||
var currentState = state as DiaryEditLoadedState;
|
var currentState = state as DiaryEditLoadedState;
|
||||||
var updatedState =
|
var updatedState = currentState.copyWith(selectedMood: event.selectedElement);
|
||||||
currentState.copyWith(selectedMood: event.selectedElement);
|
|
||||||
|
|
||||||
// Отправляем данные по HTTP маршруту и ждем ответ
|
// Отправляем данные по HTTP маршруту и ждем ответ
|
||||||
var response = await sendMoodData(
|
var response = await sendMoodData(
|
||||||
currentState.token,
|
currentState.token,
|
||||||
event.selectedElement,
|
event.selectedElement,
|
||||||
currentState.currentMeal?.id,
|
currentState.currentMeal?.id,
|
||||||
currentState.diaryId,);
|
currentState.diaryId,
|
||||||
|
);
|
||||||
|
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
print(
|
print(
|
||||||
'Mood change success! meal_id: ${currentState.currentMeal?.id}, mood: ${event.selectedElement}',);
|
'Mood change success! meal_id: ${currentState.currentMeal?.id}, mood: ${event.selectedElement}',
|
||||||
|
);
|
||||||
updatedState.selectedMood = event.selectedElement;
|
updatedState.selectedMood = event.selectedElement;
|
||||||
emit(updatedState); // Передаем обновленное состояние в emit
|
emit(updatedState); // Передаем обновленное состояние в emit
|
||||||
}
|
}
|
||||||
@@ -397,33 +419,38 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
int? mealID,
|
int? mealID,
|
||||||
int diaryID,
|
int diaryID,
|
||||||
) async {
|
) async {
|
||||||
String url =
|
String url = dotenv.env['SERVER_ROOT']! + '/diary/$diaryID/meal/$mealID/mood/fill';
|
||||||
dotenv.env['SERVER_ROOT']! + '/diary/$diaryID/meal/$mealID/mood/fill';
|
|
||||||
final Map<String, dynamic> credentials = {
|
final Map<String, dynamic> credentials = {
|
||||||
'mood': selectedMood,
|
'mood': selectedMood,
|
||||||
};
|
};
|
||||||
|
|
||||||
var response = await http.post(Uri.parse(url),
|
var response = await http.post(
|
||||||
headers: {
|
Uri.parse(url),
|
||||||
'Content-Type': 'application/json',
|
headers: {
|
||||||
'Authorization': 'Bearer $token',
|
'Content-Type': 'application/json',
|
||||||
},
|
'Authorization': 'Bearer $token',
|
||||||
body: json.encode(credentials),
|
},
|
||||||
encoding: utf8,);
|
body: json.encode(credentials),
|
||||||
|
encoding: utf8,
|
||||||
|
);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _changeWakeup(
|
FutureOr<void> _changeWakeup(
|
||||||
WakeupEvent event, Emitter<DiaryEditState> emit,) async {
|
WakeupEvent event,
|
||||||
|
Emitter<DiaryEditState> emit,
|
||||||
|
) async {
|
||||||
if (state is DiaryEditLoadedState) {
|
if (state is DiaryEditLoadedState) {
|
||||||
var currentState = state as DiaryEditLoadedState;
|
var currentState = state as DiaryEditLoadedState;
|
||||||
var response = await sendWakeupData(
|
var response = await sendWakeupData(
|
||||||
currentState.token, event.selectedTime, currentState.diaryId,);
|
currentState.token,
|
||||||
|
event.selectedTime,
|
||||||
|
currentState.diaryId,
|
||||||
|
);
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
await reloadScreen(event, emit);
|
await reloadScreen(event, emit);
|
||||||
var updatedState =
|
var updatedState = currentState.copyWith(wakeupController: event.selectedTime);
|
||||||
currentState.copyWith(wakeupController: event.selectedTime);
|
|
||||||
print("Wakeup time changed to ${event.selectedTime}");
|
print("Wakeup time changed to ${event.selectedTime}");
|
||||||
emit(updatedState); // Передаем обновленное состояние в emit
|
emit(updatedState); // Передаем обновленное состояние в emit
|
||||||
} else
|
} else
|
||||||
@@ -432,15 +459,19 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _changeRetire(
|
FutureOr<void> _changeRetire(
|
||||||
RetireEvent event, Emitter<DiaryEditState> emit,) async {
|
RetireEvent event,
|
||||||
|
Emitter<DiaryEditState> emit,
|
||||||
|
) async {
|
||||||
if (state is DiaryEditLoadedState) {
|
if (state is DiaryEditLoadedState) {
|
||||||
var currentState = state as DiaryEditLoadedState;
|
var currentState = state as DiaryEditLoadedState;
|
||||||
var response = await sendRetireData(
|
var response = await sendRetireData(
|
||||||
currentState.token, event.selectedTime, currentState.diaryId,);
|
currentState.token,
|
||||||
|
event.selectedTime,
|
||||||
|
currentState.diaryId,
|
||||||
|
);
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
await reloadScreen(event, emit);
|
await reloadScreen(event, emit);
|
||||||
var updatedState =
|
var updatedState = currentState.copyWith(retireController: event.selectedTime);
|
||||||
currentState.copyWith(retireController: event.selectedTime);
|
|
||||||
print("Retire time changed to ${event.selectedTime}");
|
print("Retire time changed to ${event.selectedTime}");
|
||||||
emit(updatedState); // Передаем обновленное состояние в emit
|
emit(updatedState); // Передаем обновленное состояние в emit
|
||||||
} else
|
} else
|
||||||
@@ -455,46 +486,53 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
) async {
|
) async {
|
||||||
String url = dotenv.env['SERVER_ROOT']! + '/diary/$diaryID/wakeUp/fill';
|
String url = dotenv.env['SERVER_ROOT']! + '/diary/$diaryID/wakeUp/fill';
|
||||||
final formatter = DateFormat('HH:mm');
|
final formatter = DateFormat('HH:mm');
|
||||||
final wakeupString =
|
final wakeupString = formatter.format(DateTime(2022, 1, 1, wakeup.hour, wakeup.minute));
|
||||||
formatter.format(DateTime(2022, 1, 1, wakeup.hour, wakeup.minute));
|
|
||||||
final Map<String, dynamic> credentials = {
|
final Map<String, dynamic> credentials = {
|
||||||
'wakeUp': wakeupString,
|
'wakeUp': wakeupString,
|
||||||
};
|
};
|
||||||
|
|
||||||
var response = await http.post(Uri.parse(url),
|
var response = await http.post(
|
||||||
headers: {
|
Uri.parse(url),
|
||||||
'Content-Type': 'application/json',
|
headers: {
|
||||||
'Authorization': 'Bearer $token',
|
'Content-Type': 'application/json',
|
||||||
},
|
'Authorization': 'Bearer $token',
|
||||||
body: json.encode(credentials),
|
},
|
||||||
encoding: utf8,);
|
body: json.encode(credentials),
|
||||||
|
encoding: utf8,
|
||||||
|
);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<http.Response> sendRetireData(
|
Future<http.Response> sendRetireData(
|
||||||
String? token, TimeOfDay retire, int diaryID,) async {
|
String? token,
|
||||||
|
TimeOfDay retire,
|
||||||
|
int diaryID,
|
||||||
|
) async {
|
||||||
String url = dotenv.env['SERVER_ROOT']! + '/diary/$diaryID/retire/fill';
|
String url = dotenv.env['SERVER_ROOT']! + '/diary/$diaryID/retire/fill';
|
||||||
final formatter = DateFormat('HH:mm');
|
final formatter = DateFormat('HH:mm');
|
||||||
final retireString =
|
final retireString = formatter.format(DateTime(2022, 1, 1, retire.hour, retire.minute));
|
||||||
formatter.format(DateTime(2022, 1, 1, retire.hour, retire.minute));
|
|
||||||
final Map<String, dynamic> credentials = {
|
final Map<String, dynamic> credentials = {
|
||||||
'retire': retireString,
|
'retire': retireString,
|
||||||
};
|
};
|
||||||
|
|
||||||
var response = await http.post(Uri.parse(url),
|
var response = await http.post(
|
||||||
headers: {
|
Uri.parse(url),
|
||||||
'Content-Type': 'application/json',
|
headers: {
|
||||||
'Authorization': 'Bearer $token',
|
'Content-Type': 'application/json',
|
||||||
},
|
'Authorization': 'Bearer $token',
|
||||||
body: json.encode(credentials),
|
},
|
||||||
encoding: utf8,);
|
body: json.encode(credentials),
|
||||||
|
encoding: utf8,
|
||||||
|
);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _changeMealTime(
|
FutureOr<void> _changeMealTime(
|
||||||
ChangeMealTime event, Emitter<DiaryEditState> emit,) async {
|
ChangeMealTime event,
|
||||||
|
Emitter<DiaryEditState> emit,
|
||||||
|
) async {
|
||||||
if (state is DiaryEditLoadedState) {
|
if (state is DiaryEditLoadedState) {
|
||||||
var currentState = state as DiaryEditLoadedState;
|
var currentState = state as DiaryEditLoadedState;
|
||||||
var updatedState = currentState.copyWith(mealTimeController: event.time);
|
var updatedState = currentState.copyWith(mealTimeController: event.time);
|
||||||
@@ -516,51 +554,58 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
'diary_id': diaryID,
|
'diary_id': diaryID,
|
||||||
};
|
};
|
||||||
|
|
||||||
var response = await http.post(Uri.parse(url),
|
var response = await http.post(
|
||||||
headers: {
|
Uri.parse(url),
|
||||||
'Content-Type': 'application/json',
|
headers: {
|
||||||
'Authorization': 'Bearer $token',
|
'Content-Type': 'application/json',
|
||||||
},
|
'Authorization': 'Bearer $token',
|
||||||
body: json.encode(credentials),
|
},
|
||||||
encoding: utf8,);
|
body: json.encode(credentials),
|
||||||
|
encoding: utf8,
|
||||||
|
);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _changeMeal(
|
FutureOr<void> _changeMeal(
|
||||||
ChangeMeal event, Emitter<DiaryEditState> emit,) async {
|
ChangeMeal event,
|
||||||
|
Emitter<DiaryEditState> emit,
|
||||||
|
) async {
|
||||||
if (state is DiaryEditLoadedState) {
|
if (state is DiaryEditLoadedState) {
|
||||||
var currentState = state as DiaryEditLoadedState;
|
var currentState = state as DiaryEditLoadedState;
|
||||||
final meal = currentState.meals?.firstWhere(
|
final meal = currentState.meals?.firstWhere(
|
||||||
(meal) => meal['id'] == event.value.id,
|
(meal) => meal['id'] == event.value.id,
|
||||||
orElse: () => null,);
|
orElse: () => null,
|
||||||
|
);
|
||||||
int? id = event.value.id;
|
int? id = event.value.id;
|
||||||
print(meal['photos']);
|
|
||||||
DiaryEditLoadedState updatedState = currentState.copyWith(
|
DiaryEditLoadedState updatedState = currentState.copyWith(
|
||||||
currentMeal: event.value,
|
currentMeal: event.value,
|
||||||
portions: meal['portions'],
|
portions: meal['portions'],
|
||||||
photos: meal['photos'],
|
photos: meal['photos'],
|
||||||
mealTimeController: toTime(meal['time'] ?? "1$id:00"),
|
mealTimeController: toTime(meal['time'] ?? "1$id:00"),
|
||||||
selectedMood: meal['mood'],
|
selectedMood: meal['mood'],
|
||||||
selectedSatiety: meal['satiety'],);
|
selectedSatiety: meal['satiety'],
|
||||||
|
);
|
||||||
print(updatedState.photos);
|
print(updatedState.photos);
|
||||||
emit(updatedState);
|
emit(updatedState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FutureOr<void> _clearInput(
|
FutureOr<void> _clearInput(
|
||||||
ClearInput event, Emitter<DiaryEditState> emit,) {
|
ClearInput event,
|
||||||
|
Emitter<DiaryEditState> emit,
|
||||||
|
) {
|
||||||
if (state is DiaryEditLoadedState) {
|
if (state is DiaryEditLoadedState) {
|
||||||
var currentState = state as DiaryEditLoadedState;
|
var currentState = state as DiaryEditLoadedState;
|
||||||
DiaryEditLoadedState updatedState = currentState.copyWith(
|
DiaryEditLoadedState updatedState = currentState.copyWith();
|
||||||
);
|
|
||||||
emit(updatedState);
|
emit(updatedState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _changePortion(
|
FutureOr<void> _changePortion(
|
||||||
ChangePortion event, Emitter<DiaryEditState> emit,) {
|
ChangePortion event,
|
||||||
|
Emitter<DiaryEditState> emit,
|
||||||
|
) {
|
||||||
if (state is DiaryEditLoadedState) {
|
if (state is DiaryEditLoadedState) {
|
||||||
var currentState = state as DiaryEditLoadedState;
|
var currentState = state as DiaryEditLoadedState;
|
||||||
DiaryEditLoadedState updatedState = currentState.copyWith(
|
DiaryEditLoadedState updatedState = currentState.copyWith(
|
||||||
@@ -571,7 +616,9 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _toggleMood(
|
FutureOr<void> _toggleMood(
|
||||||
ToggleMoodExpandedEvent event, Emitter<DiaryEditState> emit,) {
|
ToggleMoodExpandedEvent event,
|
||||||
|
Emitter<DiaryEditState> emit,
|
||||||
|
) {
|
||||||
if (state is DiaryEditLoadedState) {
|
if (state is DiaryEditLoadedState) {
|
||||||
var currentState = state as DiaryEditLoadedState;
|
var currentState = state as DiaryEditLoadedState;
|
||||||
|
|
||||||
@@ -581,7 +628,9 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _toggleWakeup(
|
FutureOr<void> _toggleWakeup(
|
||||||
ToggleWakeupExpandedEvent event, Emitter<DiaryEditState> emit,) {
|
ToggleWakeupExpandedEvent event,
|
||||||
|
Emitter<DiaryEditState> emit,
|
||||||
|
) {
|
||||||
if (state is DiaryEditLoadedState) {
|
if (state is DiaryEditLoadedState) {
|
||||||
var currentState = state as DiaryEditLoadedState;
|
var currentState = state as DiaryEditLoadedState;
|
||||||
|
|
||||||
@@ -591,7 +640,9 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _addPortion(
|
FutureOr<void> _addPortion(
|
||||||
AddPortionEvent event, Emitter<DiaryEditState> emit,) async {
|
AddPortionEvent event,
|
||||||
|
Emitter<DiaryEditState> emit,
|
||||||
|
) async {
|
||||||
if (state is DiaryEditLoadedState) {
|
if (state is DiaryEditLoadedState) {
|
||||||
var currentState = state as DiaryEditLoadedState;
|
var currentState = state as DiaryEditLoadedState;
|
||||||
|
|
||||||
@@ -609,15 +660,21 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
await reloadScreen(event, emit);
|
await reloadScreen(event, emit);
|
||||||
} else {
|
} else {
|
||||||
print(
|
print(
|
||||||
'Failed to add portion. Status Code: ${response.statusCode} ${response.body}',);
|
'Failed to add portion. Status Code: ${response.statusCode} ${response.body}',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<http.Response> sendPortionData(String? token, String? name,
|
FutureOr<http.Response> sendPortionData(
|
||||||
String portion, int? quantity, int? mealID, int diaryID,) async {
|
String? token,
|
||||||
String url =
|
String? name,
|
||||||
'${dotenv.env['SERVER_ROOT']!}/diary/$diaryID/meal/$mealID/portions/create';
|
String portion,
|
||||||
|
int? quantity,
|
||||||
|
int? mealID,
|
||||||
|
int diaryID,
|
||||||
|
) async {
|
||||||
|
String url = '${dotenv.env['SERVER_ROOT']!}/diary/$diaryID/meal/$mealID/portions/create';
|
||||||
|
|
||||||
final Map<String, dynamic> credentials = {
|
final Map<String, dynamic> credentials = {
|
||||||
'product_name': name,
|
'product_name': name,
|
||||||
@@ -639,14 +696,17 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _inputProduct(
|
Future<void> _inputProduct(
|
||||||
ProductInput event, Emitter<DiaryEditState> emit,) async {
|
ProductInput event,
|
||||||
|
Emitter<DiaryEditState> emit,
|
||||||
|
) async {
|
||||||
if (state is DiaryEditLoadedState) {
|
if (state is DiaryEditLoadedState) {
|
||||||
var currentState = state as DiaryEditLoadedState;
|
var currentState = state as DiaryEditLoadedState;
|
||||||
String? token = currentState.token;
|
String? token = currentState.token;
|
||||||
|
|
||||||
final Map<String, dynamic> credentials = {'name': event.input};
|
final Map<String, dynamic> credentials = {'name': event.input};
|
||||||
final uri = Uri.parse(
|
final uri = Uri.parse(
|
||||||
'${dotenv.env['SERVER_ROOT']!}/diary/product_nutritional_values/filter?${Uri(queryParameters: credentials).query}',);
|
'${dotenv.env['SERVER_ROOT']!}/diary/product_nutritional_values/filter?${Uri(queryParameters: credentials).query}',
|
||||||
|
);
|
||||||
|
|
||||||
final response = await http.get(
|
final response = await http.get(
|
||||||
uri,
|
uri,
|
||||||
@@ -656,16 +716,13 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
final productNutritionalValues =
|
final productNutritionalValues = jsonDecode(response.body)['product_nutritional_value'];
|
||||||
jsonDecode(response.body)['product_nutritional_value'];
|
|
||||||
|
|
||||||
if (productNutritionalValues is List<dynamic>) {
|
if (productNutritionalValues is List<dynamic>) {
|
||||||
// Create a new controller with the input text and update the autocomplete list
|
// Create a new controller with the input text and update the autocomplete list
|
||||||
var updatedState = currentState.copyWith(
|
var updatedState = currentState.copyWith(
|
||||||
productNameController: TextEditingController(text: event.input),
|
productNameController: TextEditingController(text: event.input),
|
||||||
autocompleteList: productNutritionalValues
|
autocompleteList: productNutritionalValues.map((product) => product['name']).toList(),
|
||||||
.map((product) => product['name'])
|
|
||||||
.toList(),
|
|
||||||
);
|
);
|
||||||
if (event.input.length > 3) {
|
if (event.input.length > 3) {
|
||||||
updatedState = updatedState.copyWith(moderationExpanded: true);
|
updatedState = updatedState.copyWith(moderationExpanded: true);
|
||||||
@@ -679,12 +736,13 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _removePortion(
|
Future<void> _removePortion(
|
||||||
RemovePortionEvent event, Emitter<DiaryEditState> emit,) async {
|
RemovePortionEvent event,
|
||||||
|
Emitter<DiaryEditState> emit,
|
||||||
|
) async {
|
||||||
if (state is DiaryEditLoadedState) {
|
if (state is DiaryEditLoadedState) {
|
||||||
var currentState = state as DiaryEditLoadedState;
|
var currentState = state as DiaryEditLoadedState;
|
||||||
|
|
||||||
int? mealId =
|
int? mealId = currentState.currentMeal?.id; // Rename id to mealId for clarity
|
||||||
currentState.currentMeal?.id; // Rename id to mealId for clarity
|
|
||||||
|
|
||||||
var response = await sendRemovePortion(
|
var response = await sendRemovePortion(
|
||||||
currentState.token,
|
currentState.token,
|
||||||
@@ -697,15 +755,19 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
await reloadScreen(event, emit);
|
await reloadScreen(event, emit);
|
||||||
} else {
|
} else {
|
||||||
print(
|
print(
|
||||||
'Failed to add portion. Status Code: ${response.statusCode} ${response.body}',);
|
'Failed to add portion. Status Code: ${response.statusCode} ${response.body}',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<http.Response> sendRemovePortion(
|
Future<http.Response> sendRemovePortion(
|
||||||
String? token, int? portionID, int? mealID, int diaryID,) async {
|
String? token,
|
||||||
String url =
|
int? portionID,
|
||||||
'${dotenv.env['SERVER_ROOT']!}/diary/$diaryID/meal/$mealID/portions/$portionID/delete';
|
int? mealID,
|
||||||
|
int diaryID,
|
||||||
|
) async {
|
||||||
|
String url = '${dotenv.env['SERVER_ROOT']!}/diary/$diaryID/meal/$mealID/portions/$portionID/delete';
|
||||||
|
|
||||||
var response = await http.delete(
|
var response = await http.delete(
|
||||||
Uri.parse(url),
|
Uri.parse(url),
|
||||||
@@ -720,7 +782,9 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _removeImage(
|
FutureOr<void> _removeImage(
|
||||||
RemoveImageEvent event, Emitter<DiaryEditState> emit,) async {
|
RemoveImageEvent event,
|
||||||
|
Emitter<DiaryEditState> emit,
|
||||||
|
) async {
|
||||||
if (state is DiaryEditLoadedState) {
|
if (state is DiaryEditLoadedState) {
|
||||||
var currentState = state as DiaryEditLoadedState;
|
var currentState = state as DiaryEditLoadedState;
|
||||||
|
|
||||||
@@ -736,15 +800,20 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
await reloadScreen(event, emit);
|
await reloadScreen(event, emit);
|
||||||
} else {
|
} else {
|
||||||
print(
|
print(
|
||||||
'Failed to remove photo. Status Code: ${response.statusCode} ${response.body}',);
|
'Failed to remove photo. Status Code: ${response.statusCode} ${response.body}',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<http.Response> sendRemovePhoto(String? token, String? path,
|
Future<http.Response> sendRemovePhoto(
|
||||||
String? photoID, int? mealID, int diaryID,) async {
|
String? token,
|
||||||
String url =
|
String? path,
|
||||||
'${dotenv.env['SERVER_ROOT']!}/diary/$diaryID/meal/$mealID/photo/delete';
|
String? photoID,
|
||||||
|
int? mealID,
|
||||||
|
int diaryID,
|
||||||
|
) async {
|
||||||
|
String url = '${dotenv.env['SERVER_ROOT']!}/diary/$diaryID/meal/$mealID/photo/delete';
|
||||||
final Map<String, dynamic> credentials = {
|
final Map<String, dynamic> credentials = {
|
||||||
'id': photoID,
|
'id': photoID,
|
||||||
'path': path,
|
'path': path,
|
||||||
@@ -780,13 +849,16 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<http.Response> sendFinishDay(String? token, int diaryID,
|
Future<http.Response> sendFinishDay(
|
||||||
TimeOfDay? wakeup, TimeOfDay? retire, String? comment,) async {
|
String? token,
|
||||||
|
int diaryID,
|
||||||
|
TimeOfDay? wakeup,
|
||||||
|
TimeOfDay? retire,
|
||||||
|
String? comment,
|
||||||
|
) async {
|
||||||
final formatter = DateFormat('HH:mm');
|
final formatter = DateFormat('HH:mm');
|
||||||
final wakeupString =
|
final wakeupString = formatter.format(DateTime(2022, 1, 1, wakeup!.hour, wakeup.minute));
|
||||||
formatter.format(DateTime(2022, 1, 1, wakeup!.hour, wakeup.minute));
|
final retireString = formatter.format(DateTime(2022, 1, 1, retire!.hour, retire.minute));
|
||||||
final retireString =
|
|
||||||
formatter.format(DateTime(2022, 1, 1, retire!.hour, retire.minute));
|
|
||||||
|
|
||||||
final Map<String, dynamic> credentials = {
|
final Map<String, dynamic> credentials = {
|
||||||
'wakeup': wakeupString,
|
'wakeup': wakeupString,
|
||||||
@@ -810,21 +882,30 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _uploadImages(
|
Future<void> _uploadImages(
|
||||||
UploadImages event, Emitter<DiaryEditState> emit,) async {
|
UploadImages event,
|
||||||
|
Emitter<DiaryEditState> emit,
|
||||||
|
) async {
|
||||||
if (state is DiaryEditLoadedState) {
|
if (state is DiaryEditLoadedState) {
|
||||||
var currentState = state as DiaryEditLoadedState;
|
var currentState = state as DiaryEditLoadedState;
|
||||||
|
|
||||||
emit(currentState.copyWith(isLoading: true));
|
emit(currentState.copyWith(isLoading: true));
|
||||||
await uploadImageToServer(event.image.path, currentState.diaryId,
|
await uploadImageToServer(
|
||||||
currentState.currentMeal!.id!, currentState.token,);
|
event.image.path,
|
||||||
|
currentState.diaryId,
|
||||||
|
currentState.currentMeal!.id!,
|
||||||
|
currentState.token,
|
||||||
|
);
|
||||||
await reloadScreen(event, emit);
|
await reloadScreen(event, emit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> uploadImageToServer(
|
Future<String> uploadImageToServer(
|
||||||
String imagePath, int diaryID, int mealId, String? token,) async {
|
String imagePath,
|
||||||
String url =
|
int diaryID,
|
||||||
'${dotenv.env['SERVER_ROOT']!}/diary/$diaryID/meal/$mealId/photo/upload';
|
int mealId,
|
||||||
|
String? token,
|
||||||
|
) async {
|
||||||
|
String url = '${dotenv.env['SERVER_ROOT']!}/diary/$diaryID/meal/$mealId/photo/upload';
|
||||||
|
|
||||||
var request = http.MultipartRequest('POST', Uri.parse(url));
|
var request = http.MultipartRequest('POST', Uri.parse(url));
|
||||||
request.headers['Authorization'] = 'Bearer $token';
|
request.headers['Authorization'] = 'Bearer $token';
|
||||||
@@ -841,12 +922,15 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
return imageUrl;
|
return imageUrl;
|
||||||
} else {
|
} else {
|
||||||
throw Exception(
|
throw Exception(
|
||||||
'Failed to upload image. Status code: ${streamedResponse.statusCode}}',);
|
'Failed to upload image. Status code: ${streamedResponse.statusCode}}',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _sendModeration(
|
FutureOr<void> _sendModeration(
|
||||||
SendModeration event, Emitter<DiaryEditState> emit,) async {
|
SendModeration event,
|
||||||
|
Emitter<DiaryEditState> emit,
|
||||||
|
) async {
|
||||||
if (state is DiaryEditLoadedState) {
|
if (state is DiaryEditLoadedState) {
|
||||||
var currentState = state as DiaryEditLoadedState;
|
var currentState = state as DiaryEditLoadedState;
|
||||||
final response = await _sendModerationData(
|
final response = await _sendModerationData(
|
||||||
@@ -866,14 +950,16 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<http.Response> _sendModerationData(
|
Future<http.Response> _sendModerationData(
|
||||||
String name,
|
String name,
|
||||||
String energy_on_100gr,
|
String energy_on_100gr,
|
||||||
String proteins_on_100gr,
|
String proteins_on_100gr,
|
||||||
String fats_on_100gr,
|
String fats_on_100gr,
|
||||||
String carbohydrates_on_100gr,
|
String carbohydrates_on_100gr,
|
||||||
String? token,) async {
|
String? token,
|
||||||
|
) async {
|
||||||
final Uri url = Uri.parse(
|
final Uri url = Uri.parse(
|
||||||
'${dotenv.env['SERVER_ROOT']!}/diary/product_nutritional_values/sendToModeration',);
|
'${dotenv.env['SERVER_ROOT']!}/diary/product_nutritional_values/sendToModeration',
|
||||||
|
);
|
||||||
final Uri serverURL = Uri.parse('${dotenv.env['SERVER_ROOT']!}');
|
final Uri serverURL = Uri.parse('${dotenv.env['SERVER_ROOT']!}');
|
||||||
String host = serverURL.host;
|
String host = serverURL.host;
|
||||||
final Map<String, String> credentials = {
|
final Map<String, String> credentials = {
|
||||||
@@ -901,12 +987,15 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
return response;
|
return response;
|
||||||
} else {
|
} else {
|
||||||
throw Exception(
|
throw Exception(
|
||||||
'Failed to send a product for moderation ${response.statusCode}',);
|
'Failed to send a product for moderation ${response.statusCode}',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _addComment(
|
FutureOr<void> _addComment(
|
||||||
AddComment event, Emitter<DiaryEditState> emit,) async {
|
AddComment event,
|
||||||
|
Emitter<DiaryEditState> emit,
|
||||||
|
) async {
|
||||||
if (state is DiaryEditLoadedState) {
|
if (state is DiaryEditLoadedState) {
|
||||||
var currentState = state as DiaryEditLoadedState;
|
var currentState = state as DiaryEditLoadedState;
|
||||||
var updatedState = currentState.copyWith(
|
var updatedState = currentState.copyWith(
|
||||||
@@ -915,7 +1004,10 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
|
|
||||||
// Отправляем данные по HTTP маршруту и ждем ответ
|
// Отправляем данные по HTTP маршруту и ждем ответ
|
||||||
var response = await sendCommentData(
|
var response = await sendCommentData(
|
||||||
currentState.token, event.comment, currentState.diaryId,);
|
currentState.token,
|
||||||
|
event.comment,
|
||||||
|
currentState.diaryId,
|
||||||
|
);
|
||||||
|
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
emit(updatedState); // Передаем обновленное состояние в emit
|
emit(updatedState); // Передаем обновленное состояние в emit
|
||||||
@@ -924,19 +1016,24 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<http.Response> sendCommentData(
|
Future<http.Response> sendCommentData(
|
||||||
String? token, String comment, int diaryID,) async {
|
String? token,
|
||||||
|
String comment,
|
||||||
|
int diaryID,
|
||||||
|
) async {
|
||||||
String url = dotenv.env['SERVER_ROOT']! + '/diary/$diaryID/retire/fill';
|
String url = dotenv.env['SERVER_ROOT']! + '/diary/$diaryID/retire/fill';
|
||||||
final Map<String, dynamic> credentials = {
|
final Map<String, dynamic> credentials = {
|
||||||
'comment': comment,
|
'comment': comment,
|
||||||
};
|
};
|
||||||
|
|
||||||
var response = await http.post(Uri.parse(url),
|
var response = await http.post(
|
||||||
headers: {
|
Uri.parse(url),
|
||||||
'Content-Type': 'application/json',
|
headers: {
|
||||||
'Authorization': 'Bearer $token',
|
'Content-Type': 'application/json',
|
||||||
},
|
'Authorization': 'Bearer $token',
|
||||||
body: json.encode(credentials),
|
},
|
||||||
encoding: utf8,);
|
body: json.encode(credentials),
|
||||||
|
encoding: utf8,
|
||||||
|
);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
@@ -969,3 +1066,13 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int convertToInt(dynamic value) {
|
||||||
|
if (value is int) {
|
||||||
|
return value;
|
||||||
|
} else if (value is double) {
|
||||||
|
return value.toInt();
|
||||||
|
} else {
|
||||||
|
throw FormatException('Unexpected value type: ${value.runtimeType}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,43 +12,42 @@ class DiaryEditState extends Equatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class DiaryEditInitialState extends DiaryEditState {
|
class DiaryEditInitialState extends DiaryEditState {
|
||||||
DiaryEditInitialState({required DiaryEditModel diaryEditModelObj})
|
DiaryEditInitialState({required DiaryEditModel diaryEditModelObj}) : super(diaryEditModelObj: diaryEditModelObj);
|
||||||
: super(diaryEditModelObj: diaryEditModelObj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents the state of DiaryEdit in the application.
|
/// Represents the state of DiaryEdit in the application.
|
||||||
class DiaryEditLoadedState extends DiaryEditState {
|
class DiaryEditLoadedState extends DiaryEditState {
|
||||||
DiaryEditLoadedState(
|
DiaryEditLoadedState({
|
||||||
{this.diaryEditModelObj,
|
this.diaryEditModelObj,
|
||||||
this.diaryDate,
|
this.diaryDate,
|
||||||
this.token,
|
this.token,
|
||||||
this.meals,
|
this.meals,
|
||||||
this.portions,
|
this.portions,
|
||||||
this.photos,
|
this.photos,
|
||||||
this.autocompleteList,
|
this.autocompleteList,
|
||||||
this.wakeupController,
|
this.wakeupController,
|
||||||
this.retireController,
|
this.retireController,
|
||||||
this.commentController,
|
this.commentController,
|
||||||
this.mealTimeController,
|
this.mealTimeController,
|
||||||
this.portionController,
|
this.portionController,
|
||||||
this.productNameController,
|
this.productNameController,
|
||||||
this.productQuantityController,
|
this.productQuantityController,
|
||||||
this.selectedMood,
|
this.selectedMood,
|
||||||
this.currentMeal,
|
this.currentMeal,
|
||||||
this.caloriesController,
|
this.caloriesController,
|
||||||
this.fatsController,
|
this.fatsController,
|
||||||
this.proteinsController,
|
this.proteinsController,
|
||||||
this.carbsController,
|
this.carbsController,
|
||||||
this.isLoading = false,
|
this.isLoading = false,
|
||||||
this.isAdded = false,
|
this.isAdded = false,
|
||||||
required this.recommendedChartValues,
|
required this.recommendedChartValues,
|
||||||
required this.consumedChartValues,
|
required this.consumedChartValues,
|
||||||
required this.diaryId,
|
required this.diaryId,
|
||||||
required this.selectedSatiety,
|
required this.selectedSatiety,
|
||||||
required this.moderationExpanded,
|
required this.moderationExpanded,
|
||||||
required this.wakeupExpanded,
|
required this.wakeupExpanded,
|
||||||
required this.moodExpanded,})
|
required this.moodExpanded,
|
||||||
: super(diaryEditModelObj: null);
|
}) : super(diaryEditModelObj: null);
|
||||||
|
|
||||||
DiaryEditModel? diaryEditModelObj;
|
DiaryEditModel? diaryEditModelObj;
|
||||||
String? diaryDate;
|
String? diaryDate;
|
||||||
@@ -57,8 +56,8 @@ class DiaryEditLoadedState extends DiaryEditState {
|
|||||||
List<dynamic>? portions;
|
List<dynamic>? portions;
|
||||||
List<dynamic>? photos;
|
List<dynamic>? photos;
|
||||||
List<dynamic>? autocompleteList;
|
List<dynamic>? autocompleteList;
|
||||||
List<double> recommendedChartValues;
|
List<int> recommendedChartValues;
|
||||||
List<double> consumedChartValues;
|
List<int> consumedChartValues;
|
||||||
SelectionPopupModel? currentMeal;
|
SelectionPopupModel? currentMeal;
|
||||||
SelectionPopupModel? portionController;
|
SelectionPopupModel? portionController;
|
||||||
TimeOfDay? wakeupController;
|
TimeOfDay? wakeupController;
|
||||||
@@ -117,8 +116,8 @@ class DiaryEditLoadedState extends DiaryEditState {
|
|||||||
SelectionPopupModel? portionController,
|
SelectionPopupModel? portionController,
|
||||||
String? diaryDate,
|
String? diaryDate,
|
||||||
String? token,
|
String? token,
|
||||||
List<double>? recommendedChartValues,
|
List<int>? recommendedChartValues,
|
||||||
List<double>? consumedChartValues,
|
List<int>? consumedChartValues,
|
||||||
List<dynamic>? meals,
|
List<dynamic>? meals,
|
||||||
List<dynamic>? portions,
|
List<dynamic>? portions,
|
||||||
List<dynamic>? photos,
|
List<dynamic>? photos,
|
||||||
@@ -143,38 +142,36 @@ class DiaryEditLoadedState extends DiaryEditState {
|
|||||||
bool? isAdded,
|
bool? isAdded,
|
||||||
}) {
|
}) {
|
||||||
return DiaryEditLoadedState(
|
return DiaryEditLoadedState(
|
||||||
diaryEditModelObj: diaryEditModelObj ?? this.diaryEditModelObj,
|
diaryEditModelObj: diaryEditModelObj ?? this.diaryEditModelObj,
|
||||||
diaryDate: diaryDate ?? this.diaryDate,
|
diaryDate: diaryDate ?? this.diaryDate,
|
||||||
token: token ?? this.token,
|
token: token ?? this.token,
|
||||||
meals: meals ?? this.meals,
|
meals: meals ?? this.meals,
|
||||||
photos: photos ?? this.photos,
|
photos: photos ?? this.photos,
|
||||||
autocompleteList: autocompleteList ?? this.autocompleteList,
|
autocompleteList: autocompleteList ?? this.autocompleteList,
|
||||||
portions: portions ?? this.portions,
|
portions: portions ?? this.portions,
|
||||||
recommendedChartValues:
|
recommendedChartValues: recommendedChartValues ?? this.recommendedChartValues,
|
||||||
recommendedChartValues ?? this.recommendedChartValues,
|
consumedChartValues: consumedChartValues ?? this.consumedChartValues,
|
||||||
consumedChartValues: consumedChartValues ?? this.consumedChartValues,
|
wakeupController: wakeupController ?? this.wakeupController,
|
||||||
wakeupController: wakeupController ?? this.wakeupController,
|
retireController: retireController ?? this.retireController,
|
||||||
retireController: retireController ?? this.retireController,
|
mealTimeController: mealTimeController ?? this.mealTimeController,
|
||||||
mealTimeController: mealTimeController ?? this.mealTimeController,
|
commentController: commentController ?? this.commentController,
|
||||||
commentController: commentController ?? this.commentController,
|
portionController: portionController ?? this.portionController,
|
||||||
portionController: portionController ?? this.portionController,
|
productNameController: productNameController ?? this.productNameController,
|
||||||
productNameController:
|
productQuantityController: productQuantityController ?? this.productQuantityController,
|
||||||
productNameController ?? this.productNameController,
|
selectedMood: selectedMood ?? this.selectedMood,
|
||||||
productQuantityController:
|
selectedSatiety: selectedSatiety ?? this.selectedSatiety,
|
||||||
productQuantityController ?? this.productQuantityController,
|
diaryId: diaryId ?? this.diaryId,
|
||||||
selectedMood: selectedMood ?? this.selectedMood,
|
currentMeal: currentMeal ?? this.currentMeal,
|
||||||
selectedSatiety: selectedSatiety ?? this.selectedSatiety,
|
caloriesController: caloriesController ?? this.caloriesController,
|
||||||
diaryId: diaryId ?? this.diaryId,
|
fatsController: fatsController ?? this.fatsController,
|
||||||
currentMeal: currentMeal ?? this.currentMeal,
|
proteinsController: proteinsController ?? this.proteinsController,
|
||||||
caloriesController: caloriesController ?? this.caloriesController,
|
carbsController: carbsController ?? this.carbsController,
|
||||||
fatsController: fatsController ?? this.fatsController,
|
wakeupExpanded: wakeupExpanded ?? this.wakeupExpanded,
|
||||||
proteinsController: proteinsController ?? this.proteinsController,
|
moderationExpanded: moderationExpanded ?? this.moderationExpanded,
|
||||||
carbsController: carbsController ?? this.carbsController,
|
moodExpanded: moodExpanded ?? this.moodExpanded,
|
||||||
wakeupExpanded: wakeupExpanded ?? this.wakeupExpanded,
|
isAdded: isAdded ?? this.isAdded,
|
||||||
moderationExpanded: moderationExpanded ?? this.moderationExpanded,
|
isLoading: isLoading ?? this.isLoading,
|
||||||
moodExpanded: moodExpanded ?? this.moodExpanded,
|
);
|
||||||
isAdded: isAdded ?? this.isAdded,
|
|
||||||
isLoading: isLoading ?? this.isLoading,);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ class DiaryEditScreen extends StatelessWidget {
|
|||||||
|
|
||||||
static Widget builder(BuildContext context) {
|
static Widget builder(BuildContext context) {
|
||||||
return BlocProvider<DiaryEditBloc>(
|
return BlocProvider<DiaryEditBloc>(
|
||||||
create: (context) => DiaryEditBloc(DiaryEditState(diaryEditModelObj: DiaryEditModel()))..add(DiaryEditInitialEvent()), child: DiaryEditScreen(),);
|
create: (context) => DiaryEditBloc(DiaryEditState(diaryEditModelObj: DiaryEditModel()))..add(DiaryEditInitialEvent()),
|
||||||
|
child: DiaryEditScreen(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -264,237 +266,241 @@ class DiaryEditScreen extends StatelessWidget {
|
|||||||
//print(_options);
|
//print(_options);
|
||||||
FocusNode focusNodeName = FocusNode();
|
FocusNode focusNodeName = FocusNode();
|
||||||
return Container(
|
return Container(
|
||||||
margin: EdgeInsets.symmetric(horizontal: 16.h),
|
margin: EdgeInsets.symmetric(horizontal: 16.h),
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(
|
||||||
horizontal: 24.h,
|
horizontal: 24.h,
|
||||||
vertical: 12.v,
|
vertical: 12.v,
|
||||||
),
|
),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(12)),
|
borderRadius: const BorderRadius.all(Radius.circular(12)),
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: Colors.grey.withOpacity(0.5),
|
color: Colors.grey.withOpacity(0.5),
|
||||||
spreadRadius: 2,
|
spreadRadius: 2,
|
||||||
blurRadius: 5,
|
blurRadius: 5,
|
||||||
offset: Offset(0, 3),
|
offset: Offset(0, 3),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 10.h),
|
padding: EdgeInsets.symmetric(horizontal: 10.h),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Время приема пищи",
|
"Время приема пищи",
|
||||||
style: CustomTextStyles.bodyMediumBlack900,
|
style: CustomTextStyles.bodyMediumBlack900,
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
// Adding Expanded widget
|
// Adding Expanded widget
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 10.h),
|
padding: EdgeInsets.symmetric(horizontal: 10.h),
|
||||||
child: ConstrainedBox(
|
child: ConstrainedBox(
|
||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(
|
||||||
maxWidth: MediaQuery.of(context).size.width - 260,
|
maxWidth: MediaQuery.of(context).size.width - 260,
|
||||||
),
|
),
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () => _selectMealTime(context, state),
|
onTap: () => _selectMealTime(context, state),
|
||||||
child: AbsorbPointer(
|
child: AbsorbPointer(
|
||||||
child: CustomTextFormField(
|
child: CustomTextFormField(
|
||||||
hintText: state.mealTimeController?.format(context).toString(),
|
hintText: state.mealTimeController?.format(context).toString(),
|
||||||
autofocus: false,
|
autofocus: false,
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 20.v),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10.h),
|
||||||
|
child: BlocSelector<DiaryEditBloc, DiaryEditState, DiaryEditModel?>(
|
||||||
|
selector: (state) => state.diaryEditModelObj,
|
||||||
|
builder: (context, diaryEditModelObj) {
|
||||||
|
return CustomDropDown(
|
||||||
|
hintText: "Прием пищи",
|
||||||
|
items: diaryEditModelObj?.mealList,
|
||||||
|
contentPadding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 10.h,
|
||||||
|
vertical: 9.v,
|
||||||
|
),
|
||||||
|
defaultValue: diaryEditModelObj?.mealList[0],
|
||||||
|
onChanged: changeMeal(context, state),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 20.v),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10.h),
|
||||||
|
child: RawAutocomplete<String>(
|
||||||
|
optionsBuilder: buildOptions(_options),
|
||||||
|
fieldViewBuilder: (
|
||||||
|
BuildContext context,
|
||||||
|
TextEditingController productEditingController,
|
||||||
|
FocusNode focusNodeName,
|
||||||
|
VoidCallback onFieldSubmitted,
|
||||||
|
) {
|
||||||
|
if (state.isAdded) {
|
||||||
|
print("Clear");
|
||||||
|
}
|
||||||
|
return CustomTextFormField(
|
||||||
|
hintText: "Введите название продукта",
|
||||||
|
controller: productEditingController,
|
||||||
|
focusNode: focusNodeName,
|
||||||
|
onChanged: getAutocomplete(context, focusNodeName),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
optionsViewBuilder: (
|
||||||
|
BuildContext context,
|
||||||
|
AutocompleteOnSelected<String> onSelected,
|
||||||
|
Iterable<String> options,
|
||||||
|
) {
|
||||||
|
return Align(
|
||||||
|
alignment: Alignment.topLeft,
|
||||||
|
child: Material(
|
||||||
|
elevation: 4.0,
|
||||||
|
child: SizedBox(
|
||||||
|
height: 200.0,
|
||||||
|
child: ListView.builder(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
itemCount: options.length,
|
||||||
|
itemBuilder: (BuildContext context, int index) {
|
||||||
|
final String option = options.elementAt(index);
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: selectProduct(onSelected, option, state),
|
||||||
|
child: ListTile(
|
||||||
|
title: Text(option),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 20.v),
|
||||||
|
if (state.moderationExpanded)
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10.h),
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () => openCaloriesDialog(context, state),
|
||||||
|
child: Text("Отправить на модерацию"),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 20.v),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10.h),
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
CustomTextFormField(
|
||||||
|
width: 150.h,
|
||||||
|
hintText: "Кол-во",
|
||||||
|
textInputAction: TextInputAction.done,
|
||||||
|
// focusNode: focusNodeQuantity,
|
||||||
|
controller: state.productQuantityController,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
inputFormatters: <TextInputFormatter>[digitsOnly],
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(left: 30.h),
|
||||||
|
child: BlocSelector<DiaryEditBloc, DiaryEditState, DiaryEditModel?>(
|
||||||
|
selector: (state) => state.diaryEditModelObj,
|
||||||
|
builder: (context, diaryEditModelObj) {
|
||||||
|
return CustomDropDown(
|
||||||
|
items: diaryEditModelObj?.portionList,
|
||||||
|
defaultValue: diaryEditModelObj?.portionList?[0],
|
||||||
|
onChanged: changePortion(context, state),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 20.v),
|
),
|
||||||
Padding(
|
SizedBox(height: 30.v),
|
||||||
padding: EdgeInsets.symmetric(horizontal: 10.h),
|
_buildAddProduct(context, state),
|
||||||
child: BlocSelector<DiaryEditBloc, DiaryEditState, DiaryEditModel?>(
|
SizedBox(height: 30.v),
|
||||||
selector: (state) => state.diaryEditModelObj,
|
...state.portions!.map((portion) => _buildProduct(context, portion)).toList(),
|
||||||
builder: (context, diaryEditModelObj) {
|
SizedBox(height: 30.v),
|
||||||
return CustomDropDown(
|
/*...state.photos != null
|
||||||
hintText: "Прием пищи",
|
|
||||||
items: diaryEditModelObj?.mealList,
|
|
||||||
contentPadding: EdgeInsets.symmetric(
|
|
||||||
horizontal: 10.h,
|
|
||||||
vertical: 9.v,
|
|
||||||
),
|
|
||||||
defaultValue: diaryEditModelObj?.mealList[0],
|
|
||||||
onChanged: changeMeal(context, state),
|
|
||||||
);
|
|
||||||
},),),
|
|
||||||
SizedBox(height: 20.v),
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.symmetric(horizontal: 10.h),
|
|
||||||
child: RawAutocomplete<String>(
|
|
||||||
optionsBuilder: buildOptions(_options),
|
|
||||||
fieldViewBuilder: (
|
|
||||||
BuildContext context,
|
|
||||||
TextEditingController productEditingController,
|
|
||||||
FocusNode focusNodeName,
|
|
||||||
VoidCallback onFieldSubmitted,
|
|
||||||
) {
|
|
||||||
if (state.isAdded) {
|
|
||||||
print("Clear");
|
|
||||||
}
|
|
||||||
return CustomTextFormField(
|
|
||||||
hintText: "Введите название продукта",
|
|
||||||
controller: productEditingController,
|
|
||||||
focusNode: focusNodeName,
|
|
||||||
onChanged: getAutocomplete(context, focusNodeName),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
optionsViewBuilder: (
|
|
||||||
BuildContext context,
|
|
||||||
AutocompleteOnSelected<String> onSelected,
|
|
||||||
Iterable<String> options,
|
|
||||||
) {
|
|
||||||
return Align(
|
|
||||||
alignment: Alignment.topLeft,
|
|
||||||
child: Material(
|
|
||||||
elevation: 4.0,
|
|
||||||
child: SizedBox(
|
|
||||||
height: 200.0,
|
|
||||||
child: ListView.builder(
|
|
||||||
padding: const EdgeInsets.all(8.0),
|
|
||||||
itemCount: options.length,
|
|
||||||
itemBuilder: (BuildContext context, int index) {
|
|
||||||
final String option = options.elementAt(index);
|
|
||||||
return GestureDetector(
|
|
||||||
onTap: selectProduct(onSelected, option, state),
|
|
||||||
child: ListTile(
|
|
||||||
title: Text(option),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},),
|
|
||||||
),
|
|
||||||
SizedBox(height: 20.v),
|
|
||||||
if (state.moderationExpanded)
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.symmetric(horizontal: 10.h),
|
|
||||||
child: GestureDetector(
|
|
||||||
onTap: () => openCaloriesDialog(context, state),
|
|
||||||
child: Text("Отправить на модерацию"),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 20.v),
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.symmetric(horizontal: 10.h),
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
scrollDirection: Axis.horizontal,
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
CustomTextFormField(
|
|
||||||
width: 150.h,
|
|
||||||
hintText: "Кол-во",
|
|
||||||
textInputAction: TextInputAction.done,
|
|
||||||
// focusNode: focusNodeQuantity,
|
|
||||||
controller: state.productQuantityController,
|
|
||||||
keyboardType: TextInputType.number,
|
|
||||||
inputFormatters: <TextInputFormatter>[digitsOnly],
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.only(left: 30.h),
|
|
||||||
child: BlocSelector<DiaryEditBloc, DiaryEditState, DiaryEditModel?>(
|
|
||||||
selector: (state) => state.diaryEditModelObj,
|
|
||||||
builder: (context, diaryEditModelObj) {
|
|
||||||
return CustomDropDown(
|
|
||||||
items: diaryEditModelObj?.portionList,
|
|
||||||
defaultValue: diaryEditModelObj?.portionList?[0],
|
|
||||||
onChanged: changePortion(context, state),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 30.v),
|
|
||||||
_buildAddProduct(context, state),
|
|
||||||
SizedBox(height: 30.v),
|
|
||||||
...state.portions!.map((portion) => _buildProduct(context, portion)).toList(),
|
|
||||||
SizedBox(height: 30.v),
|
|
||||||
/*...state.photos != null
|
|
||||||
? state.photos!.isEmpty
|
? state.photos!.isEmpty
|
||||||
? [Text('Фото пока нет')]
|
? [Text('Фото пока нет')]
|
||||||
: state.photos!
|
: state.photos!
|
||||||
.map((photo) => _buildPhoto(context, photo))
|
.map((photo) => _buildPhoto(context, photo))
|
||||||
.toList()
|
.toList()
|
||||||
: [Text('Фото нет')],*/
|
: [Text('Фото нет')],*/
|
||||||
_buildCarousel(context, state),
|
_buildCarousel(context, state),
|
||||||
SizedBox(height: 20.v),
|
SizedBox(height: 20.v),
|
||||||
_buildAddPhoto(context, state),
|
_buildAddPhoto(context, state),
|
||||||
SizedBox(height: 30.v),
|
SizedBox(height: 30.v),
|
||||||
Text(
|
Text(
|
||||||
"Ваша сытость после приёма пищи",
|
"Ваша сытость после приёма пищи",
|
||||||
style: CustomTextStyles.bodyMediumBlack900,
|
style: CustomTextStyles.bodyMediumBlack900,
|
||||||
),
|
),
|
||||||
SizedBox(height: 15.v),
|
SizedBox(height: 15.v),
|
||||||
BlocBuilder<DiaryEditBloc, DiaryEditState>(
|
BlocBuilder<DiaryEditBloc, DiaryEditState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
if (state is DiaryEditLoadedState) {
|
if (state is DiaryEditLoadedState) {
|
||||||
return Row(
|
return Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text("😭"),
|
Text("😭"),
|
||||||
ScaleElement(
|
ScaleElement(
|
||||||
color: Colors.red,
|
color: Colors.red,
|
||||||
isSelected: state.selectedSatiety == 0,
|
isSelected: state.selectedSatiety == 0,
|
||||||
onTap: changeSatiety(context, 0),
|
onTap: changeSatiety(context, 0),
|
||||||
),
|
),
|
||||||
ScaleElement(
|
ScaleElement(
|
||||||
color: Colors.orange,
|
color: Colors.orange,
|
||||||
isSelected: state.selectedSatiety == 1,
|
isSelected: state.selectedSatiety == 1,
|
||||||
onTap: changeSatiety(context, 1),
|
onTap: changeSatiety(context, 1),
|
||||||
),
|
),
|
||||||
ScaleElement(
|
ScaleElement(
|
||||||
color: Colors.yellow,
|
color: Colors.yellow,
|
||||||
isSelected: state.selectedSatiety == 2,
|
isSelected: state.selectedSatiety == 2,
|
||||||
onTap: changeSatiety(context, 2),
|
onTap: changeSatiety(context, 2),
|
||||||
),
|
),
|
||||||
ScaleElement(
|
ScaleElement(
|
||||||
color: Colors.lime,
|
color: Colors.lime,
|
||||||
isSelected: state.selectedSatiety == 3,
|
isSelected: state.selectedSatiety == 3,
|
||||||
onTap: changeSatiety(context, 3),
|
onTap: changeSatiety(context, 3),
|
||||||
),
|
),
|
||||||
ScaleElement(
|
ScaleElement(
|
||||||
color: Colors.lightGreen,
|
color: Colors.lightGreen,
|
||||||
isSelected: state.selectedSatiety == 4,
|
isSelected: state.selectedSatiety == 4,
|
||||||
onTap: changeSatiety(context, 4),
|
onTap: changeSatiety(context, 4),
|
||||||
),
|
),
|
||||||
ScaleElement(
|
ScaleElement(
|
||||||
color: Colors.green,
|
color: Colors.green,
|
||||||
isSelected: state.selectedSatiety == 5,
|
isSelected: state.selectedSatiety == 5,
|
||||||
onTap: changeSatiety(context, 5),
|
onTap: changeSatiety(context, 5),
|
||||||
),
|
),
|
||||||
Text("😊"),
|
Text("😊"),
|
||||||
// Остальные элементы шкалы
|
// Остальные элементы шкалы
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return Container(); // Возвращаем пустой контейнер, если состояние не является DiaryEditLoadedState
|
return Container(); // Возвращаем пустой контейнер, если состояние не является DiaryEditLoadedState
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),);
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
openCaloriesDialog(BuildContext context, DiaryEditLoadedState state) {
|
openCaloriesDialog(BuildContext context, DiaryEditLoadedState state) {
|
||||||
@@ -542,8 +548,15 @@ class DiaryEditScreen extends StatelessWidget {
|
|||||||
child: Text('Отмена'),
|
child: Text('Отмена'),
|
||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: triggerModeration(context, state.productNameController!.text, state.caloriesController!.text, state.proteinsController!.text,
|
onPressed: triggerModeration(
|
||||||
state.fatsController!.text, state.carbsController!.text, dialogContext,),
|
context,
|
||||||
|
state.productNameController!.text,
|
||||||
|
state.caloriesController!.text,
|
||||||
|
state.proteinsController!.text,
|
||||||
|
state.fatsController!.text,
|
||||||
|
state.carbsController!.text,
|
||||||
|
dialogContext,
|
||||||
|
),
|
||||||
child: Text('Отправить'),
|
child: Text('Отправить'),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -552,12 +565,26 @@ class DiaryEditScreen extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
triggerModeration(BuildContext context, String name, String energyOn100gr, String proteinsOn100gr, String fatsOn100gr, String carbohydratesOn100gr,
|
triggerModeration(
|
||||||
BuildContext dialogContext,) {
|
BuildContext context,
|
||||||
|
String name,
|
||||||
|
String energyOn100gr,
|
||||||
|
String proteinsOn100gr,
|
||||||
|
String fatsOn100gr,
|
||||||
|
String carbohydratesOn100gr,
|
||||||
|
BuildContext dialogContext,
|
||||||
|
) {
|
||||||
return () {
|
return () {
|
||||||
// Call function to send moderation with the entered values
|
// Call function to send moderation with the entered values
|
||||||
context.read<DiaryEditBloc>().add(SendModeration(
|
context.read<DiaryEditBloc>().add(
|
||||||
name: name, energyOn100gr: energyOn100gr, proteinsOn100gr: proteinsOn100gr, fatsOn100gr: fatsOn100gr, carbohydratesOn100gr: carbohydratesOn100gr,),);
|
SendModeration(
|
||||||
|
name: name,
|
||||||
|
energyOn100gr: energyOn100gr,
|
||||||
|
proteinsOn100gr: proteinsOn100gr,
|
||||||
|
fatsOn100gr: fatsOn100gr,
|
||||||
|
carbohydratesOn100gr: carbohydratesOn100gr,
|
||||||
|
),
|
||||||
|
);
|
||||||
Navigator.of(dialogContext).pop(); // Dismiss the dialog
|
Navigator.of(dialogContext).pop(); // Dismiss the dialog
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -640,14 +667,15 @@ class DiaryEditScreen extends StatelessWidget {
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
left: 7.h,
|
left: 7.h,
|
||||||
top: 5.v,
|
top: 5.v,
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
portion['product_name'].length > 8 ? portion['product_name'].substring(0, 8) : portion['product_name'],
|
portion['product_name'].length > 8 ? portion['product_name'].substring(0, 8) : portion['product_name'],
|
||||||
style: CustomTextStyles.titleMedium16,
|
style: CustomTextStyles.titleMedium16,
|
||||||
),),
|
),
|
||||||
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
left: 20.h,
|
left: 20.h,
|
||||||
@@ -660,14 +688,15 @@ class DiaryEditScreen extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
Spacer(),
|
Spacer(),
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: removePortion(context, portion),
|
onTap: removePortion(context, portion),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(right: 10),
|
padding: const EdgeInsets.only(right: 10),
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.close,
|
Icons.close,
|
||||||
color: appTheme.blueGray300,
|
color: appTheme.blueGray300,
|
||||||
),
|
),
|
||||||
),),
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -720,8 +749,8 @@ class DiaryEditScreen extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_buildNutritionChart(BuildContext context, DiaryEditLoadedState state) {
|
_buildNutritionChart(BuildContext context, DiaryEditLoadedState state) {
|
||||||
final List<double> recommendedValues = state.recommendedChartValues; // Рекомендуемые значения: калории, жиры, белки, углеводы
|
final List<int> recommendedValues = state.recommendedChartValues; // Рекомендуемые значения: калории, жиры, белки, углеводы
|
||||||
final List<double> consumedValues = state.consumedChartValues; //
|
final List<int> consumedValues = state.consumedChartValues; //
|
||||||
return Container(
|
return Container(
|
||||||
margin: EdgeInsets.symmetric(horizontal: 16.h),
|
margin: EdgeInsets.symmetric(horizontal: 16.h),
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(
|
||||||
@@ -779,30 +808,42 @@ class DiaryEditScreen extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
borderData: FlBorderData(show: false),
|
borderData: FlBorderData(show: false),
|
||||||
barGroups: [
|
barGroups: [
|
||||||
BarChartGroupData(x: 0, barRods: [
|
BarChartGroupData(
|
||||||
BarChartRodData(
|
x: 0,
|
||||||
toY: consumedValues[0] / recommendedValues[0] * 100,
|
barRods: [
|
||||||
color: checkConsumedValues([recommendedValues[0]], [consumedValues[1]]) ? Colors.red : Colors.blue,
|
BarChartRodData(
|
||||||
),
|
toY: consumedValues[0] / recommendedValues[0] * 100,
|
||||||
],),
|
color: checkConsumedValues([recommendedValues[0]], [consumedValues[1]]) ? Colors.red : Colors.blue,
|
||||||
BarChartGroupData(x: 1, barRods: [
|
),
|
||||||
BarChartRodData(
|
],
|
||||||
toY: consumedValues[1] / recommendedValues[1] * 100,
|
),
|
||||||
color: checkConsumedValues([recommendedValues[1]], [consumedValues[1]]) ? Colors.red : Colors.blue,
|
BarChartGroupData(
|
||||||
),
|
x: 1,
|
||||||
],),
|
barRods: [
|
||||||
BarChartGroupData(x: 2, barRods: [
|
BarChartRodData(
|
||||||
BarChartRodData(
|
toY: consumedValues[1] / recommendedValues[1] * 100,
|
||||||
toY: consumedValues[2] / recommendedValues[2] * 100,
|
color: checkConsumedValues([recommendedValues[1]], [consumedValues[1]]) ? Colors.red : Colors.blue,
|
||||||
color: checkConsumedValues([recommendedValues[2]], [consumedValues[2]]) ? Colors.red : Colors.blue,
|
),
|
||||||
),
|
],
|
||||||
],),
|
),
|
||||||
BarChartGroupData(x: 3, barRods: [
|
BarChartGroupData(
|
||||||
BarChartRodData(
|
x: 2,
|
||||||
toY: consumedValues[3] / recommendedValues[3] * 100,
|
barRods: [
|
||||||
color: checkConsumedValues([recommendedValues[3]], [consumedValues[3]]) ? Colors.red : Colors.blue,
|
BarChartRodData(
|
||||||
),
|
toY: consumedValues[2] / recommendedValues[2] * 100,
|
||||||
],),
|
color: checkConsumedValues([recommendedValues[2]], [consumedValues[2]]) ? Colors.red : Colors.blue,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
BarChartGroupData(
|
||||||
|
x: 3,
|
||||||
|
barRods: [
|
||||||
|
BarChartRodData(
|
||||||
|
toY: consumedValues[3] / recommendedValues[3] * 100,
|
||||||
|
color: checkConsumedValues([recommendedValues[3]], [consumedValues[3]]) ? Colors.red : Colors.blue,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -1077,24 +1118,25 @@ class DiaryEditScreen extends StatelessWidget {
|
|||||||
|
|
||||||
_buildMood(BuildContext context, DiaryEditLoadedState state) {
|
_buildMood(BuildContext context, DiaryEditLoadedState state) {
|
||||||
return Container(
|
return Container(
|
||||||
margin: EdgeInsets.symmetric(horizontal: 16.h),
|
margin: EdgeInsets.symmetric(horizontal: 16.h),
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(
|
||||||
horizontal: 24.h,
|
horizontal: 24.h,
|
||||||
vertical: 12.v,
|
vertical: 12.v,
|
||||||
),
|
),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(12)),
|
borderRadius: const BorderRadius.all(Radius.circular(12)),
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: Colors.grey.withOpacity(0.5),
|
color: Colors.grey.withOpacity(0.5),
|
||||||
spreadRadius: 2,
|
spreadRadius: 2,
|
||||||
blurRadius: 5,
|
blurRadius: 5,
|
||||||
offset: Offset(0, 3),
|
offset: Offset(0, 3),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
child: Column(children: [
|
child: Column(
|
||||||
|
children: [
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: toggleMood(context),
|
onTap: toggleMood(context),
|
||||||
child: Row(
|
child: Row(
|
||||||
@@ -1147,7 +1189,9 @@ class DiaryEditScreen extends StatelessWidget {
|
|||||||
// Остальные элементы шкалы
|
// Остальные элементы шкалы
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],),);
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
changeMood(BuildContext context, int satiety) {
|
changeMood(BuildContext context, int satiety) {
|
||||||
@@ -1196,7 +1240,7 @@ class DiaryEditScreen extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkConsumedValues(List<double> recommendedValues, List<double> consumedValues) {
|
bool checkConsumedValues(List<int> recommendedValues, List<int> consumedValues) {
|
||||||
for (int i = 0; i < recommendedValues.length; i++) {
|
for (int i = 0; i < recommendedValues.length; i++) {
|
||||||
if (consumedValues[i] > recommendedValues[i]) {
|
if (consumedValues[i] > recommendedValues[i]) {
|
||||||
// Если хотя бы одно потребленное значение превышает рекомендованное
|
// Если хотя бы одно потребленное значение превышает рекомендованное
|
||||||
|
|||||||
Reference in New Issue
Block a user