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