Some cleanup
This commit is contained in:
parent
69120efb25
commit
40266f8741
|
@ -14,7 +14,7 @@ import org.mercury_im.messenger.android.di.component.AppComponent;
|
||||||
import org.mercury_im.messenger.android.di.module.AppModule;
|
import org.mercury_im.messenger.android.di.module.AppModule;
|
||||||
import org.mercury_im.messenger.entity.Account;
|
import org.mercury_im.messenger.entity.Account;
|
||||||
import org.mercury_im.messenger.android.service.MercuryForegroundService;
|
import org.mercury_im.messenger.android.service.MercuryForegroundService;
|
||||||
import org.mercury_im.messenger.core.xmpp.CsiManager;
|
import org.mercury_im.messenger.core.connection.CsiManager;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,7 @@ public class AccountDetailsFragment extends Fragment {
|
||||||
|
|
||||||
this.adapter = new ToggleableFingerprintsAdapter(
|
this.adapter = new ToggleableFingerprintsAdapter(
|
||||||
(fingerprint, checked) -> viewModel.markFingerprintTrusted(fingerprint, checked));
|
(fingerprint, checked) -> viewModel.markFingerprintTrusted(fingerprint, checked));
|
||||||
|
this.adapter.setItemLongClickListener(fingerprint -> viewModel.unpublishPublicKey(fingerprint));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void observe() {
|
private void observe() {
|
||||||
|
|
|
@ -28,6 +28,8 @@ import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import io.reactivex.Completable;
|
||||||
|
|
||||||
public class AndroidAccountDetailsViewModel extends AndroidViewModel implements MercuryAndroidViewModel<AccountDetailsViewModel> {
|
public class AndroidAccountDetailsViewModel extends AndroidViewModel implements MercuryAndroidViewModel<AccountDetailsViewModel> {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(AndroidAccountDetailsViewModel.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(AndroidAccountDetailsViewModel.class.getName());
|
||||||
|
@ -89,6 +91,14 @@ public class AndroidAccountDetailsViewModel extends AndroidViewModel implements
|
||||||
return remoteFingerprints;
|
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 static class AndroidAccountDetailsViewModelFactory implements ViewModelProvider.Factory {
|
public static class AndroidAccountDetailsViewModelFactory implements ViewModelProvider.Factory {
|
||||||
|
|
||||||
private final Application application;
|
private final Application application;
|
||||||
|
|
|
@ -62,8 +62,12 @@ public class AccountListRecyclerViewAdapter extends RecyclerView.Adapter<Account
|
||||||
holder.jid.setText(account.getAddress());
|
holder.jid.setText(account.getAddress());
|
||||||
holder.avatar.setImageDrawable(new AvatarDrawable(account.getAddress(), account.getAddress()));
|
holder.avatar.setImageDrawable(new AvatarDrawable(account.getAddress(), account.getAddress()));
|
||||||
holder.enabled.setChecked(account.isEnabled());
|
holder.enabled.setChecked(account.isEnabled());
|
||||||
holder.enabled.setOnCheckedChangeListener((compoundButton, checked) ->
|
holder.enabled.setOnCheckedChangeListener((compoundButton, checked) -> {
|
||||||
viewModel.setAccountEnabled(account, checked));
|
if (!compoundButton.isPressed()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
viewModel.setAccountEnabled(account, checked);
|
||||||
|
});
|
||||||
holder.status.setText(viewItem.getConnectivityState().toString());
|
holder.status.setText(viewItem.getConnectivityState().toString());
|
||||||
|
|
||||||
holder.mView.setOnLongClickListener(v -> {
|
holder.mView.setOnLongClickListener(v -> {
|
||||||
|
|
|
@ -22,6 +22,7 @@ public class ToggleableFingerprintsAdapter extends RecyclerView.Adapter<Toggleab
|
||||||
|
|
||||||
private final List<FingerprintViewItem> fingerprints = new ArrayList<>();
|
private final List<FingerprintViewItem> fingerprints = new ArrayList<>();
|
||||||
private final OnFingerprintItemToggleListener toggleListener;
|
private final OnFingerprintItemToggleListener toggleListener;
|
||||||
|
private OnFingerprintItemLongClickListener longClickListener = null;
|
||||||
|
|
||||||
private static final DateFormat dateFormat = SimpleDateFormat.getDateInstance();
|
private static final DateFormat dateFormat = SimpleDateFormat.getDateInstance();
|
||||||
|
|
||||||
|
@ -59,6 +60,13 @@ public class ToggleableFingerprintsAdapter extends RecyclerView.Adapter<Toggleab
|
||||||
holder.trustSwitch.setOnCheckedChangeListener(
|
holder.trustSwitch.setOnCheckedChangeListener(
|
||||||
(buttonView, isChecked) -> toggleListener.onFingerprintToggled(fingerprint, isChecked));
|
(buttonView, isChecked) -> toggleListener.onFingerprintToggled(fingerprint, isChecked));
|
||||||
holder.divider.setVisibility(position == fingerprints.size() - 1 ? View.GONE : View.VISIBLE);
|
holder.divider.setVisibility(position == fingerprints.size() - 1 ? View.GONE : View.VISIBLE);
|
||||||
|
|
||||||
|
holder.itemView.setOnLongClickListener(v -> {
|
||||||
|
if (longClickListener != null) {
|
||||||
|
longClickListener.onFingerprintItemLongClick(fingerprint);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,8 +91,17 @@ public class ToggleableFingerprintsAdapter extends RecyclerView.Adapter<Toggleab
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setItemLongClickListener(OnFingerprintItemLongClickListener longClickListener) {
|
||||||
|
this.longClickListener = longClickListener;
|
||||||
|
}
|
||||||
|
|
||||||
public interface OnFingerprintItemToggleListener {
|
public interface OnFingerprintItemToggleListener {
|
||||||
|
|
||||||
void onFingerprintToggled(OpenPgpV4Fingerprint fingerprint, boolean checked);
|
void onFingerprintToggled(OpenPgpV4Fingerprint fingerprint, boolean checked);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface OnFingerprintItemLongClickListener {
|
||||||
|
|
||||||
|
void onFingerprintItemLongClick(OpenPgpV4Fingerprint fingerprint);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.mercury_im.messenger.cli.di.component.CliComponent;
|
||||||
import org.mercury_im.messenger.cli.di.component.DaggerCliComponent;
|
import org.mercury_im.messenger.cli.di.component.DaggerCliComponent;
|
||||||
import org.mercury_im.messenger.core.Messenger;
|
import org.mercury_im.messenger.core.Messenger;
|
||||||
import org.mercury_im.messenger.core.viewmodel.account.LoginViewModel;
|
import org.mercury_im.messenger.core.viewmodel.account.LoginViewModel;
|
||||||
import org.mercury_im.messenger.core.xmpp.MercuryConnection;
|
import org.mercury_im.messenger.core.connection.MercuryConnection;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import org.jivesoftware.smack.tcp.XMPPTCPConnection;
|
||||||
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
|
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
|
||||||
import org.jivesoftware.smack.util.TLSUtils;
|
import org.jivesoftware.smack.util.TLSUtils;
|
||||||
import org.jxmpp.stringprep.XmppStringprepException;
|
import org.jxmpp.stringprep.XmppStringprepException;
|
||||||
import org.mercury_im.messenger.core.xmpp.XmppConnectionFactory;
|
import org.mercury_im.messenger.core.connection.XmppConnectionFactory;
|
||||||
import org.mercury_im.messenger.entity.Account;
|
import org.mercury_im.messenger.entity.Account;
|
||||||
|
|
||||||
public class X509WorkaroundConnectionFactory implements XmppConnectionFactory {
|
public class X509WorkaroundConnectionFactory implements XmppConnectionFactory {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.mercury_im.messenger.cli.di.module;
|
package org.mercury_im.messenger.cli.di.module;
|
||||||
|
|
||||||
import org.mercury_im.messenger.cli.X509WorkaroundConnectionFactory;
|
import org.mercury_im.messenger.cli.X509WorkaroundConnectionFactory;
|
||||||
import org.mercury_im.messenger.core.xmpp.XmppConnectionFactory;
|
import org.mercury_im.messenger.core.connection.XmppConnectionFactory;
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
package org.mercury_im.messenger.data.enums;
|
|
||||||
|
|
||||||
public enum MessageContentType {
|
|
||||||
/**
|
|
||||||
* Content is a message body.
|
|
||||||
*/
|
|
||||||
body
|
|
||||||
}
|
|
|
@ -11,11 +11,11 @@ import org.jivesoftware.smackx.ox_im.OXInstantMessagingManager;
|
||||||
import org.jxmpp.jid.EntityBareJid;
|
import org.jxmpp.jid.EntityBareJid;
|
||||||
import org.jxmpp.jid.impl.JidCreate;
|
import org.jxmpp.jid.impl.JidCreate;
|
||||||
import org.jxmpp.stringprep.XmppStringprepException;
|
import org.jxmpp.stringprep.XmppStringprepException;
|
||||||
|
import org.mercury_im.messenger.core.connection.MercuryConnection;
|
||||||
|
import org.mercury_im.messenger.core.connection.MercuryConnectionManager;
|
||||||
import org.mercury_im.messenger.core.data.repository.Repositories;
|
import org.mercury_im.messenger.core.data.repository.Repositories;
|
||||||
import org.mercury_im.messenger.core.exception.ConnectionNotFoundException;
|
import org.mercury_im.messenger.core.exception.ConnectionNotFoundException;
|
||||||
import org.mercury_im.messenger.core.exception.ContactAlreadyAddedException;
|
import org.mercury_im.messenger.core.exception.ContactAlreadyAddedException;
|
||||||
import org.mercury_im.messenger.core.xmpp.MercuryConnection;
|
|
||||||
import org.mercury_im.messenger.core.xmpp.MercuryConnectionManager;
|
|
||||||
import org.mercury_im.messenger.entity.contact.Peer;
|
import org.mercury_im.messenger.entity.contact.Peer;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
|
@ -5,8 +5,6 @@ import javax.inject.Named;
|
||||||
|
|
||||||
import io.reactivex.CompletableTransformer;
|
import io.reactivex.CompletableTransformer;
|
||||||
import io.reactivex.MaybeTransformer;
|
import io.reactivex.MaybeTransformer;
|
||||||
import io.reactivex.Observable;
|
|
||||||
import io.reactivex.ObservableSource;
|
|
||||||
import io.reactivex.ObservableTransformer;
|
import io.reactivex.ObservableTransformer;
|
||||||
import io.reactivex.Scheduler;
|
import io.reactivex.Scheduler;
|
||||||
import io.reactivex.SingleTransformer;
|
import io.reactivex.SingleTransformer;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package org.mercury_im.messenger.core.xmpp;
|
package org.mercury_im.messenger.core.connection;
|
||||||
|
|
||||||
import org.jivesoftware.smack.SmackException;
|
import org.jivesoftware.smack.SmackException;
|
||||||
import org.jivesoftware.smackx.csi.ClientStateIndicationManager;
|
import org.jivesoftware.smackx.csi.ClientStateIndicationManager;
|
|
@ -1,4 +1,4 @@
|
||||||
package org.mercury_im.messenger.core.xmpp;
|
package org.mercury_im.messenger.core.connection;
|
||||||
|
|
||||||
import org.jivesoftware.smack.AbstractXMPPConnection;
|
import org.jivesoftware.smack.AbstractXMPPConnection;
|
||||||
import org.jivesoftware.smack.ConnectionListener;
|
import org.jivesoftware.smack.ConnectionListener;
|
||||||
|
@ -8,15 +8,15 @@ import org.jivesoftware.smack.SmackException;
|
||||||
import org.jivesoftware.smack.XMPPConnection;
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
import org.jivesoftware.smack.XMPPException;
|
import org.jivesoftware.smack.XMPPException;
|
||||||
import org.jivesoftware.smack.sasl.SASLErrorException;
|
import org.jivesoftware.smack.sasl.SASLErrorException;
|
||||||
import org.mercury_im.messenger.core.xmpp.exception.InvalidCredentialsException;
|
import org.mercury_im.messenger.core.connection.exception.InvalidCredentialsException;
|
||||||
import org.mercury_im.messenger.core.xmpp.exception.ServerUnreachableException;
|
import org.mercury_im.messenger.core.connection.exception.ServerUnreachableException;
|
||||||
import org.mercury_im.messenger.core.xmpp.state.ConnectivityState;
|
import org.mercury_im.messenger.core.connection.state.ConnectionState;
|
||||||
|
import org.mercury_im.messenger.core.connection.state.ConnectivityState;
|
||||||
import org.mercury_im.messenger.entity.Account;
|
import org.mercury_im.messenger.entity.Account;
|
||||||
import org.mercury_im.messenger.core.xmpp.state.ConnectionState;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
@ -28,7 +28,6 @@ import lombok.Getter;
|
||||||
public class MercuryConnection {
|
public class MercuryConnection {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(MercuryConnection.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(MercuryConnection.class.getName());
|
||||||
private AtomicBoolean connecting = new AtomicBoolean(false);
|
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private XMPPConnection connection;
|
private XMPPConnection connection;
|
||||||
|
@ -36,15 +35,21 @@ public class MercuryConnection {
|
||||||
@Getter
|
@Getter
|
||||||
private final Account account;
|
private final Account account;
|
||||||
|
|
||||||
private final BehaviorSubject<ConnectionState> stateObservable;
|
private final MercuryConnectionListener connectionListener;
|
||||||
|
|
||||||
|
|
||||||
public MercuryConnection(XMPPConnection connection, Account account) {
|
public MercuryConnection(XMPPConnection connection, Account account) {
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
this.account = account;
|
this.account = account;
|
||||||
|
|
||||||
this.stateObservable = BehaviorSubject.createDefault(new ConnectionState(account.getId(), this,
|
if (connection.isConnected()) {
|
||||||
ConnectivityState.disconnected, false, false));
|
throw new IllegalStateException("Connection" + account.getJid() + " MUST NOT be connected at this point.");
|
||||||
|
}
|
||||||
|
|
||||||
|
connectionListener = new MercuryConnectionListener(account.getId(), this);
|
||||||
connection.addConnectionListener(connectionListener);
|
connection.addConnectionListener(connectionListener);
|
||||||
|
|
||||||
|
initialConnectionSetup();
|
||||||
}
|
}
|
||||||
|
|
||||||
public UUID getAccountId() {
|
public UUID getAccountId() {
|
||||||
|
@ -52,34 +57,31 @@ public class MercuryConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Observable<ConnectionState> observeConnection() {
|
public Observable<ConnectionState> observeConnection() {
|
||||||
return stateObservable;
|
return connectionListener.connectionState;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Completable connect() {
|
public Completable connect() {
|
||||||
return Completable.fromAction(this::doConnect)
|
return Completable.fromAction(this::doConnect)
|
||||||
.doOnError(error -> LOGGER.log(Level.WARNING, "Connection error for account " + account, error));
|
.doOnError(error -> LOGGER.log(Level.WARNING, "connect(): Connection error for account " + account, error));
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void doConnect() throws ServerUnreachableException {
|
private synchronized void doConnect() throws ServerUnreachableException {
|
||||||
if (connecting.compareAndSet(false, true)) {
|
ConnectivityState connectivity = connectionListener.connectivity.get();
|
||||||
AbstractXMPPConnection connection = (AbstractXMPPConnection) getConnection();
|
if (connectivity != ConnectivityState.disconnected) {
|
||||||
if (connection.isConnected()) {
|
LOGGER.log(Level.WARNING, "doConnect(): Connection " + account.getJid() + " is not disconnected: " + connectivity);
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
try {
|
|
||||||
connection.connect();
|
|
||||||
connecting.set(false);
|
|
||||||
} catch (SmackException.EndpointConnectionException e) {
|
|
||||||
connection.disconnect();
|
|
||||||
throw new ServerUnreachableException("Cannot connect to server " + connection.getXMPPServiceDomain().asUnescapedString(), e);
|
|
||||||
} catch (IOException | InterruptedException | XMPPException | SmackException e) {
|
|
||||||
throw new AssertionError("Unexpected exception.", e);
|
|
||||||
}
|
|
||||||
stateObservable.onNext(stateObservable.getValue().withConnectivity(ConnectivityState.connecting));
|
|
||||||
LOGGER.log(Level.INFO, "Connected!");
|
|
||||||
} else {
|
|
||||||
LOGGER.log(Level.INFO, "Already connecting.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AbstractXMPPConnection connection = (AbstractXMPPConnection) getConnection();
|
||||||
|
try {
|
||||||
|
connection.connect();
|
||||||
|
} catch (SmackException.EndpointConnectionException e) {
|
||||||
|
connection.disconnect();
|
||||||
|
throw new ServerUnreachableException("doConnect(): Cannot connect to server " + connection.getXMPPServiceDomain().asUnescapedString(), e);
|
||||||
|
} catch (IOException | InterruptedException | XMPPException | SmackException e) {
|
||||||
|
throw new AssertionError("Unexpected exception.", e);
|
||||||
|
}
|
||||||
|
LOGGER.log(Level.INFO, "Connected!");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Completable login() {
|
public Completable login() {
|
||||||
|
@ -88,8 +90,9 @@ public class MercuryConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void doLogin() throws InvalidCredentialsException {
|
private synchronized void doLogin() throws InvalidCredentialsException {
|
||||||
if (connection.isAuthenticated()) {
|
ConnectivityState connectivity = connectionListener.connectivity.get();
|
||||||
return;
|
if (connectivity != ConnectivityState.connected) {
|
||||||
|
LOGGER.log(Level.WARNING, "doLogin(): Connection " + account.getJid() + " is not connected: " + connectivity);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
((AbstractXMPPConnection) getConnection()).login();
|
((AbstractXMPPConnection) getConnection()).login();
|
||||||
|
@ -102,7 +105,7 @@ public class MercuryConnection {
|
||||||
|
|
||||||
public Completable shutdown() {
|
public Completable shutdown() {
|
||||||
return Completable.fromAction(this::doShutdown)
|
return Completable.fromAction(this::doShutdown)
|
||||||
.doOnError(error -> LOGGER.log(Level.WARNING, "Shutdown error for account " + account, error));
|
.doOnError(error -> LOGGER.log(Level.WARNING, "Shutdown error for account " + account.getJid(), error));
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void doShutdown() {
|
public synchronized void doShutdown() {
|
||||||
|
@ -113,43 +116,6 @@ public class MercuryConnection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ConnectionListener connectionListener = new ConnectionListener() {
|
|
||||||
@Override
|
|
||||||
public void connected(XMPPConnection connection) {
|
|
||||||
connecting.set(false);
|
|
||||||
stateObservable.onNext(stateObservable.getValue()
|
|
||||||
.withConnectivity(ConnectivityState.connected)
|
|
||||||
.withAuthenticated(false));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void authenticated(XMPPConnection connection, boolean isResumed) {
|
|
||||||
stateObservable.onNext(stateObservable.getValue()
|
|
||||||
.withConnectivity(ConnectivityState.connected)
|
|
||||||
.withAuthenticated(true)
|
|
||||||
.withResumed(isResumed));
|
|
||||||
if (!isResumed) {
|
|
||||||
initialConnectionSetup();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void connectionClosed() {
|
|
||||||
connecting.set(false);
|
|
||||||
stateObservable.onNext(stateObservable.getValue()
|
|
||||||
.withConnectivity(ConnectivityState.disconnected)
|
|
||||||
.withAuthenticated(false));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void connectionClosedOnError(Exception e) {
|
|
||||||
connecting.set(false);
|
|
||||||
stateObservable.onNext(stateObservable.getValue()
|
|
||||||
.withConnectivity(ConnectivityState.disconnected)
|
|
||||||
.withAuthenticated(false));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private void initialConnectionSetup() {
|
private void initialConnectionSetup() {
|
||||||
ReconnectionManager.getInstanceFor((AbstractXMPPConnection) getConnection())
|
ReconnectionManager.getInstanceFor((AbstractXMPPConnection) getConnection())
|
||||||
.addReconnectionListener(new ReconnectionListener() {
|
.addReconnectionListener(new ReconnectionListener() {
|
||||||
|
@ -164,4 +130,55 @@ public class MercuryConnection {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class MercuryConnectionListener implements ConnectionListener {
|
||||||
|
|
||||||
|
private final AtomicReference<ConnectivityState> connectivity;
|
||||||
|
private final BehaviorSubject<ConnectionState> connectionState;
|
||||||
|
|
||||||
|
public MercuryConnectionListener(UUID accountId, MercuryConnection connection) {
|
||||||
|
this.connectionState = BehaviorSubject.createDefault(new ConnectionState(accountId, connection));
|
||||||
|
this.connectivity = new AtomicReference<>(ConnectivityState.disconnected);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connecting(XMPPConnection connection) {
|
||||||
|
changeConnectivity(ConnectivityState.connecting);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connected(XMPPConnection connection) {
|
||||||
|
changeConnectivity(ConnectivityState.connected);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void authenticated(XMPPConnection connection, boolean resumed) {
|
||||||
|
connectivity.set(ConnectivityState.authenticated);
|
||||||
|
|
||||||
|
ConnectionState state = connectionState.getValue()
|
||||||
|
.withConnectivity(ConnectivityState.authenticated)
|
||||||
|
.withResumed(resumed);
|
||||||
|
connectionState.onNext(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connectionClosed() {
|
||||||
|
changeConnectivity(ConnectivityState.disconnected);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connectionClosedOnError(Exception e) {
|
||||||
|
changeConnectivity(ConnectivityState.disconnectedOnError);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void changeConnectivity(ConnectivityState newConnectivity) {
|
||||||
|
connectivity.set(newConnectivity);
|
||||||
|
|
||||||
|
ConnectionState state = connectionState.getValue()
|
||||||
|
.withConnectivity(newConnectivity);
|
||||||
|
connectionState.onNext(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,22 +1,19 @@
|
||||||
package org.mercury_im.messenger.core.xmpp;
|
package org.mercury_im.messenger.core.connection;
|
||||||
|
|
||||||
import org.jivesoftware.smack.chat2.ChatManager;
|
import org.jivesoftware.smack.chat2.ChatManager;
|
||||||
import org.jivesoftware.smackx.caps.EntityCapsManager;
|
import org.jivesoftware.smackx.caps.EntityCapsManager;
|
||||||
import org.mercury_im.messenger.core.SchedulersFacade;
|
import org.mercury_im.messenger.core.SchedulersFacade;
|
||||||
|
import org.mercury_im.messenger.core.connection.state.ConnectionPoolState;
|
||||||
|
import org.mercury_im.messenger.core.connection.state.ConnectionState;
|
||||||
import org.mercury_im.messenger.core.crypto.MercuryOpenPgpManager;
|
import org.mercury_im.messenger.core.crypto.MercuryOpenPgpManager;
|
||||||
import org.mercury_im.messenger.core.data.repository.AccountRepository;
|
import org.mercury_im.messenger.core.data.repository.AccountRepository;
|
||||||
import org.mercury_im.messenger.core.data.repository.DirectChatRepository;
|
|
||||||
import org.mercury_im.messenger.core.data.repository.MessageRepository;
|
|
||||||
import org.mercury_im.messenger.core.data.repository.PeerRepository;
|
|
||||||
import org.mercury_im.messenger.core.data.repository.Repositories;
|
import org.mercury_im.messenger.core.data.repository.Repositories;
|
||||||
import org.mercury_im.messenger.core.store.message.MercuryMessageStoreFactory;
|
|
||||||
import org.mercury_im.messenger.core.xmpp.state.ConnectionPoolState;
|
|
||||||
import org.mercury_im.messenger.entity.Account;
|
|
||||||
import org.mercury_im.messenger.core.store.caps.MercuryEntityCapsStore;
|
import org.mercury_im.messenger.core.store.caps.MercuryEntityCapsStore;
|
||||||
import org.mercury_im.messenger.core.store.message.MercuryMessageStore;
|
import org.mercury_im.messenger.core.store.message.MercuryMessageStore;
|
||||||
|
import org.mercury_im.messenger.core.store.message.MercuryMessageStoreFactory;
|
||||||
import org.mercury_im.messenger.core.usecase.RosterStoreBinder;
|
import org.mercury_im.messenger.core.usecase.RosterStoreBinder;
|
||||||
import org.mercury_im.messenger.core.util.Optional;
|
import org.mercury_im.messenger.core.util.Optional;
|
||||||
import org.mercury_im.messenger.core.xmpp.state.ConnectionState;
|
import org.mercury_im.messenger.entity.Account;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -33,6 +30,7 @@ import io.reactivex.Completable;
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
import io.reactivex.disposables.CompositeDisposable;
|
import io.reactivex.disposables.CompositeDisposable;
|
||||||
import io.reactivex.disposables.Disposable;
|
import io.reactivex.disposables.Disposable;
|
||||||
|
import io.reactivex.functions.BiPredicate;
|
||||||
import io.reactivex.schedulers.Schedulers;
|
import io.reactivex.schedulers.Schedulers;
|
||||||
import io.reactivex.subjects.BehaviorSubject;
|
import io.reactivex.subjects.BehaviorSubject;
|
||||||
|
|
||||||
|
@ -45,10 +43,6 @@ public class MercuryConnectionManager {
|
||||||
private final MercuryMessageStoreFactory messageStoreFactory;
|
private final MercuryMessageStoreFactory messageStoreFactory;
|
||||||
private final AccountRepository accountRepository;
|
private final AccountRepository accountRepository;
|
||||||
private final RosterStoreBinder rosterStoreBinder;
|
private final RosterStoreBinder rosterStoreBinder;
|
||||||
private final MercuryEntityCapsStore entityCapsStore;
|
|
||||||
private final PeerRepository peerRepository;
|
|
||||||
private final DirectChatRepository directChatRepository;
|
|
||||||
private final MessageRepository messageRepository;
|
|
||||||
private final MercuryOpenPgpManager cryptoManager;
|
private final MercuryOpenPgpManager cryptoManager;
|
||||||
private final SchedulersFacade schedulers;
|
private final SchedulersFacade schedulers;
|
||||||
|
|
||||||
|
@ -73,21 +67,18 @@ public class MercuryConnectionManager {
|
||||||
SchedulersFacade schedulers) {
|
SchedulersFacade schedulers) {
|
||||||
this.accountRepository = repositories.getAccountRepository();
|
this.accountRepository = repositories.getAccountRepository();
|
||||||
this.rosterStoreBinder = rosterStoreBinder;
|
this.rosterStoreBinder = rosterStoreBinder;
|
||||||
this.entityCapsStore = entityCapsStore;
|
|
||||||
this.peerRepository = repositories.getPeerRepository();
|
|
||||||
this.directChatRepository = repositories.getDirectChatRepository();
|
|
||||||
this.messageRepository = repositories.getMessageRepository();
|
|
||||||
this.connectionFactory = connectionFactory;
|
this.connectionFactory = connectionFactory;
|
||||||
this.messageStoreFactory = messageStoreFactory;
|
this.messageStoreFactory = messageStoreFactory;
|
||||||
this.cryptoManager = cryptoManager;
|
this.cryptoManager = cryptoManager;
|
||||||
this.schedulers = schedulers;
|
this.schedulers = schedulers;
|
||||||
|
|
||||||
EntityCapsManager.setPersistentCache(entityCapsStore);
|
EntityCapsManager.setPersistentCache(entityCapsStore);
|
||||||
start();
|
registerNewConnections();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void start() {
|
public synchronized void registerNewConnections() {
|
||||||
disposable.add(accountRepository.observeAllAccounts()
|
disposable.add(accountRepository.observeAllAccounts()
|
||||||
|
.distinctUntilChanged((a,b) -> a.size() != b.size())
|
||||||
.subscribeOn(schedulers.getIoScheduler())
|
.subscribeOn(schedulers.getIoScheduler())
|
||||||
.subscribe(this::doRegisterConnections));
|
.subscribe(this::doRegisterConnections));
|
||||||
}
|
}
|
||||||
|
@ -131,21 +122,27 @@ public class MercuryConnectionManager {
|
||||||
putConnection(connection);
|
putConnection(connection);
|
||||||
disposable.add(accountRepository
|
disposable.add(accountRepository
|
||||||
.observeAccount(connection.getAccountId())
|
.observeAccount(connection.getAccountId())
|
||||||
.subscribeOn(Schedulers.newThread())
|
.subscribeOn(schedulers.getNewThread())
|
||||||
.observeOn(Schedulers.newThread())
|
.observeOn(schedulers.getNewThread())
|
||||||
.subscribe(event ->
|
.distinctUntilChanged(accountNotToggledNorRemoved)
|
||||||
handleOptionalAccountChangedEvent(connection, event)));
|
.subscribe(event -> handleOptionalAccountChangedEvent(connection, event)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private BiPredicate<Optional<Account>, Optional<Account>> accountNotToggledNorRemoved = (first, second) ->
|
||||||
|
// Account not removed
|
||||||
|
first.isPresent() == second.isPresent()
|
||||||
|
// If account is not removed check if not toggled
|
||||||
|
&& (!first.isPresent() || first.getItem().isEnabled() == second.getItem().isEnabled());
|
||||||
|
|
||||||
private synchronized void putConnection(MercuryConnection connection) {
|
private synchronized void putConnection(MercuryConnection connection) {
|
||||||
connectionsMap.put(connection.getAccountId(), connection);
|
connectionsMap.put(connection.getAccountId(), connection);
|
||||||
connectionDisposables.put(connection.getAccountId(), connection.observeConnection()
|
connectionDisposables.put(connection.getAccountId(),
|
||||||
.subscribe(this::insertConnectionToPoolState));
|
connection.observeConnection().subscribe(this::insertConnectionToPoolState));
|
||||||
bindConnection(connection);
|
bindConnection(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void insertConnectionToPoolState(ConnectionState s) {
|
private void insertConnectionToPoolState(ConnectionState s) {
|
||||||
LOGGER.log(Level.INFO, "Insert new connection to pool state: " + s);
|
LOGGER.log(Level.INFO, "Insert new connection to pool state: " + s + " " + s.getConnection().getAccount().getJid());
|
||||||
connectionPoolObservable.onNext(updatePoolState(connectionPoolObservable.getValue(), s));
|
connectionPoolObservable.onNext(updatePoolState(connectionPoolObservable.getValue(), s));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,17 +165,16 @@ public class MercuryConnectionManager {
|
||||||
cryptoManager.initialize(connection);
|
cryptoManager.initialize(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleOptionalAccountChangedEvent(MercuryConnection connection, Optional<Account> event) {
|
private synchronized void handleOptionalAccountChangedEvent(MercuryConnection connection, Optional<Account> event) {
|
||||||
synchronized (connection) {
|
if (event.isPresent()) {
|
||||||
if (event.isPresent()) {
|
handleAccountChangedEvent(connection, event.getItem());
|
||||||
handleAccountChangedEvent(connection, event.getItem());
|
} else {
|
||||||
} else {
|
handleAccountRemoved(connection);
|
||||||
handleAccountRemoved(connection);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void handleAccountChangedEvent(MercuryConnection connection, Account account) {
|
private synchronized void handleAccountChangedEvent(MercuryConnection connection, Account account) {
|
||||||
|
LOGGER.log(Level.INFO, "handleAccountChangedEvent: " + account);
|
||||||
if (account.isEnabled()) {
|
if (account.isEnabled()) {
|
||||||
handleAccountEnabled(connection);
|
handleAccountEnabled(connection);
|
||||||
} else {
|
} else {
|
|
@ -1,7 +1,6 @@
|
||||||
package org.mercury_im.messenger.core.xmpp;
|
package org.mercury_im.messenger.core.connection;
|
||||||
|
|
||||||
import org.jivesoftware.smack.ReconnectionManager;
|
import org.jivesoftware.smack.ReconnectionManager;
|
||||||
import org.jivesoftware.smack.SmackConfiguration;
|
|
||||||
import org.jivesoftware.smack.roster.Roster;
|
import org.jivesoftware.smack.roster.Roster;
|
||||||
import org.jivesoftware.smackx.carbons.CarbonManager;
|
import org.jivesoftware.smackx.carbons.CarbonManager;
|
||||||
import org.jivesoftware.smackx.iqversion.VersionManager;
|
import org.jivesoftware.smackx.iqversion.VersionManager;
|
||||||
|
@ -11,7 +10,7 @@ import org.jivesoftware.smackx.sid.StableUniqueStanzaIdManager;
|
||||||
public class SmackConfig {
|
public class SmackConfig {
|
||||||
|
|
||||||
static void staticConfiguration() {
|
static void staticConfiguration() {
|
||||||
SmackConfiguration.DEBUG = false;
|
//SmackConfiguration.DEBUG = true;
|
||||||
ReconnectionManager.setEnabledPerDefault(true);
|
ReconnectionManager.setEnabledPerDefault(true);
|
||||||
ReconnectionManager.setDefaultReconnectionPolicy(ReconnectionManager.ReconnectionPolicy.RANDOM_INCREASING_DELAY);
|
ReconnectionManager.setDefaultReconnectionPolicy(ReconnectionManager.ReconnectionPolicy.RANDOM_INCREASING_DELAY);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package org.mercury_im.messenger.core.xmpp;
|
package org.mercury_im.messenger.core.connection;
|
||||||
|
|
||||||
import org.jivesoftware.smack.AbstractXMPPConnection;
|
import org.jivesoftware.smack.AbstractXMPPConnection;
|
||||||
import org.mercury_im.messenger.entity.Account;
|
import org.mercury_im.messenger.entity.Account;
|
|
@ -1,4 +1,4 @@
|
||||||
package org.mercury_im.messenger.core.xmpp;
|
package org.mercury_im.messenger.core.connection;
|
||||||
|
|
||||||
import org.jivesoftware.smack.XMPPConnection;
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
import org.jivesoftware.smack.chat2.Chat;
|
import org.jivesoftware.smack.chat2.Chat;
|
||||||
|
@ -15,10 +15,10 @@ import org.mercury_im.messenger.core.data.repository.DirectChatRepository;
|
||||||
import org.mercury_im.messenger.core.data.repository.MessageRepository;
|
import org.mercury_im.messenger.core.data.repository.MessageRepository;
|
||||||
import org.mercury_im.messenger.core.data.repository.PeerRepository;
|
import org.mercury_im.messenger.core.data.repository.PeerRepository;
|
||||||
import org.mercury_im.messenger.core.data.repository.Repositories;
|
import org.mercury_im.messenger.core.data.repository.Repositories;
|
||||||
|
import org.mercury_im.messenger.core.listener.IncomingDirectMessageListener;
|
||||||
import org.mercury_im.messenger.entity.Account;
|
import org.mercury_im.messenger.entity.Account;
|
||||||
import org.mercury_im.messenger.entity.chat.DirectChat;
|
import org.mercury_im.messenger.entity.chat.DirectChat;
|
||||||
import org.mercury_im.messenger.entity.message.Message;
|
import org.mercury_im.messenger.entity.message.Message;
|
||||||
import org.mercury_im.messenger.core.listener.IncomingDirectMessageListener;
|
|
||||||
|
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
|
@ -1,9 +1,8 @@
|
||||||
package org.mercury_im.messenger.core.xmpp;
|
package org.mercury_im.messenger.core.connection;
|
||||||
|
|
||||||
import org.jivesoftware.smack.AbstractXMPPConnection;
|
import org.jivesoftware.smack.AbstractXMPPConnection;
|
||||||
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
|
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
|
||||||
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
|
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
|
||||||
import org.jivesoftware.smack.util.TLSUtils;
|
|
||||||
import org.jxmpp.stringprep.XmppStringprepException;
|
import org.jxmpp.stringprep.XmppStringprepException;
|
||||||
import org.mercury_im.messenger.entity.Account;
|
import org.mercury_im.messenger.entity.Account;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package org.mercury_im.messenger.core.xmpp.exception;
|
package org.mercury_im.messenger.core.connection.exception;
|
||||||
|
|
||||||
public class InvalidCredentialsException extends Exception {
|
public class InvalidCredentialsException extends Exception {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package org.mercury_im.messenger.core.xmpp.exception;
|
package org.mercury_im.messenger.core.connection.exception;
|
||||||
|
|
||||||
public class ServerUnreachableException extends Exception {
|
public class ServerUnreachableException extends Exception {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package org.mercury_im.messenger.core.xmpp.state;
|
package org.mercury_im.messenger.core.connection.state;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
|
@ -1,6 +1,6 @@
|
||||||
package org.mercury_im.messenger.core.xmpp.state;
|
package org.mercury_im.messenger.core.connection.state;
|
||||||
|
|
||||||
import org.mercury_im.messenger.core.xmpp.MercuryConnection;
|
import org.mercury_im.messenger.core.connection.MercuryConnection;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@ -19,15 +19,16 @@ public class ConnectionState {
|
||||||
@With
|
@With
|
||||||
ConnectivityState connectivity;
|
ConnectivityState connectivity;
|
||||||
@With
|
@With
|
||||||
boolean authenticated;
|
|
||||||
@With
|
|
||||||
boolean resumed;
|
boolean resumed;
|
||||||
|
|
||||||
public ConnectionState(UUID id, MercuryConnection connection, ConnectivityState connectivity, boolean authenticated, boolean resumed) {
|
public ConnectionState(UUID id, MercuryConnection connection, ConnectivityState connectivity, boolean resumed) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
this.connectivity = connectivity;
|
this.connectivity = connectivity;
|
||||||
this.authenticated = authenticated;
|
|
||||||
this.resumed = resumed;
|
this.resumed = resumed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ConnectionState(UUID accountId, MercuryConnection connection) {
|
||||||
|
this(accountId, connection, ConnectivityState.disconnected, false);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package org.mercury_im.messenger.core.connection.state;
|
||||||
|
|
||||||
|
public enum ConnectivityState {
|
||||||
|
disconnected,
|
||||||
|
connecting,
|
||||||
|
connected,
|
||||||
|
authenticated,
|
||||||
|
disconnectedOnError
|
||||||
|
}
|
|
@ -12,11 +12,11 @@ import org.jivesoftware.smackx.ox.util.SecretKeyBackupHelper;
|
||||||
import org.jivesoftware.smackx.ox_im.OXInstantMessagingManager;
|
import org.jivesoftware.smackx.ox_im.OXInstantMessagingManager;
|
||||||
import org.jivesoftware.smackx.pubsub.PubSubException;
|
import org.jivesoftware.smackx.pubsub.PubSubException;
|
||||||
import org.mercury_im.messenger.core.SchedulersFacade;
|
import org.mercury_im.messenger.core.SchedulersFacade;
|
||||||
|
import org.mercury_im.messenger.core.connection.MercuryConnection;
|
||||||
import org.mercury_im.messenger.core.data.repository.OpenPgpRepository;
|
import org.mercury_im.messenger.core.data.repository.OpenPgpRepository;
|
||||||
import org.mercury_im.messenger.core.data.repository.Repositories;
|
import org.mercury_im.messenger.core.data.repository.Repositories;
|
||||||
import org.mercury_im.messenger.core.store.crypto.MercuryOpenPgpStore;
|
import org.mercury_im.messenger.core.store.crypto.MercuryOpenPgpStore;
|
||||||
import org.mercury_im.messenger.core.store.message.MercuryMessageStore;
|
import org.mercury_im.messenger.core.store.message.MercuryMessageStore;
|
||||||
import org.mercury_im.messenger.core.xmpp.MercuryConnection;
|
|
||||||
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
@ -56,14 +56,14 @@ public class MercuryOpenPgpManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setup(MercuryConnection connection) {
|
private void setup(MercuryConnection connection) {
|
||||||
|
final String temporaryFixedTestingPassword = "71ZA-Y416-UA7A-7NCE-3SNM-88EF";
|
||||||
OpenPgpStore store = new MercuryOpenPgpStore(connection.getAccountId(), openPgpRepository, schedulers);
|
OpenPgpStore store = new MercuryOpenPgpStore(connection.getAccountId(), openPgpRepository, schedulers);
|
||||||
OpenPgpProvider provider = new PainlessOpenPgpProvider(store);
|
OpenPgpProvider provider = new PainlessOpenPgpProvider(store);
|
||||||
OpenPgpManager oxManager = OpenPgpManager.getInstanceFor(connection.getConnection());
|
OpenPgpManager oxManager = OpenPgpManager.getInstanceFor(connection.getConnection());
|
||||||
oxManager.setOpenPgpProvider(provider);
|
oxManager.setOpenPgpProvider(provider);
|
||||||
SecretKeyBackupHelper.setBackupCodeGenerator(
|
SecretKeyBackupHelper.setBackupCodeGenerator(
|
||||||
// TODO: REMOVE IN PRODUCTION!!!
|
// TODO: REMOVE IN PRODUCTION!!!
|
||||||
() -> "71ZA-Y416-UA7A-7NCE-3SNM-88EF"
|
() -> temporaryFixedTestingPassword);
|
||||||
);
|
|
||||||
try {
|
try {
|
||||||
boolean mustGenerate = false;
|
boolean mustGenerate = false;
|
||||||
if (!oxManager.hasSecretKeysAvailable()) {
|
if (!oxManager.hasSecretKeysAvailable()) {
|
||||||
|
@ -71,9 +71,7 @@ public class MercuryOpenPgpManager {
|
||||||
if (OpenPgpManager.serverSupportsSecretKeyBackups(connection.getConnection())) {
|
if (OpenPgpManager.serverSupportsSecretKeyBackups(connection.getConnection())) {
|
||||||
try {
|
try {
|
||||||
oxManager.restoreSecretKeyServerBackup(
|
oxManager.restoreSecretKeyServerBackup(
|
||||||
//() -> "RW8X-367S-A2C3-QYAL-VG6E-Z2IM");
|
() -> temporaryFixedTestingPassword);
|
||||||
//() -> "KISJ-5Z1T-FGDW-WMDK-SC2U-SQUA");
|
|
||||||
() -> "71ZA-Y416-UA7A-7NCE-3SNM-88EF");
|
|
||||||
mustGenerate = false;
|
mustGenerate = false;
|
||||||
LOGGER.log(Level.INFO, "Successfully restored secret key backup!");
|
LOGGER.log(Level.INFO, "Successfully restored secret key backup!");
|
||||||
} catch (NoBackupFoundException | PubSubException.NotALeafNodeException | InvalidBackupCodeException e) {
|
} catch (NoBackupFoundException | PubSubException.NotALeafNodeException | InvalidBackupCodeException e) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.mercury_im.messenger.core.data.repository;
|
package org.mercury_im.messenger.core.data.repository;
|
||||||
|
|
||||||
import org.mercury_im.messenger.entity.Account;
|
|
||||||
import org.mercury_im.messenger.core.util.Optional;
|
import org.mercury_im.messenger.core.util.Optional;
|
||||||
|
import org.mercury_im.messenger.entity.Account;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package org.mercury_im.messenger.core.data.repository;
|
package org.mercury_im.messenger.core.data.repository;
|
||||||
|
|
||||||
|
import org.mercury_im.messenger.core.util.Optional;
|
||||||
import org.mercury_im.messenger.entity.Account;
|
import org.mercury_im.messenger.entity.Account;
|
||||||
import org.mercury_im.messenger.entity.chat.GroupChat;
|
import org.mercury_im.messenger.entity.chat.GroupChat;
|
||||||
import org.mercury_im.messenger.core.util.Optional;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
|
@ -5,7 +5,6 @@ import org.mercury_im.messenger.entity.chat.GroupChat;
|
||||||
import org.mercury_im.messenger.entity.message.Message;
|
import org.mercury_im.messenger.entity.message.Message;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import io.reactivex.Completable;
|
import io.reactivex.Completable;
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package org.mercury_im.messenger.core.di.component;
|
package org.mercury_im.messenger.core.di.component;
|
||||||
|
|
||||||
|
import org.mercury_im.messenger.core.viewmodel.account.LoginViewModel;
|
||||||
import org.mercury_im.messenger.core.viewmodel.account.detail.AccountDetailsViewModel;
|
import org.mercury_im.messenger.core.viewmodel.account.detail.AccountDetailsViewModel;
|
||||||
import org.mercury_im.messenger.core.viewmodel.account.list.AccountListViewModel;
|
import org.mercury_im.messenger.core.viewmodel.account.list.AccountListViewModel;
|
||||||
import org.mercury_im.messenger.core.viewmodel.account.LoginViewModel;
|
|
||||||
import org.mercury_im.messenger.core.viewmodel.chat.ChatViewModel;
|
import org.mercury_im.messenger.core.viewmodel.chat.ChatViewModel;
|
||||||
import org.mercury_im.messenger.core.viewmodel.openpgp.OxSecretKeyBackupRestoreViewModel;
|
import org.mercury_im.messenger.core.viewmodel.openpgp.OxSecretKeyBackupRestoreViewModel;
|
||||||
|
|
||||||
|
|
|
@ -2,18 +2,17 @@ package org.mercury_im.messenger.core.di.module;
|
||||||
|
|
||||||
import org.mercury_im.messenger.core.Messenger;
|
import org.mercury_im.messenger.core.Messenger;
|
||||||
import org.mercury_im.messenger.core.SchedulersFacade;
|
import org.mercury_im.messenger.core.SchedulersFacade;
|
||||||
|
import org.mercury_im.messenger.core.connection.MercuryConnectionManager;
|
||||||
import org.mercury_im.messenger.core.data.repository.AccountRepository;
|
import org.mercury_im.messenger.core.data.repository.AccountRepository;
|
||||||
import org.mercury_im.messenger.core.data.repository.DirectChatRepository;
|
import org.mercury_im.messenger.core.data.repository.DirectChatRepository;
|
||||||
import org.mercury_im.messenger.core.data.repository.MessageRepository;
|
import org.mercury_im.messenger.core.data.repository.MessageRepository;
|
||||||
import org.mercury_im.messenger.core.data.repository.OpenPgpRepository;
|
import org.mercury_im.messenger.core.data.repository.OpenPgpRepository;
|
||||||
import org.mercury_im.messenger.core.data.repository.PeerRepository;
|
import org.mercury_im.messenger.core.data.repository.PeerRepository;
|
||||||
import org.mercury_im.messenger.core.data.repository.Repositories;
|
import org.mercury_im.messenger.core.viewmodel.account.LoginViewModel;
|
||||||
import org.mercury_im.messenger.core.viewmodel.account.detail.AccountDetailsViewModel;
|
import org.mercury_im.messenger.core.viewmodel.account.detail.AccountDetailsViewModel;
|
||||||
import org.mercury_im.messenger.core.viewmodel.account.list.AccountListViewModel;
|
import org.mercury_im.messenger.core.viewmodel.account.list.AccountListViewModel;
|
||||||
import org.mercury_im.messenger.core.viewmodel.account.LoginViewModel;
|
|
||||||
import org.mercury_im.messenger.core.viewmodel.chat.ChatListViewModel;
|
import org.mercury_im.messenger.core.viewmodel.chat.ChatListViewModel;
|
||||||
import org.mercury_im.messenger.core.viewmodel.chat.ChatViewModel;
|
import org.mercury_im.messenger.core.viewmodel.chat.ChatViewModel;
|
||||||
import org.mercury_im.messenger.core.xmpp.MercuryConnectionManager;
|
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
@ -42,10 +41,11 @@ public class ViewModelModule {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
static AccountDetailsViewModel provideAccountDetailsViewModel(OpenPgpRepository openPgpRepository,
|
static AccountDetailsViewModel provideAccountDetailsViewModel(MercuryConnectionManager connectionManager,
|
||||||
|
OpenPgpRepository openPgpRepository,
|
||||||
AccountRepository accountRepository,
|
AccountRepository accountRepository,
|
||||||
SchedulersFacade schedulers) {
|
SchedulersFacade schedulers) {
|
||||||
return new AccountDetailsViewModel(openPgpRepository, accountRepository, schedulers);
|
return new AccountDetailsViewModel(connectionManager, openPgpRepository, accountRepository, schedulers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
@ -60,8 +60,8 @@ public class ViewModelModule {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
static ChatListViewModel provideChatListViewModel(DirectChatRepository directChatRepository, SchedulersFacade schedulers) {
|
static ChatListViewModel provideChatListViewModel(DirectChatRepository directChatRepository) {
|
||||||
return new ChatListViewModel(directChatRepository, schedulers);
|
return new ChatListViewModel(directChatRepository);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.mercury_im.messenger.core.di.module;
|
package org.mercury_im.messenger.core.di.module;
|
||||||
|
|
||||||
import org.mercury_im.messenger.core.xmpp.XmppConnectionFactory;
|
import org.mercury_im.messenger.core.connection.XmppConnectionFactory;
|
||||||
import org.mercury_im.messenger.core.xmpp.XmppTcpConnectionFactory;
|
import org.mercury_im.messenger.core.connection.XmppTcpConnectionFactory;
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
package org.mercury_im.messenger.core.exception;
|
|
||||||
|
|
||||||
public class IllegalUsernameException extends RuntimeException {
|
|
||||||
|
|
||||||
public IllegalUsernameException(Throwable cause) {
|
|
||||||
super(cause);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
package org.mercury_im.messenger.core.logging;
|
|
||||||
|
|
||||||
public class Tags {
|
|
||||||
|
|
||||||
public static final String TAG_XMPP = "MercuryXMPP";
|
|
||||||
public static final String TAG_DB = "MercuryDB";
|
|
||||||
public static final String TAG_ANDROID = "MercuryAndroid";
|
|
||||||
public static final String TAG_DOMAIN = "MercuryDomain";
|
|
||||||
}
|
|
|
@ -7,7 +7,6 @@ import org.jivesoftware.smackx.disco.packet.DiscoverInfo;
|
||||||
import org.mercury_im.messenger.core.SchedulersFacade;
|
import org.mercury_im.messenger.core.SchedulersFacade;
|
||||||
import org.mercury_im.messenger.core.data.repository.EntityCapsRepository;
|
import org.mercury_im.messenger.core.data.repository.EntityCapsRepository;
|
||||||
import org.mercury_im.messenger.entity.caps.EntityCapsRecord;
|
import org.mercury_im.messenger.entity.caps.EntityCapsRecord;
|
||||||
import org.mercury_im.messenger.core.logging.Tags;
|
|
||||||
|
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
@ -21,7 +20,7 @@ import io.reactivex.disposables.CompositeDisposable;
|
||||||
@Singleton
|
@Singleton
|
||||||
public class MercuryEntityCapsStore implements EntityCapsPersistentCache {
|
public class MercuryEntityCapsStore implements EntityCapsPersistentCache {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(Tags.TAG_DOMAIN);
|
private static final Logger LOGGER = Logger.getLogger(MercuryEntityCapsStore.class.getName());
|
||||||
|
|
||||||
private final CompositeDisposable disposable = new CompositeDisposable();
|
private final CompositeDisposable disposable = new CompositeDisposable();
|
||||||
private final EntityCapsRepository repository;
|
private final EntityCapsRepository repository;
|
||||||
|
|
|
@ -10,9 +10,9 @@ import org.jivesoftware.smack.roster.SubscribeListener;
|
||||||
import org.jxmpp.jid.BareJid;
|
import org.jxmpp.jid.BareJid;
|
||||||
import org.jxmpp.jid.FullJid;
|
import org.jxmpp.jid.FullJid;
|
||||||
import org.jxmpp.jid.Jid;
|
import org.jxmpp.jid.Jid;
|
||||||
|
import org.mercury_im.messenger.core.connection.MercuryConnection;
|
||||||
import org.mercury_im.messenger.core.store.roster.MercuryRosterStore;
|
import org.mercury_im.messenger.core.store.roster.MercuryRosterStore;
|
||||||
import org.mercury_im.messenger.core.store.roster.MercuryRosterStoreFactory;
|
import org.mercury_im.messenger.core.store.roster.MercuryRosterStoreFactory;
|
||||||
import org.mercury_im.messenger.core.xmpp.MercuryConnection;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
|
@ -7,13 +7,13 @@ import org.jxmpp.stringprep.XmppStringprepException;
|
||||||
import org.mercury_im.messenger.core.SchedulersFacade;
|
import org.mercury_im.messenger.core.SchedulersFacade;
|
||||||
import org.mercury_im.messenger.core.account.error.PasswordError;
|
import org.mercury_im.messenger.core.account.error.PasswordError;
|
||||||
import org.mercury_im.messenger.core.account.error.UsernameError;
|
import org.mercury_im.messenger.core.account.error.UsernameError;
|
||||||
|
import org.mercury_im.messenger.core.connection.MercuryConnection;
|
||||||
|
import org.mercury_im.messenger.core.connection.MercuryConnectionManager;
|
||||||
|
import org.mercury_im.messenger.core.connection.exception.InvalidCredentialsException;
|
||||||
|
import org.mercury_im.messenger.core.connection.exception.ServerUnreachableException;
|
||||||
import org.mercury_im.messenger.core.data.repository.AccountRepository;
|
import org.mercury_im.messenger.core.data.repository.AccountRepository;
|
||||||
import org.mercury_im.messenger.core.util.Optional;
|
import org.mercury_im.messenger.core.util.Optional;
|
||||||
import org.mercury_im.messenger.core.viewmodel.MercuryViewModel;
|
import org.mercury_im.messenger.core.viewmodel.MercuryViewModel;
|
||||||
import org.mercury_im.messenger.core.xmpp.MercuryConnection;
|
|
||||||
import org.mercury_im.messenger.core.xmpp.MercuryConnectionManager;
|
|
||||||
import org.mercury_im.messenger.core.xmpp.exception.InvalidCredentialsException;
|
|
||||||
import org.mercury_im.messenger.core.xmpp.exception.ServerUnreachableException;
|
|
||||||
import org.mercury_im.messenger.entity.Account;
|
import org.mercury_im.messenger.entity.Account;
|
||||||
|
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
|
@ -1,8 +1,16 @@
|
||||||
package org.mercury_im.messenger.core.viewmodel.account.detail;
|
package org.mercury_im.messenger.core.viewmodel.account.detail;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
|
import org.jivesoftware.smackx.ox.element.PublicKeysListElement;
|
||||||
import org.jivesoftware.smackx.ox.store.definition.OpenPgpTrustStore;
|
import org.jivesoftware.smackx.ox.store.definition.OpenPgpTrustStore;
|
||||||
|
import org.jivesoftware.smackx.ox.util.OpenPgpPubSubUtil;
|
||||||
|
import org.jivesoftware.smackx.pep.PepManager;
|
||||||
|
import org.jivesoftware.smackx.pubsub.LeafNode;
|
||||||
|
import org.jivesoftware.smackx.pubsub.PayloadItem;
|
||||||
|
import org.jivesoftware.smackx.pubsub.PubSubManager;
|
||||||
import org.jxmpp.jid.EntityBareJid;
|
import org.jxmpp.jid.EntityBareJid;
|
||||||
import org.mercury_im.messenger.core.SchedulersFacade;
|
import org.mercury_im.messenger.core.SchedulersFacade;
|
||||||
|
import org.mercury_im.messenger.core.connection.MercuryConnectionManager;
|
||||||
import org.mercury_im.messenger.core.data.repository.AccountRepository;
|
import org.mercury_im.messenger.core.data.repository.AccountRepository;
|
||||||
import org.mercury_im.messenger.core.data.repository.OpenPgpRepository;
|
import org.mercury_im.messenger.core.data.repository.OpenPgpRepository;
|
||||||
import org.mercury_im.messenger.core.util.Optional;
|
import org.mercury_im.messenger.core.util.Optional;
|
||||||
|
@ -15,16 +23,24 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import io.reactivex.Completable;
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
import io.reactivex.Single;
|
import io.reactivex.Single;
|
||||||
|
|
||||||
|
import static org.jivesoftware.smackx.ox.util.OpenPgpPubSubUtil.PEP_NODE_PUBLIC_KEYS;
|
||||||
|
|
||||||
public class AccountDetailsViewModel implements MercuryViewModel {
|
public class AccountDetailsViewModel implements MercuryViewModel {
|
||||||
|
|
||||||
|
private MercuryConnectionManager connectionManager;
|
||||||
private final OpenPgpRepository openPgpRepository;
|
private final OpenPgpRepository openPgpRepository;
|
||||||
private final AccountRepository accountRepository;
|
private final AccountRepository accountRepository;
|
||||||
private final SchedulersFacade schedulers;
|
private final SchedulersFacade schedulers;
|
||||||
|
|
||||||
public AccountDetailsViewModel(OpenPgpRepository openPgpRepository, AccountRepository accountRepository, SchedulersFacade schedulers) {
|
@Inject
|
||||||
|
public AccountDetailsViewModel(MercuryConnectionManager connectionManager, OpenPgpRepository openPgpRepository, AccountRepository accountRepository, SchedulersFacade schedulers) {
|
||||||
|
this.connectionManager = connectionManager;
|
||||||
this.openPgpRepository = openPgpRepository;
|
this.openPgpRepository = openPgpRepository;
|
||||||
this.accountRepository = accountRepository;
|
this.accountRepository = accountRepository;
|
||||||
this.schedulers = schedulers;
|
this.schedulers = schedulers;
|
||||||
|
@ -64,4 +80,37 @@ public class AccountDetailsViewModel implements MercuryViewModel {
|
||||||
return remoteFingerprints;
|
return remoteFingerprints;
|
||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Completable unpublishPublicKey(UUID accountId, OpenPgpV4Fingerprint fingerprint) {
|
||||||
|
return deletePublicKeyNode(accountId, fingerprint)
|
||||||
|
.andThen(removePublicKeyFromPubKeyList(accountId, fingerprint));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Completable removePublicKeyFromPubKeyList(UUID accountId, OpenPgpV4Fingerprint fingerprint) {
|
||||||
|
return Completable.fromAction(() -> {
|
||||||
|
XMPPConnection xmppConnection = connectionManager.getConnection(accountId).getConnection();
|
||||||
|
PepManager pepManager = PepManager.getInstanceFor(xmppConnection);
|
||||||
|
PubSubManager pubSubManager = pepManager.getPepPubSubManager();
|
||||||
|
PublicKeysListElement publishedKeys = OpenPgpPubSubUtil.fetchPubkeysList(xmppConnection);
|
||||||
|
PublicKeysListElement.Builder builder = PublicKeysListElement.builder();
|
||||||
|
for (PublicKeysListElement.PubkeyMetadataElement meta : publishedKeys.getMetadata().values()) {
|
||||||
|
if (meta.getV4Fingerprint().equals(fingerprint)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
builder.addMetadata(meta);
|
||||||
|
}
|
||||||
|
publishedKeys = builder.build();
|
||||||
|
|
||||||
|
LeafNode metadataNode = pubSubManager.getOrCreateLeafNode(PEP_NODE_PUBLIC_KEYS);
|
||||||
|
metadataNode.publish(new PayloadItem<>(publishedKeys));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private Completable deletePublicKeyNode(UUID accountId, OpenPgpV4Fingerprint fingerprint) {
|
||||||
|
return Completable.fromAction(() -> {
|
||||||
|
XMPPConnection xmppConnection = connectionManager.getConnection(accountId).getConnection();
|
||||||
|
PepManager pepManager = PepManager.getInstanceFor(xmppConnection);
|
||||||
|
OpenPgpPubSubUtil.deletePublicKeyNode(pepManager, fingerprint);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,12 @@ package org.mercury_im.messenger.core.viewmodel.account.list;
|
||||||
|
|
||||||
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
|
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
|
||||||
import org.mercury_im.messenger.core.SchedulersFacade;
|
import org.mercury_im.messenger.core.SchedulersFacade;
|
||||||
|
import org.mercury_im.messenger.core.connection.MercuryConnectionManager;
|
||||||
|
import org.mercury_im.messenger.core.connection.state.ConnectionPoolState;
|
||||||
|
import org.mercury_im.messenger.core.connection.state.ConnectionState;
|
||||||
import org.mercury_im.messenger.core.data.repository.AccountRepository;
|
import org.mercury_im.messenger.core.data.repository.AccountRepository;
|
||||||
import org.mercury_im.messenger.core.data.repository.OpenPgpRepository;
|
import org.mercury_im.messenger.core.data.repository.OpenPgpRepository;
|
||||||
import org.mercury_im.messenger.core.viewmodel.MercuryViewModel;
|
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.mercury_im.messenger.entity.Account;
|
||||||
import org.pgpainless.key.OpenPgpV4Fingerprint;
|
import org.pgpainless.key.OpenPgpV4Fingerprint;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package org.mercury_im.messenger.core.viewmodel.account.list;
|
package org.mercury_im.messenger.core.viewmodel.account.list;
|
||||||
|
|
||||||
import org.mercury_im.messenger.core.xmpp.state.ConnectivityState;
|
import org.mercury_im.messenger.core.connection.state.ConnectivityState;
|
||||||
import org.mercury_im.messenger.entity.Account;
|
import org.mercury_im.messenger.entity.Account;
|
||||||
import org.pgpainless.key.OpenPgpV4Fingerprint;
|
import org.pgpainless.key.OpenPgpV4Fingerprint;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.mercury_im.messenger.core.viewmodel.chat;
|
package org.mercury_im.messenger.core.viewmodel.chat;
|
||||||
|
|
||||||
import org.mercury_im.messenger.core.SchedulersFacade;
|
|
||||||
import org.mercury_im.messenger.core.data.repository.DirectChatRepository;
|
import org.mercury_im.messenger.core.data.repository.DirectChatRepository;
|
||||||
import org.mercury_im.messenger.core.viewmodel.MercuryViewModel;
|
import org.mercury_im.messenger.core.viewmodel.MercuryViewModel;
|
||||||
import org.mercury_im.messenger.entity.chat.DirectChat;
|
import org.mercury_im.messenger.entity.chat.DirectChat;
|
||||||
|
@ -14,15 +13,13 @@ import io.reactivex.subjects.BehaviorSubject;
|
||||||
|
|
||||||
public class ChatListViewModel implements MercuryViewModel {
|
public class ChatListViewModel implements MercuryViewModel {
|
||||||
|
|
||||||
private final SchedulersFacade schedulers;
|
|
||||||
private final DirectChatRepository directChatRepository;
|
private final DirectChatRepository directChatRepository;
|
||||||
|
|
||||||
private final BehaviorSubject<Observable<List<DirectChat>>> chatSourceObservable;
|
private final BehaviorSubject<Observable<List<DirectChat>>> chatSourceObservable;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ChatListViewModel(DirectChatRepository directChatRepository, SchedulersFacade schedulers) {
|
public ChatListViewModel(DirectChatRepository directChatRepository) {
|
||||||
this.directChatRepository = directChatRepository;
|
this.directChatRepository = directChatRepository;
|
||||||
this.schedulers = schedulers;
|
|
||||||
|
|
||||||
chatSourceObservable = BehaviorSubject.createDefault(directChatRepository.observeAllDirectChats());
|
chatSourceObservable = BehaviorSubject.createDefault(directChatRepository.observeAllDirectChats());
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,6 @@ import org.mercury_im.messenger.core.SchedulersFacade;
|
||||||
import org.mercury_im.messenger.core.data.repository.DirectChatRepository;
|
import org.mercury_im.messenger.core.data.repository.DirectChatRepository;
|
||||||
import org.mercury_im.messenger.core.data.repository.MessageRepository;
|
import org.mercury_im.messenger.core.data.repository.MessageRepository;
|
||||||
import org.mercury_im.messenger.core.data.repository.PeerRepository;
|
import org.mercury_im.messenger.core.data.repository.PeerRepository;
|
||||||
import org.mercury_im.messenger.core.data.repository.Repositories;
|
|
||||||
import org.mercury_im.messenger.core.store.message.MercuryMessageStore;
|
|
||||||
import org.mercury_im.messenger.core.util.Optional;
|
import org.mercury_im.messenger.core.util.Optional;
|
||||||
import org.mercury_im.messenger.core.viewmodel.MercuryViewModel;
|
import org.mercury_im.messenger.core.viewmodel.MercuryViewModel;
|
||||||
import org.mercury_im.messenger.entity.chat.DirectChat;
|
import org.mercury_im.messenger.entity.chat.DirectChat;
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
package org.mercury_im.messenger.core.xmpp.state;
|
|
||||||
|
|
||||||
public enum ConnectivityState {
|
|
||||||
disconnected,
|
|
||||||
connecting,
|
|
||||||
connected,
|
|
||||||
disconnecting
|
|
||||||
}
|
|
Loading…
Reference in New Issue