From db218d662183575a88384d988880cfc723a72340 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20B=C3=A9raud?= <adrien.beraud@savoirfairelinux.com> Date: Mon, 27 Sep 2021 16:03:06 -0400 Subject: [PATCH] account creation: handle fragment recreation Change-Id: I8ca295fe140d369fa6ec13b270eb54d909a47098 --- .../account/JamiAccountCreationFragment.kt | 23 +- .../account/JamiAccountPasswordFragment.java | 208 ------------------ .../account/JamiAccountPasswordFragment.kt | 163 ++++++++++++++ 3 files changed, 174 insertions(+), 220 deletions(-) delete mode 100644 ring-android/app/src/main/java/cx/ring/account/JamiAccountPasswordFragment.java create mode 100644 ring-android/app/src/main/java/cx/ring/account/JamiAccountPasswordFragment.kt diff --git a/ring-android/app/src/main/java/cx/ring/account/JamiAccountCreationFragment.kt b/ring-android/app/src/main/java/cx/ring/account/JamiAccountCreationFragment.kt index 349247325..883abc70b 100644 --- a/ring-android/app/src/main/java/cx/ring/account/JamiAccountCreationFragment.kt +++ b/ring-android/app/src/main/java/cx/ring/account/JamiAccountCreationFragment.kt @@ -105,20 +105,19 @@ class JamiAccountCreationFragment : Fragment() { var mRegisteredFragments = SparseArray<Fragment>() private var mCurrentPosition = -1 override fun getItem(position: Int): Fragment { - var fragment: Fragment? = null - val ringAccountViewModel = AccountCreationModelImpl() - when (position) { - 0 -> fragment = JamiAccountUsernameFragment.newInstance(ringAccountViewModel) - 1 -> fragment = JamiAccountPasswordFragment.newInstance(ringAccountViewModel) - 2 -> fragment = ProfileCreationFragment.newInstance(ringAccountViewModel) + val accountViewModel = AccountCreationModelImpl() + return when (position) { + 0 -> JamiAccountUsernameFragment.newInstance(accountViewModel) + 1 -> JamiAccountPasswordFragment.newInstance(accountViewModel) + 2 -> ProfileCreationFragment.newInstance(accountViewModel) + else -> throw IllegalStateException() } - return fragment!! } - override fun setPrimaryItem(container: ViewGroup, position: Int, `object`: Any) { - super.setPrimaryItem(container, position, `object`) + override fun setPrimaryItem(container: ViewGroup, position: Int, o: Any) { + super.setPrimaryItem(container, position, o) if (position != mCurrentPosition && container is WizardViewPager) { - val fragment = `object` as Fragment + val fragment = o as Fragment if (fragment.view != null) { mCurrentPosition = position container.measureCurrentView(fragment.view) @@ -132,9 +131,9 @@ class JamiAccountCreationFragment : Fragment() { return super.instantiateItem(container, position) } - override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) { + override fun destroyItem(container: ViewGroup, position: Int, o: Any) { mRegisteredFragments.remove(position) - super.destroyItem(container, position, `object`) + super.destroyItem(container, position, o) } override fun getCount(): Int { diff --git a/ring-android/app/src/main/java/cx/ring/account/JamiAccountPasswordFragment.java b/ring-android/app/src/main/java/cx/ring/account/JamiAccountPasswordFragment.java deleted file mode 100644 index 49ff65322..000000000 --- a/ring-android/app/src/main/java/cx/ring/account/JamiAccountPasswordFragment.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (C) 2004-2021 Savoir-faire Linux Inc. - * - * Authors: AmirHossein Naghshzan <amirhossein.naghshzan@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -package cx.ring.account; - -import android.app.Activity; -import android.content.Context; -import android.os.Bundle; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputMethodManager; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import cx.ring.R; -import cx.ring.databinding.FragAccJamiPasswordBinding; - -import net.jami.account.JamiAccountCreationPresenter; -import net.jami.account.JamiAccountCreationView; -import net.jami.model.AccountCreationModel; -import cx.ring.mvp.BaseSupportFragment; -import dagger.hilt.android.AndroidEntryPoint; - -@AndroidEntryPoint -public class JamiAccountPasswordFragment extends BaseSupportFragment<JamiAccountCreationPresenter, JamiAccountCreationView> - implements JamiAccountCreationView { - - private static final String KEY_MODEL = "model"; - private AccountCreationModel model; - private FragAccJamiPasswordBinding binding; - - private boolean mIsChecked = false; - - public static JamiAccountPasswordFragment newInstance(AccountCreationModelImpl ringAccountViewModel) { - JamiAccountPasswordFragment fragment = new JamiAccountPasswordFragment(); - fragment.model = ringAccountViewModel; - return fragment; - } - - @Override - public void onSaveInstanceState(@NonNull Bundle outState) { - if (model != null) - outState.putSerializable(KEY_MODEL, model); - } - - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - setRetainInstance(true); - if (savedInstanceState != null && model == null) { - model = (AccountCreationModelImpl) savedInstanceState.getSerializable(KEY_MODEL); - } - binding = FragAccJamiPasswordBinding.inflate(inflater, container, false); - return binding.getRoot(); - } - - @Override - public void onDestroyView() { - super.onDestroyView(); - binding = null; - } - - @Override - public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - - binding.createAccount.setOnClickListener(v -> presenter.createAccount()); - binding.ringPasswordSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - mIsChecked = isChecked; - if (isChecked) { - binding.passwordTxtBox.setVisibility(View.VISIBLE); - binding.ringPasswordRepeatTxtBox.setVisibility(View.VISIBLE); - binding.placeholder.setVisibility(View.GONE); - CharSequence password = binding.ringPassword.getText(); - presenter.passwordChanged(password == null ? null : password.toString(), binding.ringPasswordRepeat.getText()); - } else { - binding.passwordTxtBox.setVisibility(View.GONE); - binding.ringPasswordRepeatTxtBox.setVisibility(View.GONE); - binding.placeholder.setVisibility(View.VISIBLE); - presenter.passwordUnset(); - } - }); - binding.ringPassword.addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) {} - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - presenter.passwordChanged(s.toString()); - } - - @Override - public void afterTextChanged(Editable s) {} - }); - binding.ringPasswordRepeat.addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) {} - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - presenter.passwordConfirmChanged(s.toString()); - } - - @Override - public void afterTextChanged(Editable s) {} - }); - binding.ringPasswordRepeat.setOnEditorActionListener((v, actionId, event) -> { - if (actionId == EditorInfo.IME_ACTION_DONE) { - presenter.createAccount(); - } - return false; - }); - binding.ringPasswordRepeat.setOnEditorActionListener((v, actionId, event) -> { - if (actionId == EditorInfo.IME_ACTION_DONE && binding.createAccount.isEnabled()) { - InputMethodManager inputMethodManager = (InputMethodManager) v.getContext().getSystemService(Activity.INPUT_METHOD_SERVICE); - if (inputMethodManager != null) - inputMethodManager.hideSoftInputFromWindow(v.getWindowToken(), 0); - presenter.createAccount(); - return true; - } - return false; - }); - - presenter.init(model); - } - - @Override - public void updateUsernameAvailability(UsernameAvailabilityStatus status) { - } - - @Override - public void showInvalidPasswordError(final boolean display) { - if (display) { - binding.passwordTxtBox.setError(getString(R.string.error_password_char_count)); - } else { - binding.passwordTxtBox.setError(null); - } - } - - @Override - public void showNonMatchingPasswordError(final boolean display) { - if (display) { - binding.ringPasswordRepeatTxtBox.setError(getString(R.string.error_passwords_not_equals)); - } else { - binding.ringPasswordRepeatTxtBox.setError(null); - } - } - - @Override - public void enableNextButton(final boolean enabled) { - if (!mIsChecked) { - binding.createAccount.setEnabled(true); - return; - } - - binding.createAccount.setEnabled(enabled); - } - - @Override - public void goToAccountCreation(AccountCreationModel accountCreationModel) { - Activity wizardActivity = getActivity(); - if (wizardActivity instanceof AccountWizardActivity) { - AccountWizardActivity wizard = (AccountWizardActivity) wizardActivity; - wizard.createAccount(accountCreationModel); - JamiAccountCreationFragment parent = (JamiAccountCreationFragment) getParentFragment(); - if (parent != null) { - parent.scrollPagerFragment(accountCreationModel); - InputMethodManager imm = (InputMethodManager) wizard.getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm != null) - imm.hideSoftInputFromWindow(binding.ringPassword.getWindowToken(), 0); - } - } - } - - @Override - public void cancel() { - Activity wizardActivity = getActivity(); - if (wizardActivity != null) { - wizardActivity.onBackPressed(); - } - } - - public void setUsername(String username) { - model.setUsername(username); - } - -} diff --git a/ring-android/app/src/main/java/cx/ring/account/JamiAccountPasswordFragment.kt b/ring-android/app/src/main/java/cx/ring/account/JamiAccountPasswordFragment.kt new file mode 100644 index 000000000..02ce3ceb3 --- /dev/null +++ b/ring-android/app/src/main/java/cx/ring/account/JamiAccountPasswordFragment.kt @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2004-2021 Savoir-faire Linux Inc. + * + * Authors: AmirHossein Naghshzan <amirhossein.naghshzan@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +package cx.ring.account + +import android.app.Activity +import android.content.Context +import android.os.Bundle +import android.text.Editable +import android.text.TextWatcher +import android.view.KeyEvent +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.view.inputmethod.EditorInfo +import android.view.inputmethod.InputMethodManager +import android.widget.CompoundButton +import android.widget.TextView +import cx.ring.R +import cx.ring.databinding.FragAccJamiPasswordBinding +import cx.ring.mvp.BaseSupportFragment +import dagger.hilt.android.AndroidEntryPoint +import net.jami.account.JamiAccountCreationPresenter +import net.jami.account.JamiAccountCreationView +import net.jami.account.JamiAccountCreationView.UsernameAvailabilityStatus +import net.jami.model.AccountCreationModel + +@AndroidEntryPoint +class JamiAccountPasswordFragment : BaseSupportFragment<JamiAccountCreationPresenter, JamiAccountCreationView>(), + JamiAccountCreationView { + private var model: AccountCreationModel? = null + private var binding: FragAccJamiPasswordBinding? = null + private var mIsChecked = false + override fun onSaveInstanceState(outState: Bundle) { + if (model != null) outState.putSerializable(KEY_MODEL, model) + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { + if (savedInstanceState != null && model == null) { + model = savedInstanceState.getSerializable(KEY_MODEL) as AccountCreationModelImpl? + } + binding = FragAccJamiPasswordBinding.inflate(inflater, container, false) + return binding!!.root + } + + override fun onDestroyView() { + super.onDestroyView() + binding = null + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding!!.createAccount.setOnClickListener { presenter.createAccount() } + binding!!.ringPasswordSwitch.setOnCheckedChangeListener { buttonView: CompoundButton?, isChecked: Boolean -> + mIsChecked = isChecked + if (isChecked) { + binding!!.passwordTxtBox.visibility = View.VISIBLE + binding!!.ringPasswordRepeatTxtBox.visibility = View.VISIBLE + binding!!.placeholder.visibility = View.GONE + val password: CharSequence? = binding!!.ringPassword.text + presenter.passwordChanged(password.toString(), binding!!.ringPasswordRepeat.text!!) + } else { + binding!!.passwordTxtBox.visibility = View.GONE + binding!!.ringPasswordRepeatTxtBox.visibility = View.GONE + binding!!.placeholder.visibility = View.VISIBLE + presenter.passwordUnset() + } + } + binding!!.ringPassword.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} + override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { + presenter.passwordChanged(s.toString()) + } + + override fun afterTextChanged(s: Editable) {} + }) + binding!!.ringPasswordRepeat.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} + override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { + presenter.passwordConfirmChanged(s.toString()) + } + + override fun afterTextChanged(s: Editable) {} + }) + binding!!.ringPasswordRepeat.setOnEditorActionListener { v: TextView?, actionId: Int, event: KeyEvent? -> + if (actionId == EditorInfo.IME_ACTION_DONE) { + presenter.createAccount() + } + false + } + binding!!.ringPasswordRepeat.setOnEditorActionListener { v: TextView, actionId: Int, event: KeyEvent? -> + if (actionId == EditorInfo.IME_ACTION_DONE && binding!!.createAccount.isEnabled) { + val inputMethodManager = v.context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager + inputMethodManager.hideSoftInputFromWindow(v.windowToken, 0) + presenter.createAccount() + return@setOnEditorActionListener true + } + false + } + presenter.init(model) + } + + override fun updateUsernameAvailability(status: UsernameAvailabilityStatus) {} + + override fun showInvalidPasswordError(display: Boolean) { + binding!!.passwordTxtBox.error = if (display) getString(R.string.error_password_char_count) else null + } + + override fun showNonMatchingPasswordError(display: Boolean) { + binding!!.ringPasswordRepeatTxtBox.error = if (display) getString(R.string.error_passwords_not_equals) else null + } + + override fun enableNextButton(enabled: Boolean) { + binding!!.createAccount.isEnabled = if (mIsChecked) enabled else true + } + + override fun goToAccountCreation(accountCreationModel: AccountCreationModel) { + val wizardActivity: Activity? = activity + if (wizardActivity is AccountWizardActivity) { + wizardActivity.createAccount(accountCreationModel) + val parent = parentFragment as JamiAccountCreationFragment? + if (parent != null) { + parent.scrollPagerFragment(accountCreationModel) + val imm = wizardActivity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + imm.hideSoftInputFromWindow(binding!!.ringPassword.windowToken, 0) + } + } + } + + override fun cancel() { + val wizardActivity: Activity? = activity + wizardActivity?.onBackPressed() + } + + fun setUsername(username: String) { + model!!.username = username + } + + companion object { + private const val KEY_MODEL = "model" + fun newInstance(ringAccountViewModel: AccountCreationModelImpl): JamiAccountPasswordFragment { + val fragment = JamiAccountPasswordFragment() + fragment.model = ringAccountViewModel + return fragment + } + } +} \ No newline at end of file -- GitLab