package org.mercury_im.messenger.android.ui.account.detail; import android.app.Application; import androidx.annotation.NonNull; import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModelProvider; import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.impl.JidCreate; import org.mercury_im.messenger.android.MercuryImApplication; import org.mercury_im.messenger.android.ui.MercuryAndroidViewModel; import org.mercury_im.messenger.core.SchedulersFacade; import org.mercury_im.messenger.core.util.DefaultUtil; import org.mercury_im.messenger.core.util.Optional; import org.mercury_im.messenger.core.viewmodel.account.detail.AccountDetailsViewModel; import org.mercury_im.messenger.core.viewmodel.openpgp.FingerprintViewItem; import org.pgpainless.key.OpenPgpV4Fingerprint; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.UUID; import java.util.logging.Level; import java.util.logging.Logger; import javax.inject.Inject; import io.reactivex.Completable; public class AndroidAccountDetailsViewModel extends AndroidViewModel implements MercuryAndroidViewModel { private static final Logger LOGGER = Logger.getLogger(AndroidAccountDetailsViewModel.class.getName()); @Inject SchedulersFacade schedulers; @Inject AccountDetailsViewModel commonViewModel; private final UUID accountId; private MutableLiveData> ikeyFingerprint = new MutableLiveData<>(); private MutableLiveData localFingerprint = new MutableLiveData<>(); private MutableLiveData> remoteFingerprints = new MutableLiveData<>(new ArrayList<>()); private MutableLiveData jid = new MutableLiveData<>(DefaultUtil.defaultJid()); public AndroidAccountDetailsViewModel(@NonNull Application application, UUID accountId) { super(application); this.accountId = accountId; LOGGER.log(Level.INFO, "Creating AndroidAccountDetailsViewModel"); ((MercuryImApplication) application).getAppComponent().inject(this); addDisposable(getCommonViewModel().observeLocalFingerprint(accountId) .compose(schedulers.executeUiSafeObservable()) .filter(Optional::isPresent) .map(Optional::getItem) .subscribe(localFingerprint::postValue)); addDisposable(getCommonViewModel().observeIkeyFingerprint(accountId) .compose(schedulers.executeUiSafeObservable()) .subscribe(ikeyFingerprint::postValue, e -> LOGGER.log(Level.SEVERE, "Error displaying ikey fingerprint", e))); addDisposable(getCommonViewModel().observeRemoteFingerprints(accountId) .compose(schedulers.executeUiSafeObservable()) .subscribe(list -> { LOGGER.log(Level.INFO, "Set remote fingerprints to list: " + Arrays.toString(list.toArray())); remoteFingerprints.postValue(list); }, e -> LOGGER.log(Level.SEVERE, "Error observing remote fingerprints.", e), () -> LOGGER.log(Level.INFO, "observing remote fingerprint onComplete."))); addDisposable(getCommonViewModel().getJid(accountId).subscribe(jid::postValue)); } @Override public AccountDetailsViewModel getCommonViewModel() { return commonViewModel; } public LiveData getJid() { return jid; } public void markFingerprintTrusted(OpenPgpV4Fingerprint fingerprint, boolean trusted) { getCommonViewModel().markFingerprintTrusted(accountId, fingerprint, trusted); } public LiveData> getIkeyFingerprint() { return ikeyFingerprint; } public LiveData getLocalFingerprint() { return localFingerprint; } public LiveData> getRemoteFingerprints() { return remoteFingerprints; } public void unpublishPublicKey(OpenPgpV4Fingerprint fingerprint) { addDisposable(getCommonViewModel().unpublishPublicKey(accountId, fingerprint) .subscribeOn(schedulers.getNewThread()) .observeOn(schedulers.getUiScheduler()) .subscribe(() -> LOGGER.log(Level.INFO, "Successfully unpublished fingerprint " + fingerprint), e -> LOGGER.log(Level.SEVERE, "Error unpublishing fingerprint " + fingerprint, e))); } public void onGenerateIkey() { addDisposable(getCommonViewModel().generateIkey(accountId) .subscribeOn(schedulers.getNewThread()) .observeOn(schedulers.getUiScheduler()) .subscribe(() -> LOGGER.log(Level.INFO, "IKey generated for account " + accountId), e -> LOGGER.log(Level.SEVERE, "Could not generate Ikey", e))); } public void onDeleteIkey() { addDisposable(getCommonViewModel().deleteIkey(accountId) .subscribeOn(schedulers.getNewThread()) .observeOn(schedulers.getUiScheduler()) .subscribe(() -> LOGGER.log(Level.INFO, "IKey deleted for account " + accountId), e -> LOGGER.log(Level.SEVERE, "Could not delete Ikey", e))); } public void onRestoreIkeyBackup() { addDisposable(getCommonViewModel().restoreIkeyBackup(accountId) .subscribeOn(schedulers.getNewThread()) .observeOn(schedulers.getUiScheduler()) .subscribe(() -> LOGGER.log(Level.INFO, "IKey restored for account " + accountId), e -> LOGGER.log(Level.SEVERE, "Could not restore Ikey backup", e))); } public static class AndroidAccountDetailsViewModelFactory implements ViewModelProvider.Factory { private final Application application; private final UUID accountId; public AndroidAccountDetailsViewModelFactory(Application application, UUID accountId) { this.application = application; this.accountId = accountId; } @NonNull @Override public T create(@NonNull Class modelClass) { return (T) new AndroidAccountDetailsViewModel(application, accountId); } } }