feat(chat): add init and dispose chat, typing info, receive a messages

This commit is contained in:
alex
2024-07-03 16:50:09 +03:00
parent 424ce3cb34
commit 4c7519ee4c
27 changed files with 553 additions and 167 deletions

View File

@@ -3,29 +3,13 @@ import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/core/initialization_cubit/initialization_state.dart';
import 'package:eatvio_app/core/token_storage.dart';
import 'package:eatvio_app/features/chat/repositories/chat_repository.dart';
import 'package:dio/dio.dart';
class InitializationCubit extends Cubit<InitializationState> {
final ChatRepository chatRepository;
InitializationCubit({required this.chatRepository}) : super(const InitializationState.loading());
// final myPrivateChannel = client.privateChannel(
// 'private-new-chat-messages.${wsUrl.userId}',
// authorizationDelegate: EndpointAuthorizableChannelTokenAuthorizationDelegate.forPrivateChannel(
// authorizationEndpoint: Uri.parse('https://mobile-stage.eatvio.ru/broadcasting/auth'),
// headers: {
// 'Authorization': 'Bearer ${await TokenStorage.getTokenFromStorage()}',
// },
// ),
// );
// myPrivateChannel.subscribe();
// myPrivateChannel.bindToAll().listen((event) {
// print(event.name);
// });
runInitialization() async {
Future<void> runInitialization() async {
try {
await TokenStorage.haveTokenInStorage();
final wsUrl = await chatRepository.getWebsocket();
@@ -63,6 +47,7 @@ class InitializationCubit extends Cubit<InitializationState> {
emit(InitializationState.error(
errorMessage: e.toString(),
));
rethrow;
}
}
}

View File

@@ -6,7 +6,7 @@ part of 'blog_post_service.dart';
// RetrofitGenerator
// **************************************************************************
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element
class _BlogPostService implements BlogPostService {
_BlogPostService(
@@ -41,8 +41,8 @@ class _BlogPostService implements BlogPostService {
_dio.options.baseUrl,
baseUrl,
))));
final value = BlogPostModel.fromJson(_result.data!);
return value;
final _value = BlogPostModel.fromJson(_result.data!);
return _value;
}
RequestOptions _setStreamType<T>(RequestOptions requestOptions) {

View File

@@ -6,7 +6,7 @@ part of 'blog_service.dart';
// RetrofitGenerator
// **************************************************************************
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element
class _BlogService implements BlogService {
_BlogService(
@@ -42,8 +42,8 @@ class _BlogService implements BlogService {
_dio.options.baseUrl,
baseUrl,
))));
final value = BlogPostCreateCredentialsModel.fromJson(_result.data!);
return value;
final _value = BlogPostCreateCredentialsModel.fromJson(_result.data!);
return _value;
}
RequestOptions _setStreamType<T>(RequestOptions requestOptions) {

View File

@@ -9,7 +9,7 @@ class ChatMessageModel with _$ChatMessageModel {
const factory ChatMessageModel({
required int id,
required String data,
@JsonKey(name: 'media_data') required List<dynamic> mediaData,
@JsonKey(name: 'media_data') required List<dynamic>? mediaData,
@JsonKey(name: 'author_id') required int authorId,
@JsonKey(name: 'updated_at') required String updatedAt,
}) = _ChatMessageModel;

View File

@@ -23,7 +23,7 @@ mixin _$ChatMessageModel {
int get id => throw _privateConstructorUsedError;
String get data => throw _privateConstructorUsedError;
@JsonKey(name: 'media_data')
List<dynamic> get mediaData => throw _privateConstructorUsedError;
List<dynamic>? get mediaData => throw _privateConstructorUsedError;
@JsonKey(name: 'author_id')
int get authorId => throw _privateConstructorUsedError;
@JsonKey(name: 'updated_at')
@@ -44,7 +44,7 @@ abstract class $ChatMessageModelCopyWith<$Res> {
$Res call(
{int id,
String data,
@JsonKey(name: 'media_data') List<dynamic> mediaData,
@JsonKey(name: 'media_data') List<dynamic>? mediaData,
@JsonKey(name: 'author_id') int authorId,
@JsonKey(name: 'updated_at') String updatedAt});
}
@@ -64,7 +64,7 @@ class _$ChatMessageModelCopyWithImpl<$Res, $Val extends ChatMessageModel>
$Res call({
Object? id = null,
Object? data = null,
Object? mediaData = null,
Object? mediaData = freezed,
Object? authorId = null,
Object? updatedAt = null,
}) {
@@ -77,10 +77,10 @@ class _$ChatMessageModelCopyWithImpl<$Res, $Val extends ChatMessageModel>
? _value.data
: data // ignore: cast_nullable_to_non_nullable
as String,
mediaData: null == mediaData
mediaData: freezed == mediaData
? _value.mediaData
: mediaData // ignore: cast_nullable_to_non_nullable
as List<dynamic>,
as List<dynamic>?,
authorId: null == authorId
? _value.authorId
: authorId // ignore: cast_nullable_to_non_nullable
@@ -104,7 +104,7 @@ abstract class _$$ChatMessageModelImplCopyWith<$Res>
$Res call(
{int id,
String data,
@JsonKey(name: 'media_data') List<dynamic> mediaData,
@JsonKey(name: 'media_data') List<dynamic>? mediaData,
@JsonKey(name: 'author_id') int authorId,
@JsonKey(name: 'updated_at') String updatedAt});
}
@@ -122,7 +122,7 @@ class __$$ChatMessageModelImplCopyWithImpl<$Res>
$Res call({
Object? id = null,
Object? data = null,
Object? mediaData = null,
Object? mediaData = freezed,
Object? authorId = null,
Object? updatedAt = null,
}) {
@@ -135,10 +135,10 @@ class __$$ChatMessageModelImplCopyWithImpl<$Res>
? _value.data
: data // ignore: cast_nullable_to_non_nullable
as String,
mediaData: null == mediaData
mediaData: freezed == mediaData
? _value._mediaData
: mediaData // ignore: cast_nullable_to_non_nullable
as List<dynamic>,
as List<dynamic>?,
authorId: null == authorId
? _value.authorId
: authorId // ignore: cast_nullable_to_non_nullable
@@ -157,7 +157,7 @@ class _$ChatMessageModelImpl implements _ChatMessageModel {
const _$ChatMessageModelImpl(
{required this.id,
required this.data,
@JsonKey(name: 'media_data') required final List<dynamic> mediaData,
@JsonKey(name: 'media_data') required final List<dynamic>? mediaData,
@JsonKey(name: 'author_id') required this.authorId,
@JsonKey(name: 'updated_at') required this.updatedAt})
: _mediaData = mediaData;
@@ -169,13 +169,15 @@ class _$ChatMessageModelImpl implements _ChatMessageModel {
final int id;
@override
final String data;
final List<dynamic> _mediaData;
final List<dynamic>? _mediaData;
@override
@JsonKey(name: 'media_data')
List<dynamic> get mediaData {
List<dynamic>? get mediaData {
final value = _mediaData;
if (value == null) return null;
if (_mediaData is EqualUnmodifiableListView) return _mediaData;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_mediaData);
return EqualUnmodifiableListView(value);
}
@override
@@ -229,7 +231,7 @@ abstract class _ChatMessageModel implements ChatMessageModel {
const factory _ChatMessageModel(
{required final int id,
required final String data,
@JsonKey(name: 'media_data') required final List<dynamic> mediaData,
@JsonKey(name: 'media_data') required final List<dynamic>? mediaData,
@JsonKey(name: 'author_id') required final int authorId,
@JsonKey(name: 'updated_at') required final String updatedAt}) =
_$ChatMessageModelImpl;
@@ -243,7 +245,7 @@ abstract class _ChatMessageModel implements ChatMessageModel {
String get data;
@override
@JsonKey(name: 'media_data')
List<dynamic> get mediaData;
List<dynamic>? get mediaData;
@override
@JsonKey(name: 'author_id')
int get authorId;

View File

@@ -11,7 +11,7 @@ _$ChatMessageModelImpl _$$ChatMessageModelImplFromJson(
_$ChatMessageModelImpl(
id: (json['id'] as num).toInt(),
data: json['data'] as String,
mediaData: json['media_data'] as List<dynamic>,
mediaData: json['media_data'] as List<dynamic>?,
authorId: (json['author_id'] as num).toInt(),
updatedAt: json['updated_at'] as String,
);

View File

@@ -0,0 +1,16 @@
import 'package:eatvio_app/features/chat/models/chat_message_model.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'chat_messages_model.freezed.dart';
part 'chat_messages_model.g.dart';
@freezed
class ChatMessagesModel with _$ChatMessagesModel {
const factory ChatMessagesModel({
@JsonKey(name: 'data')
required List<ChatMessageModel> messagesList,
}) = _ChatMessagesModel;
factory ChatMessagesModel.fromJson(Map<String, Object?> json) => _$ChatMessagesModelFromJson(json);
}

View File

@@ -0,0 +1,168 @@
// 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_messages_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');
ChatMessagesModel _$ChatMessagesModelFromJson(Map<String, dynamic> json) {
return _ChatMessagesModel.fromJson(json);
}
/// @nodoc
mixin _$ChatMessagesModel {
@JsonKey(name: 'data')
List<ChatMessageModel> get messagesList => throw _privateConstructorUsedError;
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$ChatMessagesModelCopyWith<ChatMessagesModel> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $ChatMessagesModelCopyWith<$Res> {
factory $ChatMessagesModelCopyWith(
ChatMessagesModel value, $Res Function(ChatMessagesModel) then) =
_$ChatMessagesModelCopyWithImpl<$Res, ChatMessagesModel>;
@useResult
$Res call({@JsonKey(name: 'data') List<ChatMessageModel> messagesList});
}
/// @nodoc
class _$ChatMessagesModelCopyWithImpl<$Res, $Val extends ChatMessagesModel>
implements $ChatMessagesModelCopyWith<$Res> {
_$ChatMessagesModelCopyWithImpl(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? messagesList = null,
}) {
return _then(_value.copyWith(
messagesList: null == messagesList
? _value.messagesList
: messagesList // ignore: cast_nullable_to_non_nullable
as List<ChatMessageModel>,
) as $Val);
}
}
/// @nodoc
abstract class _$$ChatMessagesModelImplCopyWith<$Res>
implements $ChatMessagesModelCopyWith<$Res> {
factory _$$ChatMessagesModelImplCopyWith(_$ChatMessagesModelImpl value,
$Res Function(_$ChatMessagesModelImpl) then) =
__$$ChatMessagesModelImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({@JsonKey(name: 'data') List<ChatMessageModel> messagesList});
}
/// @nodoc
class __$$ChatMessagesModelImplCopyWithImpl<$Res>
extends _$ChatMessagesModelCopyWithImpl<$Res, _$ChatMessagesModelImpl>
implements _$$ChatMessagesModelImplCopyWith<$Res> {
__$$ChatMessagesModelImplCopyWithImpl(_$ChatMessagesModelImpl _value,
$Res Function(_$ChatMessagesModelImpl) _then)
: super(_value, _then);
@pragma('vm:prefer-inline')
@override
$Res call({
Object? messagesList = null,
}) {
return _then(_$ChatMessagesModelImpl(
messagesList: null == messagesList
? _value._messagesList
: messagesList // ignore: cast_nullable_to_non_nullable
as List<ChatMessageModel>,
));
}
}
/// @nodoc
@JsonSerializable()
class _$ChatMessagesModelImpl implements _ChatMessagesModel {
const _$ChatMessagesModelImpl(
{@JsonKey(name: 'data')
required final List<ChatMessageModel> messagesList})
: _messagesList = messagesList;
factory _$ChatMessagesModelImpl.fromJson(Map<String, dynamic> json) =>
_$$ChatMessagesModelImplFromJson(json);
final List<ChatMessageModel> _messagesList;
@override
@JsonKey(name: 'data')
List<ChatMessageModel> get messagesList {
if (_messagesList is EqualUnmodifiableListView) return _messagesList;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_messagesList);
}
@override
String toString() {
return 'ChatMessagesModel(messagesList: $messagesList)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$ChatMessagesModelImpl &&
const DeepCollectionEquality()
.equals(other._messagesList, _messagesList));
}
@JsonKey(ignore: true)
@override
int get hashCode => Object.hash(
runtimeType, const DeepCollectionEquality().hash(_messagesList));
@JsonKey(ignore: true)
@override
@pragma('vm:prefer-inline')
_$$ChatMessagesModelImplCopyWith<_$ChatMessagesModelImpl> get copyWith =>
__$$ChatMessagesModelImplCopyWithImpl<_$ChatMessagesModelImpl>(
this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$ChatMessagesModelImplToJson(
this,
);
}
}
abstract class _ChatMessagesModel implements ChatMessagesModel {
const factory _ChatMessagesModel(
{@JsonKey(name: 'data')
required final List<ChatMessageModel> messagesList}) =
_$ChatMessagesModelImpl;
factory _ChatMessagesModel.fromJson(Map<String, dynamic> json) =
_$ChatMessagesModelImpl.fromJson;
@override
@JsonKey(name: 'data')
List<ChatMessageModel> get messagesList;
@override
@JsonKey(ignore: true)
_$$ChatMessagesModelImplCopyWith<_$ChatMessagesModelImpl> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@@ -0,0 +1,21 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'chat_messages_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_$ChatMessagesModelImpl _$$ChatMessagesModelImplFromJson(
Map<String, dynamic> json) =>
_$ChatMessagesModelImpl(
messagesList: (json['data'] as List<dynamic>)
.map((e) => ChatMessageModel.fromJson(e as Map<String, dynamic>))
.toList(),
);
Map<String, dynamic> _$$ChatMessagesModelImplToJson(
_$ChatMessagesModelImpl instance) =>
<String, dynamic>{
'data': instance.messagesList,
};

View File

@@ -1,4 +1,3 @@
import 'package:eatvio_app/features/chat/models/chat_message_model.dart';
import 'package:eatvio_app/features/chat/models/chat_room_settings_model.dart';
import 'package:eatvio_app/features/chat/models/chat_user_model.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
@@ -12,7 +11,6 @@ class ChatRoomModel with _$ChatRoomModel {
const factory ChatRoomModel({
required String id,
@JsonKey(name: 'chat_room_setting') required ChatRoomSettingsModel chatRoomSettings,
required List<ChatMessageModel> messages,
required Map<String, ChatUserModel> users,
}) = _ChatRoomModel;

View File

@@ -24,7 +24,6 @@ mixin _$ChatRoomModel {
@JsonKey(name: 'chat_room_setting')
ChatRoomSettingsModel get chatRoomSettings =>
throw _privateConstructorUsedError;
List<ChatMessageModel> get messages => throw _privateConstructorUsedError;
Map<String, ChatUserModel> get users => throw _privateConstructorUsedError;
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@@ -43,7 +42,6 @@ abstract class $ChatRoomModelCopyWith<$Res> {
{String id,
@JsonKey(name: 'chat_room_setting')
ChatRoomSettingsModel chatRoomSettings,
List<ChatMessageModel> messages,
Map<String, ChatUserModel> users});
$ChatRoomSettingsModelCopyWith<$Res> get chatRoomSettings;
@@ -64,7 +62,6 @@ class _$ChatRoomModelCopyWithImpl<$Res, $Val extends ChatRoomModel>
$Res call({
Object? id = null,
Object? chatRoomSettings = null,
Object? messages = null,
Object? users = null,
}) {
return _then(_value.copyWith(
@@ -76,10 +73,6 @@ class _$ChatRoomModelCopyWithImpl<$Res, $Val extends ChatRoomModel>
? _value.chatRoomSettings
: chatRoomSettings // ignore: cast_nullable_to_non_nullable
as ChatRoomSettingsModel,
messages: null == messages
? _value.messages
: messages // ignore: cast_nullable_to_non_nullable
as List<ChatMessageModel>,
users: null == users
? _value.users
: users // ignore: cast_nullable_to_non_nullable
@@ -109,7 +102,6 @@ abstract class _$$ChatRoomModelImplCopyWith<$Res>
{String id,
@JsonKey(name: 'chat_room_setting')
ChatRoomSettingsModel chatRoomSettings,
List<ChatMessageModel> messages,
Map<String, ChatUserModel> users});
@override
@@ -129,7 +121,6 @@ class __$$ChatRoomModelImplCopyWithImpl<$Res>
$Res call({
Object? id = null,
Object? chatRoomSettings = null,
Object? messages = null,
Object? users = null,
}) {
return _then(_$ChatRoomModelImpl(
@@ -141,10 +132,6 @@ class __$$ChatRoomModelImplCopyWithImpl<$Res>
? _value.chatRoomSettings
: chatRoomSettings // ignore: cast_nullable_to_non_nullable
as ChatRoomSettingsModel,
messages: null == messages
? _value._messages
: messages // ignore: cast_nullable_to_non_nullable
as List<ChatMessageModel>,
users: null == users
? _value._users
: users // ignore: cast_nullable_to_non_nullable
@@ -159,10 +146,8 @@ class _$ChatRoomModelImpl implements _ChatRoomModel {
const _$ChatRoomModelImpl(
{required this.id,
@JsonKey(name: 'chat_room_setting') required this.chatRoomSettings,
required final List<ChatMessageModel> messages,
required final Map<String, ChatUserModel> users})
: _messages = messages,
_users = users;
: _users = users;
factory _$ChatRoomModelImpl.fromJson(Map<String, dynamic> json) =>
_$$ChatRoomModelImplFromJson(json);
@@ -172,14 +157,6 @@ class _$ChatRoomModelImpl implements _ChatRoomModel {
@override
@JsonKey(name: 'chat_room_setting')
final ChatRoomSettingsModel chatRoomSettings;
final List<ChatMessageModel> _messages;
@override
List<ChatMessageModel> get messages {
if (_messages is EqualUnmodifiableListView) return _messages;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_messages);
}
final Map<String, ChatUserModel> _users;
@override
Map<String, ChatUserModel> get users {
@@ -190,7 +167,7 @@ class _$ChatRoomModelImpl implements _ChatRoomModel {
@override
String toString() {
return 'ChatRoomModel(id: $id, chatRoomSettings: $chatRoomSettings, messages: $messages, users: $users)';
return 'ChatRoomModel(id: $id, chatRoomSettings: $chatRoomSettings, users: $users)';
}
@override
@@ -201,17 +178,12 @@ class _$ChatRoomModelImpl implements _ChatRoomModel {
(identical(other.id, id) || other.id == id) &&
(identical(other.chatRoomSettings, chatRoomSettings) ||
other.chatRoomSettings == chatRoomSettings) &&
const DeepCollectionEquality().equals(other._messages, _messages) &&
const DeepCollectionEquality().equals(other._users, _users));
}
@JsonKey(ignore: true)
@override
int get hashCode => Object.hash(
runtimeType,
id,
chatRoomSettings,
const DeepCollectionEquality().hash(_messages),
int get hashCode => Object.hash(runtimeType, id, chatRoomSettings,
const DeepCollectionEquality().hash(_users));
@JsonKey(ignore: true)
@@ -233,7 +205,6 @@ abstract class _ChatRoomModel implements ChatRoomModel {
{required final String id,
@JsonKey(name: 'chat_room_setting')
required final ChatRoomSettingsModel chatRoomSettings,
required final List<ChatMessageModel> messages,
required final Map<String, ChatUserModel> users}) = _$ChatRoomModelImpl;
factory _ChatRoomModel.fromJson(Map<String, dynamic> json) =
@@ -245,8 +216,6 @@ abstract class _ChatRoomModel implements ChatRoomModel {
@JsonKey(name: 'chat_room_setting')
ChatRoomSettingsModel get chatRoomSettings;
@override
List<ChatMessageModel> get messages;
@override
Map<String, ChatUserModel> get users;
@override
@JsonKey(ignore: true)

View File

@@ -11,9 +11,6 @@ _$ChatRoomModelImpl _$$ChatRoomModelImplFromJson(Map<String, dynamic> json) =>
id: json['id'] as String,
chatRoomSettings: ChatRoomSettingsModel.fromJson(
json['chat_room_setting'] as Map<String, dynamic>),
messages: (json['messages'] as List<dynamic>)
.map((e) => ChatMessageModel.fromJson(e as Map<String, dynamic>))
.toList(),
users: (json['users'] as Map<String, dynamic>).map(
(k, e) =>
MapEntry(k, ChatUserModel.fromJson(e as Map<String, dynamic>)),
@@ -24,6 +21,5 @@ Map<String, dynamic> _$$ChatRoomModelImplToJson(_$ChatRoomModelImpl instance) =>
<String, dynamic>{
'id': instance.id,
'chat_room_setting': instance.chatRoomSettings,
'messages': instance.messages,
'users': instance.users,
};

View File

@@ -1,20 +1,108 @@
import 'dart:convert';
import 'package:dart_pusher_channels/dart_pusher_channels.dart';
import 'package:easy_debounce/easy_debounce.dart';
import 'package:eatvio_app/core/initialization_cubit/initialization_cubit.dart';
import 'package:eatvio_app/core/initialization_cubit/initialization_state.dart';
import 'package:eatvio_app/core/token_storage.dart';
import 'package:eatvio_app/features/chat/models/chat_message_model.dart';
import 'package:eatvio_app/features/chat/presentation/bloc/chat_room_cubit/chat_room_state.dart';
import 'package:eatvio_app/features/chat/repositories/chat_repository.dart';
import 'package:eatvio_app/locator_service.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class ChatRoomCubit extends Cubit<ChatRoomState> {
final ChatRepository chatRepository;
late final PusherChannelsClient client;
late final PrivateChannel privateChannel;
ChatRoomCubit({
required this.chatRepository,
}) : super(ChatRoomState.loading());
initChat(String chatId) async {
try {
final chatRoomModel = await chatRepository.getChatRoom(chatId);
emit(ChatRoomState.loaded(chatRoomModel: chatRoomModel));
final chatRoom = await chatRepository.getChatRoom(chatId);
final chatMessages = await chatRepository.getChatMessages(chatId);
final initCubit = sl<InitializationCubit>();
if (initCubit.state is InitializationStateSuccess) {
await subscribeToChatChannel(initCubit: initCubit, chatId: chatId);
} else {
await initCubit.runInitialization();
await subscribeToChatChannel(initCubit: initCubit, chatId: chatId);
}
emit(ChatRoomState.loaded(
chatRoom: chatRoom,
chatMessages: chatMessages,
isTyping: false,
));
} catch (e) {
emit(ChatRoomState.error(errorMessage: 'Ошибка получеия данных'));
}
}
Future<void> subscribeToChatChannel({
required InitializationCubit initCubit,
required String chatId,
}) async {
client = (initCubit.state as InitializationStateSuccess).client;
privateChannel = await client.privateChannel(
'private-direct-chat.$chatId',
authorizationDelegate: EndpointAuthorizableChannelTokenAuthorizationDelegate.forPrivateChannel(
authorizationEndpoint: Uri.parse('https://mobile-stage.eatvio.ru/broadcasting/auth'),
headers: {
'Authorization': 'Bearer ${await TokenStorage.getTokenFromStorage()}',
},
),
);
privateChannel.subscribe();
privateChannel.bind('App\\Events\\ChatMessageUpdated').listen((event) {
List<ChatMessageModel> messagesList = [
ChatMessageModel.fromJson(jsonDecode(event.data)['message']),
...(state as ChatRoomStateLoaded).chatMessages.messagesList,
];
emit(
ChatRoomState.loaded(
chatRoom: (state as ChatRoomStateLoaded).chatRoom,
chatMessages: (state as ChatRoomStateLoaded).chatMessages.copyWith(messagesList: messagesList),
isTyping: (state as ChatRoomStateLoaded).isTyping,
),
);
});
privateChannel.bind('client-typing').listen((event) {
emit(
ChatRoomState.loaded(
chatRoom: (state as ChatRoomStateLoaded).chatRoom,
chatMessages: (state as ChatRoomStateLoaded).chatMessages,
isTyping: true,
),
);
EasyDebounce.debounce(
'client-typing',
Duration(seconds: 3),
() => emit(
ChatRoomState.loaded(
chatRoom: (state as ChatRoomStateLoaded).chatRoom,
chatMessages: (state as ChatRoomStateLoaded).chatMessages,
isTyping: false,
),
),
);
});
}
@override
Future<void> close() async {
privateChannel.unsubscribe();
super.close();
}
}

View File

@@ -1,3 +1,4 @@
import 'package:eatvio_app/features/chat/models/chat_messages_model.dart';
import 'package:eatvio_app/features/chat/models/chat_room_model.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
@@ -10,7 +11,9 @@ abstract class ChatRoomState with _$ChatRoomState {
const factory ChatRoomState.loading() = ChatRoomStateLoading;
const factory ChatRoomState.loaded({
required ChatRoomModel chatRoomModel,
required ChatRoomModel chatRoom,
required ChatMessagesModel chatMessages,
required bool isTyping,
}) = ChatRoomStateLoaded;
const factory ChatRoomState.error({

View File

@@ -20,7 +20,9 @@ mixin _$ChatRoomState {
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() loading,
required TResult Function(ChatRoomModel chatRoomModel) loaded,
required TResult Function(ChatRoomModel chatRoom,
ChatMessagesModel chatMessages, bool isTyping)
loaded,
required TResult Function(String errorMessage) error,
}) =>
throw _privateConstructorUsedError;
@@ -28,7 +30,9 @@ mixin _$ChatRoomState {
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function()? loading,
TResult? Function(ChatRoomModel chatRoomModel)? loaded,
TResult? Function(ChatRoomModel chatRoom, ChatMessagesModel chatMessages,
bool isTyping)?
loaded,
TResult? Function(String errorMessage)? error,
}) =>
throw _privateConstructorUsedError;
@@ -36,7 +40,9 @@ mixin _$ChatRoomState {
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function()? loading,
TResult Function(ChatRoomModel chatRoomModel)? loaded,
TResult Function(ChatRoomModel chatRoom, ChatMessagesModel chatMessages,
bool isTyping)?
loaded,
TResult Function(String errorMessage)? error,
required TResult orElse(),
}) =>
@@ -126,7 +132,9 @@ class _$ChatRoomStateImpl implements _ChatRoomState {
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() loading,
required TResult Function(ChatRoomModel chatRoomModel) loaded,
required TResult Function(ChatRoomModel chatRoom,
ChatMessagesModel chatMessages, bool isTyping)
loaded,
required TResult Function(String errorMessage) error,
}) {
return $default();
@@ -137,7 +145,9 @@ class _$ChatRoomStateImpl implements _ChatRoomState {
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function()? loading,
TResult? Function(ChatRoomModel chatRoomModel)? loaded,
TResult? Function(ChatRoomModel chatRoom, ChatMessagesModel chatMessages,
bool isTyping)?
loaded,
TResult? Function(String errorMessage)? error,
}) {
return $default?.call();
@@ -148,7 +158,9 @@ class _$ChatRoomStateImpl implements _ChatRoomState {
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function()? loading,
TResult Function(ChatRoomModel chatRoomModel)? loaded,
TResult Function(ChatRoomModel chatRoom, ChatMessagesModel chatMessages,
bool isTyping)?
loaded,
TResult Function(String errorMessage)? error,
required TResult orElse(),
}) {
@@ -241,7 +253,9 @@ class _$ChatRoomStateLoadingImpl implements ChatRoomStateLoading {
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() loading,
required TResult Function(ChatRoomModel chatRoomModel) loaded,
required TResult Function(ChatRoomModel chatRoom,
ChatMessagesModel chatMessages, bool isTyping)
loaded,
required TResult Function(String errorMessage) error,
}) {
return loading();
@@ -252,7 +266,9 @@ class _$ChatRoomStateLoadingImpl implements ChatRoomStateLoading {
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function()? loading,
TResult? Function(ChatRoomModel chatRoomModel)? loaded,
TResult? Function(ChatRoomModel chatRoom, ChatMessagesModel chatMessages,
bool isTyping)?
loaded,
TResult? Function(String errorMessage)? error,
}) {
return loading?.call();
@@ -263,7 +279,9 @@ class _$ChatRoomStateLoadingImpl implements ChatRoomStateLoading {
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function()? loading,
TResult Function(ChatRoomModel chatRoomModel)? loaded,
TResult Function(ChatRoomModel chatRoom, ChatMessagesModel chatMessages,
bool isTyping)?
loaded,
TResult Function(String errorMessage)? error,
required TResult orElse(),
}) {
@@ -321,9 +339,11 @@ abstract class _$$ChatRoomStateLoadedImplCopyWith<$Res> {
$Res Function(_$ChatRoomStateLoadedImpl) then) =
__$$ChatRoomStateLoadedImplCopyWithImpl<$Res>;
@useResult
$Res call({ChatRoomModel chatRoomModel});
$Res call(
{ChatRoomModel chatRoom, ChatMessagesModel chatMessages, bool isTyping});
$ChatRoomModelCopyWith<$Res> get chatRoomModel;
$ChatRoomModelCopyWith<$Res> get chatRoom;
$ChatMessagesModelCopyWith<$Res> get chatMessages;
}
/// @nodoc
@@ -337,21 +357,39 @@ class __$$ChatRoomStateLoadedImplCopyWithImpl<$Res>
@pragma('vm:prefer-inline')
@override
$Res call({
Object? chatRoomModel = null,
Object? chatRoom = null,
Object? chatMessages = null,
Object? isTyping = null,
}) {
return _then(_$ChatRoomStateLoadedImpl(
chatRoomModel: null == chatRoomModel
? _value.chatRoomModel
: chatRoomModel // ignore: cast_nullable_to_non_nullable
chatRoom: null == chatRoom
? _value.chatRoom
: chatRoom // ignore: cast_nullable_to_non_nullable
as ChatRoomModel,
chatMessages: null == chatMessages
? _value.chatMessages
: chatMessages // ignore: cast_nullable_to_non_nullable
as ChatMessagesModel,
isTyping: null == isTyping
? _value.isTyping
: isTyping // ignore: cast_nullable_to_non_nullable
as bool,
));
}
@override
@pragma('vm:prefer-inline')
$ChatRoomModelCopyWith<$Res> get chatRoomModel {
return $ChatRoomModelCopyWith<$Res>(_value.chatRoomModel, (value) {
return _then(_value.copyWith(chatRoomModel: value));
$ChatRoomModelCopyWith<$Res> get chatRoom {
return $ChatRoomModelCopyWith<$Res>(_value.chatRoom, (value) {
return _then(_value.copyWith(chatRoom: value));
});
}
@override
@pragma('vm:prefer-inline')
$ChatMessagesModelCopyWith<$Res> get chatMessages {
return $ChatMessagesModelCopyWith<$Res>(_value.chatMessages, (value) {
return _then(_value.copyWith(chatMessages: value));
});
}
}
@@ -359,14 +397,21 @@ class __$$ChatRoomStateLoadedImplCopyWithImpl<$Res>
/// @nodoc
class _$ChatRoomStateLoadedImpl implements ChatRoomStateLoaded {
const _$ChatRoomStateLoadedImpl({required this.chatRoomModel});
const _$ChatRoomStateLoadedImpl(
{required this.chatRoom,
required this.chatMessages,
required this.isTyping});
@override
final ChatRoomModel chatRoomModel;
final ChatRoomModel chatRoom;
@override
final ChatMessagesModel chatMessages;
@override
final bool isTyping;
@override
String toString() {
return 'ChatRoomState.loaded(chatRoomModel: $chatRoomModel)';
return 'ChatRoomState.loaded(chatRoom: $chatRoom, chatMessages: $chatMessages, isTyping: $isTyping)';
}
@override
@@ -374,12 +419,17 @@ class _$ChatRoomStateLoadedImpl implements ChatRoomStateLoaded {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$ChatRoomStateLoadedImpl &&
(identical(other.chatRoomModel, chatRoomModel) ||
other.chatRoomModel == chatRoomModel));
(identical(other.chatRoom, chatRoom) ||
other.chatRoom == chatRoom) &&
(identical(other.chatMessages, chatMessages) ||
other.chatMessages == chatMessages) &&
(identical(other.isTyping, isTyping) ||
other.isTyping == isTyping));
}
@override
int get hashCode => Object.hash(runtimeType, chatRoomModel);
int get hashCode =>
Object.hash(runtimeType, chatRoom, chatMessages, isTyping);
@JsonKey(ignore: true)
@override
@@ -393,10 +443,12 @@ class _$ChatRoomStateLoadedImpl implements ChatRoomStateLoaded {
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() loading,
required TResult Function(ChatRoomModel chatRoomModel) loaded,
required TResult Function(ChatRoomModel chatRoom,
ChatMessagesModel chatMessages, bool isTyping)
loaded,
required TResult Function(String errorMessage) error,
}) {
return loaded(chatRoomModel);
return loaded(chatRoom, chatMessages, isTyping);
}
@override
@@ -404,10 +456,12 @@ class _$ChatRoomStateLoadedImpl implements ChatRoomStateLoaded {
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function()? loading,
TResult? Function(ChatRoomModel chatRoomModel)? loaded,
TResult? Function(ChatRoomModel chatRoom, ChatMessagesModel chatMessages,
bool isTyping)?
loaded,
TResult? Function(String errorMessage)? error,
}) {
return loaded?.call(chatRoomModel);
return loaded?.call(chatRoom, chatMessages, isTyping);
}
@override
@@ -415,12 +469,14 @@ class _$ChatRoomStateLoadedImpl implements ChatRoomStateLoaded {
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function()? loading,
TResult Function(ChatRoomModel chatRoomModel)? loaded,
TResult Function(ChatRoomModel chatRoom, ChatMessagesModel chatMessages,
bool isTyping)?
loaded,
TResult Function(String errorMessage)? error,
required TResult orElse(),
}) {
if (loaded != null) {
return loaded(chatRoomModel);
return loaded(chatRoom, chatMessages, isTyping);
}
return orElse();
}
@@ -465,9 +521,13 @@ class _$ChatRoomStateLoadedImpl implements ChatRoomStateLoaded {
abstract class ChatRoomStateLoaded implements ChatRoomState {
const factory ChatRoomStateLoaded(
{required final ChatRoomModel chatRoomModel}) = _$ChatRoomStateLoadedImpl;
{required final ChatRoomModel chatRoom,
required final ChatMessagesModel chatMessages,
required final bool isTyping}) = _$ChatRoomStateLoadedImpl;
ChatRoomModel get chatRoomModel;
ChatRoomModel get chatRoom;
ChatMessagesModel get chatMessages;
bool get isTyping;
@JsonKey(ignore: true)
_$$ChatRoomStateLoadedImplCopyWith<_$ChatRoomStateLoadedImpl> get copyWith =>
throw _privateConstructorUsedError;
@@ -541,7 +601,9 @@ class _$ChatRoomStateErrorImpl implements ChatRoomStateError {
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() loading,
required TResult Function(ChatRoomModel chatRoomModel) loaded,
required TResult Function(ChatRoomModel chatRoom,
ChatMessagesModel chatMessages, bool isTyping)
loaded,
required TResult Function(String errorMessage) error,
}) {
return error(errorMessage);
@@ -552,7 +614,9 @@ class _$ChatRoomStateErrorImpl implements ChatRoomStateError {
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function()? loading,
TResult? Function(ChatRoomModel chatRoomModel)? loaded,
TResult? Function(ChatRoomModel chatRoom, ChatMessagesModel chatMessages,
bool isTyping)?
loaded,
TResult? Function(String errorMessage)? error,
}) {
return error?.call(errorMessage);
@@ -563,7 +627,9 @@ class _$ChatRoomStateErrorImpl implements ChatRoomStateError {
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function()? loading,
TResult Function(ChatRoomModel chatRoomModel)? loaded,
TResult Function(ChatRoomModel chatRoom, ChatMessagesModel chatMessages,
bool isTyping)?
loaded,
TResult Function(String errorMessage)? error,
required TResult orElse(),
}) {

View File

@@ -19,6 +19,8 @@ class ChatScreen extends StatefulWidget {
}
class _ChatScreenState extends State<ChatScreen> {
final scrollController = ScrollController();
Widget build(BuildContext context) {
return BlocProvider<ChatRoomCubit>(
create: (BuildContext context) => sl()..initChat(widget.chatId),
@@ -33,7 +35,12 @@ class _ChatScreenState extends State<ChatScreen> {
} else if (state is ChatRoomStateLoaded) {
return _buildChat(context, state);
} else if (state is ChatRoomStateError) {
return Center(child: Text(state.errorMessage));
return Scaffold(
appBar: AppBar(),
body: Center(
child: Text(state.errorMessage),
),
);
} else {
return Scaffold(
body: Center(
@@ -46,6 +53,16 @@ class _ChatScreenState extends State<ChatScreen> {
);
}
void setupScrollController(BuildContext context) {
scrollController.addListener(() {
if (scrollController.position.atEdge) {
if (scrollController.position.pixels != 0) {
context.read<ChatRoomCubit>();
}
}
});
}
_buildChat(BuildContext context, ChatRoomStateLoaded state) {
mediaQueryData = MediaQuery.of(context);
return Scaffold(
@@ -68,7 +85,7 @@ class _ChatScreenState extends State<ChatScreen> {
shape: BoxShape.circle,
),
child: Text(
state.chatRoomModel.users['to_chat_user']!.name.split(' ').first[0] + state.chatRoomModel.users['to_chat_user']!.name.split(' ')[1][0],
state.chatRoom.users['to_chat_user']!.name.split(' ').first[0] + state.chatRoom.users['to_chat_user']!.name.split(' ')[1][0],
style: TextStyle(
color: Color(0xFF7F9CF5),
fontWeight: FontWeight.w400,
@@ -77,11 +94,27 @@ class _ChatScreenState extends State<ChatScreen> {
),
),
SizedBox(width: 16),
Text(
state.chatRoomModel.users['to_chat_user']!.name,
style: CustomTextStyles.titleSmallBold.copyWith(
color: PrimaryColors().blueGray800,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
state.chatRoom.users['to_chat_user']!.name,
style: CustomTextStyles.titleSmallBold.copyWith(
color: PrimaryColors().blueGray800,
),
),
AnimatedCrossFade(
firstChild: Text(
'Печатает...',
style: CustomTextStyles.bodySmallMulishPrimary,
),
firstCurve: Curves.easeIn,
secondCurve: Curves.easeOut,
secondChild: const SizedBox.shrink(),
crossFadeState: state.isTyping ? CrossFadeState.showFirst : CrossFadeState.showSecond,
duration: Duration(milliseconds: 150),
),
],
),
],
),
@@ -95,6 +128,8 @@ class _ChatScreenState extends State<ChatScreen> {
color: Color(0xFFF0F2F5),
width: double.maxFinite,
child: CustomScrollView(
physics: BouncingScrollPhysics(),
controller: scrollController,
reverse: true,
slivers: [
SliverPadding(
@@ -102,12 +137,11 @@ class _ChatScreenState extends State<ChatScreen> {
sliver: SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => ChatBubbleWidget(
text: state.chatRoomModel.messages[state.chatRoomModel.messages.length - index - 1].data,
isCurrentUser: state.chatRoomModel.users['to_chat_user']!.id !=
state.chatRoomModel.messages[state.chatRoomModel.messages.length - index - 1].authorId,
mediaData: state.chatRoomModel.messages[state.chatRoomModel.messages.length - index - 1].mediaData,
text: state.chatMessages.messagesList[index].data.trim(),
isCurrentUser: state.chatRoom.users['to_chat_user']!.id != state.chatMessages.messagesList[index].authorId,
mediaData: state.chatMessages.messagesList[index].mediaData ?? [],
),
childCount: state.chatRoomModel.messages.length,
childCount: state.chatMessages.messagesList.length,
),
),
),

View File

@@ -80,7 +80,7 @@ class ChatEntryWidget extends StatelessWidget {
),
SizedBox(height: 6.v),
Text(
chatEntryObj.greetingText!,
chatEntryObj.greetingText!.trim(),
style: CustomTextStyles.bodyMediumBluegray800,
),
],

View File

@@ -11,12 +11,12 @@ class ChatBubbleWidget extends StatelessWidget {
super.key,
required this.text,
required this.isCurrentUser,
this.mediaData,
required this.mediaData,
});
final String text;
final bool isCurrentUser;
final List<dynamic>? mediaData;
final List<dynamic> mediaData;
@override
Widget build(BuildContext context) {
@@ -32,23 +32,24 @@ class ChatBubbleWidget extends StatelessWidget {
child: Padding(
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (mediaData != null)
if (mediaData.isNotEmpty)
CustomScrollView(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
slivers: [
SliverList.separated(
itemBuilder: (BuildContext context, int index) {
if (!mediaData![index].toString().contains('.png') &&
!mediaData![index].toString().contains('.jpg') &&
!mediaData![index].toString().contains('.jpeg')) {
if (!mediaData[index].toString().contains('.png') &&
!mediaData[index].toString().contains('.jpg') &&
!mediaData[index].toString().contains('.jpeg')) {
return ListTile(
contentPadding: EdgeInsets.zero,
horizontalTitleGap: 8,
onTap: () async {
if (!await launchUrl(Uri.parse(dotenv.env['STORAGE_URL']! + mediaData![index].toString()))) {
throw Exception('Could not launch ${mediaData![index].toString()}');
if (!await launchUrl(Uri.parse(dotenv.env['STORAGE_URL']! + mediaData[index].toString()))) {
throw Exception('Could not launch ${mediaData[index].toString()}');
}
},
leading: Icon(
@@ -60,7 +61,7 @@ class ChatBubbleWidget extends StatelessWidget {
color: Color(0xFF2F80ED),
),
title: Text(
mediaData![index].toString().replaceAll('chat_files/', ''),
mediaData[index].toString().replaceAll('chat_files/', ''),
maxLines: 2,
style: TextStyle(
color: Color(0xFF323F4B),
@@ -74,29 +75,29 @@ class ChatBubbleWidget extends StatelessWidget {
onTap: () {
context.pushTransparentRoute(
PhotoViewScreen(
imageUrls: mediaData!.map((e) => dotenv.env['STORAGE_URL']! + e.toString()).toList(),
imageUrls: mediaData.map((e) => dotenv.env['STORAGE_URL']! + e.toString()).toList(),
index: index,
),
);
},
child: Hero(
tag: dotenv.env['STORAGE_URL']! + '${mediaData![index]}',
tag: dotenv.env['STORAGE_URL']! + '${mediaData[index]}',
transitionOnUserGestures: true,
child: ClipRRect(
borderRadius: BorderRadiusStyle.roundedBorder8,
child: CachedNetworkImage(
imageUrl: dotenv.env['STORAGE_URL']! + '${mediaData![index]}',
imageUrl: dotenv.env['STORAGE_URL']! + '${mediaData[index]}',
),
),
),
);
},
separatorBuilder: (BuildContext context, int index) => const SizedBox(height: 8),
itemCount: mediaData!.length,
itemCount: mediaData.length,
),
],
),
if (mediaData!.length > 0 && text.isNotEmpty) SizedBox(height: 8),
if (mediaData.length > 0 && text.isNotEmpty) SizedBox(height: 8),
if (text.isNotEmpty)
Text(
text,

View File

@@ -1,3 +1,4 @@
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/websocket_info_model.dart';
import 'package:eatvio_app/features/chat/services/chat_service.dart';
@@ -9,23 +10,30 @@ class ChatRepository {
required this.chatService,
});
/// TODO use "dartz" package because need Either<Failure, Result> for error handling
Future<ChatRoomModel> getChatRoom(String chatId) async {
try {
return (await chatService.getChatRoomModel(chatId))['chatRoom']!;
return (await chatService.getChatRoom(chatId))['chatRoom']!;
} catch (e) {
print(e);
throw (e);
rethrow;
}
}
Future<ChatMessagesModel> getChatMessages(String chatId) async {
try {
return (await chatService.getChatMessages(chatId));
} catch (e) {
print(e);
rethrow;
}
}
/// TODO use "dartz" package because need Either<Failure, Result> for error handling
Future<WebsocketInfoModel> getWebsocket() async {
try {
return (await chatService.getWebsocket());
} catch (e) {
print(e);
throw (e);
rethrow;
}
}
}

View File

@@ -1,3 +1,4 @@
import 'package:eatvio_app/features/chat/models/chat_messages_model.dart';
import 'package:eatvio_app/features/chat/models/chat_room_model.dart';
import 'package:dio/dio.dart';
import 'package:eatvio_app/features/chat/models/websocket_info_model.dart';
@@ -10,7 +11,10 @@ abstract class ChatService {
factory ChatService(Dio dio, {String baseUrl}) = _ChatService;
@GET('/chat/show/{id}')
Future<Map<String, ChatRoomModel>> getChatRoomModel(@Path() String id);
Future<Map<String, ChatRoomModel>> getChatRoom(@Path() String id);
@GET('/chat/show/{id}/messages')
Future<ChatMessagesModel> getChatMessages(@Path() String id);
@GET('/profile/ws/params')
Future<WebsocketInfoModel> getWebsocket();

View File

@@ -6,7 +6,7 @@ part of 'chat_service.dart';
// RetrofitGenerator
// **************************************************************************
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element
class _ChatService implements ChatService {
_ChatService(
@@ -19,7 +19,7 @@ class _ChatService implements ChatService {
String? baseUrl;
@override
Future<Map<String, ChatRoomModel>> getChatRoomModel(String id) async {
Future<Map<String, ChatRoomModel>> getChatRoom(String id) async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _headers = <String, dynamic>{};
@@ -41,9 +41,36 @@ class _ChatService implements ChatService {
_dio.options.baseUrl,
baseUrl,
))));
var value = _result.data!.map((k, dynamic v) =>
var _value = _result.data!.map((k, dynamic v) =>
MapEntry(k, ChatRoomModel.fromJson(v as Map<String, dynamic>)));
return value;
return _value;
}
@override
Future<ChatMessagesModel> getChatMessages(String id) async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _headers = <String, dynamic>{};
const Map<String, dynamic>? _data = null;
final _result = await _dio
.fetch<Map<String, dynamic>>(_setStreamType<ChatMessagesModel>(Options(
method: 'GET',
headers: _headers,
extra: _extra,
)
.compose(
_dio.options,
'/chat/show/${id}/messages',
queryParameters: queryParameters,
data: _data,
)
.copyWith(
baseUrl: _combineBaseUrls(
_dio.options.baseUrl,
baseUrl,
))));
final _value = ChatMessagesModel.fromJson(_result.data!);
return _value;
}
@override
@@ -69,8 +96,8 @@ class _ChatService implements ChatService {
_dio.options.baseUrl,
baseUrl,
))));
final value = WebsocketInfoModel.fromJson(_result.data!);
return value;
final _value = WebsocketInfoModel.fromJson(_result.data!);
return _value;
}
RequestOptions _setStreamType<T>(RequestOptions requestOptions) {

View File

@@ -6,7 +6,7 @@ part of 'feed_service.dart';
// RetrofitGenerator
// **************************************************************************
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element
class _FeedService implements FeedService {
_FeedService(
@@ -41,11 +41,11 @@ class _FeedService implements FeedService {
_dio.options.baseUrl,
baseUrl,
))));
var value = _result.data!
var _value = _result.data!
.map((dynamic i) =>
FeedBlogPostModel.fromJson(i as Map<String, dynamic>))
.toList();
return value;
return _value;
}
RequestOptions _setStreamType<T>(RequestOptions requestOptions) {

View File

@@ -16,7 +16,8 @@ final sl = GetIt.instance;
Future<void> init() async {
// BLoC / Cubit
sl.registerFactory<InitializationCubit>(() => InitializationCubit(chatRepository: sl()));
sl.registerLazySingleton<InitializationCubit>(() => InitializationCubit(chatRepository: sl()));
sl.registerFactory<ChatRoomCubit>(() => ChatRoomCubit(chatRepository: sl()));
sl.registerFactory<FeedCubit>(() => FeedCubit(feedRepository: sl()));
sl.registerFactory<BlogPostCubit>(() => BlogPostCubit(blogPostRepository: sl()));

View File

@@ -42,7 +42,7 @@ class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider<InitializationCubit>(create: (context) => InitializationCubit(chatRepository: sl())..runInitialization()),
BlocProvider<InitializationCubit>(create: (context) => InitializationCubit(chatRepository: sl())),
BlocProvider<ThemeBloc>(create: (context) => ThemeBloc(ThemeState(themeType: PrefUtils().getThemeData()))),
BlocProvider<FeedCubit>(create: (context) => sl<FeedCubit>()..loadFeedBlogPostList()),
BlocProvider<MyProfileBloc>(create: (context) => MyProfileBloc(MyProfileState(myProfileModelObj: MyProfileModel()))..add(MyProfileInitialEvent())),

View File

@@ -156,7 +156,6 @@ class _AppNavigationScreenState extends State<AppNavigationScreen> {
style: TextStyle(
color: Color(0XFF000000),
fontSize: 20.fSize,
fontFamily: 'Roboto',
fontWeight: FontWeight.w400,
),
),
@@ -173,7 +172,6 @@ class _AppNavigationScreenState extends State<AppNavigationScreen> {
style: TextStyle(
color: Color(0XFF888888),
fontSize: 16.fSize,
fontFamily: 'Roboto',
fontWeight: FontWeight.w400,
),
),
@@ -215,7 +213,6 @@ class _AppNavigationScreenState extends State<AppNavigationScreen> {
style: TextStyle(
color: Color(0XFF000000),
fontSize: 20.fSize,
fontFamily: 'Roboto',
fontWeight: FontWeight.w400,
),
),

View File

@@ -121,7 +121,7 @@ class TextThemes {
bodySmall: TextStyle(
color: appTheme.gray500,
fontSize: 10.fSize,
fontFamily: 'Roboto',
fontFamily: 'Mulish',
fontWeight: FontWeight.w400,
),
labelLarge: TextStyle(

View File

@@ -64,8 +64,10 @@ dependencies:
# photo gallery viewer + dismissible page
photo_view: ^0.15.0
dismissible_page: ^1.0.2
#url launcher
# url launcher
url_launcher: ^6.3.0
# debounce
easy_debounce: ^2.0.3
dev_dependencies:
build_runner: ^2.4.11