Wip: Work on enabling accounts from accounts fragment

This commit is contained in:
Paul Schaub 2020-05-16 17:13:51 +02:00
parent 44d066117d
commit 10ed534876
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
11 changed files with 54 additions and 60 deletions

View File

@ -64,14 +64,8 @@ public class AccountsFragment extends Fragment {
} }
private void observeViewModel() { private void observeViewModel() {
viewModel.getConnectionPool().observe(this, pool -> { viewModel.getConnectionPool().observe(this, pool ->
Collection<ConnectionState> connectionStateList = pool.getConnectionStates().values(); adapter.setValues(new ArrayList<>(pool.getConnectionStates().values())));
List<MercuryConnection> connections = new ArrayList<>(connectionStateList.size());
for (ConnectionState state : connectionStateList) {
connections.add(state.getConnection());
}
adapter.setValues(connections);
});
} }
@Override @Override

View File

@ -7,7 +7,6 @@ import android.widget.ImageView;
import android.widget.Switch; import android.widget.Switch;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DiffUtil; import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -18,15 +17,14 @@ import org.mercury_im.messenger.ui.avatar.AvatarDrawable;
import org.mercury_im.messenger.ui.account.AccountsFragment.OnAccountListItemClickListener; import org.mercury_im.messenger.ui.account.AccountsFragment.OnAccountListItemClickListener;
import org.mercury_im.messenger.util.AbstractDiffCallback; import org.mercury_im.messenger.util.AbstractDiffCallback;
import org.mercury_im.messenger.xmpp.MercuryConnection; import org.mercury_im.messenger.xmpp.MercuryConnection;
import org.mercury_im.messenger.xmpp.state.ConnectionState;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import io.reactivex.android.schedulers.AndroidSchedulers;
public class AccountsRecyclerViewAdapter extends RecyclerView.Adapter<AccountsRecyclerViewAdapter.ViewHolder> { public class AccountsRecyclerViewAdapter extends RecyclerView.Adapter<AccountsRecyclerViewAdapter.ViewHolder> {
private final List<MercuryConnection> connections = new ArrayList<>(); private final List<ConnectionState> connectionStates = new ArrayList<>();
private final OnAccountListItemClickListener onAccountClickListener; private final OnAccountListItemClickListener onAccountClickListener;
private final AccountsViewModel viewModel; private final AccountsViewModel viewModel;
@ -43,22 +41,23 @@ public class AccountsRecyclerViewAdapter extends RecyclerView.Adapter<AccountsRe
return new ViewHolder(view); return new ViewHolder(view);
} }
public void setValues(List<MercuryConnection> values) { public void setValues(List<ConnectionState> values) {
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff( DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(
new AccountsDiffCallback(values, connections), true); new AccountsDiffCallback(values, connectionStates), true);
connections.clear(); connectionStates.clear();
connections.addAll(values); connectionStates.addAll(values);
diffResult.dispatchUpdatesTo(this); diffResult.dispatchUpdatesTo(this);
} }
@Override @Override
public int getItemCount() { public int getItemCount() {
return connections.size(); return connectionStates.size();
} }
@Override @Override
public void onBindViewHolder(final ViewHolder holder, int position) { public void onBindViewHolder(final ViewHolder holder, int position) {
MercuryConnection connection = connections.get(position); ConnectionState state = connectionStates.get(position);
MercuryConnection connection = state.getConnection();
Account account = connection.getAccount(); Account account = connection.getAccount();
holder.account = account; holder.account = account;
@ -67,23 +66,7 @@ public class AccountsRecyclerViewAdapter extends RecyclerView.Adapter<AccountsRe
holder.enabled.setChecked(account.isEnabled()); holder.enabled.setChecked(account.isEnabled());
holder.enabled.setOnCheckedChangeListener((compoundButton, checked) -> holder.enabled.setOnCheckedChangeListener((compoundButton, checked) ->
viewModel.setAccountEnabled(account, checked)); viewModel.setAccountEnabled(account, checked));
holder.status.setText(state.getConnectivity().toString());
setClickListenersOnViewHolder(holder);
}
private void setClickListenersOnViewHolder(ViewHolder holder) {
holder.mView.setOnClickListener(v -> {
if (null != onAccountClickListener) {
onAccountClickListener.onAccountListItemClick(holder.account);
}
});
holder.mView.setOnLongClickListener(v -> {
if (null != onAccountClickListener) {
onAccountClickListener.onAccountListItemLongClick(holder.account);
}
return true;
});
} }
class ViewHolder extends RecyclerView.ViewHolder { class ViewHolder extends RecyclerView.ViewHolder {
@ -104,21 +87,22 @@ public class AccountsRecyclerViewAdapter extends RecyclerView.Adapter<AccountsRe
} }
} }
public class AccountsDiffCallback extends AbstractDiffCallback<MercuryConnection> { public class AccountsDiffCallback extends AbstractDiffCallback<ConnectionState> {
public AccountsDiffCallback(List<MercuryConnection> newItems, List<MercuryConnection> oldItems) { public AccountsDiffCallback(List<ConnectionState> newItems, List<ConnectionState> oldItems) {
super(newItems, oldItems); super(newItems, oldItems);
} }
@Override @Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) { public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
return oldItems.get(oldItemPosition).getAccount().getId().equals(newItems.get(newItemPosition).getAccount().getId()); return oldItems.get(oldItemPosition).getConnection().getAccount().getId()
.equals(newItems.get(newItemPosition).getConnection().getAccount().getId());
} }
@Override @Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) { public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
Account oldM = oldItems.get(oldItemPosition).getAccount(); ConnectionState oldM = oldItems.get(oldItemPosition);
Account newM = newItems.get(newItemPosition).getAccount(); ConnectionState newM = newItems.get(newItemPosition);
return oldM.equals(newM); return oldM.equals(newM);
} }
} }

