103 lines
3.3 KiB
Dart
103 lines
3.3 KiB
Dart
import "package:moxxyv2/shared/events.dart";
|
|
import "package:moxxyv2/shared/commands.dart";
|
|
import "package:moxxyv2/shared/helpers.dart";
|
|
import "package:moxxyv2/shared/models/roster.dart";
|
|
import "package:moxxyv2/shared/models/conversation.dart";
|
|
import "package:moxxyv2/shared/backgroundsender.dart";
|
|
import "package:moxxyv2/ui/bloc/conversations_bloc.dart";
|
|
import "package:moxxyv2/ui/bloc/conversation_bloc.dart";
|
|
|
|
import "package:bloc/bloc.dart";
|
|
import "package:freezed_annotation/freezed_annotation.dart";
|
|
import "package:get_it/get_it.dart";
|
|
|
|
part "newconversation_state.dart";
|
|
part "newconversation_event.dart";
|
|
part "newconversation_bloc.freezed.dart";
|
|
|
|
class NewConversationBloc extends Bloc<NewConversationEvent, NewConversationState> {
|
|
NewConversationBloc() : super(NewConversationState()) {
|
|
on<NewConversationInitEvent>(_onInit);
|
|
on<NewConversationAddedEvent>(_onAdded);
|
|
on<NewConversationRosterItemRemovedEvent>(_onRosterItemRemoved);
|
|
on<RosterPushedEvent>(_onRosterPushed);
|
|
}
|
|
|
|
Future<void> _onInit(NewConversationInitEvent event, Emitter<NewConversationState> emit) async {
|
|
return emit(
|
|
state.copyWith(
|
|
roster: event.roster
|
|
)
|
|
);
|
|
}
|
|
|
|
Future<void> _onAdded(NewConversationAddedEvent event, Emitter<NewConversationState> emit) async {
|
|
final conversations = GetIt.I.get<ConversationsBloc>();
|
|
|
|
// Guard against an unneccessary roundtrip
|
|
if (listContains(conversations.state.conversations, (Conversation c) => c.jid == event.jid)) {
|
|
GetIt.I.get<ConversationBloc>().add(
|
|
RequestedConversationEvent(
|
|
event.jid,
|
|
event.title,
|
|
event.avatarUrl,
|
|
removeUntilConversations: true
|
|
)
|
|
);
|
|
return;
|
|
}
|
|
|
|
final result = await GetIt.I.get<BackgroundServiceDataSender>().sendData(
|
|
AddConversationCommand(
|
|
title: event.title,
|
|
jid: event.jid,
|
|
avatarUrl: event.avatarUrl,
|
|
lastMessageBody: ""
|
|
)
|
|
);
|
|
|
|
if (result is NoConversationModifiedEvent) {
|
|
// Fall through
|
|
} else if (result is ConversationUpdatedEvent) {
|
|
conversations.add(ConversationsUpdatedEvent(result.conversation));
|
|
} else if (result is ConversationAddedEvent) {
|
|
conversations.add(ConversationsAddedEvent(result.conversation));
|
|
}
|
|
|
|
GetIt.I.get<ConversationBloc>().add(
|
|
RequestedConversationEvent(
|
|
event.jid,
|
|
event.title,
|
|
event.avatarUrl,
|
|
removeUntilConversations: true
|
|
)
|
|
);
|
|
}
|
|
|
|
Future<void> _onRosterItemRemoved(NewConversationRosterItemRemovedEvent event, Emitter<NewConversationState> emit) async {
|
|
return emit(
|
|
state.copyWith(
|
|
roster: state.roster.where(
|
|
(item) => item.jid != event.jid
|
|
).toList()
|
|
)
|
|
);
|
|
}
|
|
|
|
Future<void> _onRosterPushed(RosterPushedEvent event, Emitter<NewConversationState> emit) async {
|
|
// TODO: Should we guard against adding the same entries multiple times?
|
|
final roster = List<RosterItem>.from(event.added, growable: true);
|
|
|
|
for (final item in state.roster) {
|
|
final modified = firstWhereOrNull(event.modified, (RosterItem i) => i.id == item.id);
|
|
if (modified != null) {
|
|
roster.add(modified);
|
|
} else {
|
|
roster.add(item);
|
|
}
|
|
}
|
|
|
|
emit(state.copyWith(roster: roster));
|
|
}
|
|
}
|