Mercury-IM/domain/src/main/java/org/mercury_im/messenger/core/viewmodel/chat/ChatViewModel.java

104 lines
4.2 KiB
Java

package org.mercury_im.messenger.core.viewmodel.chat;
import org.jxmpp.jid.EntityBareJid;
import org.mercury_im.messenger.core.Messenger;
import org.mercury_im.messenger.core.SchedulersFacade;
import org.mercury_im.messenger.core.data.repository.DirectChatRepository;
import org.mercury_im.messenger.core.data.repository.MessageRepository;
import org.mercury_im.messenger.core.data.repository.PeerRepository;
import org.mercury_im.messenger.core.data.repository.Repositories;
import org.mercury_im.messenger.core.util.Optional;
import org.mercury_im.messenger.core.viewmodel.MercuryViewModel;
import org.mercury_im.messenger.entity.chat.DirectChat;
import org.mercury_im.messenger.entity.contact.Peer;
import org.mercury_im.messenger.entity.message.Message;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import io.reactivex.Observable;
import io.reactivex.subjects.BehaviorSubject;
import lombok.Getter;
public class ChatViewModel implements MercuryViewModel {
private static final Logger LOGGER = Logger.getLogger(ChatViewModel.class.getName());
private final Messenger messenger;
private final PeerRepository contactRepository;
private final DirectChatRepository directChatRepository;
private final MessageRepository messageRepository;
private final SchedulersFacade schedulers;
private DirectChat chat;
@Getter
private BehaviorSubject<Optional<Peer>> peer = BehaviorSubject.createDefault(new Optional<>());
@Getter
private Observable<List<Message>> messages;
@Getter
private Observable<String> contactDisplayName;
private final BehaviorSubject<Observable<List<Message>>> messageQueryObservable = BehaviorSubject.create();
public ChatViewModel(Messenger messenger,
PeerRepository peerRepository,
DirectChatRepository directChatRepository,
MessageRepository messageRepository,
SchedulersFacade schedulers) {
this.messenger = messenger;
this.contactRepository = peerRepository;
this.directChatRepository = directChatRepository;
this.messageRepository = messageRepository;
this.schedulers = schedulers;
}
public void init(UUID accountId, EntityBareJid contactJid) {
addDisposable(contactRepository.getOrCreatePeer(accountId, contactJid)
.flatMap(directChatRepository::getOrCreateChatWithPeer)
.subscribe(this::init,
e -> LOGGER.log(Level.SEVERE, "Error subscribing to peer data", e)));
}
public void init(DirectChat directChat) {
this.chat = directChat;
messageQueryObservable.onNext(messageRepository.observeMessages(chat));
messages = Observable.switchOnNext(messageQueryObservable);
contactRepository.observePeer(chat.getPeer().getId()).subscribe(peer);
contactDisplayName = peer.map(optional -> optional.isPresent() ? optional.getItem().getDisplayName() : "DELETED");
}
public void onQueryTextChanged(String query) {
if (query.trim().isEmpty()) {
messageQueryObservable.onNext(messageRepository.observeMessages(chat));
} else {
messageQueryObservable.onNext(messageRepository.findMessagesWithBody(chat, query));
}
}
public void deleteContact() {
addDisposable(peer.single(new Optional<>())
.filter(Optional::isPresent)
.map(Optional::getItem)
.flatMapCompletable(messenger::deleteContact)
.compose(schedulers.executeUiSafeCompletable())
.subscribe(
() -> LOGGER.log(Level.INFO, "Contact deleted."),
e -> LOGGER.log(Level.SEVERE, "Error deleting contact.", e)));
}
public void sendMessage(String body) {
addDisposable(messenger.sendEncryptedMessage(getPeer().getValue().getItem(), body)
.compose(schedulers.executeUiSafeCompletable())
.subscribe(() -> LOGGER.log(Level.INFO, "Successfully sent encrypted message."),
e -> LOGGER.log(Level.SEVERE, "Error sending encrypted message.", e)));
}
}