forked from eatvio/eatvio_app
feat(profile): add subscribers and subscriptions
This commit is contained in:
@@ -13,7 +13,7 @@ class ChatSelectCubit extends Cubit<ChatSelectState> {
|
||||
emit(ChatSelectState.loading());
|
||||
try {
|
||||
emit(ChatSelectState.loaded(
|
||||
chatRooms: (await chatRepository.getChatRoomPreiews(query: query)),
|
||||
chatRooms: (await chatRepository.getChatRoomPreviews(query: query)),
|
||||
));
|
||||
} catch (e) {
|
||||
emit(
|
||||
|
||||
@@ -55,7 +55,7 @@ class ChatRepository {
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<ChatRoom>> getChatRoomPreiews({String? query}) async {
|
||||
Future<List<ChatRoom>> getChatRoomPreviews({String? query}) async {
|
||||
try {
|
||||
return (await chatService.getChatRoomPreviews(query: query)).chatRooms;
|
||||
} catch (e) {
|
||||
@@ -81,4 +81,13 @@ class ChatRepository {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<ChatRoomModel> getChatRoomIdByUserSlug({required String slug}) async {
|
||||
try {
|
||||
return (await chatService.getChatRoomIdByUserSlug(user: slug));
|
||||
} catch (e) {
|
||||
print(e);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
19
lib/features/profile/models/badge_model.dart
Normal file
19
lib/features/profile/models/badge_model.dart
Normal file
@@ -0,0 +1,19 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'badge_model.freezed.dart';
|
||||
|
||||
part 'badge_model.g.dart';
|
||||
|
||||
@freezed
|
||||
class BadgeModel with _$BadgeModel {
|
||||
const factory BadgeModel({
|
||||
required int id,
|
||||
required String title,
|
||||
required String description,
|
||||
required String image,
|
||||
required String type,
|
||||
required String parameters,
|
||||
}) = _BadgeModel;
|
||||
|
||||
factory BadgeModel.fromJson(Map<String, Object?> json) => _$BadgeModelFromJson(json);
|
||||
}
|
||||
271
lib/features/profile/models/badge_model.freezed.dart
Normal file
271
lib/features/profile/models/badge_model.freezed.dart
Normal file
@@ -0,0 +1,271 @@
|
||||
// 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 'badge_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');
|
||||
|
||||
BadgeModel _$BadgeModelFromJson(Map<String, dynamic> json) {
|
||||
return _BadgeModel.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$BadgeModel {
|
||||
int get id => throw _privateConstructorUsedError;
|
||||
String get title => throw _privateConstructorUsedError;
|
||||
String get description => throw _privateConstructorUsedError;
|
||||
String get image => throw _privateConstructorUsedError;
|
||||
String get type => throw _privateConstructorUsedError;
|
||||
String get parameters => throw _privateConstructorUsedError;
|
||||
|
||||
/// Serializes this BadgeModel to a JSON map.
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
|
||||
/// Create a copy of BadgeModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$BadgeModelCopyWith<BadgeModel> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $BadgeModelCopyWith<$Res> {
|
||||
factory $BadgeModelCopyWith(
|
||||
BadgeModel value, $Res Function(BadgeModel) then) =
|
||||
_$BadgeModelCopyWithImpl<$Res, BadgeModel>;
|
||||
@useResult
|
||||
$Res call(
|
||||
{int id,
|
||||
String title,
|
||||
String description,
|
||||
String image,
|
||||
String type,
|
||||
String parameters});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$BadgeModelCopyWithImpl<$Res, $Val extends BadgeModel>
|
||||
implements $BadgeModelCopyWith<$Res> {
|
||||
_$BadgeModelCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of BadgeModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? id = null,
|
||||
Object? title = null,
|
||||
Object? description = null,
|
||||
Object? image = null,
|
||||
Object? type = null,
|
||||
Object? parameters = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
id: null == id
|
||||
? _value.id
|
||||
: id // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
title: null == title
|
||||
? _value.title
|
||||
: title // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
description: null == description
|
||||
? _value.description
|
||||
: description // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
image: null == image
|
||||
? _value.image
|
||||
: image // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
type: null == type
|
||||
? _value.type
|
||||
: type // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
parameters: null == parameters
|
||||
? _value.parameters
|
||||
: parameters // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$BadgeModelImplCopyWith<$Res>
|
||||
implements $BadgeModelCopyWith<$Res> {
|
||||
factory _$$BadgeModelImplCopyWith(
|
||||
_$BadgeModelImpl value, $Res Function(_$BadgeModelImpl) then) =
|
||||
__$$BadgeModelImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call(
|
||||
{int id,
|
||||
String title,
|
||||
String description,
|
||||
String image,
|
||||
String type,
|
||||
String parameters});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$BadgeModelImplCopyWithImpl<$Res>
|
||||
extends _$BadgeModelCopyWithImpl<$Res, _$BadgeModelImpl>
|
||||
implements _$$BadgeModelImplCopyWith<$Res> {
|
||||
__$$BadgeModelImplCopyWithImpl(
|
||||
_$BadgeModelImpl _value, $Res Function(_$BadgeModelImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of BadgeModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? id = null,
|
||||
Object? title = null,
|
||||
Object? description = null,
|
||||
Object? image = null,
|
||||
Object? type = null,
|
||||
Object? parameters = null,
|
||||
}) {
|
||||
return _then(_$BadgeModelImpl(
|
||||
id: null == id
|
||||
? _value.id
|
||||
: id // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
title: null == title
|
||||
? _value.title
|
||||
: title // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
description: null == description
|
||||
? _value.description
|
||||
: description // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
image: null == image
|
||||
? _value.image
|
||||
: image // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
type: null == type
|
||||
? _value.type
|
||||
: type // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
parameters: null == parameters
|
||||
? _value.parameters
|
||||
: parameters // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
class _$BadgeModelImpl implements _BadgeModel {
|
||||
const _$BadgeModelImpl(
|
||||
{required this.id,
|
||||
required this.title,
|
||||
required this.description,
|
||||
required this.image,
|
||||
required this.type,
|
||||
required this.parameters});
|
||||
|
||||
factory _$BadgeModelImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$BadgeModelImplFromJson(json);
|
||||
|
||||
@override
|
||||
final int id;
|
||||
@override
|
||||
final String title;
|
||||
@override
|
||||
final String description;
|
||||
@override
|
||||
final String image;
|
||||
@override
|
||||
final String type;
|
||||
@override
|
||||
final String parameters;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'BadgeModel(id: $id, title: $title, description: $description, image: $image, type: $type, parameters: $parameters)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$BadgeModelImpl &&
|
||||
(identical(other.id, id) || other.id == id) &&
|
||||
(identical(other.title, title) || other.title == title) &&
|
||||
(identical(other.description, description) ||
|
||||
other.description == description) &&
|
||||
(identical(other.image, image) || other.image == image) &&
|
||||
(identical(other.type, type) || other.type == type) &&
|
||||
(identical(other.parameters, parameters) ||
|
||||
other.parameters == parameters));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode =>
|
||||
Object.hash(runtimeType, id, title, description, image, type, parameters);
|
||||
|
||||
/// Create a copy of BadgeModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$BadgeModelImplCopyWith<_$BadgeModelImpl> get copyWith =>
|
||||
__$$BadgeModelImplCopyWithImpl<_$BadgeModelImpl>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$$BadgeModelImplToJson(
|
||||
this,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _BadgeModel implements BadgeModel {
|
||||
const factory _BadgeModel(
|
||||
{required final int id,
|
||||
required final String title,
|
||||
required final String description,
|
||||
required final String image,
|
||||
required final String type,
|
||||
required final String parameters}) = _$BadgeModelImpl;
|
||||
|
||||
factory _BadgeModel.fromJson(Map<String, dynamic> json) =
|
||||
_$BadgeModelImpl.fromJson;
|
||||
|
||||
@override
|
||||
int get id;
|
||||
@override
|
||||
String get title;
|
||||
@override
|
||||
String get description;
|
||||
@override
|
||||
String get image;
|
||||
@override
|
||||
String get type;
|
||||
@override
|
||||
String get parameters;
|
||||
|
||||
/// Create a copy of BadgeModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$BadgeModelImplCopyWith<_$BadgeModelImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
27
lib/features/profile/models/badge_model.g.dart
Normal file
27
lib/features/profile/models/badge_model.g.dart
Normal file
@@ -0,0 +1,27 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'badge_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_$BadgeModelImpl _$$BadgeModelImplFromJson(Map<String, dynamic> json) =>
|
||||
_$BadgeModelImpl(
|
||||
id: (json['id'] as num).toInt(),
|
||||
title: json['title'] as String,
|
||||
description: json['description'] as String,
|
||||
image: json['image'] as String,
|
||||
type: json['type'] as String,
|
||||
parameters: json['parameters'] as String,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$BadgeModelImplToJson(_$BadgeModelImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'title': instance.title,
|
||||
'description': instance.description,
|
||||
'image': instance.image,
|
||||
'type': instance.type,
|
||||
'parameters': instance.parameters,
|
||||
};
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:eatvio_app/features/profile/models/badge_model.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'profile_model.freezed.dart';
|
||||
@@ -16,7 +17,10 @@ class ProfileModel with _$ProfileModel {
|
||||
@JsonKey(name: "is_public_profile") required bool isPublicProfile,
|
||||
@JsonKey(name: "slug") required String slug,
|
||||
@JsonKey(name: "profile_photo_url") required String profilePhotoUrl,
|
||||
required String role,
|
||||
@JsonKey(name: "role") required String role,
|
||||
@JsonKey(name: "badges") required List<BadgeModel> badges,
|
||||
@JsonKey(name: "subscriptions") required List<ProfilePreviewModel> subscriptions,
|
||||
@JsonKey(name: "subscribers") required List<ProfilePreviewModel> subscribers,
|
||||
}) = _ProfileModel;
|
||||
|
||||
factory ProfileModel.fromJson(Map<String, dynamic> json) => _$ProfileModelFromJson(json);
|
||||
@@ -56,3 +60,12 @@ class ProfileDetailsModel with _$ProfileDetailsModel {
|
||||
|
||||
factory ProfileDetailsModel.fromJson(Map<String, dynamic> json) => _$ProfileDetailsModelFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class ProfilePreviewModel with _$ProfilePreviewModel {
|
||||
const factory ProfilePreviewModel({
|
||||
@JsonKey(name: "profile_photo_url") required String profilePhotoUrl,
|
||||
}) = _ProfilePreviewModel;
|
||||
|
||||
factory ProfilePreviewModel.fromJson(Map<String, dynamic> json) => _$ProfilePreviewModelFromJson(json);
|
||||
}
|
||||
|
||||
@@ -38,7 +38,16 @@ mixin _$ProfileModel {
|
||||
String get slug => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: "profile_photo_url")
|
||||
String get profilePhotoUrl => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: "role")
|
||||
String get role => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: "badges")
|
||||
List<BadgeModel> get badges => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: "subscriptions")
|
||||
List<ProfilePreviewModel> get subscriptions =>
|
||||
throw _privateConstructorUsedError;
|
||||
@JsonKey(name: "subscribers")
|
||||
List<ProfilePreviewModel> get subscribers =>
|
||||
throw _privateConstructorUsedError;
|
||||
|
||||
/// Serializes this ProfileModel to a JSON map.
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
@@ -66,7 +75,10 @@ abstract class $ProfileModelCopyWith<$Res> {
|
||||
@JsonKey(name: "is_public_profile") bool isPublicProfile,
|
||||
@JsonKey(name: "slug") String slug,
|
||||
@JsonKey(name: "profile_photo_url") String profilePhotoUrl,
|
||||
String role});
|
||||
@JsonKey(name: "role") String role,
|
||||
@JsonKey(name: "badges") List<BadgeModel> badges,
|
||||
@JsonKey(name: "subscriptions") List<ProfilePreviewModel> subscriptions,
|
||||
@JsonKey(name: "subscribers") List<ProfilePreviewModel> subscribers});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@@ -94,6 +106,9 @@ class _$ProfileModelCopyWithImpl<$Res, $Val extends ProfileModel>
|
||||
Object? slug = null,
|
||||
Object? profilePhotoUrl = null,
|
||||
Object? role = null,
|
||||
Object? badges = null,
|
||||
Object? subscriptions = null,
|
||||
Object? subscribers = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
id: null == id
|
||||
@@ -136,6 +151,18 @@ class _$ProfileModelCopyWithImpl<$Res, $Val extends ProfileModel>
|
||||
? _value.role
|
||||
: role // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
badges: null == badges
|
||||
? _value.badges
|
||||
: badges // ignore: cast_nullable_to_non_nullable
|
||||
as List<BadgeModel>,
|
||||
subscriptions: null == subscriptions
|
||||
? _value.subscriptions
|
||||
: subscriptions // ignore: cast_nullable_to_non_nullable
|
||||
as List<ProfilePreviewModel>,
|
||||
subscribers: null == subscribers
|
||||
? _value.subscribers
|
||||
: subscribers // ignore: cast_nullable_to_non_nullable
|
||||
as List<ProfilePreviewModel>,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
@@ -158,7 +185,10 @@ abstract class _$$ProfileModelImplCopyWith<$Res>
|
||||
@JsonKey(name: "is_public_profile") bool isPublicProfile,
|
||||
@JsonKey(name: "slug") String slug,
|
||||
@JsonKey(name: "profile_photo_url") String profilePhotoUrl,
|
||||
String role});
|
||||
@JsonKey(name: "role") String role,
|
||||
@JsonKey(name: "badges") List<BadgeModel> badges,
|
||||
@JsonKey(name: "subscriptions") List<ProfilePreviewModel> subscriptions,
|
||||
@JsonKey(name: "subscribers") List<ProfilePreviewModel> subscribers});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@@ -184,6 +214,9 @@ class __$$ProfileModelImplCopyWithImpl<$Res>
|
||||
Object? slug = null,
|
||||
Object? profilePhotoUrl = null,
|
||||
Object? role = null,
|
||||
Object? badges = null,
|
||||
Object? subscriptions = null,
|
||||
Object? subscribers = null,
|
||||
}) {
|
||||
return _then(_$ProfileModelImpl(
|
||||
id: null == id
|
||||
@@ -226,6 +259,18 @@ class __$$ProfileModelImplCopyWithImpl<$Res>
|
||||
? _value.role
|
||||
: role // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
badges: null == badges
|
||||
? _value._badges
|
||||
: badges // ignore: cast_nullable_to_non_nullable
|
||||
as List<BadgeModel>,
|
||||
subscriptions: null == subscriptions
|
||||
? _value._subscriptions
|
||||
: subscriptions // ignore: cast_nullable_to_non_nullable
|
||||
as List<ProfilePreviewModel>,
|
||||
subscribers: null == subscribers
|
||||
? _value._subscribers
|
||||
: subscribers // ignore: cast_nullable_to_non_nullable
|
||||
as List<ProfilePreviewModel>,
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -243,7 +288,15 @@ class _$ProfileModelImpl implements _ProfileModel {
|
||||
@JsonKey(name: "is_public_profile") required this.isPublicProfile,
|
||||
@JsonKey(name: "slug") required this.slug,
|
||||
@JsonKey(name: "profile_photo_url") required this.profilePhotoUrl,
|
||||
required this.role});
|
||||
@JsonKey(name: "role") required this.role,
|
||||
@JsonKey(name: "badges") required final List<BadgeModel> badges,
|
||||
@JsonKey(name: "subscriptions")
|
||||
required final List<ProfilePreviewModel> subscriptions,
|
||||
@JsonKey(name: "subscribers")
|
||||
required final List<ProfilePreviewModel> subscribers})
|
||||
: _badges = badges,
|
||||
_subscriptions = subscriptions,
|
||||
_subscribers = subscribers;
|
||||
|
||||
factory _$ProfileModelImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$ProfileModelImplFromJson(json);
|
||||
@@ -276,11 +329,38 @@ class _$ProfileModelImpl implements _ProfileModel {
|
||||
@JsonKey(name: "profile_photo_url")
|
||||
final String profilePhotoUrl;
|
||||
@override
|
||||
@JsonKey(name: "role")
|
||||
final String role;
|
||||
final List<BadgeModel> _badges;
|
||||
@override
|
||||
@JsonKey(name: "badges")
|
||||
List<BadgeModel> get badges {
|
||||
if (_badges is EqualUnmodifiableListView) return _badges;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_badges);
|
||||
}
|
||||
|
||||
final List<ProfilePreviewModel> _subscriptions;
|
||||
@override
|
||||
@JsonKey(name: "subscriptions")
|
||||
List<ProfilePreviewModel> get subscriptions {
|
||||
if (_subscriptions is EqualUnmodifiableListView) return _subscriptions;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_subscriptions);
|
||||
}
|
||||
|
||||
final List<ProfilePreviewModel> _subscribers;
|
||||
@override
|
||||
@JsonKey(name: "subscribers")
|
||||
List<ProfilePreviewModel> get subscribers {
|
||||
if (_subscribers is EqualUnmodifiableListView) return _subscribers;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_subscribers);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ProfileModel(id: $id, name: $name, email: $email, emailVerifiedAt: $emailVerifiedAt, createdAt: $createdAt, updatedAt: $updatedAt, isPublicProfile: $isPublicProfile, slug: $slug, profilePhotoUrl: $profilePhotoUrl, role: $role)';
|
||||
return 'ProfileModel(id: $id, name: $name, email: $email, emailVerifiedAt: $emailVerifiedAt, createdAt: $createdAt, updatedAt: $updatedAt, isPublicProfile: $isPublicProfile, slug: $slug, profilePhotoUrl: $profilePhotoUrl, role: $role, badges: $badges, subscriptions: $subscriptions, subscribers: $subscribers)';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -302,13 +382,31 @@ class _$ProfileModelImpl implements _ProfileModel {
|
||||
(identical(other.slug, slug) || other.slug == slug) &&
|
||||
(identical(other.profilePhotoUrl, profilePhotoUrl) ||
|
||||
other.profilePhotoUrl == profilePhotoUrl) &&
|
||||
(identical(other.role, role) || other.role == role));
|
||||
(identical(other.role, role) || other.role == role) &&
|
||||
const DeepCollectionEquality().equals(other._badges, _badges) &&
|
||||
const DeepCollectionEquality()
|
||||
.equals(other._subscriptions, _subscriptions) &&
|
||||
const DeepCollectionEquality()
|
||||
.equals(other._subscribers, _subscribers));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, id, name, email, emailVerifiedAt,
|
||||
createdAt, updatedAt, isPublicProfile, slug, profilePhotoUrl, role);
|
||||
int get hashCode => Object.hash(
|
||||
runtimeType,
|
||||
id,
|
||||
name,
|
||||
email,
|
||||
emailVerifiedAt,
|
||||
createdAt,
|
||||
updatedAt,
|
||||
isPublicProfile,
|
||||
slug,
|
||||
profilePhotoUrl,
|
||||
role,
|
||||
const DeepCollectionEquality().hash(_badges),
|
||||
const DeepCollectionEquality().hash(_subscriptions),
|
||||
const DeepCollectionEquality().hash(_subscribers));
|
||||
|
||||
/// Create a copy of ProfileModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@@ -337,7 +435,13 @@ abstract class _ProfileModel implements ProfileModel {
|
||||
@JsonKey(name: "is_public_profile") required final bool isPublicProfile,
|
||||
@JsonKey(name: "slug") required final String slug,
|
||||
@JsonKey(name: "profile_photo_url") required final String profilePhotoUrl,
|
||||
required final String role}) = _$ProfileModelImpl;
|
||||
@JsonKey(name: "role") required final String role,
|
||||
@JsonKey(name: "badges") required final List<BadgeModel> badges,
|
||||
@JsonKey(name: "subscriptions")
|
||||
required final List<ProfilePreviewModel> subscriptions,
|
||||
@JsonKey(name: "subscribers")
|
||||
required final List<ProfilePreviewModel>
|
||||
subscribers}) = _$ProfileModelImpl;
|
||||
|
||||
factory _ProfileModel.fromJson(Map<String, dynamic> json) =
|
||||
_$ProfileModelImpl.fromJson;
|
||||
@@ -370,7 +474,17 @@ abstract class _ProfileModel implements ProfileModel {
|
||||
@JsonKey(name: "profile_photo_url")
|
||||
String get profilePhotoUrl;
|
||||
@override
|
||||
@JsonKey(name: "role")
|
||||
String get role;
|
||||
@override
|
||||
@JsonKey(name: "badges")
|
||||
List<BadgeModel> get badges;
|
||||
@override
|
||||
@JsonKey(name: "subscriptions")
|
||||
List<ProfilePreviewModel> get subscriptions;
|
||||
@override
|
||||
@JsonKey(name: "subscribers")
|
||||
List<ProfilePreviewModel> get subscribers;
|
||||
|
||||
/// Create a copy of ProfileModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@@ -1190,3 +1304,160 @@ abstract class _ProfileDetailsModel implements ProfileDetailsModel {
|
||||
_$$ProfileDetailsModelImplCopyWith<_$ProfileDetailsModelImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
ProfilePreviewModel _$ProfilePreviewModelFromJson(Map<String, dynamic> json) {
|
||||
return _ProfilePreviewModel.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$ProfilePreviewModel {
|
||||
@JsonKey(name: "profile_photo_url")
|
||||
String get profilePhotoUrl => throw _privateConstructorUsedError;
|
||||
|
||||
/// Serializes this ProfilePreviewModel to a JSON map.
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
|
||||
/// Create a copy of ProfilePreviewModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$ProfilePreviewModelCopyWith<ProfilePreviewModel> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $ProfilePreviewModelCopyWith<$Res> {
|
||||
factory $ProfilePreviewModelCopyWith(
|
||||
ProfilePreviewModel value, $Res Function(ProfilePreviewModel) then) =
|
||||
_$ProfilePreviewModelCopyWithImpl<$Res, ProfilePreviewModel>;
|
||||
@useResult
|
||||
$Res call({@JsonKey(name: "profile_photo_url") String profilePhotoUrl});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$ProfilePreviewModelCopyWithImpl<$Res, $Val extends ProfilePreviewModel>
|
||||
implements $ProfilePreviewModelCopyWith<$Res> {
|
||||
_$ProfilePreviewModelCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of ProfilePreviewModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? profilePhotoUrl = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
profilePhotoUrl: null == profilePhotoUrl
|
||||
? _value.profilePhotoUrl
|
||||
: profilePhotoUrl // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$ProfilePreviewModelImplCopyWith<$Res>
|
||||
implements $ProfilePreviewModelCopyWith<$Res> {
|
||||
factory _$$ProfilePreviewModelImplCopyWith(_$ProfilePreviewModelImpl value,
|
||||
$Res Function(_$ProfilePreviewModelImpl) then) =
|
||||
__$$ProfilePreviewModelImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({@JsonKey(name: "profile_photo_url") String profilePhotoUrl});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$ProfilePreviewModelImplCopyWithImpl<$Res>
|
||||
extends _$ProfilePreviewModelCopyWithImpl<$Res, _$ProfilePreviewModelImpl>
|
||||
implements _$$ProfilePreviewModelImplCopyWith<$Res> {
|
||||
__$$ProfilePreviewModelImplCopyWithImpl(_$ProfilePreviewModelImpl _value,
|
||||
$Res Function(_$ProfilePreviewModelImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of ProfilePreviewModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? profilePhotoUrl = null,
|
||||
}) {
|
||||
return _then(_$ProfilePreviewModelImpl(
|
||||
profilePhotoUrl: null == profilePhotoUrl
|
||||
? _value.profilePhotoUrl
|
||||
: profilePhotoUrl // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
class _$ProfilePreviewModelImpl implements _ProfilePreviewModel {
|
||||
const _$ProfilePreviewModelImpl(
|
||||
{@JsonKey(name: "profile_photo_url") required this.profilePhotoUrl});
|
||||
|
||||
factory _$ProfilePreviewModelImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$ProfilePreviewModelImplFromJson(json);
|
||||
|
||||
@override
|
||||
@JsonKey(name: "profile_photo_url")
|
||||
final String profilePhotoUrl;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ProfilePreviewModel(profilePhotoUrl: $profilePhotoUrl)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$ProfilePreviewModelImpl &&
|
||||
(identical(other.profilePhotoUrl, profilePhotoUrl) ||
|
||||
other.profilePhotoUrl == profilePhotoUrl));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, profilePhotoUrl);
|
||||
|
||||
/// Create a copy of ProfilePreviewModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$ProfilePreviewModelImplCopyWith<_$ProfilePreviewModelImpl> get copyWith =>
|
||||
__$$ProfilePreviewModelImplCopyWithImpl<_$ProfilePreviewModelImpl>(
|
||||
this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$$ProfilePreviewModelImplToJson(
|
||||
this,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _ProfilePreviewModel implements ProfilePreviewModel {
|
||||
const factory _ProfilePreviewModel(
|
||||
{@JsonKey(name: "profile_photo_url")
|
||||
required final String profilePhotoUrl}) = _$ProfilePreviewModelImpl;
|
||||
|
||||
factory _ProfilePreviewModel.fromJson(Map<String, dynamic> json) =
|
||||
_$ProfilePreviewModelImpl.fromJson;
|
||||
|
||||
@override
|
||||
@JsonKey(name: "profile_photo_url")
|
||||
String get profilePhotoUrl;
|
||||
|
||||
/// Create a copy of ProfilePreviewModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$ProfilePreviewModelImplCopyWith<_$ProfilePreviewModelImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,15 @@ _$ProfileModelImpl _$$ProfileModelImplFromJson(Map<String, dynamic> json) =>
|
||||
slug: json['slug'] as String,
|
||||
profilePhotoUrl: json['profile_photo_url'] as String,
|
||||
role: json['role'] as String,
|
||||
badges: (json['badges'] as List<dynamic>)
|
||||
.map((e) => BadgeModel.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
subscriptions: (json['subscriptions'] as List<dynamic>)
|
||||
.map((e) => ProfilePreviewModel.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
subscribers: (json['subscribers'] as List<dynamic>)
|
||||
.map((e) => ProfilePreviewModel.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$ProfileModelImplToJson(_$ProfileModelImpl instance) =>
|
||||
@@ -38,6 +47,9 @@ Map<String, dynamic> _$$ProfileModelImplToJson(_$ProfileModelImpl instance) =>
|
||||
'slug': instance.slug,
|
||||
'profile_photo_url': instance.profilePhotoUrl,
|
||||
'role': instance.role,
|
||||
'badges': instance.badges,
|
||||
'subscriptions': instance.subscriptions,
|
||||
'subscribers': instance.subscribers,
|
||||
};
|
||||
|
||||
_$ProfileDetailsModelImpl _$$ProfileDetailsModelImplFromJson(
|
||||
@@ -107,3 +119,15 @@ Map<String, dynamic> _$$ProfileDetailsModelImplToJson(
|
||||
'is_bedtime_fillable': instance.isBedtimeFillable,
|
||||
'activity_coefficient': instance.activityCoefficient,
|
||||
};
|
||||
|
||||
_$ProfilePreviewModelImpl _$$ProfilePreviewModelImplFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$ProfilePreviewModelImpl(
|
||||
profilePhotoUrl: json['profile_photo_url'] as String,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$ProfilePreviewModelImplToJson(
|
||||
_$ProfilePreviewModelImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'profile_photo_url': instance.profilePhotoUrl,
|
||||
};
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import 'package:eatvio_app/features/chat/repositories/chat_repository.dart';
|
||||
import 'package:eatvio_app/features/profile/presentation/bloc/profile_cubit/profile_state.dart';
|
||||
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class ProfileCubit extends Cubit<ProfileState> {
|
||||
final ProfileRepository profileRepository;
|
||||
final ChatRepository chatRepository;
|
||||
String _currentPeriod = '1';
|
||||
|
||||
ProfileCubit({
|
||||
required this.profileRepository,
|
||||
required this.chatRepository,
|
||||
}) : super(const ProfileState.loading());
|
||||
|
||||
getProfileBySlug(String slug) async {
|
||||
@@ -71,4 +74,15 @@ class ProfileCubit extends Cubit<ProfileState> {
|
||||
print(e);
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> getChatRoomIdBySlug({
|
||||
required String slug,
|
||||
}) async {
|
||||
try {
|
||||
return (await chatRepository.getChatRoomIdByUserSlug(slug: slug)).id;
|
||||
} catch (e) {
|
||||
print(e);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,10 @@ import 'package:rive/rive.dart';
|
||||
class ProfileScreen extends StatefulWidget {
|
||||
final Author? author;
|
||||
|
||||
const ProfileScreen({super.key, this.author});
|
||||
const ProfileScreen({
|
||||
super.key,
|
||||
this.author,
|
||||
});
|
||||
|
||||
@override
|
||||
State<ProfileScreen> createState() => _ProfileScreenState();
|
||||
@@ -49,254 +52,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
circumferencePoints = state.circumferencePoints!;
|
||||
weightPoints = state.weightPoints!;
|
||||
}
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.grey.shade200,
|
||||
appBar: widget.author == null ? AppBar(toolbarHeight: 0) : AppBar(),
|
||||
body: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.vertical(
|
||||
bottom: Radius.circular(16),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Row(
|
||||
children: [
|
||||
CircleAvatar(
|
||||
radius: 32,
|
||||
backgroundImage: NetworkImage(state.profile.profilePhotoUrl),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
state.profile.name,
|
||||
style: TextStyle(
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w500,
|
||||
height: 1,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.info_outline,
|
||||
size: 20,
|
||||
color: Color(0xFF6D6F71),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
'Дополнительно',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF6D6F71),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
const Spacer(),
|
||||
IconButton(
|
||||
onPressed: () {},
|
||||
icon: Icon(Icons.more_horiz_rounded),
|
||||
),
|
||||
// Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.end,
|
||||
// crossAxisAlignment: CrossAxisAlignment.center,
|
||||
// children: [
|
||||
// Container(
|
||||
// child: SvgPicture.asset(
|
||||
// height: 28,
|
||||
// width: 28,
|
||||
// 'assets/icons/subscribers.svg',
|
||||
// colorFilter: ColorFilter.mode(appTheme.blueA400, BlendMode.srcIn),
|
||||
// ),
|
||||
// ),
|
||||
// SizedBox(width: 8),
|
||||
// Column(
|
||||
// children: [
|
||||
// Text(
|
||||
// '123',
|
||||
// style: TextStyle(
|
||||
// height: 1,
|
||||
// fontSize: 18,
|
||||
// fontWeight: FontWeight.w500,
|
||||
// color: Colors.black87,
|
||||
// ),
|
||||
// ),
|
||||
// Text(
|
||||
// 'Подписчика',
|
||||
// style: TextStyle(
|
||||
// height: 1,
|
||||
// fontSize: 12,
|
||||
// fontWeight: FontWeight.w400,
|
||||
// color: Colors.black38,
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// GestureDetector(
|
||||
// onTap: () => Share.shareUri(
|
||||
// Uri.parse(
|
||||
// baseUrl + '/ru/profile/' + state.profile.slug,
|
||||
// ),
|
||||
// ),
|
||||
// child: Container(
|
||||
// padding: EdgeInsets.only(left: 16),
|
||||
// child: SvgPicture.asset(
|
||||
// height: 24,
|
||||
// width: 24,
|
||||
// 'assets/icons/share.svg',
|
||||
// colorFilter: ColorFilter.mode(appTheme.blueA400, BlendMode.srcIn),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (state.profileDetails.additionalInfo.isNotEmpty)
|
||||
Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Text(
|
||||
state.profileDetails.additionalInfo,
|
||||
style: TextStyle(
|
||||
color: Colors.black.withOpacity(0.4),
|
||||
height: 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (widget.author != null) const SizedBox(height: 8),
|
||||
if (widget.author != null)
|
||||
Row(
|
||||
children: [
|
||||
SizedBox(width: 16),
|
||||
GestureDetector(
|
||||
onTap: () => GoRouter.of(context).pushNamed(
|
||||
'chatScreen',
|
||||
),
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
padding: EdgeInsets.all(8),
|
||||
width: (MediaQuery.of(context).size.width - 40) / 2,
|
||||
decoration: BoxDecoration(
|
||||
color: appTheme.blueA400.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
child: Text(
|
||||
'Сообщение',
|
||||
style: TextStyle(
|
||||
color: appTheme.blueA400,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Container(
|
||||
alignment: Alignment.center,
|
||||
padding: EdgeInsets.all(8),
|
||||
width: (MediaQuery.of(context).size.width - 40) / 2,
|
||||
decoration: BoxDecoration(
|
||||
color: appTheme.blueA400,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
child: Text(
|
||||
'Подписаться',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 16),
|
||||
],
|
||||
),
|
||||
if (widget.author != null) SizedBox(height: 16),
|
||||
if (widget.author == null) _divider(context),
|
||||
if (widget.author == null)
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 8),
|
||||
SingleChildScrollView(
|
||||
padding: EdgeInsets.symmetric(horizontal: 16),
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
children: [
|
||||
_choiceChipWidget(0),
|
||||
SizedBox(width: 8),
|
||||
_choiceChipWidget(1),
|
||||
SizedBox(width: 8),
|
||||
_choiceChipWidget(2),
|
||||
],
|
||||
),
|
||||
),
|
||||
Builder(
|
||||
builder: (context) {
|
||||
switch (_selectedChipIndex) {
|
||||
case 0:
|
||||
return WeightChartWidget(
|
||||
weightPoints: weightPoints,
|
||||
profileCubit: profileCubit,
|
||||
);
|
||||
case 1:
|
||||
return CircumferenceChartWidget(
|
||||
circumferencePoints: circumferencePoints,
|
||||
profileCubit: profileCubit,
|
||||
);
|
||||
case 2:
|
||||
return ImtChartWidget(
|
||||
weightPoints: weightPoints,
|
||||
);
|
||||
}
|
||||
return SizedBox.shrink();
|
||||
},
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
Row(
|
||||
children: [
|
||||
SizedBox(width: 16),
|
||||
_choiceIntervalChipWidget(0),
|
||||
SizedBox(width: 8),
|
||||
_choiceIntervalChipWidget(1),
|
||||
SizedBox(width: 8),
|
||||
_choiceIntervalChipWidget(2),
|
||||
SizedBox(width: 8),
|
||||
_choiceIntervalChipWidget(3),
|
||||
SizedBox(width: 8),
|
||||
_choiceIntervalChipWidget(4),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
ListView.separated(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemBuilder: (context, index) => BlogPostWidget(feedBlogPostModel: state.blogPosts[index]),
|
||||
separatorBuilder: (context, index) => SizedBox(height: 8),
|
||||
itemCount: state.blogPosts.length,
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
return _profileScreen(state);
|
||||
} else if (state is ProfileStateError) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(),
|
||||
@@ -325,13 +81,388 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
_divider(BuildContext context) {
|
||||
_profileScreen(ProfileStateLoaded state) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.grey.shade200,
|
||||
appBar: widget.author == null ? AppBar(toolbarHeight: 0) : AppBar(),
|
||||
body: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.vertical(
|
||||
bottom: Radius.circular(16),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
_header(state),
|
||||
if (state.profileDetails.additionalInfo.isNotEmpty) _additionalInfo(state),
|
||||
if (widget.author != null) const SizedBox(height: 8),
|
||||
if (widget.author != null) _messageAndSubscribe(),
|
||||
if (widget.author != null) SizedBox(height: 16),
|
||||
],
|
||||
),
|
||||
),
|
||||
_subscriptionsAndSubscribers(state),
|
||||
_badges(state),
|
||||
if (widget.author == null) SizedBox(height: 16),
|
||||
if (widget.author == null) _charts(),
|
||||
_blogPosts(state),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_badges(ProfileStateLoaded state) {
|
||||
if (state.profile.badges.isEmpty) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4),
|
||||
child: InkWell(
|
||||
onTap: () {},
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: Ink(
|
||||
padding: const EdgeInsets.all(8),
|
||||
width: MediaQuery.of(context).size.width,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Достижения',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF6D6F71),
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
children: [
|
||||
// CircleAvatar(
|
||||
// backgroundImage: NetworkImage(
|
||||
// state.profile.badges.first.image,
|
||||
// ),
|
||||
// radius: 20,
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_subscriptionsAndSubscribers(ProfileStateLoaded state) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(4),
|
||||
child: Row(
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () {},
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: Ink(
|
||||
padding: const EdgeInsets.all(8),
|
||||
width: MediaQuery.of(context).size.width / 2 - 6,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Подписки',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF6D6F71),
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'${state.profile.subscriptions.length}',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF323F4B),
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(right: 8),
|
||||
child: _miniAvatars(state.profile.subscriptions.map((e) => e.profilePhotoUrl).toList()),
|
||||
),
|
||||
],
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 4),
|
||||
InkWell(
|
||||
onTap: () {},
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: Ink(
|
||||
padding: const EdgeInsets.all(8),
|
||||
width: MediaQuery.of(context).size.width / 2 - 6,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Подписчики',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF6D6F71),
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'${state.profile.subscribers.length}',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF323F4B),
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(right: 8),
|
||||
child: _miniAvatars(state.profile.subscribers.map((e) => e.profilePhotoUrl).toList()),
|
||||
),
|
||||
],
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_miniAvatars(List<String> urls) {
|
||||
int maxLength = urls.length > 2 ? 3 : urls.length;
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
for (int i = 0; i < maxLength; i++)
|
||||
Align(
|
||||
widthFactor: 0.8,
|
||||
child: CircleAvatar(
|
||||
radius: 14,
|
||||
backgroundImage: NetworkImage(
|
||||
urls[i],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
_blogPosts(ProfileStateLoaded state) {
|
||||
return ListView.separated(
|
||||
padding: EdgeInsets.symmetric(vertical: 16),
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemBuilder: (context, index) => BlogPostWidget(feedBlogPostModel: state.blogPosts[index]),
|
||||
separatorBuilder: (context, index) => SizedBox(height: 8),
|
||||
itemCount: state.blogPosts.length,
|
||||
);
|
||||
}
|
||||
|
||||
_additionalInfo(ProfileStateLoaded state) {
|
||||
return Container(
|
||||
height: 0.4,
|
||||
width: MediaQuery.of(context).size.width - 32,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black26,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
alignment: Alignment.centerLeft,
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Text(
|
||||
state.profileDetails.additionalInfo,
|
||||
style: TextStyle(
|
||||
color: Colors.black.withOpacity(0.4),
|
||||
height: 1,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_header(ProfileStateLoaded state) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Row(
|
||||
children: [
|
||||
CircleAvatar(
|
||||
radius: 32,
|
||||
backgroundImage: NetworkImage(state.profile.profilePhotoUrl),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
state.profile.name,
|
||||
style: TextStyle(
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w500,
|
||||
height: 1,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.info_outline,
|
||||
size: 20,
|
||||
color: Color(0xFF6D6F71),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
'Дополнительно',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF6D6F71),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
const Spacer(),
|
||||
IconButton(
|
||||
onPressed: () {},
|
||||
icon: Icon(Icons.more_horiz_rounded),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_messageAndSubscribe() {
|
||||
return Row(
|
||||
children: [
|
||||
SizedBox(width: 16),
|
||||
GestureDetector(
|
||||
onTap: () async {
|
||||
GoRouter.of(context).pushNamed(
|
||||
'chatScreen',
|
||||
extra: await profileCubit.getChatRoomIdBySlug(slug: widget.author!.authorSlug),
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
padding: EdgeInsets.all(8),
|
||||
width: (MediaQuery.of(context).size.width - 40) / 2,
|
||||
decoration: BoxDecoration(
|
||||
color: appTheme.blueA400.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
child: Text(
|
||||
'Сообщение',
|
||||
style: TextStyle(
|
||||
color: appTheme.blueA400,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Container(
|
||||
alignment: Alignment.center,
|
||||
padding: EdgeInsets.all(8),
|
||||
width: (MediaQuery.of(context).size.width - 40) / 2,
|
||||
decoration: BoxDecoration(
|
||||
color: appTheme.blueA400,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
child: Text(
|
||||
'Подписаться',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 16),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
_charts() {
|
||||
return Material(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 8),
|
||||
SingleChildScrollView(
|
||||
padding: EdgeInsets.symmetric(horizontal: 16),
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
children: [
|
||||
_choiceChipWidget(0),
|
||||
SizedBox(width: 8),
|
||||
_choiceChipWidget(1),
|
||||
SizedBox(width: 8),
|
||||
_choiceChipWidget(2),
|
||||
],
|
||||
),
|
||||
),
|
||||
Builder(
|
||||
builder: (context) {
|
||||
switch (_selectedChipIndex) {
|
||||
case 0:
|
||||
return WeightChartWidget(
|
||||
weightPoints: weightPoints,
|
||||
profileCubit: profileCubit,
|
||||
);
|
||||
case 1:
|
||||
return CircumferenceChartWidget(
|
||||
circumferencePoints: circumferencePoints,
|
||||
profileCubit: profileCubit,
|
||||
);
|
||||
case 2:
|
||||
return ImtChartWidget(
|
||||
weightPoints: weightPoints,
|
||||
);
|
||||
}
|
||||
return SizedBox.shrink();
|
||||
},
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
Row(
|
||||
children: [
|
||||
SizedBox(width: 16),
|
||||
_choiceIntervalChipWidget(0),
|
||||
SizedBox(width: 8),
|
||||
_choiceIntervalChipWidget(1),
|
||||
SizedBox(width: 8),
|
||||
_choiceIntervalChipWidget(2),
|
||||
SizedBox(width: 8),
|
||||
_choiceIntervalChipWidget(3),
|
||||
SizedBox(width: 8),
|
||||
_choiceIntervalChipWidget(4),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ Future<void> init() async {
|
||||
sl.registerFactory<RecipesCubit>(() => RecipesCubit(feedRepository: sl(), recipeRepository: sl()));
|
||||
sl.registerFactory<DiaryBloc>(() => DiaryBloc(diaryRepository: sl()));
|
||||
sl.registerFactory<CalendarCubit>(() => CalendarCubit(calendarRepository: sl()));
|
||||
sl.registerFactory<ProfileCubit>(() => ProfileCubit(profileRepository: sl()));
|
||||
sl.registerFactory<ProfileCubit>(() => ProfileCubit(profileRepository: sl(), chatRepository: sl()));
|
||||
sl.registerFactory<ProfileAvatarCubit>(() => ProfileAvatarCubit(profileRepository: sl()));
|
||||
sl.registerFactory<RecipeCreateCubit>(() => RecipeCreateCubit(recipeRepository: sl()));
|
||||
sl.registerFactory<DietsCubit>(() => DietsCubit(feedRepository: sl()));
|
||||
|
||||
Reference in New Issue
Block a user