Fix chat search

This commit is contained in:
Paul Schaub 2020-07-13 20:50:44 +02:00
parent dc5df7117f
commit 102f6d9ab1
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
8 changed files with 73 additions and 43 deletions

View File

@ -35,9 +35,6 @@ import io.reactivex.schedulers.Schedulers;
public class AndroidChatViewModel extends ViewModel implements MercuryAndroidViewModel<ChatViewModel> {
private final CompositeDisposable disposable = new CompositeDisposable();
private static final Logger LOGGER = Logger.getLogger(AndroidChatViewModel.class.getName());
@Inject
ChatViewModel commonViewModel;
@ -57,28 +54,22 @@ public class AndroidChatViewModel extends ViewModel implements MercuryAndroidVie
public void init(UUID accountId, EntityBareJid jid) {
commonViewModel.init(accountId, jid);
}
addDisposable(commonViewModel.getPeer()
.filter(Optional::isPresent).map(Optional::getItem)
.compose(schedulers.executeUiSafeObservable())
.subscribe(contact::setValue));
public void init(DirectChat chat) {
this.chat.setValue(chat);
this.contact.setValue(chat.getPeer());
this.commonViewModel.init(chat);
// Subscribe peer
disposable.add(commonViewModel.getContactDisplayName()
.subscribe(name -> contactDisplayName.setValue(name),
error -> LOGGER.log(Level.SEVERE, "Error subscribing display name to peer", error)));
// Subscribe messages
addDisposable(commonViewModel.getMessages()
.subscribe(messageList -> AndroidChatViewModel.this.messages.postValue(messageList),
error -> LOGGER.log(Level.SEVERE, "Error subscribing to messages", error)));
}
.compose(schedulers.executeUiSafeObservable())
.subscribe(messages::setValue));
@Override
protected void onCleared() {
super.onCleared();
disposable.clear();
addDisposable(commonViewModel.getContactDisplayName()
.compose(schedulers.executeUiSafeObservable())
.subscribe(contactDisplayName::setValue));
addDisposable(commonViewModel.getChat()
.compose(schedulers.executeUiSafeObservable())
.subscribe(chat::setValue));
}
public LiveData<List<Message>> getMessages() {

View File

@ -52,4 +52,8 @@ public class AndroidChatListViewModel extends AndroidViewModel implements Mercur
public ChatListViewModel getCommonViewModel() {
return commonViewModel;
}
public void onQueryTextChanged(String query) {
getCommonViewModel().onQueryTextChanged(query);
}
}

View File

@ -74,6 +74,7 @@ public class ChatListFragment extends Fragment implements SearchView.OnQueryText
@Override
public boolean onQueryTextChange(String newText) {
viewModel.onQueryTextChanged(newText);
return false;
}
}

View File

@ -7,6 +7,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.SearchView;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
@ -39,6 +40,12 @@ public class ContactListFragment extends Fragment implements SearchView.OnQueryT
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
viewModel = new ViewModelProvider(this).get(AndroidContactListViewModel.class);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
@ -57,9 +64,8 @@ public class ContactListFragment extends Fragment implements SearchView.OnQueryT
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
viewModel = new ViewModelProvider(this).get(AndroidContactListViewModel.class);
public void onResume() {
super.onResume();
observeViewModel(viewModel);
}

View File

@ -4,6 +4,7 @@ import org.mercury_im.messenger.core.data.repository.DirectChatRepository;
import org.mercury_im.messenger.core.util.Optional;
import org.mercury_im.messenger.data.mapping.DirectChatMapping;
import org.mercury_im.messenger.data.model.DirectChatModel;
import org.mercury_im.messenger.data.model.PeerModel;
import org.mercury_im.messenger.data.repository.dao.DirectChatDao;
import org.mercury_im.messenger.entity.chat.DirectChat;
import org.mercury_im.messenger.entity.contact.Peer;
@ -124,4 +125,16 @@ public class RxDirectChatRepository
return dao.delete(chatId)
.ignoreElement();
}
@Override
public Observable<List<DirectChat>> findChatsByQuery(String query) {
return data().select(DirectChatModel.class)
.join(PeerModel.class)
.on(DirectChatModel.PEER_ID.eq(PeerModel.ID))
.where(PeerModel.NAME.like("%" + query + "%")
.or(PeerModel.ADDRESS.like("%" + query + "%")))
.get().observableResult()
.map(ResultDelegate::toList)
.map(this::chatModelsToEntities);
}
}