View File

@ -10,11 +10,17 @@ import org.mercury_im.messenger.MercuryImApplication;
import org.mercury_im.messenger.Messenger; import org.mercury_im.messenger.Messenger;
import org.mercury_im.messenger.data.repository.AccountRepository; import org.mercury_im.messenger.data.repository.AccountRepository;
import org.mercury_im.messenger.entity.Account; import org.mercury_im.messenger.entity.Account;
import org.mercury_im.messenger.xmpp.MercuryConnection;
import org.mercury_im.messenger.xmpp.exception.InvalidCredentialsException;
import org.mercury_im.messenger.xmpp.exception.ServerUnreachableException;
import org.mercury_im.messenger.xmpp.state.ConnectionPoolState; import org.mercury_im.messenger.xmpp.state.ConnectionPoolState;
import javax.inject.Inject; import javax.inject.Inject;
import io.reactivex.Scheduler;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers;
public class AccountsViewModel extends AndroidViewModel { public class AccountsViewModel extends AndroidViewModel {
@ -54,5 +60,17 @@ public class AccountsViewModel extends AndroidViewModel {
accountModel.setEnabled(enabled); accountModel.setEnabled(enabled);
repository.upsertAccount(accountModel) repository.upsertAccount(accountModel)
.subscribe(); .subscribe();
MercuryConnection connection = messenger.getConnectionManager().getConnection(accountModel);
if (connection != null) {
if (enabled) {
connection.connect()
.andThen(connection.login())
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe();
} else {
connection.shutdown();
}
}
} }
} }

View File

