diff --git a/app/src/main/java/org/mercury_im/messenger/ui/account/AccountsFragment.java b/app/src/main/java/org/mercury_im/messenger/ui/account/AccountsFragment.java index 59a4208..84da9b0 100644 --- a/app/src/main/java/org/mercury_im/messenger/ui/account/AccountsFragment.java +++ b/app/src/main/java/org/mercury_im/messenger/ui/account/AccountsFragment.java @@ -58,7 +58,7 @@ public class AccountsFragment extends Fragment { } private void observeViewModel() { - viewModel.getAccounts().observe(this, adapter::setValues); + viewModel.getConnections().observe(this, adapter::setValues); } @Override diff --git a/app/src/main/java/org/mercury_im/messenger/ui/account/AccountsRecyclerViewAdapter.java b/app/src/main/java/org/mercury_im/messenger/ui/account/AccountsRecyclerViewAdapter.java index f022fac..716a169 100644 --- a/app/src/main/java/org/mercury_im/messenger/ui/account/AccountsRecyclerViewAdapter.java +++ b/app/src/main/java/org/mercury_im/messenger/ui/account/AccountsRecyclerViewAdapter.java @@ -17,13 +17,14 @@ import org.mercury_im.messenger.entity.Account; import org.mercury_im.messenger.ui.avatar.AvatarDrawable; import org.mercury_im.messenger.ui.account.AccountsFragment.OnAccountListItemClickListener; import org.mercury_im.messenger.util.AbstractDiffCallback; +import org.mercury_im.messenger.xmpp.MercuryConnection; import java.util.ArrayList; import java.util.List; public class AccountsRecyclerViewAdapter extends RecyclerView.Adapter { - private final List accounts = new ArrayList<>(); + private final List connections = new ArrayList<>(); private final OnAccountListItemClickListener onAccountClickListener; private final AccountsViewModel viewModel; @@ -40,22 +41,23 @@ public class AccountsRecyclerViewAdapter extends RecyclerView.Adapter values) { + public void setValues(List values) { DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff( - new AccountsDiffCallback(values, accounts), true); - accounts.clear(); - accounts.addAll(values); + new AccountsDiffCallback(values, connections), true); + connections.clear(); + connections.addAll(values); diffResult.dispatchUpdatesTo(this); } @Override public int getItemCount() { - return accounts.size(); + return connections.size(); } @Override public void onBindViewHolder(final ViewHolder holder, int position) { - Account account = accounts.get(position); + MercuryConnection connection = connections.get(position); + Account account = connection.getAccount(); holder.account = account; holder.jid.setText(account.getAddress()); @@ -64,6 +66,8 @@ public class AccountsRecyclerViewAdapter extends RecyclerView.Adapter viewModel.setAccountEnabled(account, checked)); + connection.getState().subscribe(state -> holder.status.setText(state.toString())); + setClickListenersOnViewHolder(holder); } @@ -100,21 +104,21 @@ public class AccountsRecyclerViewAdapter extends RecyclerView.Adapter { + public class AccountsDiffCallback extends AbstractDiffCallback { - public AccountsDiffCallback(List newItems, List oldItems) { + public AccountsDiffCallback(List newItems, List oldItems) { super(newItems, oldItems); } @Override public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) { - return oldItems.get(oldItemPosition).getId() == newItems.get(newItemPosition).getId(); + return oldItems.get(oldItemPosition).getAccount().getId() == newItems.get(newItemPosition).getAccount().getId(); } @Override public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) { - Account oldM = oldItems.get(oldItemPosition); - Account newM = newItems.get(newItemPosition); + Account oldM = oldItems.get(oldItemPosition).getAccount(); + Account newM = newItems.get(newItemPosition).getAccount(); return oldM.equals(newM); } } diff --git a/app/src/main/java/org/mercury_im/messenger/ui/account/AccountsViewModel.java b/app/src/main/java/org/mercury_im/messenger/ui/account/AccountsViewModel.java index 090de68..6db3209 100644 --- a/app/src/main/java/org/mercury_im/messenger/ui/account/AccountsViewModel.java +++ b/app/src/main/java/org/mercury_im/messenger/ui/account/AccountsViewModel.java @@ -7,10 +7,14 @@ import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import org.mercury_im.messenger.MercuryImApplication; +import org.mercury_im.messenger.Messenger; import org.mercury_im.messenger.data.repository.AccountRepository; import org.mercury_im.messenger.entity.Account; +import org.mercury_im.messenger.xmpp.MercuryConnection; +import java.util.ArrayList; import java.util.List; +import java.util.Map; import javax.inject.Inject; @@ -21,15 +25,20 @@ public class AccountsViewModel extends AndroidViewModel { @Inject AccountRepository repository; - private final MutableLiveData> accounts = new MutableLiveData<>(); + @Inject + Messenger messenger; + + private final MutableLiveData> connections = new MutableLiveData<>(); private final CompositeDisposable compositeDisposable = new CompositeDisposable(); @Inject public AccountsViewModel(Application application) { super(application); MercuryImApplication.getApplication().getAppComponent().inject(this); - compositeDisposable.add(repository.observeAllAccounts() - .subscribe(accounts::setValue)); + compositeDisposable.add(messenger.getConnectionManager() + .observeConnections() + .map(Map::values) + .subscribe(conns -> connections.postValue(new ArrayList<>(conns)))); } @Override @@ -38,8 +47,8 @@ public class AccountsViewModel extends AndroidViewModel { compositeDisposable.clear(); } - public LiveData> getAccounts() { - return accounts; + public LiveData> getConnections() { + return connections; } public void setAccountEnabled(Account accountModel, boolean enabled) { diff --git a/domain/src/main/java/org/mercury_im/messenger/xmpp/MercuryConnection.java b/domain/src/main/java/org/mercury_im/messenger/xmpp/MercuryConnection.java index 3401845..7b47e6c 100644 --- a/domain/src/main/java/org/mercury_im/messenger/xmpp/MercuryConnection.java +++ b/domain/src/main/java/org/mercury_im/messenger/xmpp/MercuryConnection.java @@ -6,6 +6,7 @@ import org.mercury_im.messenger.data.repository.AccountRepository; import org.mercury_im.messenger.entity.Account; import org.mercury_im.messenger.util.Optional; +import io.reactivex.Observable; import io.reactivex.disposables.CompositeDisposable; import io.reactivex.subjects.BehaviorSubject; @@ -29,6 +30,10 @@ public class MercuryConnection { observeAccountAndConnection(); } + public Observable getState() { + return state; + } + private void observeAccountAndConnection() { observeAccount(); observeConnection(); diff --git a/domain/src/main/java/org/mercury_im/messenger/xmpp/MercuryConnectionManager.java b/domain/src/main/java/org/mercury_im/messenger/xmpp/MercuryConnectionManager.java index 5f59226..0336b00 100644 --- a/domain/src/main/java/org/mercury_im/messenger/xmpp/MercuryConnectionManager.java +++ b/domain/src/main/java/org/mercury_im/messenger/xmpp/MercuryConnectionManager.java @@ -19,12 +19,14 @@ import javax.inject.Inject; import io.reactivex.Observable; import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.subjects.BehaviorSubject; public class MercuryConnectionManager { private static final Logger LOGGER = Logger.getLogger(MercuryConnectionManager.class.getName()); private final Map connections = new ConcurrentHashMap<>(); + private final BehaviorSubject> connectionsSubject = BehaviorSubject.createDefault(connections); private final AccountRepository accountRepository; private final Messenger messenger; @@ -40,6 +42,10 @@ public class MercuryConnectionManager { return new ArrayList<>(connections.values()); } + public Observable> observeConnections() { + return connectionsSubject; + } + public MercuryConnection getConnection(Account account) { return getConnection(account.getId()); } @@ -49,7 +55,7 @@ public class MercuryConnectionManager { } public void registerConnection(MercuryConnection connection) { - messenger.bindConnection(connection); + putConnection(connection); if (connection.getConnection().isAuthenticated()) { registerLiveConnection(connection); } else { @@ -57,6 +63,12 @@ public class MercuryConnectionManager { } } + private void putConnection(MercuryConnection connection) { + connections.put(connection.getAccount().getId(), connection); + connectionsSubject.onNext(connections); + messenger.bindConnection(connection); + } + private void registerLiveConnection(MercuryConnection connection) { Observable> observableAccount = accountRepository .observeAccount(connection.getAccount().getId()); @@ -88,12 +100,7 @@ public class MercuryConnectionManager { } private void handleAccountDisabled(MercuryConnection connection) { - disconnectAndRemoveConnection(connection); - } - - private void disconnectAndRemoveConnection(MercuryConnection connection) { shutdownConnection(connection); - removeConnection(connection); } private void handleAccountEnabled(MercuryConnection connection) { @@ -110,6 +117,11 @@ public class MercuryConnectionManager { disconnectAndRemoveConnection(connection); } + private void disconnectAndRemoveConnection(MercuryConnection connection) { + shutdownConnection(connection); + removeConnection(connection); + } + private void shutdownConnection(MercuryConnection connection) { if (connection.getConnection().isAuthenticated()) { ((AbstractXMPPConnection) connection.getConnection()).instantShutdown(); @@ -118,6 +130,7 @@ public class MercuryConnectionManager { private void removeConnection(MercuryConnection connection) { connections.remove(connection.getAccount().getId()); + connectionsSubject.onNext(connections); connection.dispose(); }