package org.mercury_im.messenger.ui.roster.contacts.detail; import android.graphics.drawable.Drawable; import android.util.Log; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; import org.jivesoftware.smack.PresenceListener; import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.roster.PresenceEventListener; import org.jivesoftware.smack.roster.Roster; import org.jxmpp.jid.Jid; import org.jxmpp.jid.impl.JidCreate; import org.mercury_im.messenger.MercuryImApplication; import org.mercury_im.messenger.Messenger; import org.mercury_im.messenger.data.repository.PeerRepository; import org.mercury_im.messenger.entity.contact.Peer; import org.mercury_im.messenger.ui.avatar.AvatarDrawable; import org.mercury_im.messenger.util.CombinedPresenceListener; import java.util.UUID; import javax.inject.Inject; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.CompositeDisposable; import io.reactivex.schedulers.Schedulers; public class ContactDetailViewModel extends ViewModel { @Inject PeerRepository peerRepository; @Inject Messenger messenger; private MutableLiveData contactAccountId = new MutableLiveData<>(UUID.randomUUID()); private MutableLiveData contactAddress = new MutableLiveData<>("alice@wonderland.lit"); private MutableLiveData contactAvatar = new MutableLiveData<>(new AvatarDrawable("Alice Wonderland", "alice@wonderland.lit")); private MutableLiveData contactPresenceMode = new MutableLiveData<>(Presence.Mode.available); private MutableLiveData contactPresenceStatus = new MutableLiveData<>("Going down the rabbit hole."); private MutableLiveData contactName = new MutableLiveData<>("Alice Wonderland"); private MutableLiveData contactAccountAddress = new MutableLiveData<>("mad@hatter.lit"); private Roster roster; private CompositeDisposable disposable = new CompositeDisposable(); public ContactDetailViewModel() { super(); MercuryImApplication.getApplication().getAppComponent().inject(this); } public void bind(UUID accountId, String peerAddress) { Log.d("MMMMMM", "Bind!"); contactAddress.setValue(peerAddress); contactAccountId.setValue(accountId); disposable.add(peerRepository.observePeerByAddress(accountId, peerAddress) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(peerOptional -> { if (!peerOptional.isPresent()) { return; } Peer peer = peerOptional.getItem(); contactAccountAddress.setValue(peer.getAccount().getAddress()); contactAvatar.setValue(new AvatarDrawable(peer.getDisplayName(), peer.getAddress())); contactName.setValue(peer.getDisplayName()); })); roster = Roster.getInstanceFor(messenger.getConnectionManager().getConnection(accountId).getConnection()); roster.addPresenceEventListener(presenceEventListener); Presence presence = roster.getPresence(JidCreate.entityBareFromOrThrowUnchecked(peerAddress)); if (presence != null) { contactPresenceMode.postValue(presence.getMode()); contactPresenceStatus.postValue(presence.getStatus()); } } public LiveData getContactAddress() { return contactAddress; } @Override protected void onCleared() { super.onCleared(); disposable.dispose(); if (roster != null) { roster.removePresenceEventListener(presenceEventListener); } } public LiveData getAccountId() { return contactAccountId; } public LiveData getContactAvatar() { return contactAvatar; } public LiveData getContactPresenceMode() { return contactPresenceMode; } public LiveData getContactName() { return contactName; } public LiveData getContactPresenceStatus() { return contactPresenceStatus; } public LiveData getContactAccountAddress() { return contactAccountAddress; } private final PresenceEventListener presenceEventListener = new CombinedPresenceListener() { @Override public void presenceReceived(Jid address, Presence presence) { if (presence.getFrom().asBareJid().toString().equals(getContactAddress().getValue())) { contactPresenceMode.postValue(presence.getMode()); contactPresenceStatus.postValue(presence.getStatus()); } } }; }