@ -24,6 +24,7 @@ import java.util.logging.Logger;
import javax.inject.Inject; import javax.inject.Inject;
import io.reactivex.Completable; import io.reactivex.Completable;
import io.reactivex.Scheduler;
import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers; import io.reactivex.schedulers.Schedulers;
@ -88,9 +89,8 @@ public class LoginViewModel extends AndroidViewModel {
account.setAddress(username.asUnescapedString()); account.setAddress(username.asUnescapedString());
account.setPassword(password); account.setPassword(password);
MercuryConnection connection = messenger.getConnectionManager().createConnection(account); MercuryConnection connection = messenger.getConnectionManager().createConnection(account);
disposable.add(Completable.fromAction(() -> { disposable.add(connection.connect()
connection.connect().login(); .andThen(connection.login())
})
.subscribeOn(Schedulers.newThread()) .subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.doOnComplete(this::signalLoginSuccessful) .doOnComplete(this::signalLoginSuccessful)

View File

@ -16,6 +16,7 @@ import java.io.IOException;
import java.util.UUID; import java.util.UUID;
import java.util.logging.Logger; import java.util.logging.Logger;
import io.reactivex.Completable;
import io.reactivex.Observable; import io.reactivex.Observable;
import io.reactivex.subjects.BehaviorSubject; import io.reactivex.subjects.BehaviorSubject;
import lombok.Getter; import lombok.Getter;
@ -48,19 +49,17 @@ public class MercuryConnection {
return state; return state;
} }
public MercuryConnection connect() throws ServerUnreachableException { public Completable connect() {
if (getConnection().isConnected()) { if (getConnection().isConnected()) {
return this; return Completable.complete();
} }
doConnect(); return Completable.fromAction(this::doConnect);
return this;
} }
private MercuryConnection doConnect() throws ServerUnreachableException { private void doConnect() throws ServerUnreachableException {
AbstractXMPPConnection connection = (AbstractXMPPConnection) getConnection(); AbstractXMPPConnection connection = (AbstractXMPPConnection) getConnection();
try { try {
connection.connect(); connection.connect();
return this;
} catch (SmackException.EndpointConnectionException e) { } catch (SmackException.EndpointConnectionException e) {
connection.disconnect(); connection.disconnect();
throw new ServerUnreachableException("Cannot connect to server " + connection.getXMPPServiceDomain().asUnescapedString(), e); throw new ServerUnreachableException("Cannot connect to server " + connection.getXMPPServiceDomain().asUnescapedString(), e);
@ -69,16 +68,15 @@ public class MercuryConnection {
} }
} }
public void login() throws ServerUnreachableException, InvalidCredentialsException { public Completable login() {
if (getConnection().isAuthenticated()) { if (getConnection().isAuthenticated()) {
return; return Completable.complete();
} }
doLogin(); return Completable.fromAction(this::doLogin);
} }
private void doLogin() throws InvalidCredentialsException, ServerUnreachableException { private void doLogin() throws InvalidCredentialsException, ServerUnreachableException {
try { try {
connect();
((AbstractXMPPConnection) getConnection()).login(); ((AbstractXMPPConnection) getConnection()).login();
} catch (SASLErrorException e) { } catch (SASLErrorException e) {
throw new InvalidCredentialsException("Credentials of account " + account.getId() + " are invalid.", e); throw new InvalidCredentialsException("Credentials of account " + account.getId() + " are invalid.", e);

View File

@ -1,16 +1,17 @@
package org.mercury_im.messenger.xmpp.state; package org.mercury_im.messenger.xmpp.state;
import org.jivesoftware.smack.XMPPConnection;
import org.mercury_im.messenger.xmpp.MercuryConnection; import org.mercury_im.messenger.xmpp.MercuryConnection;
import java.util.UUID; import java.util.UUID;
import lombok.EqualsAndHashCode;
import lombok.ToString; import lombok.ToString;
import lombok.Value; import lombok.Value;
import lombok.With; import lombok.With;
@Value @Value
@ToString @ToString
@EqualsAndHashCode
public class ConnectionState { public class ConnectionState {
UUID id; UUID id;

View File

@ -5,11 +5,13 @@ import org.mercury_im.messenger.entity.contact.Peer;
import java.util.Set; import java.util.Set;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
/** /**
* An interface that describes a group chat entity. * An interface that describes a group chat entity.
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = true)
public class GroupChat extends Chat { public class GroupChat extends Chat {
Set<Peer> participants; Set<Peer> participants;
String roomAddress; String roomAddress;

View File

@ -4,9 +4,7 @@ import java.util.Date;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.With;
@Data @Data
public class Message { public class Message {

View File

@ -6,7 +6,7 @@
# http://www.gradle.org/docs/current/userguide/build_environment.html # http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process. # Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings. # The setting is particularly useful for tweaking memory settings.
android.enableJetifier=true android.enableJetifier=false
android.useAndroidX=true android.useAndroidX=true
org.gradle.jvmargs=-Xmx1536m org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode. # When configured, Gradle will run in incubating parallel mode.

@ -1 +1 @@
Subproject commit e79710840be6d6b3301e078a23688eafaa06013c Subproject commit f00acbff891ba0edd0a51e7147e0e07d0de7e4b5

View File

@ -1,7 +1,6 @@
ext { ext {
apply from: 'libs/Smack/version.gradle' shortVersion = 1
// Smack Versions // Smack Versions
// Quickly switch between unique and normal releases using the toggle below // Quickly switch between unique and normal releases using the toggle below