From 8349778e48aa331b983a0ba669c96e644bbbd390 Mon Sep 17 00:00:00 2001 From: mso7nueh Date: Wed, 21 Aug 2024 16:24:53 +0300 Subject: [PATCH] feat(chat, feed): add images, chat search, likes reply to comment --- .DS_Store | Bin 6148 -> 8196 bytes lib/app_router.dart | 2 +- .../presentation/pages/blog_post_screen.dart | 4 +- .../chat/models/chat_room_preview_model.dart | 62 + .../chat_room_preview_model.freezed.dart | 1108 +++++++++++++++++ .../models/chat_room_preview_model.g.dart | 90 ++ .../chat_select_cubit/chat_select_cubit.dart | 24 + .../chat_select_cubit/chat_select_state.dart | 19 + .../chat_select_state.freezed.dart | 623 +++++++++ .../pages/chat_select_screen.dart | 111 ++ .../bloc/chat_select_bloc.dart | 100 -- .../bloc/chat_select_event.dart | 28 - .../bloc/chat_select_state.dart | 61 - .../chat_select_screen.dart | 103 -- .../chat_select_screen/models/chat_entry.dart | 26 - .../models/chat_select_model.dart | 22 - .../widgets/chat_entry_widget.dart | 96 -- .../widgets/chat_entry_widget.dart | 116 ++ .../chat_search_bar_widget.dart} | 4 +- .../chat/repositories/chat_repository.dart | 10 + lib/features/chat/services/chat_service.dart | 6 + .../chat/services/chat_service.g.dart | 34 + lib/locator_service.dart | 2 + lib/main.dart | 7 +- 24 files changed, 2213 insertions(+), 445 deletions(-) create mode 100644 lib/features/chat/models/chat_room_preview_model.dart create mode 100644 lib/features/chat/models/chat_room_preview_model.freezed.dart create mode 100644 lib/features/chat/models/chat_room_preview_model.g.dart create mode 100644 lib/features/chat/presentation/bloc/chat_select_cubit/chat_select_cubit.dart create mode 100644 lib/features/chat/presentation/bloc/chat_select_cubit/chat_select_state.dart create mode 100644 lib/features/chat/presentation/bloc/chat_select_cubit/chat_select_state.freezed.dart create mode 100644 lib/features/chat/presentation/pages/chat_select_screen.dart delete mode 100644 lib/features/chat/presentation/pages/chat_select_screen/bloc/chat_select_bloc.dart delete mode 100644 lib/features/chat/presentation/pages/chat_select_screen/bloc/chat_select_event.dart delete mode 100644 lib/features/chat/presentation/pages/chat_select_screen/bloc/chat_select_state.dart delete mode 100644 lib/features/chat/presentation/pages/chat_select_screen/chat_select_screen.dart delete mode 100644 lib/features/chat/presentation/pages/chat_select_screen/models/chat_entry.dart delete mode 100644 lib/features/chat/presentation/pages/chat_select_screen/models/chat_select_model.dart delete mode 100644 lib/features/chat/presentation/pages/chat_select_screen/widgets/chat_entry_widget.dart create mode 100644 lib/features/chat/presentation/widgets/chat_entry_widget.dart rename lib/features/chat/presentation/{pages/chat_select_screen/chat_search_view.dart => widgets/chat_search_bar_widget.dart} (97%) diff --git a/.DS_Store b/.DS_Store index 017f6122a1c39393f4632e375b97f19d52e245e6..3d1c443933065e96a8a7ab8d541eedb9273ad506 100644 GIT binary patch delta 396 zcmZoMXmOBWU|?W$DortDU;r^WfEYvza8E20o2aMAD7-OXH}hr%jz7$c**Q2SHn1=X zZ{}gqWi;etNMp!hC}k)C!c>MLhIj@8215otpjbXbx@S&)a#Buy638T=`LaM-Z?Yb1 z_~dw2_WGpq;sU7Tj--N|%;FLQgKLaT%q*;I>>TVI+#IpN8TsYGC5a`a#ZHMu(I8$( zetu38jGdSimYG@}FCgNapI4HYnU`7w){vQ!3RDsko|%`DU+$D&nwL@x)*B3w;Naxo zj2Dooj;=N`v(Qm6GBm2yQK+^wGSE>lF*d8M<>U}m*0&Cd&(6us%kKiZ7zh{{Av6Oo zl!j5=Kn63=ubB) { return Scaffold( resizeToAvoidBottomInset: true, bottomSheet: Container( - padding: EdgeInsets.symmetric(vertical: 12), + padding: EdgeInsets.symmetric(vertical: 12) + (Platform.isIOS ? const EdgeInsets.only(bottom: 16) : EdgeInsets.zero), decoration: BoxDecoration( color: Colors.white, border: Border( diff --git a/lib/features/chat/models/chat_room_preview_model.dart b/lib/features/chat/models/chat_room_preview_model.dart new file mode 100644 index 00000000..29c5e3ac --- /dev/null +++ b/lib/features/chat/models/chat_room_preview_model.dart @@ -0,0 +1,62 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'chat_room_preview_model.freezed.dart'; +part 'chat_room_preview_model.g.dart'; + +@freezed +class ChatRoomPreviewModel with _$ChatRoomPreviewModel { + const factory ChatRoomPreviewModel({ + @JsonKey(name: "chatRooms") required List chatRooms, + }) = _ChatRoomPreviewModel; + + factory ChatRoomPreviewModel.fromJson(Map json) => _$ChatRoomPreviewModelFromJson(json); +} + +@freezed +class ChatRoom with _$ChatRoom { + const factory ChatRoom({ + @JsonKey(name: "id") required String id, + @JsonKey(name: "room_name") required String roomName, + @JsonKey(name: "last_message") required dynamic lastMessage, + @JsonKey(name: "users") required Users users, + }) = _ChatRoom; + + factory ChatRoom.fromJson(Map json) => _$ChatRoomFromJson(json); +} + +@freezed +class LastMessageClass with _$LastMessageClass { + const factory LastMessageClass({ + @JsonKey(name: "id") required int id, + @JsonKey(name: "data") required String data, + @JsonKey(name: "media_data") required List mediaData, + @JsonKey(name: "author_id") required int authorId, + @JsonKey(name: "is_author_message_auth_user") required bool isAuthorMessageAuthUser, + @JsonKey(name: "read_by_to_user") required bool readByToUser, + @JsonKey(name: "updated_at") required DateTime updatedAt, + }) = _LastMessageClass; + + factory LastMessageClass.fromJson(Map json) => _$LastMessageClassFromJson(json); +} + +@freezed +class Users with _$Users { + const factory Users({ + @JsonKey(name: "from_chat_user") required ChatUser fromChatUser, + @JsonKey(name: "to_chat_user") required ChatUser toChatUser, + }) = _Users; + + factory Users.fromJson(Map json) => _$UsersFromJson(json); +} + +@freezed +class ChatUser with _$ChatUser { + const factory ChatUser({ + @JsonKey(name: "id") required int id, + @JsonKey(name: "name") required String name, + @JsonKey(name: "profile_photo_path") required String? profilePhotoPath, + @JsonKey(name: "profile_photo_url") required String profilePhotoUrl, + }) = _ChatUser; + + factory ChatUser.fromJson(Map json) => _$ChatUserFromJson(json); +} diff --git a/lib/features/chat/models/chat_room_preview_model.freezed.dart b/lib/features/chat/models/chat_room_preview_model.freezed.dart new file mode 100644 index 00000000..8d41bd4b --- /dev/null +++ b/lib/features/chat/models/chat_room_preview_model.freezed.dart @@ -0,0 +1,1108 @@ +// 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 'chat_room_preview_model.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(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'); + +ChatRoomPreviewModel _$ChatRoomPreviewModelFromJson(Map json) { + return _ChatRoomPreviewModel.fromJson(json); +} + +/// @nodoc +mixin _$ChatRoomPreviewModel { + @JsonKey(name: "chatRooms") + List get chatRooms => throw _privateConstructorUsedError; + + Map toJson() => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + $ChatRoomPreviewModelCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $ChatRoomPreviewModelCopyWith<$Res> { + factory $ChatRoomPreviewModelCopyWith(ChatRoomPreviewModel value, + $Res Function(ChatRoomPreviewModel) then) = + _$ChatRoomPreviewModelCopyWithImpl<$Res, ChatRoomPreviewModel>; + @useResult + $Res call({@JsonKey(name: "chatRooms") List chatRooms}); +} + +/// @nodoc +class _$ChatRoomPreviewModelCopyWithImpl<$Res, + $Val extends ChatRoomPreviewModel> + implements $ChatRoomPreviewModelCopyWith<$Res> { + _$ChatRoomPreviewModelCopyWithImpl(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? chatRooms = null, + }) { + return _then(_value.copyWith( + chatRooms: null == chatRooms + ? _value.chatRooms + : chatRooms // ignore: cast_nullable_to_non_nullable + as List, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$ChatRoomPreviewModelImplCopyWith<$Res> + implements $ChatRoomPreviewModelCopyWith<$Res> { + factory _$$ChatRoomPreviewModelImplCopyWith(_$ChatRoomPreviewModelImpl value, + $Res Function(_$ChatRoomPreviewModelImpl) then) = + __$$ChatRoomPreviewModelImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({@JsonKey(name: "chatRooms") List chatRooms}); +} + +/// @nodoc +class __$$ChatRoomPreviewModelImplCopyWithImpl<$Res> + extends _$ChatRoomPreviewModelCopyWithImpl<$Res, _$ChatRoomPreviewModelImpl> + implements _$$ChatRoomPreviewModelImplCopyWith<$Res> { + __$$ChatRoomPreviewModelImplCopyWithImpl(_$ChatRoomPreviewModelImpl _value, + $Res Function(_$ChatRoomPreviewModelImpl) _then) + : super(_value, _then); + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? chatRooms = null, + }) { + return _then(_$ChatRoomPreviewModelImpl( + chatRooms: null == chatRooms + ? _value._chatRooms + : chatRooms // ignore: cast_nullable_to_non_nullable + as List, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$ChatRoomPreviewModelImpl implements _ChatRoomPreviewModel { + const _$ChatRoomPreviewModelImpl( + {@JsonKey(name: "chatRooms") required final List chatRooms}) + : _chatRooms = chatRooms; + + factory _$ChatRoomPreviewModelImpl.fromJson(Map json) => + _$$ChatRoomPreviewModelImplFromJson(json); + + final List _chatRooms; + @override + @JsonKey(name: "chatRooms") + List get chatRooms { + if (_chatRooms is EqualUnmodifiableListView) return _chatRooms; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_chatRooms); + } + + @override + String toString() { + return 'ChatRoomPreviewModel(chatRooms: $chatRooms)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ChatRoomPreviewModelImpl && + const DeepCollectionEquality() + .equals(other._chatRooms, _chatRooms)); + } + + @JsonKey(ignore: true) + @override + int get hashCode => + Object.hash(runtimeType, const DeepCollectionEquality().hash(_chatRooms)); + + @JsonKey(ignore: true) + @override + @pragma('vm:prefer-inline') + _$$ChatRoomPreviewModelImplCopyWith<_$ChatRoomPreviewModelImpl> + get copyWith => + __$$ChatRoomPreviewModelImplCopyWithImpl<_$ChatRoomPreviewModelImpl>( + this, _$identity); + + @override + Map toJson() { + return _$$ChatRoomPreviewModelImplToJson( + this, + ); + } +} + +abstract class _ChatRoomPreviewModel implements ChatRoomPreviewModel { + const factory _ChatRoomPreviewModel( + {@JsonKey(name: "chatRooms") + required final List chatRooms}) = _$ChatRoomPreviewModelImpl; + + factory _ChatRoomPreviewModel.fromJson(Map json) = + _$ChatRoomPreviewModelImpl.fromJson; + + @override + @JsonKey(name: "chatRooms") + List get chatRooms; + @override + @JsonKey(ignore: true) + _$$ChatRoomPreviewModelImplCopyWith<_$ChatRoomPreviewModelImpl> + get copyWith => throw _privateConstructorUsedError; +} + +ChatRoom _$ChatRoomFromJson(Map json) { + return _ChatRoom.fromJson(json); +} + +/// @nodoc +mixin _$ChatRoom { + @JsonKey(name: "id") + String get id => throw _privateConstructorUsedError; + @JsonKey(name: "room_name") + String get roomName => throw _privateConstructorUsedError; + @JsonKey(name: "last_message") + dynamic get lastMessage => throw _privateConstructorUsedError; + @JsonKey(name: "users") + Users get users => throw _privateConstructorUsedError; + + Map toJson() => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + $ChatRoomCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $ChatRoomCopyWith<$Res> { + factory $ChatRoomCopyWith(ChatRoom value, $Res Function(ChatRoom) then) = + _$ChatRoomCopyWithImpl<$Res, ChatRoom>; + @useResult + $Res call( + {@JsonKey(name: "id") String id, + @JsonKey(name: "room_name") String roomName, + @JsonKey(name: "last_message") dynamic lastMessage, + @JsonKey(name: "users") Users users}); + + $UsersCopyWith<$Res> get users; +} + +/// @nodoc +class _$ChatRoomCopyWithImpl<$Res, $Val extends ChatRoom> + implements $ChatRoomCopyWith<$Res> { + _$ChatRoomCopyWithImpl(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? roomName = null, + Object? lastMessage = freezed, + Object? users = null, + }) { + return _then(_value.copyWith( + id: null == id + ? _value.id + : id // ignore: cast_nullable_to_non_nullable + as String, + roomName: null == roomName + ? _value.roomName + : roomName // ignore: cast_nullable_to_non_nullable + as String, + lastMessage: freezed == lastMessage + ? _value.lastMessage + : lastMessage // ignore: cast_nullable_to_non_nullable + as dynamic, + users: null == users + ? _value.users + : users // ignore: cast_nullable_to_non_nullable + as Users, + ) as $Val); + } + + @override + @pragma('vm:prefer-inline') + $UsersCopyWith<$Res> get users { + return $UsersCopyWith<$Res>(_value.users, (value) { + return _then(_value.copyWith(users: value) as $Val); + }); + } +} + +/// @nodoc +abstract class _$$ChatRoomImplCopyWith<$Res> + implements $ChatRoomCopyWith<$Res> { + factory _$$ChatRoomImplCopyWith( + _$ChatRoomImpl value, $Res Function(_$ChatRoomImpl) then) = + __$$ChatRoomImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {@JsonKey(name: "id") String id, + @JsonKey(name: "room_name") String roomName, + @JsonKey(name: "last_message") dynamic lastMessage, + @JsonKey(name: "users") Users users}); + + @override + $UsersCopyWith<$Res> get users; +} + +/// @nodoc +class __$$ChatRoomImplCopyWithImpl<$Res> + extends _$ChatRoomCopyWithImpl<$Res, _$ChatRoomImpl> + implements _$$ChatRoomImplCopyWith<$Res> { + __$$ChatRoomImplCopyWithImpl( + _$ChatRoomImpl _value, $Res Function(_$ChatRoomImpl) _then) + : super(_value, _then); + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? id = null, + Object? roomName = null, + Object? lastMessage = freezed, + Object? users = null, + }) { + return _then(_$ChatRoomImpl( + id: null == id + ? _value.id + : id // ignore: cast_nullable_to_non_nullable + as String, + roomName: null == roomName + ? _value.roomName + : roomName // ignore: cast_nullable_to_non_nullable + as String, + lastMessage: freezed == lastMessage + ? _value.lastMessage + : lastMessage // ignore: cast_nullable_to_non_nullable + as dynamic, + users: null == users + ? _value.users + : users // ignore: cast_nullable_to_non_nullable + as Users, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$ChatRoomImpl implements _ChatRoom { + const _$ChatRoomImpl( + {@JsonKey(name: "id") required this.id, + @JsonKey(name: "room_name") required this.roomName, + @JsonKey(name: "last_message") required this.lastMessage, + @JsonKey(name: "users") required this.users}); + + factory _$ChatRoomImpl.fromJson(Map json) => + _$$ChatRoomImplFromJson(json); + + @override + @JsonKey(name: "id") + final String id; + @override + @JsonKey(name: "room_name") + final String roomName; + @override + @JsonKey(name: "last_message") + final dynamic lastMessage; + @override + @JsonKey(name: "users") + final Users users; + + @override + String toString() { + return 'ChatRoom(id: $id, roomName: $roomName, lastMessage: $lastMessage, users: $users)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ChatRoomImpl && + (identical(other.id, id) || other.id == id) && + (identical(other.roomName, roomName) || + other.roomName == roomName) && + const DeepCollectionEquality() + .equals(other.lastMessage, lastMessage) && + (identical(other.users, users) || other.users == users)); + } + + @JsonKey(ignore: true) + @override + int get hashCode => Object.hash(runtimeType, id, roomName, + const DeepCollectionEquality().hash(lastMessage), users); + + @JsonKey(ignore: true) + @override + @pragma('vm:prefer-inline') + _$$ChatRoomImplCopyWith<_$ChatRoomImpl> get copyWith => + __$$ChatRoomImplCopyWithImpl<_$ChatRoomImpl>(this, _$identity); + + @override + Map toJson() { + return _$$ChatRoomImplToJson( + this, + ); + } +} + +abstract class _ChatRoom implements ChatRoom { + const factory _ChatRoom( + {@JsonKey(name: "id") required final String id, + @JsonKey(name: "room_name") required final String roomName, + @JsonKey(name: "last_message") required final dynamic lastMessage, + @JsonKey(name: "users") required final Users users}) = _$ChatRoomImpl; + + factory _ChatRoom.fromJson(Map json) = + _$ChatRoomImpl.fromJson; + + @override + @JsonKey(name: "id") + String get id; + @override + @JsonKey(name: "room_name") + String get roomName; + @override + @JsonKey(name: "last_message") + dynamic get lastMessage; + @override + @JsonKey(name: "users") + Users get users; + @override + @JsonKey(ignore: true) + _$$ChatRoomImplCopyWith<_$ChatRoomImpl> get copyWith => + throw _privateConstructorUsedError; +} + +LastMessageClass _$LastMessageClassFromJson(Map json) { + return _LastMessageClass.fromJson(json); +} + +/// @nodoc +mixin _$LastMessageClass { + @JsonKey(name: "id") + int get id => throw _privateConstructorUsedError; + @JsonKey(name: "data") + String get data => throw _privateConstructorUsedError; + @JsonKey(name: "media_data") + List get mediaData => throw _privateConstructorUsedError; + @JsonKey(name: "author_id") + int get authorId => throw _privateConstructorUsedError; + @JsonKey(name: "is_author_message_auth_user") + bool get isAuthorMessageAuthUser => throw _privateConstructorUsedError; + @JsonKey(name: "read_by_to_user") + bool get readByToUser => throw _privateConstructorUsedError; + @JsonKey(name: "updated_at") + DateTime get updatedAt => throw _privateConstructorUsedError; + + Map toJson() => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + $LastMessageClassCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $LastMessageClassCopyWith<$Res> { + factory $LastMessageClassCopyWith( + LastMessageClass value, $Res Function(LastMessageClass) then) = + _$LastMessageClassCopyWithImpl<$Res, LastMessageClass>; + @useResult + $Res call( + {@JsonKey(name: "id") int id, + @JsonKey(name: "data") String data, + @JsonKey(name: "media_data") List mediaData, + @JsonKey(name: "author_id") int authorId, + @JsonKey(name: "is_author_message_auth_user") + bool isAuthorMessageAuthUser, + @JsonKey(name: "read_by_to_user") bool readByToUser, + @JsonKey(name: "updated_at") DateTime updatedAt}); +} + +/// @nodoc +class _$LastMessageClassCopyWithImpl<$Res, $Val extends LastMessageClass> + implements $LastMessageClassCopyWith<$Res> { + _$LastMessageClassCopyWithImpl(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? data = null, + Object? mediaData = null, + Object? authorId = null, + Object? isAuthorMessageAuthUser = null, + Object? readByToUser = null, + Object? updatedAt = null, + }) { + return _then(_value.copyWith( + id: null == id + ? _value.id + : id // ignore: cast_nullable_to_non_nullable + as int, + data: null == data + ? _value.data + : data // ignore: cast_nullable_to_non_nullable + as String, + mediaData: null == mediaData + ? _value.mediaData + : mediaData // ignore: cast_nullable_to_non_nullable + as List, + authorId: null == authorId + ? _value.authorId + : authorId // ignore: cast_nullable_to_non_nullable + as int, + isAuthorMessageAuthUser: null == isAuthorMessageAuthUser + ? _value.isAuthorMessageAuthUser + : isAuthorMessageAuthUser // ignore: cast_nullable_to_non_nullable + as bool, + readByToUser: null == readByToUser + ? _value.readByToUser + : readByToUser // ignore: cast_nullable_to_non_nullable + as bool, + updatedAt: null == updatedAt + ? _value.updatedAt + : updatedAt // ignore: cast_nullable_to_non_nullable + as DateTime, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$LastMessageClassImplCopyWith<$Res> + implements $LastMessageClassCopyWith<$Res> { + factory _$$LastMessageClassImplCopyWith(_$LastMessageClassImpl value, + $Res Function(_$LastMessageClassImpl) then) = + __$$LastMessageClassImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {@JsonKey(name: "id") int id, + @JsonKey(name: "data") String data, + @JsonKey(name: "media_data") List mediaData, + @JsonKey(name: "author_id") int authorId, + @JsonKey(name: "is_author_message_auth_user") + bool isAuthorMessageAuthUser, + @JsonKey(name: "read_by_to_user") bool readByToUser, + @JsonKey(name: "updated_at") DateTime updatedAt}); +} + +/// @nodoc +class __$$LastMessageClassImplCopyWithImpl<$Res> + extends _$LastMessageClassCopyWithImpl<$Res, _$LastMessageClassImpl> + implements _$$LastMessageClassImplCopyWith<$Res> { + __$$LastMessageClassImplCopyWithImpl(_$LastMessageClassImpl _value, + $Res Function(_$LastMessageClassImpl) _then) + : super(_value, _then); + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? id = null, + Object? data = null, + Object? mediaData = null, + Object? authorId = null, + Object? isAuthorMessageAuthUser = null, + Object? readByToUser = null, + Object? updatedAt = null, + }) { + return _then(_$LastMessageClassImpl( + id: null == id + ? _value.id + : id // ignore: cast_nullable_to_non_nullable + as int, + data: null == data + ? _value.data + : data // ignore: cast_nullable_to_non_nullable + as String, + mediaData: null == mediaData + ? _value._mediaData + : mediaData // ignore: cast_nullable_to_non_nullable + as List, + authorId: null == authorId + ? _value.authorId + : authorId // ignore: cast_nullable_to_non_nullable + as int, + isAuthorMessageAuthUser: null == isAuthorMessageAuthUser + ? _value.isAuthorMessageAuthUser + : isAuthorMessageAuthUser // ignore: cast_nullable_to_non_nullable + as bool, + readByToUser: null == readByToUser + ? _value.readByToUser + : readByToUser // ignore: cast_nullable_to_non_nullable + as bool, + updatedAt: null == updatedAt + ? _value.updatedAt + : updatedAt // ignore: cast_nullable_to_non_nullable + as DateTime, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$LastMessageClassImpl implements _LastMessageClass { + const _$LastMessageClassImpl( + {@JsonKey(name: "id") required this.id, + @JsonKey(name: "data") required this.data, + @JsonKey(name: "media_data") required final List mediaData, + @JsonKey(name: "author_id") required this.authorId, + @JsonKey(name: "is_author_message_auth_user") + required this.isAuthorMessageAuthUser, + @JsonKey(name: "read_by_to_user") required this.readByToUser, + @JsonKey(name: "updated_at") required this.updatedAt}) + : _mediaData = mediaData; + + factory _$LastMessageClassImpl.fromJson(Map json) => + _$$LastMessageClassImplFromJson(json); + + @override + @JsonKey(name: "id") + final int id; + @override + @JsonKey(name: "data") + final String data; + final List _mediaData; + @override + @JsonKey(name: "media_data") + List get mediaData { + if (_mediaData is EqualUnmodifiableListView) return _mediaData; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_mediaData); + } + + @override + @JsonKey(name: "author_id") + final int authorId; + @override + @JsonKey(name: "is_author_message_auth_user") + final bool isAuthorMessageAuthUser; + @override + @JsonKey(name: "read_by_to_user") + final bool readByToUser; + @override + @JsonKey(name: "updated_at") + final DateTime updatedAt; + + @override + String toString() { + return 'LastMessageClass(id: $id, data: $data, mediaData: $mediaData, authorId: $authorId, isAuthorMessageAuthUser: $isAuthorMessageAuthUser, readByToUser: $readByToUser, updatedAt: $updatedAt)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$LastMessageClassImpl && + (identical(other.id, id) || other.id == id) && + (identical(other.data, data) || other.data == data) && + const DeepCollectionEquality() + .equals(other._mediaData, _mediaData) && + (identical(other.authorId, authorId) || + other.authorId == authorId) && + (identical( + other.isAuthorMessageAuthUser, isAuthorMessageAuthUser) || + other.isAuthorMessageAuthUser == isAuthorMessageAuthUser) && + (identical(other.readByToUser, readByToUser) || + other.readByToUser == readByToUser) && + (identical(other.updatedAt, updatedAt) || + other.updatedAt == updatedAt)); + } + + @JsonKey(ignore: true) + @override + int get hashCode => Object.hash( + runtimeType, + id, + data, + const DeepCollectionEquality().hash(_mediaData), + authorId, + isAuthorMessageAuthUser, + readByToUser, + updatedAt); + + @JsonKey(ignore: true) + @override + @pragma('vm:prefer-inline') + _$$LastMessageClassImplCopyWith<_$LastMessageClassImpl> get copyWith => + __$$LastMessageClassImplCopyWithImpl<_$LastMessageClassImpl>( + this, _$identity); + + @override + Map toJson() { + return _$$LastMessageClassImplToJson( + this, + ); + } +} + +abstract class _LastMessageClass implements LastMessageClass { + const factory _LastMessageClass( + {@JsonKey(name: "id") required final int id, + @JsonKey(name: "data") required final String data, + @JsonKey(name: "media_data") required final List mediaData, + @JsonKey(name: "author_id") required final int authorId, + @JsonKey(name: "is_author_message_auth_user") + required final bool isAuthorMessageAuthUser, + @JsonKey(name: "read_by_to_user") required final bool readByToUser, + @JsonKey(name: "updated_at") required final DateTime updatedAt}) = + _$LastMessageClassImpl; + + factory _LastMessageClass.fromJson(Map json) = + _$LastMessageClassImpl.fromJson; + + @override + @JsonKey(name: "id") + int get id; + @override + @JsonKey(name: "data") + String get data; + @override + @JsonKey(name: "media_data") + List get mediaData; + @override + @JsonKey(name: "author_id") + int get authorId; + @override + @JsonKey(name: "is_author_message_auth_user") + bool get isAuthorMessageAuthUser; + @override + @JsonKey(name: "read_by_to_user") + bool get readByToUser; + @override + @JsonKey(name: "updated_at") + DateTime get updatedAt; + @override + @JsonKey(ignore: true) + _$$LastMessageClassImplCopyWith<_$LastMessageClassImpl> get copyWith => + throw _privateConstructorUsedError; +} + +Users _$UsersFromJson(Map json) { + return _Users.fromJson(json); +} + +/// @nodoc +mixin _$Users { + @JsonKey(name: "from_chat_user") + ChatUser get fromChatUser => throw _privateConstructorUsedError; + @JsonKey(name: "to_chat_user") + ChatUser get toChatUser => throw _privateConstructorUsedError; + + Map toJson() => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + $UsersCopyWith get copyWith => throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $UsersCopyWith<$Res> { + factory $UsersCopyWith(Users value, $Res Function(Users) then) = + _$UsersCopyWithImpl<$Res, Users>; + @useResult + $Res call( + {@JsonKey(name: "from_chat_user") ChatUser fromChatUser, + @JsonKey(name: "to_chat_user") ChatUser toChatUser}); + + $ChatUserCopyWith<$Res> get fromChatUser; + $ChatUserCopyWith<$Res> get toChatUser; +} + +/// @nodoc +class _$UsersCopyWithImpl<$Res, $Val extends Users> + implements $UsersCopyWith<$Res> { + _$UsersCopyWithImpl(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? fromChatUser = null, + Object? toChatUser = null, + }) { + return _then(_value.copyWith( + fromChatUser: null == fromChatUser + ? _value.fromChatUser + : fromChatUser // ignore: cast_nullable_to_non_nullable + as ChatUser, + toChatUser: null == toChatUser + ? _value.toChatUser + : toChatUser // ignore: cast_nullable_to_non_nullable + as ChatUser, + ) as $Val); + } + + @override + @pragma('vm:prefer-inline') + $ChatUserCopyWith<$Res> get fromChatUser { + return $ChatUserCopyWith<$Res>(_value.fromChatUser, (value) { + return _then(_value.copyWith(fromChatUser: value) as $Val); + }); + } + + @override + @pragma('vm:prefer-inline') + $ChatUserCopyWith<$Res> get toChatUser { + return $ChatUserCopyWith<$Res>(_value.toChatUser, (value) { + return _then(_value.copyWith(toChatUser: value) as $Val); + }); + } +} + +/// @nodoc +abstract class _$$UsersImplCopyWith<$Res> implements $UsersCopyWith<$Res> { + factory _$$UsersImplCopyWith( + _$UsersImpl value, $Res Function(_$UsersImpl) then) = + __$$UsersImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {@JsonKey(name: "from_chat_user") ChatUser fromChatUser, + @JsonKey(name: "to_chat_user") ChatUser toChatUser}); + + @override + $ChatUserCopyWith<$Res> get fromChatUser; + @override + $ChatUserCopyWith<$Res> get toChatUser; +} + +/// @nodoc +class __$$UsersImplCopyWithImpl<$Res> + extends _$UsersCopyWithImpl<$Res, _$UsersImpl> + implements _$$UsersImplCopyWith<$Res> { + __$$UsersImplCopyWithImpl( + _$UsersImpl _value, $Res Function(_$UsersImpl) _then) + : super(_value, _then); + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? fromChatUser = null, + Object? toChatUser = null, + }) { + return _then(_$UsersImpl( + fromChatUser: null == fromChatUser + ? _value.fromChatUser + : fromChatUser // ignore: cast_nullable_to_non_nullable + as ChatUser, + toChatUser: null == toChatUser + ? _value.toChatUser + : toChatUser // ignore: cast_nullable_to_non_nullable + as ChatUser, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$UsersImpl implements _Users { + const _$UsersImpl( + {@JsonKey(name: "from_chat_user") required this.fromChatUser, + @JsonKey(name: "to_chat_user") required this.toChatUser}); + + factory _$UsersImpl.fromJson(Map json) => + _$$UsersImplFromJson(json); + + @override + @JsonKey(name: "from_chat_user") + final ChatUser fromChatUser; + @override + @JsonKey(name: "to_chat_user") + final ChatUser toChatUser; + + @override + String toString() { + return 'Users(fromChatUser: $fromChatUser, toChatUser: $toChatUser)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$UsersImpl && + (identical(other.fromChatUser, fromChatUser) || + other.fromChatUser == fromChatUser) && + (identical(other.toChatUser, toChatUser) || + other.toChatUser == toChatUser)); + } + + @JsonKey(ignore: true) + @override + int get hashCode => Object.hash(runtimeType, fromChatUser, toChatUser); + + @JsonKey(ignore: true) + @override + @pragma('vm:prefer-inline') + _$$UsersImplCopyWith<_$UsersImpl> get copyWith => + __$$UsersImplCopyWithImpl<_$UsersImpl>(this, _$identity); + + @override + Map toJson() { + return _$$UsersImplToJson( + this, + ); + } +} + +abstract class _Users implements Users { + const factory _Users( + {@JsonKey(name: "from_chat_user") required final ChatUser fromChatUser, + @JsonKey(name: "to_chat_user") + required final ChatUser toChatUser}) = _$UsersImpl; + + factory _Users.fromJson(Map json) = _$UsersImpl.fromJson; + + @override + @JsonKey(name: "from_chat_user") + ChatUser get fromChatUser; + @override + @JsonKey(name: "to_chat_user") + ChatUser get toChatUser; + @override + @JsonKey(ignore: true) + _$$UsersImplCopyWith<_$UsersImpl> get copyWith => + throw _privateConstructorUsedError; +} + +ChatUser _$ChatUserFromJson(Map json) { + return _ChatUser.fromJson(json); +} + +/// @nodoc +mixin _$ChatUser { + @JsonKey(name: "id") + int get id => throw _privateConstructorUsedError; + @JsonKey(name: "name") + String get name => throw _privateConstructorUsedError; + @JsonKey(name: "profile_photo_path") + String? get profilePhotoPath => throw _privateConstructorUsedError; + @JsonKey(name: "profile_photo_url") + String get profilePhotoUrl => throw _privateConstructorUsedError; + + Map toJson() => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + $ChatUserCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $ChatUserCopyWith<$Res> { + factory $ChatUserCopyWith(ChatUser value, $Res Function(ChatUser) then) = + _$ChatUserCopyWithImpl<$Res, ChatUser>; + @useResult + $Res call( + {@JsonKey(name: "id") int id, + @JsonKey(name: "name") String name, + @JsonKey(name: "profile_photo_path") String? profilePhotoPath, + @JsonKey(name: "profile_photo_url") String profilePhotoUrl}); +} + +/// @nodoc +class _$ChatUserCopyWithImpl<$Res, $Val extends ChatUser> + implements $ChatUserCopyWith<$Res> { + _$ChatUserCopyWithImpl(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? name = null, + Object? profilePhotoPath = freezed, + Object? profilePhotoUrl = null, + }) { + return _then(_value.copyWith( + id: null == id + ? _value.id + : id // ignore: cast_nullable_to_non_nullable + as int, + name: null == name + ? _value.name + : name // ignore: cast_nullable_to_non_nullable + as String, + profilePhotoPath: freezed == profilePhotoPath + ? _value.profilePhotoPath + : profilePhotoPath // ignore: cast_nullable_to_non_nullable + as String?, + profilePhotoUrl: null == profilePhotoUrl + ? _value.profilePhotoUrl + : profilePhotoUrl // ignore: cast_nullable_to_non_nullable + as String, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$ChatUserImplCopyWith<$Res> + implements $ChatUserCopyWith<$Res> { + factory _$$ChatUserImplCopyWith( + _$ChatUserImpl value, $Res Function(_$ChatUserImpl) then) = + __$$ChatUserImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {@JsonKey(name: "id") int id, + @JsonKey(name: "name") String name, + @JsonKey(name: "profile_photo_path") String? profilePhotoPath, + @JsonKey(name: "profile_photo_url") String profilePhotoUrl}); +} + +/// @nodoc +class __$$ChatUserImplCopyWithImpl<$Res> + extends _$ChatUserCopyWithImpl<$Res, _$ChatUserImpl> + implements _$$ChatUserImplCopyWith<$Res> { + __$$ChatUserImplCopyWithImpl( + _$ChatUserImpl _value, $Res Function(_$ChatUserImpl) _then) + : super(_value, _then); + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? id = null, + Object? name = null, + Object? profilePhotoPath = freezed, + Object? profilePhotoUrl = null, + }) { + return _then(_$ChatUserImpl( + id: null == id + ? _value.id + : id // ignore: cast_nullable_to_non_nullable + as int, + name: null == name + ? _value.name + : name // ignore: cast_nullable_to_non_nullable + as String, + profilePhotoPath: freezed == profilePhotoPath + ? _value.profilePhotoPath + : profilePhotoPath // ignore: cast_nullable_to_non_nullable + as String?, + profilePhotoUrl: null == profilePhotoUrl + ? _value.profilePhotoUrl + : profilePhotoUrl // ignore: cast_nullable_to_non_nullable + as String, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$ChatUserImpl implements _ChatUser { + const _$ChatUserImpl( + {@JsonKey(name: "id") required this.id, + @JsonKey(name: "name") required this.name, + @JsonKey(name: "profile_photo_path") required this.profilePhotoPath, + @JsonKey(name: "profile_photo_url") required this.profilePhotoUrl}); + + factory _$ChatUserImpl.fromJson(Map json) => + _$$ChatUserImplFromJson(json); + + @override + @JsonKey(name: "id") + final int id; + @override + @JsonKey(name: "name") + final String name; + @override + @JsonKey(name: "profile_photo_path") + final String? profilePhotoPath; + @override + @JsonKey(name: "profile_photo_url") + final String profilePhotoUrl; + + @override + String toString() { + return 'ChatUser(id: $id, name: $name, profilePhotoPath: $profilePhotoPath, profilePhotoUrl: $profilePhotoUrl)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ChatUserImpl && + (identical(other.id, id) || other.id == id) && + (identical(other.name, name) || other.name == name) && + (identical(other.profilePhotoPath, profilePhotoPath) || + other.profilePhotoPath == profilePhotoPath) && + (identical(other.profilePhotoUrl, profilePhotoUrl) || + other.profilePhotoUrl == profilePhotoUrl)); + } + + @JsonKey(ignore: true) + @override + int get hashCode => + Object.hash(runtimeType, id, name, profilePhotoPath, profilePhotoUrl); + + @JsonKey(ignore: true) + @override + @pragma('vm:prefer-inline') + _$$ChatUserImplCopyWith<_$ChatUserImpl> get copyWith => + __$$ChatUserImplCopyWithImpl<_$ChatUserImpl>(this, _$identity); + + @override + Map toJson() { + return _$$ChatUserImplToJson( + this, + ); + } +} + +abstract class _ChatUser implements ChatUser { + const factory _ChatUser( + {@JsonKey(name: "id") required final int id, + @JsonKey(name: "name") required final String name, + @JsonKey(name: "profile_photo_path") + required final String? profilePhotoPath, + @JsonKey(name: "profile_photo_url") + required final String profilePhotoUrl}) = _$ChatUserImpl; + + factory _ChatUser.fromJson(Map json) = + _$ChatUserImpl.fromJson; + + @override + @JsonKey(name: "id") + int get id; + @override + @JsonKey(name: "name") + String get name; + @override + @JsonKey(name: "profile_photo_path") + String? get profilePhotoPath; + @override + @JsonKey(name: "profile_photo_url") + String get profilePhotoUrl; + @override + @JsonKey(ignore: true) + _$$ChatUserImplCopyWith<_$ChatUserImpl> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/lib/features/chat/models/chat_room_preview_model.g.dart b/lib/features/chat/models/chat_room_preview_model.g.dart new file mode 100644 index 00000000..5ae3f709 --- /dev/null +++ b/lib/features/chat/models/chat_room_preview_model.g.dart @@ -0,0 +1,90 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'chat_room_preview_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_$ChatRoomPreviewModelImpl _$$ChatRoomPreviewModelImplFromJson( + Map json) => + _$ChatRoomPreviewModelImpl( + chatRooms: (json['chatRooms'] as List) + .map((e) => ChatRoom.fromJson(e as Map)) + .toList(), + ); + +Map _$$ChatRoomPreviewModelImplToJson( + _$ChatRoomPreviewModelImpl instance) => + { + 'chatRooms': instance.chatRooms, + }; + +_$ChatRoomImpl _$$ChatRoomImplFromJson(Map json) => + _$ChatRoomImpl( + id: json['id'] as String, + roomName: json['room_name'] as String, + lastMessage: json['last_message'], + users: Users.fromJson(json['users'] as Map), + ); + +Map _$$ChatRoomImplToJson(_$ChatRoomImpl instance) => + { + 'id': instance.id, + 'room_name': instance.roomName, + 'last_message': instance.lastMessage, + 'users': instance.users, + }; + +_$LastMessageClassImpl _$$LastMessageClassImplFromJson( + Map json) => + _$LastMessageClassImpl( + id: (json['id'] as num).toInt(), + data: json['data'] as String, + mediaData: json['media_data'] as List, + authorId: (json['author_id'] as num).toInt(), + isAuthorMessageAuthUser: json['is_author_message_auth_user'] as bool, + readByToUser: json['read_by_to_user'] as bool, + updatedAt: DateTime.parse(json['updated_at'] as String), + ); + +Map _$$LastMessageClassImplToJson( + _$LastMessageClassImpl instance) => + { + 'id': instance.id, + 'data': instance.data, + 'media_data': instance.mediaData, + 'author_id': instance.authorId, + 'is_author_message_auth_user': instance.isAuthorMessageAuthUser, + 'read_by_to_user': instance.readByToUser, + 'updated_at': instance.updatedAt.toIso8601String(), + }; + +_$UsersImpl _$$UsersImplFromJson(Map json) => _$UsersImpl( + fromChatUser: + ChatUser.fromJson(json['from_chat_user'] as Map), + toChatUser: + ChatUser.fromJson(json['to_chat_user'] as Map), + ); + +Map _$$UsersImplToJson(_$UsersImpl instance) => + { + 'from_chat_user': instance.fromChatUser, + 'to_chat_user': instance.toChatUser, + }; + +_$ChatUserImpl _$$ChatUserImplFromJson(Map json) => + _$ChatUserImpl( + id: (json['id'] as num).toInt(), + name: json['name'] as String, + profilePhotoPath: json['profile_photo_path'] as String?, + profilePhotoUrl: json['profile_photo_url'] as String, + ); + +Map _$$ChatUserImplToJson(_$ChatUserImpl instance) => + { + 'id': instance.id, + 'name': instance.name, + 'profile_photo_path': instance.profilePhotoPath, + 'profile_photo_url': instance.profilePhotoUrl, + }; diff --git a/lib/features/chat/presentation/bloc/chat_select_cubit/chat_select_cubit.dart b/lib/features/chat/presentation/bloc/chat_select_cubit/chat_select_cubit.dart new file mode 100644 index 00000000..fc92f22d --- /dev/null +++ b/lib/features/chat/presentation/bloc/chat_select_cubit/chat_select_cubit.dart @@ -0,0 +1,24 @@ +import 'package:eatvio_app/core/app_export.dart'; +import 'package:eatvio_app/features/chat/presentation/bloc/chat_select_cubit/chat_select_state.dart'; +import 'package:eatvio_app/features/chat/repositories/chat_repository.dart'; + +class ChatSelectCubit extends Cubit { + final ChatRepository chatRepository; + + ChatSelectCubit({ + required this.chatRepository, + }) : super(ChatSelectState()); + + getChatRooms({String? query}) async { + emit(ChatSelectState.loading()); + try { + emit(ChatSelectState.loaded( + chatRooms: (await chatRepository.getChatRoomPreiews(query: query)), + )); + } catch (e) { + emit( + ChatSelectState.error(errorMessage: e.toString()), + ); + } + } +} diff --git a/lib/features/chat/presentation/bloc/chat_select_cubit/chat_select_state.dart b/lib/features/chat/presentation/bloc/chat_select_cubit/chat_select_state.dart new file mode 100644 index 00000000..eae74b97 --- /dev/null +++ b/lib/features/chat/presentation/bloc/chat_select_cubit/chat_select_state.dart @@ -0,0 +1,19 @@ +import 'package:eatvio_app/features/chat/models/chat_room_preview_model.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'chat_select_state.freezed.dart'; + +@freezed +abstract class ChatSelectState with _$ChatSelectState { + const factory ChatSelectState() = _ChatSelectState; + + const factory ChatSelectState.loading() = ChatSelectStateLoading; + + const factory ChatSelectState.error({ + required String errorMessage, + }) = ChatSelectStateError; + + const factory ChatSelectState.loaded({ + required List chatRooms, + }) = ChatSelectStateLoaded; +} diff --git a/lib/features/chat/presentation/bloc/chat_select_cubit/chat_select_state.freezed.dart b/lib/features/chat/presentation/bloc/chat_select_cubit/chat_select_state.freezed.dart new file mode 100644 index 00000000..9a05918d --- /dev/null +++ b/lib/features/chat/presentation/bloc/chat_select_cubit/chat_select_state.freezed.dart @@ -0,0 +1,623 @@ +// 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 'chat_select_state.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); + +/// @nodoc +mixin _$ChatSelectState { + @optionalTypeArgs + TResult when( + TResult Function() $default, { + required TResult Function() loading, + required TResult Function(String errorMessage) error, + required TResult Function(List chatRooms) loaded, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult? whenOrNull( + TResult? Function()? $default, { + TResult? Function()? loading, + TResult? Function(String errorMessage)? error, + TResult? Function(List chatRooms)? loaded, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeWhen( + TResult Function()? $default, { + TResult Function()? loading, + TResult Function(String errorMessage)? error, + TResult Function(List chatRooms)? loaded, + required TResult orElse(), + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult map( + TResult Function(_ChatSelectState value) $default, { + required TResult Function(ChatSelectStateLoading value) loading, + required TResult Function(ChatSelectStateError value) error, + required TResult Function(ChatSelectStateLoaded value) loaded, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult? mapOrNull( + TResult? Function(_ChatSelectState value)? $default, { + TResult? Function(ChatSelectStateLoading value)? loading, + TResult? Function(ChatSelectStateError value)? error, + TResult? Function(ChatSelectStateLoaded value)? loaded, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeMap( + TResult Function(_ChatSelectState value)? $default, { + TResult Function(ChatSelectStateLoading value)? loading, + TResult Function(ChatSelectStateError value)? error, + TResult Function(ChatSelectStateLoaded value)? loaded, + required TResult orElse(), + }) => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $ChatSelectStateCopyWith<$Res> { + factory $ChatSelectStateCopyWith( + ChatSelectState value, $Res Function(ChatSelectState) then) = + _$ChatSelectStateCopyWithImpl<$Res, ChatSelectState>; +} + +/// @nodoc +class _$ChatSelectStateCopyWithImpl<$Res, $Val extends ChatSelectState> + implements $ChatSelectStateCopyWith<$Res> { + _$ChatSelectStateCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; +} + +/// @nodoc +abstract class _$$ChatSelectStateImplCopyWith<$Res> { + factory _$$ChatSelectStateImplCopyWith(_$ChatSelectStateImpl value, + $Res Function(_$ChatSelectStateImpl) then) = + __$$ChatSelectStateImplCopyWithImpl<$Res>; +} + +/// @nodoc +class __$$ChatSelectStateImplCopyWithImpl<$Res> + extends _$ChatSelectStateCopyWithImpl<$Res, _$ChatSelectStateImpl> + implements _$$ChatSelectStateImplCopyWith<$Res> { + __$$ChatSelectStateImplCopyWithImpl( + _$ChatSelectStateImpl _value, $Res Function(_$ChatSelectStateImpl) _then) + : super(_value, _then); +} + +/// @nodoc + +class _$ChatSelectStateImpl implements _ChatSelectState { + const _$ChatSelectStateImpl(); + + @override + String toString() { + return 'ChatSelectState()'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && other is _$ChatSelectStateImpl); + } + + @override + int get hashCode => runtimeType.hashCode; + + @override + @optionalTypeArgs + TResult when( + TResult Function() $default, { + required TResult Function() loading, + required TResult Function(String errorMessage) error, + required TResult Function(List chatRooms) loaded, + }) { + return $default(); + } + + @override + @optionalTypeArgs + TResult? whenOrNull( + TResult? Function()? $default, { + TResult? Function()? loading, + TResult? Function(String errorMessage)? error, + TResult? Function(List chatRooms)? loaded, + }) { + return $default?.call(); + } + + @override + @optionalTypeArgs + TResult maybeWhen( + TResult Function()? $default, { + TResult Function()? loading, + TResult Function(String errorMessage)? error, + TResult Function(List chatRooms)? loaded, + required TResult orElse(), + }) { + if ($default != null) { + return $default(); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map( + TResult Function(_ChatSelectState value) $default, { + required TResult Function(ChatSelectStateLoading value) loading, + required TResult Function(ChatSelectStateError value) error, + required TResult Function(ChatSelectStateLoaded value) loaded, + }) { + return $default(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull( + TResult? Function(_ChatSelectState value)? $default, { + TResult? Function(ChatSelectStateLoading value)? loading, + TResult? Function(ChatSelectStateError value)? error, + TResult? Function(ChatSelectStateLoaded value)? loaded, + }) { + return $default?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap( + TResult Function(_ChatSelectState value)? $default, { + TResult Function(ChatSelectStateLoading value)? loading, + TResult Function(ChatSelectStateError value)? error, + TResult Function(ChatSelectStateLoaded value)? loaded, + required TResult orElse(), + }) { + if ($default != null) { + return $default(this); + } + return orElse(); + } +} + +abstract class _ChatSelectState implements ChatSelectState { + const factory _ChatSelectState() = _$ChatSelectStateImpl; +} + +/// @nodoc +abstract class _$$ChatSelectStateLoadingImplCopyWith<$Res> { + factory _$$ChatSelectStateLoadingImplCopyWith( + _$ChatSelectStateLoadingImpl value, + $Res Function(_$ChatSelectStateLoadingImpl) then) = + __$$ChatSelectStateLoadingImplCopyWithImpl<$Res>; +} + +/// @nodoc +class __$$ChatSelectStateLoadingImplCopyWithImpl<$Res> + extends _$ChatSelectStateCopyWithImpl<$Res, _$ChatSelectStateLoadingImpl> + implements _$$ChatSelectStateLoadingImplCopyWith<$Res> { + __$$ChatSelectStateLoadingImplCopyWithImpl( + _$ChatSelectStateLoadingImpl _value, + $Res Function(_$ChatSelectStateLoadingImpl) _then) + : super(_value, _then); +} + +/// @nodoc + +class _$ChatSelectStateLoadingImpl implements ChatSelectStateLoading { + const _$ChatSelectStateLoadingImpl(); + + @override + String toString() { + return 'ChatSelectState.loading()'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ChatSelectStateLoadingImpl); + } + + @override + int get hashCode => runtimeType.hashCode; + + @override + @optionalTypeArgs + TResult when( + TResult Function() $default, { + required TResult Function() loading, + required TResult Function(String errorMessage) error, + required TResult Function(List chatRooms) loaded, + }) { + return loading(); + } + + @override + @optionalTypeArgs + TResult? whenOrNull( + TResult? Function()? $default, { + TResult? Function()? loading, + TResult? Function(String errorMessage)? error, + TResult? Function(List chatRooms)? loaded, + }) { + return loading?.call(); + } + + @override + @optionalTypeArgs + TResult maybeWhen( + TResult Function()? $default, { + TResult Function()? loading, + TResult Function(String errorMessage)? error, + TResult Function(List chatRooms)? loaded, + required TResult orElse(), + }) { + if (loading != null) { + return loading(); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map( + TResult Function(_ChatSelectState value) $default, { + required TResult Function(ChatSelectStateLoading value) loading, + required TResult Function(ChatSelectStateError value) error, + required TResult Function(ChatSelectStateLoaded value) loaded, + }) { + return loading(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull( + TResult? Function(_ChatSelectState value)? $default, { + TResult? Function(ChatSelectStateLoading value)? loading, + TResult? Function(ChatSelectStateError value)? error, + TResult? Function(ChatSelectStateLoaded value)? loaded, + }) { + return loading?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap( + TResult Function(_ChatSelectState value)? $default, { + TResult Function(ChatSelectStateLoading value)? loading, + TResult Function(ChatSelectStateError value)? error, + TResult Function(ChatSelectStateLoaded value)? loaded, + required TResult orElse(), + }) { + if (loading != null) { + return loading(this); + } + return orElse(); + } +} + +abstract class ChatSelectStateLoading implements ChatSelectState { + const factory ChatSelectStateLoading() = _$ChatSelectStateLoadingImpl; +} + +/// @nodoc +abstract class _$$ChatSelectStateErrorImplCopyWith<$Res> { + factory _$$ChatSelectStateErrorImplCopyWith(_$ChatSelectStateErrorImpl value, + $Res Function(_$ChatSelectStateErrorImpl) then) = + __$$ChatSelectStateErrorImplCopyWithImpl<$Res>; + @useResult + $Res call({String errorMessage}); +} + +/// @nodoc +class __$$ChatSelectStateErrorImplCopyWithImpl<$Res> + extends _$ChatSelectStateCopyWithImpl<$Res, _$ChatSelectStateErrorImpl> + implements _$$ChatSelectStateErrorImplCopyWith<$Res> { + __$$ChatSelectStateErrorImplCopyWithImpl(_$ChatSelectStateErrorImpl _value, + $Res Function(_$ChatSelectStateErrorImpl) _then) + : super(_value, _then); + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? errorMessage = null, + }) { + return _then(_$ChatSelectStateErrorImpl( + errorMessage: null == errorMessage + ? _value.errorMessage + : errorMessage // ignore: cast_nullable_to_non_nullable + as String, + )); + } +} + +/// @nodoc + +class _$ChatSelectStateErrorImpl implements ChatSelectStateError { + const _$ChatSelectStateErrorImpl({required this.errorMessage}); + + @override + final String errorMessage; + + @override + String toString() { + return 'ChatSelectState.error(errorMessage: $errorMessage)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ChatSelectStateErrorImpl && + (identical(other.errorMessage, errorMessage) || + other.errorMessage == errorMessage)); + } + + @override + int get hashCode => Object.hash(runtimeType, errorMessage); + + @JsonKey(ignore: true) + @override + @pragma('vm:prefer-inline') + _$$ChatSelectStateErrorImplCopyWith<_$ChatSelectStateErrorImpl> + get copyWith => + __$$ChatSelectStateErrorImplCopyWithImpl<_$ChatSelectStateErrorImpl>( + this, _$identity); + + @override + @optionalTypeArgs + TResult when( + TResult Function() $default, { + required TResult Function() loading, + required TResult Function(String errorMessage) error, + required TResult Function(List chatRooms) loaded, + }) { + return error(errorMessage); + } + + @override + @optionalTypeArgs + TResult? whenOrNull( + TResult? Function()? $default, { + TResult? Function()? loading, + TResult? Function(String errorMessage)? error, + TResult? Function(List chatRooms)? loaded, + }) { + return error?.call(errorMessage); + } + + @override + @optionalTypeArgs + TResult maybeWhen( + TResult Function()? $default, { + TResult Function()? loading, + TResult Function(String errorMessage)? error, + TResult Function(List chatRooms)? loaded, + required TResult orElse(), + }) { + if (error != null) { + return error(errorMessage); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map( + TResult Function(_ChatSelectState value) $default, { + required TResult Function(ChatSelectStateLoading value) loading, + required TResult Function(ChatSelectStateError value) error, + required TResult Function(ChatSelectStateLoaded value) loaded, + }) { + return error(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull( + TResult? Function(_ChatSelectState value)? $default, { + TResult? Function(ChatSelectStateLoading value)? loading, + TResult? Function(ChatSelectStateError value)? error, + TResult? Function(ChatSelectStateLoaded value)? loaded, + }) { + return error?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap( + TResult Function(_ChatSelectState value)? $default, { + TResult Function(ChatSelectStateLoading value)? loading, + TResult Function(ChatSelectStateError value)? error, + TResult Function(ChatSelectStateLoaded value)? loaded, + required TResult orElse(), + }) { + if (error != null) { + return error(this); + } + return orElse(); + } +} + +abstract class ChatSelectStateError implements ChatSelectState { + const factory ChatSelectStateError({required final String errorMessage}) = + _$ChatSelectStateErrorImpl; + + String get errorMessage; + @JsonKey(ignore: true) + _$$ChatSelectStateErrorImplCopyWith<_$ChatSelectStateErrorImpl> + get copyWith => throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class _$$ChatSelectStateLoadedImplCopyWith<$Res> { + factory _$$ChatSelectStateLoadedImplCopyWith( + _$ChatSelectStateLoadedImpl value, + $Res Function(_$ChatSelectStateLoadedImpl) then) = + __$$ChatSelectStateLoadedImplCopyWithImpl<$Res>; + @useResult + $Res call({List chatRooms}); +} + +/// @nodoc +class __$$ChatSelectStateLoadedImplCopyWithImpl<$Res> + extends _$ChatSelectStateCopyWithImpl<$Res, _$ChatSelectStateLoadedImpl> + implements _$$ChatSelectStateLoadedImplCopyWith<$Res> { + __$$ChatSelectStateLoadedImplCopyWithImpl(_$ChatSelectStateLoadedImpl _value, + $Res Function(_$ChatSelectStateLoadedImpl) _then) + : super(_value, _then); + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? chatRooms = null, + }) { + return _then(_$ChatSelectStateLoadedImpl( + chatRooms: null == chatRooms + ? _value._chatRooms + : chatRooms // ignore: cast_nullable_to_non_nullable + as List, + )); + } +} + +/// @nodoc + +class _$ChatSelectStateLoadedImpl implements ChatSelectStateLoaded { + const _$ChatSelectStateLoadedImpl({required final List chatRooms}) + : _chatRooms = chatRooms; + + final List _chatRooms; + @override + List get chatRooms { + if (_chatRooms is EqualUnmodifiableListView) return _chatRooms; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_chatRooms); + } + + @override + String toString() { + return 'ChatSelectState.loaded(chatRooms: $chatRooms)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ChatSelectStateLoadedImpl && + const DeepCollectionEquality() + .equals(other._chatRooms, _chatRooms)); + } + + @override + int get hashCode => + Object.hash(runtimeType, const DeepCollectionEquality().hash(_chatRooms)); + + @JsonKey(ignore: true) + @override + @pragma('vm:prefer-inline') + _$$ChatSelectStateLoadedImplCopyWith<_$ChatSelectStateLoadedImpl> + get copyWith => __$$ChatSelectStateLoadedImplCopyWithImpl< + _$ChatSelectStateLoadedImpl>(this, _$identity); + + @override + @optionalTypeArgs + TResult when( + TResult Function() $default, { + required TResult Function() loading, + required TResult Function(String errorMessage) error, + required TResult Function(List chatRooms) loaded, + }) { + return loaded(chatRooms); + } + + @override + @optionalTypeArgs + TResult? whenOrNull( + TResult? Function()? $default, { + TResult? Function()? loading, + TResult? Function(String errorMessage)? error, + TResult? Function(List chatRooms)? loaded, + }) { + return loaded?.call(chatRooms); + } + + @override + @optionalTypeArgs + TResult maybeWhen( + TResult Function()? $default, { + TResult Function()? loading, + TResult Function(String errorMessage)? error, + TResult Function(List chatRooms)? loaded, + required TResult orElse(), + }) { + if (loaded != null) { + return loaded(chatRooms); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map( + TResult Function(_ChatSelectState value) $default, { + required TResult Function(ChatSelectStateLoading value) loading, + required TResult Function(ChatSelectStateError value) error, + required TResult Function(ChatSelectStateLoaded value) loaded, + }) { + return loaded(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull( + TResult? Function(_ChatSelectState value)? $default, { + TResult? Function(ChatSelectStateLoading value)? loading, + TResult? Function(ChatSelectStateError value)? error, + TResult? Function(ChatSelectStateLoaded value)? loaded, + }) { + return loaded?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap( + TResult Function(_ChatSelectState value)? $default, { + TResult Function(ChatSelectStateLoading value)? loading, + TResult Function(ChatSelectStateError value)? error, + TResult Function(ChatSelectStateLoaded value)? loaded, + required TResult orElse(), + }) { + if (loaded != null) { + return loaded(this); + } + return orElse(); + } +} + +abstract class ChatSelectStateLoaded implements ChatSelectState { + const factory ChatSelectStateLoaded( + {required final List chatRooms}) = _$ChatSelectStateLoadedImpl; + + List get chatRooms; + @JsonKey(ignore: true) + _$$ChatSelectStateLoadedImplCopyWith<_$ChatSelectStateLoadedImpl> + get copyWith => throw _privateConstructorUsedError; +} diff --git a/lib/features/chat/presentation/pages/chat_select_screen.dart b/lib/features/chat/presentation/pages/chat_select_screen.dart new file mode 100644 index 00000000..bdb3d9ce --- /dev/null +++ b/lib/features/chat/presentation/pages/chat_select_screen.dart @@ -0,0 +1,111 @@ +import 'package:easy_debounce/easy_debounce.dart'; +import 'package:eatvio_app/core/app_export.dart'; +import 'package:eatvio_app/features/chat/presentation/bloc/chat_select_cubit/chat_select_cubit.dart'; +import 'package:eatvio_app/features/chat/presentation/bloc/chat_select_cubit/chat_select_state.dart'; +import 'package:eatvio_app/features/chat/presentation/widgets/chat_entry_widget.dart'; +import 'package:eatvio_app/features/chat/presentation/widgets/chat_search_bar_widget.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class ChatSelectScreen extends StatefulWidget { + const ChatSelectScreen({Key? key}) : super(key: key); + + @override + State createState() => _ChatSelectScreenState(); +} + +class _ChatSelectScreenState extends State { + final searchController = TextEditingController(); + + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + return Scaffold( + appBar: AppBar( + backgroundColor: Colors.white, + toolbarHeight: 0, + ), + body: NestedScrollView( + headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { + return [ + SliverPadding( + padding: const EdgeInsets.only(top: 8), + sliver: SliverAppBar( + automaticallyImplyLeading: false, + stretchTriggerOffset: 1, + scrolledUnderElevation: 0, + floating: true, + snap: true, + title: Padding( + padding: const EdgeInsets.only(top: 8), + child: ChatSearchBarWidget( + onChanged: (query) { + if (query.length > 2) { + EasyDebounce.debounce( + 'searchChatRoom', + Duration(milliseconds: 300), + () => context.read().getChatRooms(query: query), + ); + } else { + context.read().getChatRooms(); + } + }, + controller: searchController, + fillColor: Color(0xFFF0F2F5), + hintText: "Поиск", + hintStyle: TextStyle( + color: Color(0xFF7B8794), + ), + ), + ), + ), + ), + ]; + }, + body: stateBuilder(state), + ), + ); + }, + ); + } + + stateBuilder(state) { + if (state is ChatSelectStateLoading) { + return Scaffold( + body: Center( + child: CupertinoActivityIndicator(), + ), + ); + } else if (state is ChatSelectStateLoaded) { + return _buildChatList(context, state); + } else if (state is ChatSelectStateError) { + return Padding( + padding: const EdgeInsets.all(16), + child: Center(child: Text(state.errorMessage)), + ); + } else { + return Scaffold( + body: Center( + child: CupertinoActivityIndicator(), + ), + ); + } + } +} + +_buildChatList(BuildContext context, ChatSelectStateLoaded state) { + return ListView.separated( + padding: EdgeInsets.all(16), + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + separatorBuilder: (context, index) { + return SizedBox( + height: 8, + ); + }, + itemCount: state.chatRooms.length, + itemBuilder: (context, index) { + return ChatEntryWidget(chatRoom: state.chatRooms[index]); + }, + ); +} diff --git a/lib/features/chat/presentation/pages/chat_select_screen/bloc/chat_select_bloc.dart b/lib/features/chat/presentation/pages/chat_select_screen/bloc/chat_select_bloc.dart deleted file mode 100644 index 0985a2f0..00000000 --- a/lib/features/chat/presentation/pages/chat_select_screen/bloc/chat_select_bloc.dart +++ /dev/null @@ -1,100 +0,0 @@ -import 'dart:convert'; - -import 'package:eatvio_app/app_router.dart'; -import 'package:eatvio_app/features/chat/presentation/pages/chat_select_screen/models/chat_entry.dart'; -import 'package:eatvio_app/features/chat/presentation/pages/chat_select_screen/models/chat_select_model.dart'; -import 'package:equatable/equatable.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; -import 'package:go_router/go_router.dart'; -import 'package:hive/hive.dart'; -import 'package:http/http.dart' as http; -import 'package:intl/intl.dart'; - -import '/core/app_export.dart'; - -part 'chat_select_event.dart'; -part 'chat_select_state.dart'; - -/// A bloc that manages the state of a ChatSelect according to the event that is dispatched to it. -/// - -class ChatSelectBloc extends Bloc { - ChatSelectBloc(ChatSelectState initialState) : super(initialState) { - on(_onInitialize); - } - - List fillChatEntryList(List chatRooms) { - List chats = []; - for (int i = 0; i < chatRooms.length; i++) { - String text = chatRooms[i]['last_message'] is List ? '' : chatRooms[i]['last_message']['data']; - if (chatRooms[i]['last_message'] is! List && chatRooms[i]['last_message']['is_author_message_auth_user'] != null) { - text = "Вы: " + text; - } - chats.add( - ChatItemModel( - id: chatRooms[i]['id'], - username: chatRooms[i]['users']['to_chat_user']['name'], - dateText: chatRooms[i]['last_message'] is List - ? '' - : DateFormat('dd.MM').format( - DateTime.parse( - chatRooms[i]['last_message']['updated_at'], - ), - ), - greetingText: text, - ), - ); - } - return chats; - } - - Future _onInitialize( - ChatSelectInitialEvent event, - Emitter emit, - ) async { - try { - final box = await Hive.openBox('token'); - final token = box.get('token'); - if (token == null) { - AppRouter.navigatorKey.currentContext?.goNamed('authScreen'); - } - final response = await http.get( - Uri.parse(baseUrl + '/api/chat/index'), - headers: { - 'Authorization': 'Bearer $token', - }, - ); - if (response.statusCode == 200) { - final data = jsonDecode(response.body); - if (data is Map && data.containsKey('chatRooms')) { - if (state is ChatSelectLoadedState) { - var currentState = state as ChatSelectLoadedState; - emit( - currentState.copyWith( - chatSelectModelObj: currentState.chatSelectModelObj, - chatRooms: currentState.chatRooms, - ), - ); - } else { - emit( - ChatSelectLoadedState( - chatRooms: fillChatEntryList(data['chatRooms']), - //chatRooms: [], - ), - ); - } - } else { - // Один или несколько ключевых полей отсутствуют, обрабатываем ошибку - emit(ChatSelectErrorState('Некоторые необходимые данные отсутствуют.')); - } - } else { - // Статус ответа не равен 200, обрабатываем ошибку - emit(ChatSelectErrorState('Ошибка сервера: ${response.statusCode}')); - } - } catch (e) { - // Ошибка при декодировании JSON или другая ошибка выполнения - emit(ChatSelectErrorState('Ошибка при получении данных о чатах: $e')); - } - } -} diff --git a/lib/features/chat/presentation/pages/chat_select_screen/bloc/chat_select_event.dart b/lib/features/chat/presentation/pages/chat_select_screen/bloc/chat_select_event.dart deleted file mode 100644 index 681736b1..00000000 --- a/lib/features/chat/presentation/pages/chat_select_screen/bloc/chat_select_event.dart +++ /dev/null @@ -1,28 +0,0 @@ -// ignore_for_file: must_be_immutable - -part of 'chat_select_bloc.dart'; - -/// Abstract class for all events that can be dispatched from the -///ChatSelect widget. -/// -/// Events must be immutable and implement the [Equatable] interface. -@immutable -abstract class ChatSelectEvent extends Equatable {} - -/// Event that is dispatched when the ChatSelect widget is first created. -class ChatSelectInitialEvent extends ChatSelectEvent { - @override - List get props => []; -} - -///event for dropdown selection -class ChangeDropDownEvent extends ChatSelectEvent { - ChangeDropDownEvent({required this.value}); - - SelectionPopupModel value; - - @override - List get props => [ - value, - ]; -} diff --git a/lib/features/chat/presentation/pages/chat_select_screen/bloc/chat_select_state.dart b/lib/features/chat/presentation/pages/chat_select_screen/bloc/chat_select_state.dart deleted file mode 100644 index 9484c0f9..00000000 --- a/lib/features/chat/presentation/pages/chat_select_screen/bloc/chat_select_state.dart +++ /dev/null @@ -1,61 +0,0 @@ -// ignore_for_file: must_be_immutable - -part of 'chat_select_bloc.dart'; - -/// Represents the state of ChatSelect in the application. -class ChatSelectState extends Equatable { - ChatSelectState({ - this.chatSelectModelObj, - }); - - ChatSelectModel? chatSelectModelObj; - - @override - List get props => [chatSelectModelObj]; - - ChatSelectState copyWith({ChatSelectModel? chatSelectModelObj}) { - return ChatSelectState( - chatSelectModelObj: chatSelectModelObj ?? this.chatSelectModelObj, - ); - } -} - -class ChatSelectInitialState extends ChatSelectState { - ChatSelectInitialState({required ChatSelectModel chatSelectModelObj}) : super(chatSelectModelObj: chatSelectModelObj); -} - -class ChatSelectLoadedState extends ChatSelectState { - ChatSelectLoadedState({ - this.chatRooms, - this.searchController, - this.chatSelectModelObj, - }) : super(chatSelectModelObj: null); - - List? chatRooms; - TextEditingController? searchController; - ChatSelectModel? chatSelectModelObj; - - @override - List get props => [chatSelectModelObj, chatRooms, searchController]; - - ChatSelectLoadedState copyWith({ - ChatSelectModel? chatSelectModelObj, - TextEditingController? searchController, - List? chatRooms, - }) { - return ChatSelectLoadedState( - chatSelectModelObj: chatSelectModelObj ?? this.chatSelectModelObj, - chatRooms: chatRooms ?? this.chatRooms, - searchController: searchController ?? this.searchController, - ); - } -} - -class ChatSelectErrorState extends ChatSelectState { - final String errorMessage; - - ChatSelectErrorState(this.errorMessage); - - @override - List get props => [errorMessage]; -} diff --git a/lib/features/chat/presentation/pages/chat_select_screen/chat_select_screen.dart b/lib/features/chat/presentation/pages/chat_select_screen/chat_select_screen.dart deleted file mode 100644 index a47c1cb8..00000000 --- a/lib/features/chat/presentation/pages/chat_select_screen/chat_select_screen.dart +++ /dev/null @@ -1,103 +0,0 @@ -import 'package:eatvio_app/core/app_export.dart'; -import 'package:eatvio_app/features/chat/presentation/pages/chat_select_screen/models/chat_entry.dart'; -import 'package:eatvio_app/features/chat/presentation/pages/chat_select_screen/widgets/chat_entry_widget.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; - -import 'bloc/chat_select_bloc.dart'; -import 'chat_search_view.dart'; -import 'models/chat_select_model.dart'; - -class ChatSelectScreen extends StatelessWidget { - const ChatSelectScreen({Key? key}) : super(key: key); - - static Widget builder(BuildContext context) { - return BlocProvider( - create: (context) => ChatSelectBloc(ChatSelectState(chatSelectModelObj: ChatSelectModel()))..add(ChatSelectInitialEvent()), - child: ChatSelectScreen(), - ); - } - - Widget build(BuildContext context) { - return BlocBuilder( - builder: (context, state) { - if (state is ChatSelectInitialState) { - return Scaffold( - body: Center( - child: CupertinoActivityIndicator(), - ), - ); - } else if (state is ChatSelectLoadedState) { - return Scaffold( - appBar: AppBar( - backgroundColor: Colors.white, - toolbarHeight: 0, - ), - body: NestedScrollView( - headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { - return [ - SliverPadding( - padding: const EdgeInsets.only(top: 8), - sliver: SliverAppBar( - automaticallyImplyLeading: false, - stretchTriggerOffset: 1, - scrolledUnderElevation: 0, - floating: true, - snap: true, - title: Padding( - padding: const EdgeInsets.only(top: 8), - child: CustomSearchView( - onChanged: (query) { - - }, - controller: state.searchController, - fillColor: Color(0xFFF0F2F5), - hintText: "Поиск", - hintStyle: TextStyle( - color: Color(0xFF7B8794), - ), - ), - ), - ), - ), - ]; - }, - body: _buildChatList(context, state), - ), - ); - } else if (state is ChatSelectErrorState) { - return Padding( - padding: const EdgeInsets.all(16), - child: Center(child: Text(state.errorMessage)), - ); - } else { - return Scaffold( - body: Center( - child: CupertinoActivityIndicator(), - ), - ); - } - }, - ); - } -} - -_buildChatList(BuildContext context, ChatSelectLoadedState state) { - return ListView.separated( - padding: EdgeInsets.all(16), - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - separatorBuilder: (context, index) { - return SizedBox( - height: 8, - ); - }, - itemCount: state.chatRooms?.length ?? 0, - itemBuilder: (context, index) { - ChatItemModel model = state.chatRooms?[index]; - return ChatEntryWidget( - chatEntryObj: model, - ); - }, - ); -} diff --git a/lib/features/chat/presentation/pages/chat_select_screen/models/chat_entry.dart b/lib/features/chat/presentation/pages/chat_select_screen/models/chat_entry.dart deleted file mode 100644 index cffee89a..00000000 --- a/lib/features/chat/presentation/pages/chat_select_screen/models/chat_entry.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:eatvio_app/core/app_export.dart'; - -/// This class is used in the [userprofile_item_widget] screen. -// ignore_for_file: must_be_immutable - -class ChatItemModel { - String? userImage; - String? username; - String? dateText; - String? greetingText; - String id; - - ChatItemModel({ - this.userImage, - this.username, - this.dateText, - this.greetingText, - required this.id, - }) { - userImage = userImage ?? ImageConstant.imageNotFound; - username = username; - dateText = dateText; - greetingText = greetingText; - id = id; - } -} diff --git a/lib/features/chat/presentation/pages/chat_select_screen/models/chat_select_model.dart b/lib/features/chat/presentation/pages/chat_select_screen/models/chat_select_model.dart deleted file mode 100644 index e87ffa2b..00000000 --- a/lib/features/chat/presentation/pages/chat_select_screen/models/chat_select_model.dart +++ /dev/null @@ -1,22 +0,0 @@ -// ignore_for_file: must_be_immutable - -import 'package:eatvio_app/features/chat/presentation/pages/chat_select_screen/models/chat_entry.dart'; -import 'package:equatable/equatable.dart'; - -/// This class defines the variables used in the [chat_select_screen], -/// and is typically used to hold data that is passed between different parts of the application. - -class ChatSelectModel extends Equatable { - ChatSelectModel({this.chatList = const []}); - - List chatList; - - ChatSelectModel copyWith({List? chatList}) { - return ChatSelectModel( - chatList: chatList ?? this.chatList, - ); - } - - @override - List get props => [chatList]; -} diff --git a/lib/features/chat/presentation/pages/chat_select_screen/widgets/chat_entry_widget.dart b/lib/features/chat/presentation/pages/chat_select_screen/widgets/chat_entry_widget.dart deleted file mode 100644 index a8bd0f79..00000000 --- a/lib/features/chat/presentation/pages/chat_select_screen/widgets/chat_entry_widget.dart +++ /dev/null @@ -1,96 +0,0 @@ -// ignore_for_file: must_be_immutable - -import 'package:eatvio_app/core/app_export.dart'; -import 'package:eatvio_app/features/chat/presentation/pages/chat_select_screen/models/chat_entry.dart'; -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; - -class ChatEntryWidget extends StatelessWidget { - ChatEntryWidget({ - required this.chatEntryObj, - super.key, - }); - - ChatItemModel chatEntryObj; - - @override - Widget build(BuildContext context) { - return InkWell( - borderRadius: BorderRadius.circular(16), - onTap: () => GoRouter.of(context).pushNamed( - 'chatScreen', - extra: chatEntryObj.id.toString(), - ), - child: Ink( - padding: EdgeInsets.all(16), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(16), - color: Color(0xFFF6FAFF), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - width: 48, - height: 48, - alignment: Alignment.center, - decoration: BoxDecoration( - color: Color(0xFFEBF4FF), - shape: BoxShape.circle, - ), - child: Text( - chatEntryObj.username!.split(' ').first[0] + chatEntryObj.username!.split(' ')[1][0], - style: TextStyle( - color: Color(0xFF7F9CF5), - fontWeight: FontWeight.w400, - fontSize: 20, - ), - ), - ), - SizedBox(width: 12), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Text( - chatEntryObj.username!.length <= 15 ? chatEntryObj.username! : chatEntryObj.username!.substring(0, 15) + '...', - style: theme.textTheme.titleMedium, - ), - Spacer(), - CustomImageView( - imagePath: ImageConstant.imageNotFound, - height: 9.v, - width: 16.h, - margin: EdgeInsets.only( - top: 4.v, - bottom: 6.v, - ), - ), - Padding( - padding: EdgeInsets.only(left: 6.h), - child: Text( - chatEntryObj.dateText!, - style: theme.textTheme.bodyMedium, - ), - ), - ], - ), - SizedBox(height: 6.v), - Text( - chatEntryObj.greetingText!.trim(), - maxLines: 2, - overflow: TextOverflow.ellipsis, - style: CustomTextStyles.bodyMediumBluegray800, - ), - ], - ), - ), - ], - ), - ), - ); - } -} diff --git a/lib/features/chat/presentation/widgets/chat_entry_widget.dart b/lib/features/chat/presentation/widgets/chat_entry_widget.dart new file mode 100644 index 00000000..0054e8f2 --- /dev/null +++ b/lib/features/chat/presentation/widgets/chat_entry_widget.dart @@ -0,0 +1,116 @@ +import 'package:eatvio_app/core/app_export.dart'; +import 'package:eatvio_app/features/chat/models/chat_room_preview_model.dart'; +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; + +class ChatEntryWidget extends StatefulWidget { + final ChatRoom chatRoom; + + ChatEntryWidget({ + required this.chatRoom, + super.key, + }); + + @override + State createState() => _ChatEntryWidgetState(); +} + +class _ChatEntryWidgetState extends State { + LastMessageClass? lastMessage; + + @override + void initState() { + super.initState(); + if (widget.chatRoom.lastMessage is Map) { + lastMessage = LastMessageClass.fromJson(widget.chatRoom.lastMessage); + } + } + + @override + Widget build(BuildContext context) { + return InkWell( + borderRadius: BorderRadius.circular(16), + onTap: () => GoRouter.of(context).pushNamed( + 'chatScreen', + extra: widget.chatRoom.id.toString(), + ), + child: Ink( + padding: EdgeInsets.all(16), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(16), + color: Color(0xFFF6FAFF), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + widget.chatRoom.users.toChatUser.profilePhotoPath == null + ? buildAvatarByUsername(widget.chatRoom.users.toChatUser.name) + : CircleAvatar( + radius: 24, + backgroundImage: NetworkImage( + widget.chatRoom.users.toChatUser.profilePhotoUrl, + ), + backgroundColor: Colors.white, + ), + SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Text( + widget.chatRoom.users.toChatUser.name.length <= 20 + ? widget.chatRoom.users.toChatUser.name + : widget.chatRoom.users.toChatUser.name.substring(0, 20) + '...', + style: theme.textTheme.titleMedium, + ), + Spacer(), + if (lastMessage != null) + Padding( + padding: EdgeInsets.only(left: 8), + child: Text( + lastMessage!.updatedAt.format('dd MMM', 'ru'), + style: theme.textTheme.bodyMedium, + ), + ), + ], + ), + SizedBox(height: 8), + if (lastMessage != null) + Text( + lastMessage!.data.toString().trim(), + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: CustomTextStyles.bodyMediumBluegray800, + ), + ], + ), + ), + ], + ), + ), + ); + } + + buildAvatarByUsername(String username) { + return Container( + width: 48, + height: 48, + alignment: Alignment.center, + decoration: BoxDecoration( + color: Color(0xFFEBF4FF), + shape: BoxShape.circle, + ), + child: Text( + username.split(' ').first[0] + username.split(' ')[1][0], + style: TextStyle( + color: Color(0xFF7F9CF5), + fontWeight: FontWeight.w400, + fontSize: 20, + ), + ), + ); + } +} diff --git a/lib/features/chat/presentation/pages/chat_select_screen/chat_search_view.dart b/lib/features/chat/presentation/widgets/chat_search_bar_widget.dart similarity index 97% rename from lib/features/chat/presentation/pages/chat_select_screen/chat_search_view.dart rename to lib/features/chat/presentation/widgets/chat_search_bar_widget.dart index 15f6c44b..d2baebb1 100644 --- a/lib/features/chat/presentation/pages/chat_select_screen/chat_search_view.dart +++ b/lib/features/chat/presentation/widgets/chat_search_bar_widget.dart @@ -1,8 +1,8 @@ import 'package:eatvio_app/core/app_export.dart'; import 'package:flutter/material.dart'; -class CustomSearchView extends StatelessWidget { - CustomSearchView({ +class ChatSearchBarWidget extends StatelessWidget { + ChatSearchBarWidget({ Key? key, this.alignment, this.width, diff --git a/lib/features/chat/repositories/chat_repository.dart b/lib/features/chat/repositories/chat_repository.dart index d5e67be1..0f0be7de 100644 --- a/lib/features/chat/repositories/chat_repository.dart +++ b/lib/features/chat/repositories/chat_repository.dart @@ -1,5 +1,6 @@ import 'dart:io'; import 'package:dio/dio.dart'; +import 'package:eatvio_app/features/chat/models/chat_room_preview_model.dart'; import 'package:http_parser/http_parser.dart'; import 'package:eatvio_app/features/chat/models/chat_messages_model.dart'; import 'package:eatvio_app/features/chat/models/chat_room_model.dart'; @@ -53,6 +54,15 @@ class ChatRepository { } } + Future> getChatRoomPreiews({String? query}) async { + try { + return (await chatService.getChatRoomPreviews(query: query)).chatRooms; + } catch (e) { + print(e); + rethrow; + } + } + Future getChatMessages(String chatId, int page) async { try { return (await chatService.getChatMessages(id: chatId, page: page)); diff --git a/lib/features/chat/services/chat_service.dart b/lib/features/chat/services/chat_service.dart index 6061e7eb..3bbb74ff 100644 --- a/lib/features/chat/services/chat_service.dart +++ b/lib/features/chat/services/chat_service.dart @@ -1,6 +1,7 @@ import 'package:dio/dio.dart'; import 'package:eatvio_app/features/chat/models/chat_messages_model.dart'; import 'package:eatvio_app/features/chat/models/chat_room_model.dart'; +import 'package:eatvio_app/features/chat/models/chat_room_preview_model.dart'; import 'package:eatvio_app/features/chat/models/websocket_info_model.dart'; import 'package:retrofit/retrofit.dart'; @@ -10,6 +11,11 @@ part 'chat_service.g.dart'; abstract class ChatService { factory ChatService(Dio dio, {String baseUrl}) = _ChatService; + @GET('/api/chat/index') + Future getChatRoomPreviews({ + @Query('find') String? query, + }); + @GET('/api/chat/show/{id}') Future> getChatRoom({ @Path() required String id, diff --git a/lib/features/chat/services/chat_service.g.dart b/lib/features/chat/services/chat_service.g.dart index efa7d26b..4e84a7b3 100644 --- a/lib/features/chat/services/chat_service.g.dart +++ b/lib/features/chat/services/chat_service.g.dart @@ -21,6 +21,40 @@ class _ChatService implements ChatService { final ParseErrorLogger? errorLogger; + @override + Future getChatRoomPreviews({String? query}) async { + final _extra = {}; + final queryParameters = {r'find': query}; + queryParameters.removeWhere((k, v) => v == null); + final _headers = {}; + const Map? _data = null; + final _options = _setStreamType(Options( + method: 'GET', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + '/api/chat/index', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + ))); + final _result = await _dio.fetch>(_options); + late ChatRoomPreviewModel _value; + try { + _value = ChatRoomPreviewModel.fromJson(_result.data!); + } on Object catch (e, s) { + errorLogger?.logError(e, s, _options); + rethrow; + } + return _value; + } + @override Future> getChatRoom({required String id}) async { final _extra = {}; diff --git a/lib/locator_service.dart b/lib/locator_service.dart index 52d3f37f..f0a28808 100644 --- a/lib/locator_service.dart +++ b/lib/locator_service.dart @@ -7,6 +7,7 @@ import 'package:eatvio_app/features/calendar/presentation/bloc/calendar_cubit.da import 'package:eatvio_app/features/calendar/repositories/calendar_repository.dart'; import 'package:eatvio_app/features/calendar/services/calendar_service.dart'; import 'package:eatvio_app/features/chat/presentation/bloc/chat_room_cubit/chat_room_cubit.dart'; +import 'package:eatvio_app/features/chat/presentation/bloc/chat_select_cubit/chat_select_cubit.dart'; import 'package:eatvio_app/features/chat/repositories/chat_repository.dart'; import 'package:eatvio_app/features/chat/services/chat_service.dart'; import 'package:eatvio_app/features/diary/presentation/bloc/diary_bloc.dart'; @@ -47,6 +48,7 @@ Future init() async { sl.registerFactory(() => RecipeCreateCubit(recipeRepository: sl())); sl.registerFactory(() => DietsCubit(feedRepository: sl())); sl.registerFactory(() => CommentsCubit(feedRepository: sl())); + sl.registerFactory(() => ChatSelectCubit(chatRepository: sl())); // Repository sl.registerLazySingleton(() => ChatRepository(chatService: sl())); diff --git a/lib/main.dart b/lib/main.dart index 8a9f334c..34f37ccf 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -4,8 +4,7 @@ import 'package:eatvio_app/core/initialization_cubit/initialization_state.dart'; import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/new_messages_cubit/new_messages_cubit.dart'; import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/notifications_cubit/notifications_cubit.dart'; import 'package:eatvio_app/features/calendar/presentation/bloc/calendar_cubit.dart'; -import 'package:eatvio_app/features/chat/presentation/pages/chat_select_screen/bloc/chat_select_bloc.dart'; -import 'package:eatvio_app/features/chat/presentation/pages/chat_select_screen/models/chat_select_model.dart'; +import 'package:eatvio_app/features/chat/presentation/bloc/chat_select_cubit/chat_select_cubit.dart'; import 'package:eatvio_app/features/diary/presentation/bloc/diary_bloc.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart'; @@ -56,9 +55,7 @@ class MyApp extends StatelessWidget { BlocProvider(create: (context) => sl()..loadDiets()), BlocProvider(create: (context) => MyProfileBloc(MyProfileState(myProfileModelObj: MyProfileModel()))..add(MyProfileInitialEvent())), BlocProvider(create: (context) => sl()..add(LoadDiary())), - BlocProvider( - create: (context) => ChatSelectBloc(ChatSelectState(chatSelectModelObj: ChatSelectModel()))..add(ChatSelectInitialEvent()), - ), + BlocProvider(create: (context) => sl()..getChatRooms()), BlocProvider(create: (context) => sl()..loadCalendarList()), BlocProvider(create: (context) => sl()..loadRecipeCreate()), ],