Отображение чатов
This commit is contained in:
@@ -1,23 +1,92 @@
|
||||
import 'dart:async';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import '../../domain/entities/chat.dart';
|
||||
import '../../domain/entities/message.dart';
|
||||
import '../../domain/repositories/chat_repository.dart';
|
||||
import 'chat_event.dart';
|
||||
import 'chat_state.dart';
|
||||
|
||||
class ChatBloc extends Bloc<ChatEvent, ChatState> {
|
||||
ChatBloc() : super(const ChatState.initial()) {
|
||||
final ChatRepository chatRepository;
|
||||
StreamSubscription? _messageSubscription;
|
||||
|
||||
ChatBloc({required this.chatRepository}) : super(const ChatState.initial()) {
|
||||
on<ChatEventStarted>(_onStarted);
|
||||
on<ChatEventChatsLoaded>(_onChatsLoaded);
|
||||
on<ChatEventChatSelected>(_onChatSelected);
|
||||
on<ChatEventMessagesRequested>(_onMessagesRequested);
|
||||
on<ChatEventMessageSent>(_onMessageSent);
|
||||
on<ChatEventFavoritesRequested>(_onFavoritesRequested);
|
||||
|
||||
_messageSubscription = chatRepository.messageStream.listen((message) {
|
||||
// Handle real-time messages
|
||||
add(ChatEvent.messagesRequested(message.chatId));
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _onStarted(ChatEventStarted event, emit) async {
|
||||
emit(const ChatState.loading());
|
||||
emit(const ChatState.chatsLoaded([]));
|
||||
Future<void> _onStarted(ChatEventStarted event, Emitter<ChatState> emit) async {
|
||||
// Start SignalR in background
|
||||
chatRepository.initSignalR().catchError((e) {
|
||||
// Log or handle SignalR init error
|
||||
});
|
||||
// Immediately trigger chats loading
|
||||
add(const ChatEvent.chatsLoaded());
|
||||
}
|
||||
|
||||
Future<void> _onChatsLoaded(ChatEventChatsLoaded event, Emitter<ChatState> emit) async {
|
||||
emit(const ChatState.loading());
|
||||
final result = await chatRepository.getChats(currentUserId: event.currentUserId);
|
||||
result.fold(
|
||||
(error) => emit(ChatState.error(error.message ?? 'Failed to load chats')),
|
||||
(chats) => emit(ChatState.chatsLoaded(chats)),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _onChatSelected(ChatEventChatSelected event, Emitter<ChatState> emit) async {
|
||||
emit(const ChatState.loading());
|
||||
final chatResult = await chatRepository.getChatById(event.chatId);
|
||||
final messagesResult = await chatRepository.getMessages(event.chatId);
|
||||
|
||||
Future<void> _onChatsLoaded(ChatEventChatsLoaded event, emit) async {}
|
||||
Future<void> _onChatSelected(ChatEventChatSelected event, emit) async {}
|
||||
Future<void> _onMessagesRequested(ChatEventMessagesRequested event, emit) async {}
|
||||
Future<void> _onMessageSent(ChatEventMessageSent event, emit) async {}
|
||||
chatResult.fold(
|
||||
(error) => emit(ChatState.error(error.message ?? 'Failed to load chat')),
|
||||
(chat) {
|
||||
messagesResult.fold(
|
||||
(error) => emit(ChatState.chatSelected(chat, [])),
|
||||
(messages) => emit(ChatState.chatSelected(chat, messages)),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _onMessagesRequested(ChatEventMessagesRequested event, Emitter<ChatState> emit) async {
|
||||
final result = await chatRepository.getMessages(event.chatId);
|
||||
result.fold(
|
||||
(error) => emit(ChatState.error(error.message ?? 'Failed to load messages')),
|
||||
(messages) => emit(ChatState.messagesLoaded(messages)),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _onMessageSent(ChatEventMessageSent event, Emitter<ChatState> emit) async {
|
||||
final result = await chatRepository.sendMessage(event.chatId, event.content);
|
||||
result.fold(
|
||||
(error) => emit(ChatState.error(error.message ?? 'Failed to send message')),
|
||||
(_) => add(ChatEvent.messagesRequested(event.chatId)),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _onFavoritesRequested(ChatEventFavoritesRequested event, Emitter<ChatState> emit) async {
|
||||
emit(const ChatState.loading());
|
||||
final result = await chatRepository.getOrCreateFavorites();
|
||||
result.fold(
|
||||
(error) => emit(ChatState.error(error.message ?? 'Failed to open Favorites')),
|
||||
(chat) => add(ChatEvent.chatSelected(chat.id)),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> close() {
|
||||
_messageSubscription?.cancel();
|
||||
chatRepository.disposeSignalR();
|
||||
return super.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,9 @@ part 'chat_event.freezed.dart';
|
||||
@freezed
|
||||
class ChatEvent with _$ChatEvent {
|
||||
const factory ChatEvent.started() = ChatEventStarted;
|
||||
const factory ChatEvent.chatsLoaded() = ChatEventChatsLoaded;
|
||||
const factory ChatEvent.chatsLoaded({String? currentUserId}) = ChatEventChatsLoaded;
|
||||
const factory ChatEvent.chatSelected(String chatId) = ChatEventChatSelected;
|
||||
const factory ChatEvent.messagesRequested(String chatId, {String? lastMessageId}) = ChatEventMessagesRequested;
|
||||
const factory ChatEvent.messagesRequested(String chatId, {String? cursor}) = ChatEventMessagesRequested;
|
||||
const factory ChatEvent.messageSent(String chatId, String content) = ChatEventMessageSent;
|
||||
const factory ChatEvent.messageRead(String chatId, String messageId) = ChatEventMessageRead;
|
||||
const factory ChatEvent.chatCreated(String title, List<String> participantIds) = ChatEventChatCreated;
|
||||
const factory ChatEvent.favoritesRequested() = ChatEventFavoritesRequested;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,6 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import '../../domain/entities/chat.dart';
|
||||
import '../../domain/entities/message.dart';
|
||||
|
||||
part 'chat_state.freezed.dart';
|
||||
|
||||
@@ -6,9 +8,8 @@ part 'chat_state.freezed.dart';
|
||||
class ChatState with _$ChatState {
|
||||
const factory ChatState.initial() = ChatInitial;
|
||||
const factory ChatState.loading() = ChatLoading;
|
||||
const factory ChatState.chatsLoaded(List<dynamic> chats) = _ChatsLoaded;
|
||||
const factory ChatState.chatSelected(String chat, List<dynamic> messages) = _ChatSelected;
|
||||
const factory ChatState.messagesLoaded(List<dynamic> messages) = _MessagesLoaded;
|
||||
const factory ChatState.messageSent() = _MessageSent;
|
||||
const factory ChatState.chatsLoaded(List<Chat> chats) = _ChatsLoaded;
|
||||
const factory ChatState.chatSelected(Chat chat, List<Message> messages) = _ChatSelected;
|
||||
const factory ChatState.messagesLoaded(List<Message> messages) = _MessagesLoaded;
|
||||
const factory ChatState.error(String message) = ChatError;
|
||||
}
|
||||
|
||||
@@ -20,10 +20,9 @@ mixin _$ChatState {
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function() initial,
|
||||
required TResult Function() loading,
|
||||
required TResult Function(List<dynamic> chats) chatsLoaded,
|
||||
required TResult Function(String chat, List<dynamic> messages) chatSelected,
|
||||
required TResult Function(List<dynamic> messages) messagesLoaded,
|
||||
required TResult Function() messageSent,
|
||||
required TResult Function(List<Chat> chats) chatsLoaded,
|
||||
required TResult Function(Chat chat, List<Message> messages) chatSelected,
|
||||
required TResult Function(List<Message> messages) messagesLoaded,
|
||||
required TResult Function(String message) error,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@@ -31,10 +30,9 @@ mixin _$ChatState {
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult? Function()? initial,
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(List<dynamic> chats)? chatsLoaded,
|
||||
TResult? Function(String chat, List<dynamic> messages)? chatSelected,
|
||||
TResult? Function(List<dynamic> messages)? messagesLoaded,
|
||||
TResult? Function()? messageSent,
|
||||
TResult? Function(List<Chat> chats)? chatsLoaded,
|
||||
TResult? Function(Chat chat, List<Message> messages)? chatSelected,
|
||||
TResult? Function(List<Message> messages)? messagesLoaded,
|
||||
TResult? Function(String message)? error,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@@ -42,10 +40,9 @@ mixin _$ChatState {
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function()? initial,
|
||||
TResult Function()? loading,
|
||||
TResult Function(List<dynamic> chats)? chatsLoaded,
|
||||
TResult Function(String chat, List<dynamic> messages)? chatSelected,
|
||||
TResult Function(List<dynamic> messages)? messagesLoaded,
|
||||
TResult Function()? messageSent,
|
||||
TResult Function(List<Chat> chats)? chatsLoaded,
|
||||
TResult Function(Chat chat, List<Message> messages)? chatSelected,
|
||||
TResult Function(List<Message> messages)? messagesLoaded,
|
||||
TResult Function(String message)? error,
|
||||
required TResult orElse(),
|
||||
}) =>
|
||||
@@ -57,7 +54,6 @@ mixin _$ChatState {
|
||||
required TResult Function(_ChatsLoaded value) chatsLoaded,
|
||||
required TResult Function(_ChatSelected value) chatSelected,
|
||||
required TResult Function(_MessagesLoaded value) messagesLoaded,
|
||||
required TResult Function(_MessageSent value) messageSent,
|
||||
required TResult Function(ChatError value) error,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@@ -68,7 +64,6 @@ mixin _$ChatState {
|
||||
TResult? Function(_ChatsLoaded value)? chatsLoaded,
|
||||
TResult? Function(_ChatSelected value)? chatSelected,
|
||||
TResult? Function(_MessagesLoaded value)? messagesLoaded,
|
||||
TResult? Function(_MessageSent value)? messageSent,
|
||||
TResult? Function(ChatError value)? error,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@@ -79,7 +74,6 @@ mixin _$ChatState {
|
||||
TResult Function(_ChatsLoaded value)? chatsLoaded,
|
||||
TResult Function(_ChatSelected value)? chatSelected,
|
||||
TResult Function(_MessagesLoaded value)? messagesLoaded,
|
||||
TResult Function(_MessageSent value)? messageSent,
|
||||
TResult Function(ChatError value)? error,
|
||||
required TResult orElse(),
|
||||
}) =>
|
||||
@@ -143,10 +137,9 @@ class _$ChatInitialImpl implements ChatInitial {
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function() initial,
|
||||
required TResult Function() loading,
|
||||
required TResult Function(List<dynamic> chats) chatsLoaded,
|
||||
required TResult Function(String chat, List<dynamic> messages) chatSelected,
|
||||
required TResult Function(List<dynamic> messages) messagesLoaded,
|
||||
required TResult Function() messageSent,
|
||||
required TResult Function(List<Chat> chats) chatsLoaded,
|
||||
required TResult Function(Chat chat, List<Message> messages) chatSelected,
|
||||
required TResult Function(List<Message> messages) messagesLoaded,
|
||||
required TResult Function(String message) error,
|
||||
}) {
|
||||
return initial();
|
||||
@@ -157,10 +150,9 @@ class _$ChatInitialImpl implements ChatInitial {
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult? Function()? initial,
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(List<dynamic> chats)? chatsLoaded,
|
||||
TResult? Function(String chat, List<dynamic> messages)? chatSelected,
|
||||
TResult? Function(List<dynamic> messages)? messagesLoaded,
|
||||
TResult? Function()? messageSent,
|
||||
TResult? Function(List<Chat> chats)? chatsLoaded,
|
||||
TResult? Function(Chat chat, List<Message> messages)? chatSelected,
|
||||
TResult? Function(List<Message> messages)? messagesLoaded,
|
||||
TResult? Function(String message)? error,
|
||||
}) {
|
||||
return initial?.call();
|
||||
@@ -171,10 +163,9 @@ class _$ChatInitialImpl implements ChatInitial {
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function()? initial,
|
||||
TResult Function()? loading,
|
||||
TResult Function(List<dynamic> chats)? chatsLoaded,
|
||||
TResult Function(String chat, List<dynamic> messages)? chatSelected,
|
||||
TResult Function(List<dynamic> messages)? messagesLoaded,
|
||||
TResult Function()? messageSent,
|
||||
TResult Function(List<Chat> chats)? chatsLoaded,
|
||||
TResult Function(Chat chat, List<Message> messages)? chatSelected,
|
||||
TResult Function(List<Message> messages)? messagesLoaded,
|
||||
TResult Function(String message)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
@@ -192,7 +183,6 @@ class _$ChatInitialImpl implements ChatInitial {
|
||||
required TResult Function(_ChatsLoaded value) chatsLoaded,
|
||||
required TResult Function(_ChatSelected value) chatSelected,
|
||||
required TResult Function(_MessagesLoaded value) messagesLoaded,
|
||||
required TResult Function(_MessageSent value) messageSent,
|
||||
required TResult Function(ChatError value) error,
|
||||
}) {
|
||||
return initial(this);
|
||||
@@ -206,7 +196,6 @@ class _$ChatInitialImpl implements ChatInitial {
|
||||
TResult? Function(_ChatsLoaded value)? chatsLoaded,
|
||||
TResult? Function(_ChatSelected value)? chatSelected,
|
||||
TResult? Function(_MessagesLoaded value)? messagesLoaded,
|
||||
TResult? Function(_MessageSent value)? messageSent,
|
||||
TResult? Function(ChatError value)? error,
|
||||
}) {
|
||||
return initial?.call(this);
|
||||
@@ -220,7 +209,6 @@ class _$ChatInitialImpl implements ChatInitial {
|
||||
TResult Function(_ChatsLoaded value)? chatsLoaded,
|
||||
TResult Function(_ChatSelected value)? chatSelected,
|
||||
TResult Function(_MessagesLoaded value)? messagesLoaded,
|
||||
TResult Function(_MessageSent value)? messageSent,
|
||||
TResult Function(ChatError value)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
@@ -275,10 +263,9 @@ class _$ChatLoadingImpl implements ChatLoading {
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function() initial,
|
||||
required TResult Function() loading,
|
||||
required TResult Function(List<dynamic> chats) chatsLoaded,
|
||||
required TResult Function(String chat, List<dynamic> messages) chatSelected,
|
||||
required TResult Function(List<dynamic> messages) messagesLoaded,
|
||||
required TResult Function() messageSent,
|
||||
required TResult Function(List<Chat> chats) chatsLoaded,
|
||||
required TResult Function(Chat chat, List<Message> messages) chatSelected,
|
||||
required TResult Function(List<Message> messages) messagesLoaded,
|
||||
required TResult Function(String message) error,
|
||||
}) {
|
||||
return loading();
|
||||
@@ -289,10 +276,9 @@ class _$ChatLoadingImpl implements ChatLoading {
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult? Function()? initial,
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(List<dynamic> chats)? chatsLoaded,
|
||||
TResult? Function(String chat, List<dynamic> messages)? chatSelected,
|
||||
TResult? Function(List<dynamic> messages)? messagesLoaded,
|
||||
TResult? Function()? messageSent,
|
||||
TResult? Function(List<Chat> chats)? chatsLoaded,
|
||||
TResult? Function(Chat chat, List<Message> messages)? chatSelected,
|
||||
TResult? Function(List<Message> messages)? messagesLoaded,
|
||||
TResult? Function(String message)? error,
|
||||
}) {
|
||||
return loading?.call();
|
||||
@@ -303,10 +289,9 @@ class _$ChatLoadingImpl implements ChatLoading {
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function()? initial,
|
||||
TResult Function()? loading,
|
||||
TResult Function(List<dynamic> chats)? chatsLoaded,
|
||||
TResult Function(String chat, List<dynamic> messages)? chatSelected,
|
||||
TResult Function(List<dynamic> messages)? messagesLoaded,
|
||||
TResult Function()? messageSent,
|
||||
TResult Function(List<Chat> chats)? chatsLoaded,
|
||||
TResult Function(Chat chat, List<Message> messages)? chatSelected,
|
||||
TResult Function(List<Message> messages)? messagesLoaded,
|
||||
TResult Function(String message)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
@@ -324,7 +309,6 @@ class _$ChatLoadingImpl implements ChatLoading {
|
||||
required TResult Function(_ChatsLoaded value) chatsLoaded,
|
||||
required TResult Function(_ChatSelected value) chatSelected,
|
||||
required TResult Function(_MessagesLoaded value) messagesLoaded,
|
||||
required TResult Function(_MessageSent value) messageSent,
|
||||
required TResult Function(ChatError value) error,
|
||||
}) {
|
||||
return loading(this);
|
||||
@@ -338,7 +322,6 @@ class _$ChatLoadingImpl implements ChatLoading {
|
||||
TResult? Function(_ChatsLoaded value)? chatsLoaded,
|
||||
TResult? Function(_ChatSelected value)? chatSelected,
|
||||
TResult? Function(_MessagesLoaded value)? messagesLoaded,
|
||||
TResult? Function(_MessageSent value)? messageSent,
|
||||
TResult? Function(ChatError value)? error,
|
||||
}) {
|
||||
return loading?.call(this);
|
||||
@@ -352,7 +335,6 @@ class _$ChatLoadingImpl implements ChatLoading {
|
||||
TResult Function(_ChatsLoaded value)? chatsLoaded,
|
||||
TResult Function(_ChatSelected value)? chatSelected,
|
||||
TResult Function(_MessagesLoaded value)? messagesLoaded,
|
||||
TResult Function(_MessageSent value)? messageSent,
|
||||
TResult Function(ChatError value)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
@@ -373,7 +355,7 @@ abstract class _$$ChatsLoadedImplCopyWith<$Res> {
|
||||
_$ChatsLoadedImpl value, $Res Function(_$ChatsLoadedImpl) then) =
|
||||
__$$ChatsLoadedImplCopyWithImpl<$Res>;
|
||||
@useResult
|
||||
$Res call({List<dynamic> chats});
|
||||
$Res call({List<Chat> chats});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@@ -393,7 +375,7 @@ class __$$ChatsLoadedImplCopyWithImpl<$Res>
|
||||
null == chats
|
||||
? _value._chats
|
||||
: chats // ignore: cast_nullable_to_non_nullable
|
||||
as List<dynamic>,
|
||||
as List<Chat>,
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -401,11 +383,11 @@ class __$$ChatsLoadedImplCopyWithImpl<$Res>
|
||||
/// @nodoc
|
||||
|
||||
class _$ChatsLoadedImpl implements _ChatsLoaded {
|
||||
const _$ChatsLoadedImpl(final List<dynamic> chats) : _chats = chats;
|
||||
const _$ChatsLoadedImpl(final List<Chat> chats) : _chats = chats;
|
||||
|
||||
final List<dynamic> _chats;
|
||||
final List<Chat> _chats;
|
||||
@override
|
||||
List<dynamic> get chats {
|
||||
List<Chat> get chats {
|
||||
if (_chats is EqualUnmodifiableListView) return _chats;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_chats);
|
||||
@@ -439,10 +421,9 @@ class _$ChatsLoadedImpl implements _ChatsLoaded {
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function() initial,
|
||||
required TResult Function() loading,
|
||||
required TResult Function(List<dynamic> chats) chatsLoaded,
|
||||
required TResult Function(String chat, List<dynamic> messages) chatSelected,
|
||||
required TResult Function(List<dynamic> messages) messagesLoaded,
|
||||
required TResult Function() messageSent,
|
||||
required TResult Function(List<Chat> chats) chatsLoaded,
|
||||
required TResult Function(Chat chat, List<Message> messages) chatSelected,
|
||||
required TResult Function(List<Message> messages) messagesLoaded,
|
||||
required TResult Function(String message) error,
|
||||
}) {
|
||||
return chatsLoaded(chats);
|
||||
@@ -453,10 +434,9 @@ class _$ChatsLoadedImpl implements _ChatsLoaded {
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult? Function()? initial,
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(List<dynamic> chats)? chatsLoaded,
|
||||
TResult? Function(String chat, List<dynamic> messages)? chatSelected,
|
||||
TResult? Function(List<dynamic> messages)? messagesLoaded,
|
||||
TResult? Function()? messageSent,
|
||||
TResult? Function(List<Chat> chats)? chatsLoaded,
|
||||
TResult? Function(Chat chat, List<Message> messages)? chatSelected,
|
||||
TResult? Function(List<Message> messages)? messagesLoaded,
|
||||
TResult? Function(String message)? error,
|
||||
}) {
|
||||
return chatsLoaded?.call(chats);
|
||||
@@ -467,10 +447,9 @@ class _$ChatsLoadedImpl implements _ChatsLoaded {
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function()? initial,
|
||||
TResult Function()? loading,
|
||||
TResult Function(List<dynamic> chats)? chatsLoaded,
|
||||
TResult Function(String chat, List<dynamic> messages)? chatSelected,
|
||||
TResult Function(List<dynamic> messages)? messagesLoaded,
|
||||
TResult Function()? messageSent,
|
||||
TResult Function(List<Chat> chats)? chatsLoaded,
|
||||
TResult Function(Chat chat, List<Message> messages)? chatSelected,
|
||||
TResult Function(List<Message> messages)? messagesLoaded,
|
||||
TResult Function(String message)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
@@ -488,7 +467,6 @@ class _$ChatsLoadedImpl implements _ChatsLoaded {
|
||||
required TResult Function(_ChatsLoaded value) chatsLoaded,
|
||||
required TResult Function(_ChatSelected value) chatSelected,
|
||||
required TResult Function(_MessagesLoaded value) messagesLoaded,
|
||||
required TResult Function(_MessageSent value) messageSent,
|
||||
required TResult Function(ChatError value) error,
|
||||
}) {
|
||||
return chatsLoaded(this);
|
||||
@@ -502,7 +480,6 @@ class _$ChatsLoadedImpl implements _ChatsLoaded {
|
||||
TResult? Function(_ChatsLoaded value)? chatsLoaded,
|
||||
TResult? Function(_ChatSelected value)? chatSelected,
|
||||
TResult? Function(_MessagesLoaded value)? messagesLoaded,
|
||||
TResult? Function(_MessageSent value)? messageSent,
|
||||
TResult? Function(ChatError value)? error,
|
||||
}) {
|
||||
return chatsLoaded?.call(this);
|
||||
@@ -516,7 +493,6 @@ class _$ChatsLoadedImpl implements _ChatsLoaded {
|
||||
TResult Function(_ChatsLoaded value)? chatsLoaded,
|
||||
TResult Function(_ChatSelected value)? chatSelected,
|
||||
TResult Function(_MessagesLoaded value)? messagesLoaded,
|
||||
TResult Function(_MessageSent value)? messageSent,
|
||||
TResult Function(ChatError value)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
@@ -528,9 +504,9 @@ class _$ChatsLoadedImpl implements _ChatsLoaded {
|
||||
}
|
||||
|
||||
abstract class _ChatsLoaded implements ChatState {
|
||||
const factory _ChatsLoaded(final List<dynamic> chats) = _$ChatsLoadedImpl;
|
||||
const factory _ChatsLoaded(final List<Chat> chats) = _$ChatsLoadedImpl;
|
||||
|
||||
List<dynamic> get chats;
|
||||
List<Chat> get chats;
|
||||
@JsonKey(ignore: true)
|
||||
_$$ChatsLoadedImplCopyWith<_$ChatsLoadedImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
@@ -542,7 +518,9 @@ abstract class _$$ChatSelectedImplCopyWith<$Res> {
|
||||
_$ChatSelectedImpl value, $Res Function(_$ChatSelectedImpl) then) =
|
||||
__$$ChatSelectedImplCopyWithImpl<$Res>;
|
||||
@useResult
|
||||
$Res call({String chat, List<dynamic> messages});
|
||||
$Res call({Chat chat, List<Message> messages});
|
||||
|
||||
$ChatCopyWith<$Res> get chat;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@@ -563,26 +541,34 @@ class __$$ChatSelectedImplCopyWithImpl<$Res>
|
||||
null == chat
|
||||
? _value.chat
|
||||
: chat // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
as Chat,
|
||||
null == messages
|
||||
? _value._messages
|
||||
: messages // ignore: cast_nullable_to_non_nullable
|
||||
as List<dynamic>,
|
||||
as List<Message>,
|
||||
));
|
||||
}
|
||||
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$ChatCopyWith<$Res> get chat {
|
||||
return $ChatCopyWith<$Res>(_value.chat, (value) {
|
||||
return _then(_value.copyWith(chat: value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$ChatSelectedImpl implements _ChatSelected {
|
||||
const _$ChatSelectedImpl(this.chat, final List<dynamic> messages)
|
||||
const _$ChatSelectedImpl(this.chat, final List<Message> messages)
|
||||
: _messages = messages;
|
||||
|
||||
@override
|
||||
final String chat;
|
||||
final List<dynamic> _messages;
|
||||
final Chat chat;
|
||||
final List<Message> _messages;
|
||||
@override
|
||||
List<dynamic> get messages {
|
||||
List<Message> get messages {
|
||||
if (_messages is EqualUnmodifiableListView) return _messages;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_messages);
|
||||
@@ -617,10 +603,9 @@ class _$ChatSelectedImpl implements _ChatSelected {
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function() initial,
|
||||
required TResult Function() loading,
|
||||
required TResult Function(List<dynamic> chats) chatsLoaded,
|
||||
required TResult Function(String chat, List<dynamic> messages) chatSelected,
|
||||
required TResult Function(List<dynamic> messages) messagesLoaded,
|
||||
required TResult Function() messageSent,
|
||||
required TResult Function(List<Chat> chats) chatsLoaded,
|
||||
required TResult Function(Chat chat, List<Message> messages) chatSelected,
|
||||
required TResult Function(List<Message> messages) messagesLoaded,
|
||||
required TResult Function(String message) error,
|
||||
}) {
|
||||
return chatSelected(chat, messages);
|
||||
@@ -631,10 +616,9 @@ class _$ChatSelectedImpl implements _ChatSelected {
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult? Function()? initial,
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(List<dynamic> chats)? chatsLoaded,
|
||||
TResult? Function(String chat, List<dynamic> messages)? chatSelected,
|
||||
TResult? Function(List<dynamic> messages)? messagesLoaded,
|
||||
TResult? Function()? messageSent,
|
||||
TResult? Function(List<Chat> chats)? chatsLoaded,
|
||||
TResult? Function(Chat chat, List<Message> messages)? chatSelected,
|
||||
TResult? Function(List<Message> messages)? messagesLoaded,
|
||||
TResult? Function(String message)? error,
|
||||
}) {
|
||||
return chatSelected?.call(chat, messages);
|
||||
@@ -645,10 +629,9 @@ class _$ChatSelectedImpl implements _ChatSelected {
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function()? initial,
|
||||
TResult Function()? loading,
|
||||
TResult Function(List<dynamic> chats)? chatsLoaded,
|
||||
TResult Function(String chat, List<dynamic> messages)? chatSelected,
|
||||
TResult Function(List<dynamic> messages)? messagesLoaded,
|
||||
TResult Function()? messageSent,
|
||||
TResult Function(List<Chat> chats)? chatsLoaded,
|
||||
TResult Function(Chat chat, List<Message> messages)? chatSelected,
|
||||
TResult Function(List<Message> messages)? messagesLoaded,
|
||||
TResult Function(String message)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
@@ -666,7 +649,6 @@ class _$ChatSelectedImpl implements _ChatSelected {
|
||||
required TResult Function(_ChatsLoaded value) chatsLoaded,
|
||||
required TResult Function(_ChatSelected value) chatSelected,
|
||||
required TResult Function(_MessagesLoaded value) messagesLoaded,
|
||||
required TResult Function(_MessageSent value) messageSent,
|
||||
required TResult Function(ChatError value) error,
|
||||
}) {
|
||||
return chatSelected(this);
|
||||
@@ -680,7 +662,6 @@ class _$ChatSelectedImpl implements _ChatSelected {
|
||||
TResult? Function(_ChatsLoaded value)? chatsLoaded,
|
||||
TResult? Function(_ChatSelected value)? chatSelected,
|
||||
TResult? Function(_MessagesLoaded value)? messagesLoaded,
|
||||
TResult? Function(_MessageSent value)? messageSent,
|
||||
TResult? Function(ChatError value)? error,
|
||||
}) {
|
||||
return chatSelected?.call(this);
|
||||
@@ -694,7 +675,6 @@ class _$ChatSelectedImpl implements _ChatSelected {
|
||||
TResult Function(_ChatsLoaded value)? chatsLoaded,
|
||||
TResult Function(_ChatSelected value)? chatSelected,
|
||||
TResult Function(_MessagesLoaded value)? messagesLoaded,
|
||||
TResult Function(_MessageSent value)? messageSent,
|
||||
TResult Function(ChatError value)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
@@ -706,11 +686,11 @@ class _$ChatSelectedImpl implements _ChatSelected {
|
||||
}
|
||||
|
||||
abstract class _ChatSelected implements ChatState {
|
||||
const factory _ChatSelected(final String chat, final List<dynamic> messages) =
|
||||
const factory _ChatSelected(final Chat chat, final List<Message> messages) =
|
||||
_$ChatSelectedImpl;
|
||||
|
||||
String get chat;
|
||||
List<dynamic> get messages;
|
||||
Chat get chat;
|
||||
List<Message> get messages;
|
||||
@JsonKey(ignore: true)
|
||||
_$$ChatSelectedImplCopyWith<_$ChatSelectedImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
@@ -722,7 +702,7 @@ abstract class _$$MessagesLoadedImplCopyWith<$Res> {
|
||||
$Res Function(_$MessagesLoadedImpl) then) =
|
||||
__$$MessagesLoadedImplCopyWithImpl<$Res>;
|
||||
@useResult
|
||||
$Res call({List<dynamic> messages});
|
||||
$Res call({List<Message> messages});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@@ -742,7 +722,7 @@ class __$$MessagesLoadedImplCopyWithImpl<$Res>
|
||||
null == messages
|
||||
? _value._messages
|
||||
: messages // ignore: cast_nullable_to_non_nullable
|
||||
as List<dynamic>,
|
||||
as List<Message>,
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -750,12 +730,12 @@ class __$$MessagesLoadedImplCopyWithImpl<$Res>
|
||||
/// @nodoc
|
||||
|
||||
class _$MessagesLoadedImpl implements _MessagesLoaded {
|
||||
const _$MessagesLoadedImpl(final List<dynamic> messages)
|
||||
const _$MessagesLoadedImpl(final List<Message> messages)
|
||||
: _messages = messages;
|
||||
|
||||
final List<dynamic> _messages;
|
||||
final List<Message> _messages;
|
||||
@override
|
||||
List<dynamic> get messages {
|
||||
List<Message> get messages {
|
||||
if (_messages is EqualUnmodifiableListView) return _messages;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_messages);
|
||||
@@ -790,10 +770,9 @@ class _$MessagesLoadedImpl implements _MessagesLoaded {
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function() initial,
|
||||
required TResult Function() loading,
|
||||
required TResult Function(List<dynamic> chats) chatsLoaded,
|
||||
required TResult Function(String chat, List<dynamic> messages) chatSelected,
|
||||
required TResult Function(List<dynamic> messages) messagesLoaded,
|
||||
required TResult Function() messageSent,
|
||||
required TResult Function(List<Chat> chats) chatsLoaded,
|
||||
required TResult Function(Chat chat, List<Message> messages) chatSelected,
|
||||
required TResult Function(List<Message> messages) messagesLoaded,
|
||||
required TResult Function(String message) error,
|
||||
}) {
|
||||
return messagesLoaded(messages);
|
||||
@@ -804,10 +783,9 @@ class _$MessagesLoadedImpl implements _MessagesLoaded {
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult? Function()? initial,
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(List<dynamic> chats)? chatsLoaded,
|
||||
TResult? Function(String chat, List<dynamic> messages)? chatSelected,
|
||||
TResult? Function(List<dynamic> messages)? messagesLoaded,
|
||||
TResult? Function()? messageSent,
|
||||
TResult? Function(List<Chat> chats)? chatsLoaded,
|
||||
TResult? Function(Chat chat, List<Message> messages)? chatSelected,
|
||||
TResult? Function(List<Message> messages)? messagesLoaded,
|
||||
TResult? Function(String message)? error,
|
||||
}) {
|
||||
return messagesLoaded?.call(messages);
|
||||
@@ -818,10 +796,9 @@ class _$MessagesLoadedImpl implements _MessagesLoaded {
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function()? initial,
|
||||
TResult Function()? loading,
|
||||
TResult Function(List<dynamic> chats)? chatsLoaded,
|
||||
TResult Function(String chat, List<dynamic> messages)? chatSelected,
|
||||
TResult Function(List<dynamic> messages)? messagesLoaded,
|
||||
TResult Function()? messageSent,
|
||||
TResult Function(List<Chat> chats)? chatsLoaded,
|
||||
TResult Function(Chat chat, List<Message> messages)? chatSelected,
|
||||
TResult Function(List<Message> messages)? messagesLoaded,
|
||||
TResult Function(String message)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
@@ -839,7 +816,6 @@ class _$MessagesLoadedImpl implements _MessagesLoaded {
|
||||
required TResult Function(_ChatsLoaded value) chatsLoaded,
|
||||
required TResult Function(_ChatSelected value) chatSelected,
|
||||
required TResult Function(_MessagesLoaded value) messagesLoaded,
|
||||
required TResult Function(_MessageSent value) messageSent,
|
||||
required TResult Function(ChatError value) error,
|
||||
}) {
|
||||
return messagesLoaded(this);
|
||||
@@ -853,7 +829,6 @@ class _$MessagesLoadedImpl implements _MessagesLoaded {
|
||||
TResult? Function(_ChatsLoaded value)? chatsLoaded,
|
||||
TResult? Function(_ChatSelected value)? chatSelected,
|
||||
TResult? Function(_MessagesLoaded value)? messagesLoaded,
|
||||
TResult? Function(_MessageSent value)? messageSent,
|
||||
TResult? Function(ChatError value)? error,
|
||||
}) {
|
||||
return messagesLoaded?.call(this);
|
||||
@@ -867,7 +842,6 @@ class _$MessagesLoadedImpl implements _MessagesLoaded {
|
||||
TResult Function(_ChatsLoaded value)? chatsLoaded,
|
||||
TResult Function(_ChatSelected value)? chatSelected,
|
||||
TResult Function(_MessagesLoaded value)? messagesLoaded,
|
||||
TResult Function(_MessageSent value)? messageSent,
|
||||
TResult Function(ChatError value)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
@@ -879,147 +853,15 @@ class _$MessagesLoadedImpl implements _MessagesLoaded {
|
||||
}
|
||||
|
||||
abstract class _MessagesLoaded implements ChatState {
|
||||
const factory _MessagesLoaded(final List<dynamic> messages) =
|
||||
const factory _MessagesLoaded(final List<Message> messages) =
|
||||
_$MessagesLoadedImpl;
|
||||
|
||||
List<dynamic> get messages;
|
||||
List<Message> get messages;
|
||||
@JsonKey(ignore: true)
|
||||
_$$MessagesLoadedImplCopyWith<_$MessagesLoadedImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$MessageSentImplCopyWith<$Res> {
|
||||
factory _$$MessageSentImplCopyWith(
|
||||
_$MessageSentImpl value, $Res Function(_$MessageSentImpl) then) =
|
||||
__$$MessageSentImplCopyWithImpl<$Res>;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$MessageSentImplCopyWithImpl<$Res>
|
||||
extends _$ChatStateCopyWithImpl<$Res, _$MessageSentImpl>
|
||||
implements _$$MessageSentImplCopyWith<$Res> {
|
||||
__$$MessageSentImplCopyWithImpl(
|
||||
_$MessageSentImpl _value, $Res Function(_$MessageSentImpl) _then)
|
||||
: super(_value, _then);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$MessageSentImpl implements _MessageSent {
|
||||
const _$MessageSentImpl();
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ChatState.messageSent()';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType && other is _$MessageSentImpl);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => runtimeType.hashCode;
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function() initial,
|
||||
required TResult Function() loading,
|
||||
required TResult Function(List<dynamic> chats) chatsLoaded,
|
||||
required TResult Function(String chat, List<dynamic> messages) chatSelected,
|
||||
required TResult Function(List<dynamic> messages) messagesLoaded,
|
||||
required TResult Function() messageSent,
|
||||
required TResult Function(String message) error,
|
||||
}) {
|
||||
return messageSent();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult? Function()? initial,
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(List<dynamic> chats)? chatsLoaded,
|
||||
TResult? Function(String chat, List<dynamic> messages)? chatSelected,
|
||||
TResult? Function(List<dynamic> messages)? messagesLoaded,
|
||||
TResult? Function()? messageSent,
|
||||
TResult? Function(String message)? error,
|
||||
}) {
|
||||
return messageSent?.call();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function()? initial,
|
||||
TResult Function()? loading,
|
||||
TResult Function(List<dynamic> chats)? chatsLoaded,
|
||||
TResult Function(String chat, List<dynamic> messages)? chatSelected,
|
||||
TResult Function(List<dynamic> messages)? messagesLoaded,
|
||||
TResult Function()? messageSent,
|
||||
TResult Function(String message)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (messageSent != null) {
|
||||
return messageSent();
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>({
|
||||
required TResult Function(ChatInitial value) initial,
|
||||
required TResult Function(ChatLoading value) loading,
|
||||
required TResult Function(_ChatsLoaded value) chatsLoaded,
|
||||
required TResult Function(_ChatSelected value) chatSelected,
|
||||
required TResult Function(_MessagesLoaded value) messagesLoaded,
|
||||
required TResult Function(_MessageSent value) messageSent,
|
||||
required TResult Function(ChatError value) error,
|
||||
}) {
|
||||
return messageSent(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>({
|
||||
TResult? Function(ChatInitial value)? initial,
|
||||
TResult? Function(ChatLoading value)? loading,
|
||||
TResult? Function(_ChatsLoaded value)? chatsLoaded,
|
||||
TResult? Function(_ChatSelected value)? chatSelected,
|
||||
TResult? Function(_MessagesLoaded value)? messagesLoaded,
|
||||
TResult? Function(_MessageSent value)? messageSent,
|
||||
TResult? Function(ChatError value)? error,
|
||||
}) {
|
||||
return messageSent?.call(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>({
|
||||
TResult Function(ChatInitial value)? initial,
|
||||
TResult Function(ChatLoading value)? loading,
|
||||
TResult Function(_ChatsLoaded value)? chatsLoaded,
|
||||
TResult Function(_ChatSelected value)? chatSelected,
|
||||
TResult Function(_MessagesLoaded value)? messagesLoaded,
|
||||
TResult Function(_MessageSent value)? messageSent,
|
||||
TResult Function(ChatError value)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (messageSent != null) {
|
||||
return messageSent(this);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _MessageSent implements ChatState {
|
||||
const factory _MessageSent() = _$MessageSentImpl;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$ChatErrorImplCopyWith<$Res> {
|
||||
factory _$$ChatErrorImplCopyWith(
|
||||
@@ -1086,10 +928,9 @@ class _$ChatErrorImpl implements ChatError {
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function() initial,
|
||||
required TResult Function() loading,
|
||||
required TResult Function(List<dynamic> chats) chatsLoaded,
|
||||
required TResult Function(String chat, List<dynamic> messages) chatSelected,
|
||||
required TResult Function(List<dynamic> messages) messagesLoaded,
|
||||
required TResult Function() messageSent,
|
||||
required TResult Function(List<Chat> chats) chatsLoaded,
|
||||
required TResult Function(Chat chat, List<Message> messages) chatSelected,
|
||||
required TResult Function(List<Message> messages) messagesLoaded,
|
||||
required TResult Function(String message) error,
|
||||
}) {
|
||||
return error(message);
|
||||
@@ -1100,10 +941,9 @@ class _$ChatErrorImpl implements ChatError {
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult? Function()? initial,
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(List<dynamic> chats)? chatsLoaded,
|
||||
TResult? Function(String chat, List<dynamic> messages)? chatSelected,
|
||||
TResult? Function(List<dynamic> messages)? messagesLoaded,
|
||||
TResult? Function()? messageSent,
|
||||
TResult? Function(List<Chat> chats)? chatsLoaded,
|
||||
TResult? Function(Chat chat, List<Message> messages)? chatSelected,
|
||||
TResult? Function(List<Message> messages)? messagesLoaded,
|
||||
TResult? Function(String message)? error,
|
||||
}) {
|
||||
return error?.call(message);
|
||||
@@ -1114,10 +954,9 @@ class _$ChatErrorImpl implements ChatError {
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function()? initial,
|
||||
TResult Function()? loading,
|
||||
TResult Function(List<dynamic> chats)? chatsLoaded,
|
||||
TResult Function(String chat, List<dynamic> messages)? chatSelected,
|
||||
TResult Function(List<dynamic> messages)? messagesLoaded,
|
||||
TResult Function()? messageSent,
|
||||
TResult Function(List<Chat> chats)? chatsLoaded,
|
||||
TResult Function(Chat chat, List<Message> messages)? chatSelected,
|
||||
TResult Function(List<Message> messages)? messagesLoaded,
|
||||
TResult Function(String message)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
@@ -1135,7 +974,6 @@ class _$ChatErrorImpl implements ChatError {
|
||||
required TResult Function(_ChatsLoaded value) chatsLoaded,
|
||||
required TResult Function(_ChatSelected value) chatSelected,
|
||||
required TResult Function(_MessagesLoaded value) messagesLoaded,
|
||||
required TResult Function(_MessageSent value) messageSent,
|
||||
required TResult Function(ChatError value) error,
|
||||
}) {
|
||||
return error(this);
|
||||
@@ -1149,7 +987,6 @@ class _$ChatErrorImpl implements ChatError {
|
||||
TResult? Function(_ChatsLoaded value)? chatsLoaded,
|
||||
TResult? Function(_ChatSelected value)? chatSelected,
|
||||
TResult? Function(_MessagesLoaded value)? messagesLoaded,
|
||||
TResult? Function(_MessageSent value)? messageSent,
|
||||
TResult? Function(ChatError value)? error,
|
||||
}) {
|
||||
return error?.call(this);
|
||||
@@ -1163,7 +1000,6 @@ class _$ChatErrorImpl implements ChatError {
|
||||
TResult Function(_ChatsLoaded value)? chatsLoaded,
|
||||
TResult Function(_ChatSelected value)? chatSelected,
|
||||
TResult Function(_MessagesLoaded value)? messagesLoaded,
|
||||
TResult Function(_MessageSent value)? messageSent,
|
||||
TResult Function(ChatError value)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
|
||||
@@ -1,13 +1,21 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:messenger_app/l10n/app_localizations.dart';
|
||||
import '../bloc/chat_bloc.dart';
|
||||
import '../bloc/chat_event.dart';
|
||||
import '../bloc/chat_state.dart';
|
||||
import '../../domain/entities/chat.dart';
|
||||
import '../../domain/entities/message.dart';
|
||||
|
||||
class ChatDetailPage extends StatefulWidget {
|
||||
final String chatId;
|
||||
final String chatTitle;
|
||||
final Chat chat;
|
||||
final String currentUserId;
|
||||
|
||||
const ChatDetailPage({
|
||||
super.key,
|
||||
required this.chatId,
|
||||
required this.chatTitle,
|
||||
required this.chat,
|
||||
required this.currentUserId,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -16,90 +24,148 @@ class ChatDetailPage extends StatefulWidget {
|
||||
|
||||
class _ChatDetailPageState extends State<ChatDetailPage> {
|
||||
final _messageController = TextEditingController();
|
||||
final _scrollController = ScrollController();
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_messageController.dispose();
|
||||
_scrollController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _sendMessage() {
|
||||
if (_messageController.text.trim().isEmpty) return;
|
||||
_messageController.clear();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(widget.chatTitle),
|
||||
title: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(widget.chat.type == 'favorites' ? AppLocalizations.of(context)!.favorites : widget.chat.title),
|
||||
if (widget.chat.type != 'favorites')
|
||||
Text(
|
||||
AppLocalizations.of(context)!.connected,
|
||||
style: const TextStyle(fontSize: 12, fontWeight: FontWeight.normal),
|
||||
),
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
IconButton(icon: const Icon(Icons.more_vert), onPressed: () {}),
|
||||
],
|
||||
),
|
||||
body: const Center(child: Text('Chat Detail')),
|
||||
bottomNavigationBar: _MessageInput(
|
||||
controller: _messageController,
|
||||
onSend: _sendMessage,
|
||||
body: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: BlocBuilder<ChatBloc, ChatState>(
|
||||
builder: (context, state) {
|
||||
return state.maybeWhen(
|
||||
chatSelected: (_, messages) => _buildMessageList(messages),
|
||||
messagesLoaded: (messages) => _buildMessageList(messages),
|
||||
loading: () => const Center(child: CircularProgressIndicator()),
|
||||
error: (msg) => Center(child: Text('Ошибка: $msg')),
|
||||
orElse: () => const Center(child: Text('Начните общение')),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
_buildMessageInput(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _MessageInput extends StatelessWidget {
|
||||
final TextEditingController controller;
|
||||
final VoidCallback onSend;
|
||||
Widget _buildMessageList(List<Message> messages) {
|
||||
if (messages.isEmpty) {
|
||||
return const Center(child: Text('Сообщений пока нет'));
|
||||
}
|
||||
|
||||
const _MessageInput({
|
||||
required this.controller,
|
||||
required this.onSend,
|
||||
});
|
||||
return ListView.builder(
|
||||
controller: _scrollController,
|
||||
reverse: true,
|
||||
padding: const EdgeInsets.all(16),
|
||||
itemCount: messages.length,
|
||||
itemBuilder: (context, index) {
|
||||
final message = messages[index];
|
||||
final isMe = message.senderId == widget.currentUserId;
|
||||
|
||||
return Align(
|
||||
alignment: isMe ? Alignment.centerRight : Alignment.centerLeft,
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(vertical: 4),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: isMe ? Theme.of(context).primaryColor : Colors.grey[200],
|
||||
borderRadius: BorderRadius.circular(16).copyWith(
|
||||
bottomRight: isMe ? const Radius.circular(0) : const Radius.circular(16),
|
||||
bottomLeft: !isMe ? const Radius.circular(0) : const Radius.circular(16),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Text(
|
||||
message.content,
|
||||
style: TextStyle(color: isMe ? Colors.white : Colors.black87),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
if (message.createdAt != null)
|
||||
Text(
|
||||
DateFormat.Hm().format(message.createdAt!),
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
color: isMe ? Colors.white70 : Colors.black45,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget _buildMessageInput() {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.1),
|
||||
color: Colors.black.withOpacity(0.05),
|
||||
offset: const Offset(0, -1),
|
||||
blurRadius: 4,
|
||||
offset: const Offset(0, -2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.attach_file),
|
||||
onPressed: () {},
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: controller,
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Сообщение',
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(24),
|
||||
borderSide: BorderSide.none,
|
||||
),
|
||||
filled: true,
|
||||
fillColor: Colors.grey[200],
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 8,
|
||||
child: SafeArea(
|
||||
child: Row(
|
||||
children: [
|
||||
IconButton(icon: const Icon(Icons.add), onPressed: () {}),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: _messageController,
|
||||
decoration: const InputDecoration(
|
||||
hintText: 'Сообщение',
|
||||
border: InputBorder.none,
|
||||
),
|
||||
onSubmitted: (_) => _sendMessage(),
|
||||
),
|
||||
maxLines: null,
|
||||
onSubmitted: (_) => onSend(),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.send),
|
||||
color: Theme.of(context).primaryColor,
|
||||
onPressed: onSend,
|
||||
),
|
||||
],
|
||||
IconButton(
|
||||
icon: const Icon(Icons.send),
|
||||
onPressed: _sendMessage,
|
||||
color: Theme.of(context).primaryColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _sendMessage() {
|
||||
final content = _messageController.text.trim();
|
||||
if (content.isNotEmpty) {
|
||||
context.read<ChatBloc>().add(ChatEvent.messageSent(widget.chat.id, content));
|
||||
_messageController.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +1,169 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import '../bloc/chat_bloc.dart';
|
||||
import '../bloc/chat_state.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:messenger_app/features/chat/presentation/bloc/chat_bloc.dart';
|
||||
import 'package:messenger_app/features/chat/presentation/bloc/chat_event.dart';
|
||||
import 'package:messenger_app/features/chat/presentation/bloc/chat_state.dart';
|
||||
import 'package:messenger_app/features/auth/presentation/bloc/auth_bloc.dart';
|
||||
import 'package:messenger_app/features/auth/presentation/bloc/auth_state.dart';
|
||||
import 'package:messenger_app/features/chat/domain/entities/chat.dart';
|
||||
import 'package:messenger_app/l10n/app_localizations.dart';
|
||||
import 'chat_detail_page.dart';
|
||||
|
||||
class ChatsPage extends StatelessWidget {
|
||||
class ChatsPage extends StatefulWidget {
|
||||
const ChatsPage({super.key});
|
||||
|
||||
@override
|
||||
State<ChatsPage> createState() => _ChatsPageState();
|
||||
}
|
||||
|
||||
class _ChatsPageState extends State<ChatsPage> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
final authState = context.read<AuthBloc>().state;
|
||||
final userId = authState.maybeWhen(
|
||||
authenticated: (id) => id,
|
||||
orElse: () => null,
|
||||
);
|
||||
context.read<ChatBloc>().add(ChatEvent.chatsLoaded(currentUserId: userId));
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<ChatBloc, ChatState>(
|
||||
builder: (context, state) {
|
||||
return state.when(
|
||||
initial: () => const Center(child: CircularProgressIndicator()),
|
||||
loading: () => const Center(child: CircularProgressIndicator()),
|
||||
chatsLoaded: (_) => const Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(Icons.chat_bubble_outline, size: 64, color: Colors.grey),
|
||||
SizedBox(height: 16),
|
||||
Text('У вас пока нет чатов'),
|
||||
],
|
||||
),
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(l10n.chats),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.bookmark_border),
|
||||
onPressed: () {
|
||||
context.read<ChatBloc>().add(const ChatEvent.favoritesRequested());
|
||||
},
|
||||
),
|
||||
chatSelected: (_, __) => const Center(child: Text('Chat selected')),
|
||||
messagesLoaded: (_) => const Center(child: Text('Messages loaded')),
|
||||
messageSent: () => const Center(child: Text('Message sent')),
|
||||
error: (message) => Center(child: Text('Ошибка: $message')),
|
||||
],
|
||||
),
|
||||
body: BlocConsumer<ChatBloc, ChatState>(
|
||||
listener: (context, state) {
|
||||
state.whenOrNull(
|
||||
chatSelected: (chat, _) {
|
||||
final authState = context.read<AuthBloc>().state;
|
||||
final userId = authState.maybeWhen(
|
||||
authenticated: (id) => id,
|
||||
orElse: () => '',
|
||||
);
|
||||
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (_) => ChatDetailPage(
|
||||
chat: chat,
|
||||
currentUserId: userId,
|
||||
),
|
||||
),
|
||||
).then((_) {
|
||||
// Reload chats when returning from detail page
|
||||
if (context.mounted) {
|
||||
context.read<ChatBloc>().add(ChatEvent.chatsLoaded(currentUserId: userId));
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
},
|
||||
builder: (context, state) {
|
||||
return state.maybeWhen(
|
||||
loading: () => const Center(child: CircularProgressIndicator()),
|
||||
chatsLoaded: (chats) => _buildChatList(chats, l10n),
|
||||
error: (message) => Center(child: Text('${l10n.error}: $message')),
|
||||
orElse: () => const Center(child: CircularProgressIndicator()),
|
||||
);
|
||||
},
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: () {
|
||||
// TODO: Open contact list to create chat
|
||||
},
|
||||
child: const Icon(Icons.edit),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildChatList(List<Chat> chats, AppLocalizations l10n) {
|
||||
if (chats.isEmpty) {
|
||||
return Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(Icons.chat_bubble_outline, size: 64, color: Colors.grey),
|
||||
const SizedBox(height: 16),
|
||||
Text(l10n.noChats),
|
||||
const SizedBox(height: 8),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
final authState = context.read<AuthBloc>().state;
|
||||
final userId = authState.maybeWhen(
|
||||
authenticated: (id) => id,
|
||||
orElse: () => null,
|
||||
);
|
||||
context.read<ChatBloc>().add(ChatEvent.chatsLoaded(currentUserId: userId));
|
||||
},
|
||||
child: Text(l10n.retry),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return ListView.separated(
|
||||
itemCount: chats.length,
|
||||
separatorBuilder: (context, index) => const Divider(height: 1),
|
||||
itemBuilder: (context, index) {
|
||||
final chat = chats[index];
|
||||
return ListTile(
|
||||
leading: CircleAvatar(
|
||||
backgroundImage: chat.avatarUrl != null ? NetworkImage(chat.avatarUrl!) : null,
|
||||
child: chat.avatarUrl == null
|
||||
? Text(chat.title.isNotEmpty ? chat.title[0].toUpperCase() : '?')
|
||||
: null,
|
||||
),
|
||||
title: Text(
|
||||
chat.type == 'favorites' ? l10n.favorites : chat.title,
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
subtitle: Text(
|
||||
chat.lastMessage?.content ?? l10n.noChats,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
trailing: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
if (chat.lastMessageTime != null)
|
||||
Text(
|
||||
DateFormat.Hm().format(chat.lastMessageTime!),
|
||||
style: const TextStyle(fontSize: 12, color: Colors.grey),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
if (chat.unreadCount > 0)
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).primaryColor,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Text(
|
||||
chat.unreadCount.toString(),
|
||||
style: const TextStyle(color: Colors.white, fontSize: 10),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
onTap: () {
|
||||
context.read<ChatBloc>().add(ChatEvent.chatSelected(chat.id));
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user