View File

@ -42,4 +42,5 @@ public interface DirectChatRepository {
Completable deleteDirectChat(UUID chatId);
Observable<List<DirectChat>> findChatsByQuery(String query);
}

View File

@ -10,19 +10,32 @@ import java.util.List;
import javax.inject.Inject;
import io.reactivex.Observable;
import io.reactivex.subjects.BehaviorSubject;
public class ChatListViewModel implements MercuryViewModel {
private final SchedulersFacade schedulers;
private final DirectChatRepository directChatRepository;
private final BehaviorSubject<Observable<List<DirectChat>>> chatSourceObservable;
@Inject
public ChatListViewModel(DirectChatRepository directChatRepository, SchedulersFacade schedulers) {
this.directChatRepository = directChatRepository;
this.schedulers = schedulers;
chatSourceObservable = BehaviorSubject.createDefault(directChatRepository.observeAllDirectChats());
}
public Observable<List<DirectChat>> observeAllDirectChats() {
return directChatRepository.observeAllDirectChats();
return Observable.switchOnNext(chatSourceObservable);
}
public void onQueryTextChanged(String query) {
if (query.trim().isEmpty()) {
chatSourceObservable.onNext(directChatRepository.observeAllDirectChats());
} else {
chatSourceObservable.onNext(directChatRepository.findChatsByQuery(query));
}
}
}

View File

@ -19,6 +19,7 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import io.reactivex.Observable;
import io.reactivex.Single;
import io.reactivex.subjects.BehaviorSubject;
import lombok.Getter;
@ -31,10 +32,14 @@ public class ChatViewModel implements MercuryViewModel {
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<>());
private BehaviorSubject<Optional<Peer>> peer = BehaviorSubject.create();
Single<DirectChat> directChat;
@Getter
private BehaviorSubject<DirectChat> chat = BehaviorSubject.create();
@Getter
private Observable<List<Message>> messages;
@ -58,28 +63,24 @@ public class ChatViewModel implements MercuryViewModel {
}
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)));
}
Single<Peer> peerSingle = contactRepository.getOrCreatePeer(accountId, contactJid);
peerSingle.flatMapObservable(contactRepository::observePeer).subscribe(peer);
directChat = peerSingle.flatMap(directChatRepository::getOrCreateChatWithPeer);
public void init(DirectChat directChat) {
this.chat = directChat;
directChat.toObservable().compose(schedulers.executeUiSafeObservable()).subscribe(chat);
messageQueryObservable.onNext(messageRepository.observeMessages(chat));
Observable<List<Message>> allMessagesObservable = directChat.flatMapObservable(messageRepository::observeMessages);
messageQueryObservable.onNext(allMessagesObservable);
messages = Observable.switchOnNext(messageQueryObservable);
contactRepository.observePeer(chat.getPeer().getId()).subscribe(peer);
contactDisplayName = peer.map(optional -> optional.isPresent() ? optional.getItem().getDisplayName() : "DELETED");
contactDisplayName = peer.filter(Optional::isPresent).map(Optional::getItem)
.map(Peer::getDisplayName);
}
public void onQueryTextChanged(String query) {
if (query.trim().isEmpty()) {
messageQueryObservable.onNext(messageRepository.observeMessages(chat));
messageQueryObservable.onNext(directChat.flatMapObservable(messageRepository::observeMessages));
} else {
messageQueryObservable.onNext(messageRepository.findMessagesWithBody(chat, query));
messageQueryObservable.onNext(directChat.flatMapObservable(c -> messageRepository.findMessagesWithBody(c, query)));
}
}
@ -95,7 +96,7 @@ public class ChatViewModel implements MercuryViewModel {
}
public void sendMessage(String body) {
addDisposable(messenger.sendEncryptedMessage(getPeer().getValue().getItem(), body)
addDisposable(messenger.sendEncryptedMessage(peer.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)));