mirror of
https://codeberg.org/Mercury-IM/Mercury-IM
synced 2025-02-07 20:06:24 +01:00
Fix progressbar and ikey generation dialog
This commit is contained in:
parent
c322f321cf
commit
748c77c092
12 changed files with 67 additions and 151 deletions
|
@ -7,7 +7,7 @@ import androidx.appcompat.app.AppCompatActivity;
|
|||
import androidx.appcompat.widget.Toolbar;
|
||||
|
||||
import org.mercury_im.messenger.R;
|
||||
import org.mercury_im.messenger.android.crypto.ikey.IkeyBackupCreationFragment;
|
||||
import org.mercury_im.messenger.android.ui.account.login.IkeyBackupCreationFragment;
|
||||
import org.mercury_im.messenger.android.ui.account.login.IkeyBackupRestoreOrSkipFragment;
|
||||
import org.mercury_im.messenger.android.ui.account.login.IkeyKeyInfoFragment;
|
||||
import org.mercury_im.messenger.android.ui.account.login.IkeySetupNavigator;
|
||||
|
|
|
@ -23,7 +23,7 @@ import com.google.android.material.card.MaterialCardView;
|
|||
|
||||
import org.mercury_im.messenger.R;
|
||||
import org.mercury_im.messenger.android.MercuryImApplication;
|
||||
import org.mercury_im.messenger.android.crypto.ikey.IkeyBackupCreationFragment;
|
||||
import org.mercury_im.messenger.android.ui.account.login.IkeyBackupCreationFragment;
|
||||
import org.mercury_im.messenger.android.ui.account.login.IkeySetupFragment;
|
||||
import org.mercury_im.messenger.android.ui.openpgp.ToggleableFingerprintsAdapter;
|
||||
import org.mercury_im.messenger.android.ui.openpgp.OpenPgpV4FingerprintFormatter;
|
||||
|
|
|
@ -18,7 +18,6 @@ import com.google.android.material.floatingactionbutton.ExtendedFloatingActionBu
|
|||
import org.mercury_im.messenger.R;
|
||||
import org.mercury_im.messenger.android.ui.account.OnAccountListItemClickListener;
|
||||
import org.mercury_im.messenger.android.ui.account.login.AddAccountActivity;
|
||||
import org.mercury_im.messenger.android.ui.account.login.AddAccountDialogFragment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
@ -102,11 +101,6 @@ public class AccountListFragment extends Fragment implements SearchView.OnQueryT
|
|||
accountClickListener = null;
|
||||
}
|
||||
|
||||
private void displayAddAccountDialog() {
|
||||
AddAccountDialogFragment addAccountDialogFragment = new AddAccountDialogFragment();
|
||||
addAccountDialogFragment.show(getParentFragmentManager(), "addAccount");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
return false;
|
||||
|
|
|
@ -13,7 +13,6 @@ import androidx.viewpager2.widget.ViewPager2;
|
|||
|
||||
import org.mercury_im.messenger.R;
|
||||
import org.mercury_im.messenger.android.MercuryImApplication;
|
||||
import org.mercury_im.messenger.android.crypto.ikey.IkeyBackupCreationFragment;
|
||||
import org.mercury_im.messenger.android.di.component.AppComponent;
|
||||
import org.mercury_im.messenger.core.util.Optional;
|
||||
import org.mercury_im.messenger.entity.Account;
|
||||
|
|
|
@ -1,126 +0,0 @@
|
|||
package org.mercury_im.messenger.android.ui.account.login;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatDialogFragment;
|
||||
|
||||
import com.google.android.material.textfield.TextInputEditText;
|
||||
import com.google.android.material.textfield.TextInputLayout;
|
||||
|
||||
import org.mercury_im.messenger.android.MercuryImApplication;
|
||||
import org.mercury_im.messenger.R;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
public class AddAccountDialogFragment extends AppCompatDialogFragment {
|
||||
|
||||
@BindView(R.id.username)
|
||||
TextInputEditText addressView;
|
||||
|
||||
@BindView(R.id.username_layout)
|
||||
TextInputLayout addressLayout;
|
||||
|
||||
@BindView(R.id.password)
|
||||
TextInputEditText passwordView;
|
||||
|
||||
@BindView(R.id.password_layout)
|
||||
TextInputLayout passwordLayout;
|
||||
|
||||
private AndroidLoginViewModel viewModel;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
|
||||
LayoutInflater inflater = requireActivity().getLayoutInflater();
|
||||
View dialogView = inflater.inflate(R.layout.view_account_credentials, null);
|
||||
ButterKnife.bind(this, dialogView);
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
|
||||
builder.setTitle(R.string.action_add_account)
|
||||
.setView(dialogView)
|
||||
.setCancelable(false)
|
||||
.setPositiveButton(R.string.action_sign_in, null)
|
||||
.setNegativeButton(R.string.button_cancel, cancelButtonClickListener);
|
||||
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
private final DialogInterface.OnClickListener cancelButtonClickListener =
|
||||
(dialog, which) -> AddAccountDialogFragment.this.onCancel(dialog);
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
final AlertDialog d = (AlertDialog)getDialog();
|
||||
if(d == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
viewModel = new AndroidLoginViewModel(MercuryImApplication.getApplication());
|
||||
|
||||
Button positiveButton = d.getButton(Dialog.BUTTON_POSITIVE);
|
||||
positiveButton.setOnClickListener(v -> viewModel.onLoginButtonClicked());
|
||||
|
||||
viewModel.getLoginUsernameError().observe(this, error -> addressLayout.setError(error));
|
||||
viewModel.getLoginPasswordError().observe(this, error -> passwordLayout.setError(error));
|
||||
viewModel.isLoginButtonEnabled().observe(this, positiveButton::setEnabled);
|
||||
|
||||
viewModel.isLoginFinished().observe(this, optAccount -> {
|
||||
if (optAccount.isPresent()) {
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
addressView.addTextChangedListener(viewModel.getUsernameTextChangedListener());
|
||||
passwordView.addTextChangedListener(viewModel.getPasswordTextChangedListener());
|
||||
|
||||
addressView.setOnEditorActionListener(focusPasswordFieldOnEnterPressed);
|
||||
passwordView.setOnEditorActionListener(loginOnEnterPressed);
|
||||
}
|
||||
|
||||
private final TextView.OnEditorActionListener focusPasswordFieldOnEnterPressed = new TextView.OnEditorActionListener() {
|
||||
@Override
|
||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||
if (actionId == EditorInfo.IME_ACTION_NEXT) {
|
||||
passwordView.requestFocus();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
private final TextView.OnEditorActionListener loginOnEnterPressed = new TextView.OnEditorActionListener() {
|
||||
@Override
|
||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||
if (actionId == EditorInfo.IME_ACTION_DONE || actionId == EditorInfo.IME_NULL) {
|
||||
viewModel.getCommonViewModel().login();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
}
|
|
@ -26,6 +26,7 @@ public class AndroidLoginViewModel extends AndroidViewModel implements MercuryAn
|
|||
private final MutableLiveData<String> loginPasswordError = new MutableLiveData<>();
|
||||
private final MutableLiveData<Boolean> loginButtonEnabled = new MutableLiveData<>(true);
|
||||
private final MutableLiveData<Optional<Account>> loginFinished = new MutableLiveData<>(new Optional<>());
|
||||
private final MutableLiveData<Boolean> displayProgressBar = new MutableLiveData<>(false);
|
||||
|
||||
@Inject
|
||||
LoginViewModel commonViewModel;
|
||||
|
@ -49,6 +50,8 @@ public class AndroidLoginViewModel extends AndroidViewModel implements MercuryAn
|
|||
.subscribe(loginButtonEnabled::setValue));
|
||||
addDisposable(getCommonViewModel().isLoginSuccessful()
|
||||
.subscribe(loginFinished::setValue));
|
||||
addDisposable(getCommonViewModel().isDisplayProgressBar()
|
||||
.subscribe(displayProgressBar::setValue));
|
||||
}
|
||||
|
||||
private final ObservableTransformer<Optional<UsernameError>, Optional<String>> usernameErrorToErrorMessage =
|
||||
|
@ -120,6 +123,10 @@ public class AndroidLoginViewModel extends AndroidViewModel implements MercuryAn
|
|||
return loginFinished;
|
||||
}
|
||||
|
||||
public LiveData<Boolean> isDisplayProgressBar() {
|
||||
return displayProgressBar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoginViewModel getCommonViewModel() {
|
||||
return commonViewModel;
|
||||
|
|
|
@ -76,8 +76,8 @@ public class EnterAccountDetailsFragment extends Fragment {
|
|||
viewModel.getLoginUsernameError().observe(this, error -> usernameLayout.setError(error));
|
||||
viewModel.getLoginPasswordError().observe(this, error -> passwordLayout.setError(error));
|
||||
viewModel.isLoginButtonEnabled().observe(this, loginButton::setEnabled);
|
||||
viewModel.isLoginButtonEnabled().observe(this, enabled ->
|
||||
progressBar.setVisibility(enabled ? View.GONE : View.VISIBLE));
|
||||
viewModel.isDisplayProgressBar().observe(this, visible ->
|
||||
progressBar.setVisibility(visible ? View.VISIBLE : View.GONE));
|
||||
|
||||
viewModel.isLoginFinished().observe(this, optAccount ->
|
||||
((AddAccountActivity) getActivity()).loginFinished(optAccount));
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package org.mercury_im.messenger.android.crypto.ikey;
|
||||
package org.mercury_im.messenger.android.ui.account.login;
|
||||
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
|
@ -11,16 +11,13 @@ import androidx.fragment.app.Fragment;
|
|||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.bouncycastle.openpgp.PGPException;
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smackx.pubsub.PubSubException;
|
||||
import org.mercury_im.messenger.R;
|
||||
import org.mercury_im.messenger.android.crypto.ikey.AndroidIkeyBackupCreationViewModel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
import butterknife.BindView;
|
||||
|
@ -36,6 +33,9 @@ public class IkeyBackupCreationFragment extends Fragment {
|
|||
@BindView(R.id.qr_code)
|
||||
ImageView qrCode;
|
||||
|
||||
@BindView(R.id.btn_done)
|
||||
Button doneButton;
|
||||
|
||||
private final UUID accountId;
|
||||
|
||||
private IkeyBackupCreationFragment(UUID accountId) {
|
||||
|
@ -60,10 +60,11 @@ public class IkeyBackupCreationFragment extends Fragment {
|
|||
viewModel = new ViewModelProvider(this).get(AndroidIkeyBackupCreationViewModel.class);
|
||||
viewModel.initialize(accountId);
|
||||
|
||||
viewModel.uploadBackup();
|
||||
viewModel.uploadBackup();
|
||||
|
||||
viewModel.getPassphrase().observe(getViewLifecycleOwner(), passphrase -> backupCode.setText(passphrase));
|
||||
viewModel.getPassphraseAsQrCode().observe(getViewLifecycleOwner(), bitmap -> qrCode.setImageBitmap(bitmap));
|
||||
doneButton.setOnClickListener(v -> getActivity().finish());
|
||||
}
|
||||
|
||||
}
|
|
@ -16,8 +16,12 @@ import androidx.annotation.Nullable;
|
|||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import org.bouncycastle.openpgp.PGPException;
|
||||
import org.mercury_im.messenger.R;
|
||||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.util.UUID;
|
||||
|
||||
import butterknife.BindView;
|
||||
|
@ -66,8 +70,20 @@ public class IkeyBackupRestoreOrSkipFragment extends Fragment {
|
|||
viewModel = new ViewModelProvider(requireActivity()).get(AndroidIkeySetupViewModel.class);
|
||||
|
||||
restoreButton.setOnClickListener(v -> onRestore());
|
||||
regenerateButton.setOnClickListener(v ->
|
||||
((IkeySetupNavigator) getActivity()).generateIkeyBackup(accountId));
|
||||
regenerateButton.setOnClickListener(v -> {
|
||||
try {
|
||||
viewModel.generateIdentityKey();
|
||||
} catch (PGPException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchProviderException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvalidAlgorithmParameterException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
((IkeySetupNavigator) getActivity()).displayInfo(accountId);
|
||||
});
|
||||
|
||||
viewModel.getPassphraseError().observe(this, opt -> {
|
||||
if (opt.isPresent()) {
|
||||
|
|
|
@ -164,15 +164,18 @@
|
|||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
android:layout_marginTop="6dp"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:layout_marginBottom="6dp">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:paddingTop="12dp">
|
||||
android:padding="8dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".android.crypto.ikey.IkeyBackupCreationFragment">
|
||||
tools:context=".android.ui.account.login.IkeyBackupCreationFragment">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/notice"
|
||||
|
@ -47,5 +47,19 @@
|
|||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/qr_code"
|
||||
tools:text="TWNK-KD5Y-MT3T-E1GS-DRDB-KVTW" />
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="end"
|
||||
app:layout_constraintTop_toBottomOf="@id/backup_code">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_done"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Done" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -38,6 +38,7 @@ public class LoginViewModel implements MercuryViewModel {
|
|||
private BehaviorSubject<Optional<PasswordError>> loginPasswordError;
|
||||
private BehaviorSubject<Boolean> isLoginPossible;
|
||||
private BehaviorSubject<Optional<Account>> isLoginSuccessful;
|
||||
private BehaviorSubject<Boolean> displayProgressBar;
|
||||
|
||||
private EntityBareJid loginUsernameValue;
|
||||
private String loginPasswordValue;
|
||||
|
@ -59,6 +60,7 @@ public class LoginViewModel implements MercuryViewModel {
|
|||
loginPasswordError = BehaviorSubject.createDefault(new Optional<>());
|
||||
isLoginPossible = BehaviorSubject.createDefault(false);
|
||||
isLoginSuccessful = BehaviorSubject.createDefault(new Optional<>());
|
||||
displayProgressBar = BehaviorSubject.createDefault(false);
|
||||
|
||||
loginUsernameValue = null;
|
||||
loginPasswordValue = null;
|
||||
|
@ -112,6 +114,7 @@ public class LoginViewModel implements MercuryViewModel {
|
|||
}
|
||||
|
||||
public synchronized Account login() {
|
||||
displayProgressBar.onNext(true);
|
||||
if (!isLoginPossible.getValue()) {
|
||||
// Prevent race condition where account would be logged in twice
|
||||
return account;
|
||||
|
@ -145,6 +148,7 @@ public class LoginViewModel implements MercuryViewModel {
|
|||
.firstOrError()
|
||||
.compose(schedulers.executeUiSafeSingle())
|
||||
.subscribe(connectivityState -> {
|
||||
displayProgressBar.onNext(false);
|
||||
if (connectivityState == ConnectivityState.disconnectedOnError) {
|
||||
onLoginFailed(new Exception());
|
||||
} else {
|
||||
|
@ -178,4 +182,8 @@ public class LoginViewModel implements MercuryViewModel {
|
|||
loginUsernameError.onNext(new Optional<>(UsernameError.unreachableServer));
|
||||
}
|
||||
}
|
||||
|
||||
public Observable<Boolean> isDisplayProgressBar() {
|
||||
return displayProgressBar;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue