Pass IDs instead of value pairs to initialize fragments/view models

This commit is contained in:
Paul Schaub 2020-08-09 13:14:49 +02:00
parent 3a7b17649a
commit 4f04a29798
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
9 changed files with 93 additions and 88 deletions

View File

@ -31,7 +31,6 @@ import java.util.logging.Logger;
import javax.inject.Inject;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
/**
* Started, Bound Service, which is responsible keeping the application alive when the app is not open.

View File

@ -51,11 +51,13 @@ public class AndroidChatViewModel extends ViewModel implements MercuryAndroidVie
MercuryImApplication.getApplication().getAppComponent().inject(this);
}
public void init(UUID accountId, EntityBareJid jid) {
commonViewModel.init(accountId, jid);
public void init(UUID chatId) {
commonViewModel.init(chatId);
bindObservablesToLiveData();
}
private void bindObservablesToLiveData() {
addDisposable(commonViewModel.getPeer()
.filter(Optional::isPresent).map(Optional::getItem)
.compose(schedulers.executeUiSafeObservable())
.subscribe(contact::setValue));

View File

@ -32,6 +32,7 @@ import io.reactivex.disposables.CompositeDisposable;
public class ChatActivity extends AppCompatActivity
implements ChatInputFragment.OnChatInputActionListener, SearchView.OnQueryTextListener {
public static final String EXTRA_CHAT_ID = "CHAT_ID";
public static final String EXTRA_JID = "JID";
public static final String EXTRA_ACCOUNT = "ACCOUNT";
@ -47,17 +48,20 @@ public class ChatActivity extends AppCompatActivity
private final CompositeDisposable disposable = new CompositeDisposable();
private EntityBareJid jid;
private UUID accountId;
private UUID chatId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("Mercury", "onCreate");
setContentView(R.layout.activity_chat);
ButterKnife.bind(this);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
recyclerView.setAdapter(recyclerViewAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
MercuryImApplication.getApplication().getAppComponent().inject(this);
if (savedInstanceState == null) {
@ -65,32 +69,22 @@ public class ChatActivity extends AppCompatActivity
if (savedInstanceState == null) return;
}
setSupportActionBar(toolbar);
// Show back arrow
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
recyclerView.setAdapter(recyclerViewAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
String jidString = savedInstanceState.getString(EXTRA_JID);
if (jidString != null) {
jid = JidCreate.entityBareFromOrThrowUnchecked(jidString);
// JID will never change, so just set it once
getSupportActionBar().setSubtitle(jid.asUnescapedString());
accountId = UUID.fromString(savedInstanceState.getString(EXTRA_ACCOUNT));
androidChatViewModel = new ViewModelProvider(this).get(AndroidChatViewModel.class);
androidChatViewModel.init(accountId, jid);
// Listen for updates to contact information and messages
observeViewModel(androidChatViewModel);
String chatIdString = savedInstanceState.getString(EXTRA_CHAT_ID);
if (chatIdString == null) {
return;
}
chatId = UUID.fromString(chatIdString);
androidChatViewModel = new ViewModelProvider(this).get(AndroidChatViewModel.class);
androidChatViewModel.init(chatId);
// Listen for updates to contact information and messages
observeViewModel(androidChatViewModel);
toolbar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(ChatActivity.this, ContactDetailActivity.class);
intent.putExtra(ContactDetailActivity.EXTRA_JID, jidString);
intent.putExtra(ContactDetailActivity.EXTRA_ACCOUNT, accountId.toString());
intent.putExtra(ContactDetailActivity.EXTRA_PEER_ID, androidChatViewModel.getContact().getValue().getId().toString());
ChatActivity.this.startActivity(intent);
}
@ -100,6 +94,8 @@ public class ChatActivity extends AppCompatActivity
public void observeViewModel(AndroidChatViewModel viewModel) {
viewModel.getContactDisplayName().observe(this,
name -> getSupportActionBar().setTitle(name));
viewModel.getContact().observe(this,
contact -> getSupportActionBar().setSubtitle(contact.getJid()));
viewModel.getMessages().observe(this, messageModels -> {
recyclerViewAdapter.updateMessages(messageModels);
@ -161,8 +157,7 @@ public class ChatActivity extends AppCompatActivity
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
outState.putString(EXTRA_JID, jid.toString());
outState.putString(EXTRA_ACCOUNT, accountId.toString());
outState.putString(EXTRA_CHAT_ID, chatId.toString());
super.onSaveInstanceState(outState);
}

View File

@ -53,8 +53,7 @@ public class ChatListRecyclerViewAdapter
holder.itemView.setOnClickListener(view -> {
Intent intent = new Intent(holder.context, ChatActivity.class);
intent.putExtra(ChatActivity.EXTRA_JID, model.getPeer().getAddress());
intent.putExtra(ChatActivity.EXTRA_ACCOUNT, model.getPeer().getAccount().getId().toString());
intent.putExtra(ChatActivity.EXTRA_CHAT_ID, model.getId().toString());
holder.context.startActivity(intent);
});

View File

@ -73,8 +73,7 @@ public class ContactListRecyclerViewAdapter
view.setOnClickListener(view -> {
Intent intent = new Intent(context, ContactDetailActivity.class);
intent.putExtra(ContactDetailActivity.EXTRA_JID, address);
intent.putExtra(ContactDetailActivity.EXTRA_ACCOUNT, contact.getAccount().getId().toString());
intent.putExtra(ContactDetailActivity.EXTRA_PEER_ID, contact.getId().toString());
context.startActivity(intent);
});

View File

@ -18,6 +18,7 @@ import butterknife.ButterKnife;
public class ContactDetailActivity extends AppCompatActivity {
public static final String EXTRA_JID = "JID";
public static final String EXTRA_ACCOUNT = "ACCOUNT";
public static final String EXTRA_PEER_ID = "PEER_ID";
@BindView(R.id.fragment)
FrameLayout container;
@ -35,13 +36,11 @@ public class ContactDetailActivity extends AppCompatActivity {
if (savedInstanceState == null) return;
}
String jidString = savedInstanceState.getString(EXTRA_JID);
if (jidString != null) {
UUID accountId = UUID.fromString(savedInstanceState.getString(EXTRA_ACCOUNT));
String peerIdString = savedInstanceState.getString(EXTRA_PEER_ID);
UUID peerId = UUID.fromString(peerIdString);
ContactDetailViewModel viewModel = new ViewModelProvider(this).get(ContactDetailViewModel.class);
viewModel.bind(accountId, jidString);
}
ContactDetailViewModel viewModel = new ViewModelProvider(this).get(ContactDetailViewModel.class);
viewModel.bind(peerId);
getSupportFragmentManager().beginTransaction().replace(R.id.fragment, new ContactDetailFragment(), "contact_details").commit();
}

View File

@ -31,6 +31,7 @@ import org.mercury_im.messenger.R;
import org.mercury_im.messenger.android.ui.chat.ChatActivity;
import org.mercury_im.messenger.android.util.ColorUtil;
import org.mercury_im.messenger.core.viewmodel.openpgp.FingerprintViewItem;
import org.mercury_im.messenger.entity.chat.DirectChat;
import java.util.Arrays;
import java.util.List;
@ -92,8 +93,7 @@ public class ContactDetailFragment extends Fragment {
if (fab != null) {
fab.setOnClickListener(v -> {
Intent intent = new Intent(getContext(), ChatActivity.class);
intent.putExtra(ChatActivity.EXTRA_JID, viewModel.getContactAddress().getValue());
intent.putExtra(ChatActivity.EXTRA_ACCOUNT, viewModel.getAccountId().getValue().toString());
intent.putExtra(ChatActivity.EXTRA_CHAT_ID, viewModel.getOrCreateChat().blockingGet().toString());
startActivity(intent);
});
}

View File

@ -22,9 +22,12 @@ import org.jxmpp.jid.impl.JidCreate;
import org.mercury_im.messenger.android.MercuryImApplication;
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.OpenPgpRepository;
import org.mercury_im.messenger.core.data.repository.PeerRepository;
import org.mercury_im.messenger.core.util.Optional;
import org.mercury_im.messenger.core.viewmodel.openpgp.FingerprintViewItem;
import org.mercury_im.messenger.entity.chat.Chat;
import org.mercury_im.messenger.entity.contact.Peer;
import org.mercury_im.messenger.android.ui.avatar.AvatarDrawable;
import org.mercury_im.messenger.core.util.CombinedPresenceListener;
@ -38,6 +41,7 @@ import java.util.UUID;
import javax.inject.Inject;
import io.reactivex.Completable;
import io.reactivex.Single;
import io.reactivex.disposables.CompositeDisposable;
public class ContactDetailViewModel extends ViewModel {
@ -45,6 +49,9 @@ public class ContactDetailViewModel extends ViewModel {
@Inject
PeerRepository peerRepository;
@Inject
DirectChatRepository directChatRepository;
@Inject
OpenPgpRepository openPgpRepository;
@ -65,6 +72,7 @@ public class ContactDetailViewModel extends ViewModel {
private MutableLiveData<List<FingerprintViewItem>> contactFingerprints = new MutableLiveData<>(Collections.emptyList());
private Roster roster;
private UUID peerId;
private CompositeDisposable disposable = new CompositeDisposable();
@ -73,26 +81,40 @@ public class ContactDetailViewModel extends ViewModel {
MercuryImApplication.getApplication().getAppComponent().inject(this);
}
public void bind(UUID accountId, String peerAddress) {
Log.d("MMMMMM", "Bind!");
EntityBareJid peerJid = JidCreate.entityBareFromOrThrowUnchecked(peerAddress);
roster = Roster.getInstanceFor(messenger.getConnectionManager().getConnection(accountId).getConnection());
roster.addPresenceEventListener(presenceEventListener);
contactAddress.setValue(peerAddress);
contactAccountId.setValue(accountId);
disposable.add(peerRepository.observePeerByAddress(accountId, peerJid)
.subscribeOn(schedulers.getIoScheduler())
.observeOn(schedulers.getUiScheduler())
.subscribe(peerOptional -> {
if (!peerOptional.isPresent()) {
return;
public void bind(UUID peerId) {
this.peerId = peerId;
disposable.add(peerRepository.getPeer(peerId)
.subscribe(p -> {
roster = Roster.getInstanceFor(messenger.getConnectionManager().getConnection(p.getAccount()).getConnection());
roster.addPresenceEventListener(presenceEventListener);
Presence presence = roster.getPresence(p.getJid());
if (presence != null) {
contactPresenceMode.postValue(presence.getMode());
contactPresenceStatus.postValue(presence.getStatus());
}
Peer peer = peerOptional.getItem();
disposable.add(openPgpRepository.observeFingerprints(p.getAccount().getId(), p.getJid())
.subscribeOn(schedulers.getIoScheduler())
.observeOn(schedulers.getUiScheduler())
.subscribe(list -> contactFingerprints.setValue(list)));
}));
disposable.add(peerRepository.observePeer(peerId)
.filter(Optional::isPresent)
.map(Optional::getItem)
.compose(schedulers.executeUiSafeObservable())
.subscribe(peer -> {
contactAddress.setValue(peer.getAddress());
contactAccountId.setValue(peer.getAccount().getId());
contactAccountAddress.setValue(peer.getAccount().getAddress());
contactAvatar.setValue(new AvatarDrawable(peer.getDisplayName(), peer.getAddress()));
contactName.setValue(peer.getDisplayName());
RosterEntry entry = roster.getEntry(JidCreate.entityBareFromOrThrowUnchecked(peerAddress));
RosterEntry entry = roster.getEntry(peer.getJid());
if (entry != null) {
List<RosterGroup> groups = entry.getGroups();
List<String> groupNames = new ArrayList<>(groups.size());
@ -102,17 +124,6 @@ public class ContactDetailViewModel extends ViewModel {
contactGroups.postValue(groupNames);
}
}));
Presence presence = roster.getPresence(peerJid);
if (presence != null) {
contactPresenceMode.postValue(presence.getMode());
contactPresenceStatus.postValue(presence.getStatus());
}
disposable.add(openPgpRepository.observeFingerprints(accountId, peerJid)
.subscribeOn(schedulers.getIoScheduler())
.observeOn(schedulers.getUiScheduler())
.subscribe(list -> contactFingerprints.setValue(list)));
}
public LiveData<String> getContactAddress() {
@ -156,6 +167,12 @@ public class ContactDetailViewModel extends ViewModel {
return contactGroups;
}
public Single<UUID> getOrCreateChat() {
return peerRepository.getPeer(peerId)
.flatMapSingle(directChatRepository::getOrCreateChatWithPeer)
.map(Chat::getId);
}
private final PresenceEventListener presenceEventListener = new CombinedPresenceListener() {
@Override
public void presenceReceived(Jid address, Presence presence) {

View File

@ -1,6 +1,5 @@
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;
@ -18,8 +17,6 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import io.reactivex.Observable;
import io.reactivex.Single;
import io.reactivex.functions.Function;
import io.reactivex.subjects.BehaviorSubject;
import lombok.Getter;
@ -34,7 +31,7 @@ public class ChatViewModel implements MercuryViewModel {
private final SchedulersFacade schedulers;
@Getter
private BehaviorSubject<Optional<Peer>> peer = BehaviorSubject.create();
private BehaviorSubject<Peer> peer = BehaviorSubject.create();
@Getter
private BehaviorSubject<DirectChat> chat = BehaviorSubject.create();
@ -60,25 +57,25 @@ public class ChatViewModel implements MercuryViewModel {
this.schedulers = schedulers;
}
public void init(UUID accountId, EntityBareJid contactJid) {
contactRepository.getOrCreatePeer(accountId, contactJid)
.flatMapObservable(contactRepository::observePeer)
.subscribe(peer);
peer.compose(schedulers.executeUiSafeObservable())
.subscribe();
peer.filter(Optional::isPresent).map(Optional::getItem)
.flatMap(p -> directChatRepository.getOrCreateChatWithPeer(p).toObservable())
public void init(UUID chatId) {
directChatRepository.observeDirectChat(chatId)
.filter(Optional::isPresent)
.map(Optional::getItem)
.compose(schedulers.executeUiSafeObservable())
.subscribe(chat);
chat.compose(schedulers.executeUiSafeObservable()).subscribe();
chat.map(DirectChat::getPeer)
.flatMap(contactRepository::observePeer)
.compose(schedulers.executeUiSafeObservable())
.filter(Optional::isPresent)
.map(Optional::getItem)
.subscribe(peer);
Observable<List<Message>> allMessagesObservable = chat.flatMap(messageRepository::observeMessages);
messageQueryObservable.onNext(allMessagesObservable);
messages = Observable.switchOnNext(messageQueryObservable);
contactDisplayName = peer.filter(Optional::isPresent).map(Optional::getItem)
.map(Peer::getDisplayName);
contactDisplayName = peer.map(Peer::getDisplayName);
}
public void onQueryTextChanged(String query) {
@ -90,9 +87,7 @@ public class ChatViewModel implements MercuryViewModel {
}
public void deleteContact() {
addDisposable(peer.single(new Optional<>())
.filter(Optional::isPresent)
.map(Optional::getItem)
addDisposable(peer.singleOrError()
.flatMapCompletable(messenger::deleteContact)
.compose(schedulers.executeUiSafeCompletable())
.subscribe(