Mercury-IM/domain/src/main/java/org/mercury_im/messenger/core/viewmodel/accounts/AccountsViewModel.java

102 lines
4.6 KiB
Java

package org.mercury_im.messenger.core.viewmodel.accounts;
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
import org.mercury_im.messenger.core.SchedulersFacade;
import org.mercury_im.messenger.core.data.repository.AccountRepository;
import org.mercury_im.messenger.core.data.repository.OpenPgpRepository;
import org.mercury_im.messenger.core.viewmodel.MercuryViewModel;
import org.mercury_im.messenger.core.xmpp.MercuryConnectionManager;
import org.mercury_im.messenger.core.xmpp.state.ConnectionPoolState;
import org.mercury_im.messenger.core.xmpp.state.ConnectionState;
import org.mercury_im.messenger.entity.Account;
import org.pgpainless.key.OpenPgpV4Fingerprint;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.inject.Inject;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;
public class AccountsViewModel implements MercuryViewModel {
private static final Logger LOGGER = Logger.getLogger(AccountsViewModel.class.getName());
private final MercuryConnectionManager connectionManager;
private final AccountRepository accountRepository;
private final OpenPgpRepository openPgpRepository;
private final SchedulersFacade schedulers;
@Inject
public AccountsViewModel(MercuryConnectionManager connectionManager,
AccountRepository accountRepository,
OpenPgpRepository openPgpRepository,
SchedulersFacade schedulers) {
this.connectionManager = connectionManager;
this.accountRepository = accountRepository;
this.openPgpRepository = openPgpRepository;
this.schedulers = schedulers;
}
public Observable<List<AccountViewItem>> observeAccounts() {
return connectionManager.observeConnectionPool()
.compose(toAccountViewItems);
}
public void onToggleAccountEnabled(Account account, boolean enabled) {
account.setEnabled(enabled);
addDisposable(accountRepository.upsertAccount(account)
.subscribeOn(schedulers.getIoScheduler())
.observeOn(schedulers.getUiScheduler())
.subscribe(
success -> logAccountToggledSuccess(success, enabled),
error -> logAccountToggleError(account, enabled, error)
)
);
}
private void logAccountToggledSuccess(Account account, boolean enabled) {
LOGGER.log(Level.INFO, "Account " + account.getAddress() + (enabled ? " enabled" : " disabled"));
}
private void logAccountToggleError(Account account, boolean enabled, Throwable error) {
LOGGER.log(Level.SEVERE, "Account " + account.getAddress() + " could not be " + (enabled ? "enabled" : "disabled"), error);
}
private final ObservableTransformer<ConnectionPoolState, List<AccountViewItem>> toAccountViewItems = new ObservableTransformer<ConnectionPoolState, List<AccountViewItem>>() {
@Override
public ObservableSource<List<AccountViewItem>> apply(Observable<ConnectionPoolState> upstream) {
return upstream.map(state -> {
List<AccountViewItem> viewItems = new ArrayList<>();
for (Map.Entry<UUID, ConnectionState> entry : state.getConnectionStates().entrySet()) {
ConnectionState connectionState = entry.getValue();
Account account = accountRepository.getAccount(entry.getKey()).blockingGet();
OpenPgpV4Fingerprint fingerprint = null;
try {
PGPSecretKeyRingCollection secretKeyRings = openPgpRepository.loadSecretKeysOf(account.getId(), account.getJid()).blockingGet();
fingerprint = new OpenPgpV4Fingerprint(secretKeyRings.getKeyRings().next());
} catch (NoSuchElementException e) {
LOGGER.log(Level.INFO, "No fingerprint found for " + account.getAddress());
}
viewItems.add(new AccountViewItem(account, connectionState.getConnectivity(), fingerprint));
}
return viewItems;
});
}
};
public void onDeleteAccount(UUID accountId) {
addDisposable(accountRepository.deleteAccount(accountId)
.subscribe(() -> LOGGER.log(Level.INFO, "Account " + accountId + " successfully deleted."),
e -> LOGGER.log(Level.SEVERE, "Could not delete account " + accountId, e)));
}
}