More account management refactoring

This commit is contained in:
Paul Schaub 2019-12-21 04:08:59 +01:00
parent ba7d983b95
commit 7e2fe55b56
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
7 changed files with 62 additions and 96 deletions

View file

@ -54,6 +54,10 @@ public class AccountsFragment extends Fragment {
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
observeViewModel();
}
private void observeViewModel() {
viewModel.getAccounts().observe(this, adapter::setValues); viewModel.getAccounts().observe(this, adapter::setValues);
} }

View file

@ -1,6 +1,5 @@
package org.mercury_im.messenger.ui.account; package org.mercury_im.messenger.ui.account;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -11,7 +10,6 @@ import android.widget.TextView;
import androidx.recyclerview.widget.DiffUtil; import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import org.mercury_im.messenger.Messenger;
import org.mercury_im.messenger.R; import org.mercury_im.messenger.R;
import org.mercury_im.messenger.entity.Account; import org.mercury_im.messenger.entity.Account;
import org.mercury_im.messenger.ui.avatar.AvatarDrawable; import org.mercury_im.messenger.ui.avatar.AvatarDrawable;
@ -23,13 +21,12 @@ import java.util.List;
public class AccountsRecyclerViewAdapter extends RecyclerView.Adapter<AccountsRecyclerViewAdapter.ViewHolder> { public class AccountsRecyclerViewAdapter extends RecyclerView.Adapter<AccountsRecyclerViewAdapter.ViewHolder> {
private final List<Account> mValues; private final List<Account> accounts = new ArrayList<>();
private final OnAccountListItemClickListener mListener; private final OnAccountListItemClickListener onAccountClickListener;
private final AccountsViewModel viewModel; private final AccountsViewModel viewModel;
public AccountsRecyclerViewAdapter(AccountsViewModel viewModel, OnAccountListItemClickListener listener) { public AccountsRecyclerViewAdapter(AccountsViewModel viewModel, OnAccountListItemClickListener listener) {
mValues = new ArrayList<>(); onAccountClickListener = listener;
mListener = listener;
this.viewModel = viewModel; this.viewModel = viewModel;
} }
@ -40,43 +37,40 @@ public class AccountsRecyclerViewAdapter extends RecyclerView.Adapter<AccountsRe
return new ViewHolder(view); return new ViewHolder(view);
} }
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
Account account = mValues.get(position);
holder.jid.setText(account.getAddress());
holder.avatar.setImageDrawable(new AvatarDrawable(account.getAddress(), account.getAddress()));
holder.enabled.setChecked(account.isEnabled());
holder.account = account;
holder.enabled.setOnCheckedChangeListener((compoundButton, b) -> {
viewModel.toggleAccountEnabled(account);
});
holder.mView.setOnClickListener(v -> {
if (null != mListener) {
// Notify the active callbacks interface (the activity, if the
// fragment is attached to one) that an item has been selected.
mListener.onAccountListItemClick(holder.account);
}
});
holder.mView.setOnLongClickListener(v -> {
if (null != mListener) {
mListener.onAccountListItemLongClick(holder.account);
}
return true;
});
}
public void setValues(List<Account> values) { public void setValues(List<Account> values) {
Log.d("AAAAA", "New values: " + values.size()); DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new AccountsDiffCallback(values, accounts), true);
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new AccountsDiffCallback(values, mValues), true); accounts.clear();
mValues.clear(); accounts.addAll(values);
mValues.addAll(values);
diffResult.dispatchUpdatesTo(this); diffResult.dispatchUpdatesTo(this);
} }
@Override @Override
public int getItemCount() { public int getItemCount() {
Log.d(Messenger.TAG, "Accounts Item Count: " + mValues.size()); return accounts.size();
return mValues.size(); }
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
Account account = accounts.get(position);
holder.account = account;
holder.jid.setText(account.getAddress());
holder.avatar.setImageDrawable(new AvatarDrawable(account.getAddress(), account.getAddress()));
holder.enabled.setChecked(account.isEnabled());
holder.enabled.setOnCheckedChangeListener((compoundButton, checked) -> viewModel.setAccountEnabled(account, checked));
holder.mView.setOnClickListener(v -> {
if (null != onAccountClickListener) {
onAccountClickListener.onAccountListItemClick(holder.account);
}
});
holder.mView.setOnLongClickListener(v -> {
if (null != onAccountClickListener) {
onAccountClickListener.onAccountListItemLongClick(holder.account);
}
return true;
});
} }
public class ViewHolder extends RecyclerView.ViewHolder { public class ViewHolder extends RecyclerView.ViewHolder {

View file

@ -42,16 +42,8 @@ public class AccountsViewModel extends AndroidViewModel {
return accounts; return accounts;
} }
public void toggleAccountEnabled(Account accountModel) { public void setAccountEnabled(Account accountModel, boolean enabled) {
/* accountModel.setEnabled(enabled);
MercuryConnection connection = connectionCenter.getConnection(accountModel);
if (connection == null) {
Toast.makeText(this.getApplication(), "MercuryConnection is null!", Toast.LENGTH_LONG).show();
return;
}
*/
accountModel.setEnabled(!accountModel.isEnabled());
repository.upsertAccount(accountModel) repository.upsertAccount(accountModel)
.subscribe(); .subscribe();
} }

View file

@ -1,21 +0,0 @@
package org.mercury_im.messenger.ui.account;
import android.content.Context;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
public class AddAccountDialog extends AlertDialog {
protected AddAccountDialog(@NonNull Context context, int themeResId) {
super(context, themeResId);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}

View file

@ -118,22 +118,6 @@ public class LoginActivity extends AppCompatActivity implements TextView.OnEdito
} }
} }
private void displayCredentials(LiveData<Account> account) {
account.observe(this, accountEvent -> {
if (accountEvent == null) {
return;
}
if (accountEvent.getAddress() != null) {
addressView.setText(accountEvent.getAddress());
}
if (accountEvent.getPassword() != null) {
passwordView.setText(accountEvent.getPassword());
}
});
}
private void setupTextInputListeners() { private void setupTextInputListeners() {
addressView.setOnEditorActionListener(this); addressView.setOnEditorActionListener(this);
passwordView.setOnEditorActionListener(this); passwordView.setOnEditorActionListener(this);

View file

@ -19,14 +19,17 @@ import org.mercury_im.messenger.R;
import javax.inject.Inject; import javax.inject.Inject;
import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers; import io.reactivex.schedulers.Schedulers;
public class LoginViewModel extends AndroidViewModel { public class LoginViewModel extends AndroidViewModel {
private MutableLiveData<Error> usernameError = new MutableLiveData<>(new Error()); private MutableLiveData<Error> usernameError = new MutableLiveData<>(new Error());
private MutableLiveData<Error> passwordError = new MutableLiveData<>(new Error()); private MutableLiveData<Error> passwordError = new MutableLiveData<>(new Error());
private MutableLiveData<Boolean> loginEnabled = new MutableLiveData<>(false); private MutableLiveData<Boolean> loginButtonEnabled = new MutableLiveData<>(false);
private MutableLiveData<Boolean> loginSuccessful = new MutableLiveData<>(false); private MutableLiveData<Boolean> loginCompleted = new MutableLiveData<>(false);
private final CompositeDisposable disposable = new CompositeDisposable();
private EntityBareJid username; private EntityBareJid username;
private String password; private String password;
@ -66,36 +69,42 @@ public class LoginViewModel extends AndroidViewModel {
} }
private void updateLoginEnabled() { private void updateLoginEnabled() {
loginEnabled.setValue(username != null && !(password == null || password.isEmpty())); loginButtonEnabled.setValue(username != null && !(password == null || password.isEmpty()));
} }
public synchronized void login() { public synchronized void login() {
if (!loginEnabled.getValue()) { if (!loginButtonEnabled.getValue()) {
// Prevent race condition where account would be logged in twice // Prevent race condition where account would be logged in twice
return; return;
} }
loginEnabled.setValue(false); loginButtonEnabled.setValue(false);
messenger.addAccount() disposable.add(messenger.addAccount()
.setAddress(username.asEntityBareJidString()) .setAddress(username.asEntityBareJidString())
.setPassword(password) .setPassword(password)
.loginAndStoreAccountIfSuccessful() .loginAndStoreAccountIfSuccessful()
.subscribeOn(Schedulers.newThread()) .subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.doOnComplete(() -> loginSuccessful.setValue(true)) .doOnComplete(() -> loginCompleted.setValue(true))
.doOnError(this::handleConnectionError) .doOnError(this::handleConnectionError)
.subscribe(); .subscribe());
} }
private void handleConnectionError(Throwable error) { private void handleConnectionError(Throwable error) {
if (error instanceof SASLErrorException) { if (error instanceof SASLErrorException) {
passwordError.setValue(new Error(getApplication().getResources().getString(R.string.error_incorrect_password))); passwordError.setValue(new Error(getApplication().getResources().getString(R.string.error_incorrect_password)));
loginEnabled.setValue(true); loginButtonEnabled.setValue(true);
} else { } else {
Toast.makeText(getApplication(), "A connection error occurred", Toast.LENGTH_LONG).show(); Toast.makeText(getApplication(), "A connection error occurred", Toast.LENGTH_LONG).show();
loginEnabled.setValue(true); loginButtonEnabled.setValue(true);
} }
} }
@Override
protected void onCleared() {
super.onCleared();
disposable.clear();
}
public LiveData<Error> getPasswordError() { public LiveData<Error> getPasswordError() {
return passwordError; return passwordError;
} }
@ -105,11 +114,11 @@ public class LoginViewModel extends AndroidViewModel {
} }
public LiveData<Boolean> isLoginSuccessful() { public LiveData<Boolean> isLoginSuccessful() {
return loginSuccessful; return loginCompleted;
} }
public LiveData<Boolean> isLoginEnabled() { public LiveData<Boolean> isLoginEnabled() {
return loginEnabled; return loginButtonEnabled;
} }
public static class Error { public static class Error {

View file

@ -30,4 +30,8 @@ public interface Account {
void setEnabled(boolean enabled); void setEnabled(boolean enabled);
boolean isEnabled(); boolean isEnabled();
default String displayName() {
return getAddress();
}
} }