diff --git a/app/build.gradle b/app/build.gradle index 42f5c188dd..2becab44ff 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -10,8 +10,8 @@ android { applicationId "org.ole.planet.myplanet" minSdkVersion 21 targetSdkVersion 34 - versionCode 1093 - versionName "0.10.93" + versionCode 1094 + versionName "0.10.94" ndkVersion '21.3.6528147' testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables.useSupportLibrary = true diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/DashboardActivity.java b/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/DashboardActivity.java index 9405f71ab5..f92bafc76d 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/DashboardActivity.java +++ b/app/src/main/java/org/ole/planet/myplanet/ui/dashboard/DashboardActivity.java @@ -1,5 +1,7 @@ package org.ole.planet.myplanet.ui.dashboard; +import android.app.Activity; +import android.app.AlertDialog; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; @@ -8,11 +10,13 @@ import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Bundle; +import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.WindowManager; +import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; @@ -49,6 +53,7 @@ import org.ole.planet.myplanet.ui.survey.SurveyFragment; import org.ole.planet.myplanet.ui.sync.DashboardElementActivity; import org.ole.planet.myplanet.ui.team.TeamFragment; +import org.ole.planet.myplanet.ui.userprofile.BecomeMemberActivity; import org.ole.planet.myplanet.utilities.BottomNavigationViewHelper; import org.ole.planet.myplanet.utilities.Constants; import org.ole.planet.myplanet.utilities.KeyboardUtils; @@ -122,9 +127,8 @@ protected void onCreate(Bundle savedInstanceState) { navigationView.setVisibility(new UserProfileDbHandler(this).getUserModel().getShowTopbar() ? View.VISIBLE : View.GONE); headerResult = getAccountHeader(); createDrawer(); - if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { + if (!(user.getId().startsWith("guest") && profileDbHandler.getOfflineVisits() >= 3) && getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { result.openDrawer(); - }//Opens drawer by default result.getStickyFooter().setPadding(0, 0, 0, 0); // moves logout button to the very bottom of the drawer. Without it, the "logout" button suspends a little. result.getActionBarDrawerToggle().setDrawerIndicatorEnabled(true); @@ -205,8 +209,30 @@ private void checkUser() { logout(); return; } - if (user.getId().startsWith("guest")) { - getTheme().applyStyle(R.style.GuestStyle, true); + if(user.getId().startsWith("guest") && profileDbHandler.getOfflineVisits() >= 3 ){ + + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle("Become a member"); + builder.setMessage("Trial period ended! Kindly complete registration to continue"); + builder.setCancelable(false); + builder.setPositiveButton("Become a member", null); + builder.setNegativeButton("Logout", null); + AlertDialog dialog = builder.create(); + dialog.show(); + Button becomeMember = dialog.getButton(AlertDialog.BUTTON_POSITIVE); + Button logout = dialog.getButton(AlertDialog.BUTTON_NEGATIVE); + becomeMember.setOnClickListener(view -> { + boolean guest = true; + Intent intent = new Intent(this, BecomeMemberActivity.class); + intent.putExtra("username", profileDbHandler.getUserModel().getName()); + intent.putExtra("guest", guest); + setResult(Activity.RESULT_OK, intent); + startActivity(intent); + }); + logout.setOnClickListener(view -> { + dialog.dismiss(); + logout(); + }); } } diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/sync/LoginActivity.java b/app/src/main/java/org/ole/planet/myplanet/ui/sync/LoginActivity.java index 16e7ef5298..98ed4ca586 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/sync/LoginActivity.java +++ b/app/src/main/java/org/ole/planet/myplanet/ui/sync/LoginActivity.java @@ -68,6 +68,7 @@ import java.util.concurrent.TimeUnit; import io.realm.Realm; +import io.realm.RealmResults; import io.realm.Sort; public class LoginActivity extends SyncActivity implements Service.CheckVersionCallback, AdapterTeam.OnUserSelectedListener { @@ -129,13 +130,17 @@ protected void onCreate(Bundle savedInstanceState) { if (!Utilities.getUrl().isEmpty()) { btnOpenCommunity.setVisibility(View.VISIBLE); btnOpenCommunity.setOnClickListener(v -> { + inputName.setText(""); new HomeCommunityDialogFragment().show(getSupportFragmentManager(), ""); }); new HomeCommunityDialogFragment().show(getSupportFragmentManager(), ""); } else { btnOpenCommunity.setVisibility(View.GONE); } - findViewById(R.id.btn_feedback).setOnClickListener(view -> new FeedbackFragment().show(getSupportFragmentManager(), "")); + findViewById(R.id.btn_feedback).setOnClickListener(view -> { + inputName.setText(""); + new FeedbackFragment().show(getSupportFragmentManager(), ""); + }); if (settings.getBoolean("firstRun", true)); @@ -238,18 +243,29 @@ public void declareElements() { }); if (!settings.contains("serverProtocol")) settings.edit().putString("serverProtocol", "http://").commit(); - findViewById(R.id.become_member).setOnClickListener(v -> becomeAMember()); - imgBtnSetting.setOnClickListener(view -> settingDialog()); - btnGuestLogin.setOnClickListener(view -> showGuestLoginDialog()); + findViewById(R.id.become_member).setOnClickListener(v -> { + inputName.setText(""); + becomeAMember(); + }); + imgBtnSetting.setOnClickListener(view -> { + inputName.setText(""); + settingDialog(); + }); + btnGuestLogin.setOnClickListener(view -> { + inputName.setText(""); + showGuestLoginDialog(); + }); SwitchCompat switchChildMode = findViewById(R.id.switch_child_mode); switchChildMode.setChecked(settings.getBoolean("isChild", false)); switchChildMode.setOnCheckedChangeListener((compoundButton, b) -> { + inputName.setText(""); settings.edit().putBoolean("isChild", b).commit(); recreate(); }); } private void becomeAMember() { + if (!Utilities.getUrl().isEmpty()) { startActivity(new Intent(this, BecomeMemberActivity.class)); } else { @@ -261,35 +277,110 @@ private void becomeAMember() { private void showGuestLoginDialog() { try { mRealm = Realm.getDefaultInstance(); - + mRealm.refresh(); editor = settings.edit(); View v = LayoutInflater.from(this).inflate(R.layout.alert_guest_login, null); TextInputEditText etUserName = v.findViewById(R.id.et_user_name); - new AlertDialog.Builder(this) - .setTitle("Login As Guest") - .setView(v) - .setPositiveButton("Login", (dialogInterface, i) -> { - if (mRealm != null && !mRealm.isClosed()) { - if (mRealm.isEmpty()) { - alertDialogOkay(getString(R.string.this_device_not_configured_properly_please_check_and_sync)); - return; - } - String username = etUserName.getText().toString().toLowerCase().trim(); - if (username.isEmpty()) { - Utilities.toast(this, getString(R.string.username_cannot_be_empty)); - return; - } - RealmUserModel model = mRealm.copyFromRealm(RealmUserModel.createGuestUser(username, mRealm, settings)); - if (model == null) { - Utilities.toast(this, getString(R.string.unable_to_login)); - } else { - saveUserInfoPref(settings, "", model); - onLogin(); - } + etUserName.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) { + char firstChar = s.length() > 0 ? s.charAt(0) : '\0'; + boolean hasInvalidCharacters = false; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c != '_' && c != '.' && c != '-' && !Character.isDigit(c) && !Character.isLetter(c)) { + hasInvalidCharacters = true; + break; + } + } + + if (!Character.isDigit(firstChar) && !Character.isLetter(firstChar)) { + etUserName.setError(getString(R.string.must_start_with_letter_or_number)); + } else if (hasInvalidCharacters) { + etUserName.setError(getString(R.string.only_letters_numbers_and_are_allowed)); + } else { + String lowercaseText = s.toString().toLowerCase(Locale.ROOT); + if (!s.toString().equals(lowercaseText)) { + etUserName.setText(lowercaseText); + etUserName.setSelection(lowercaseText.length()); } - }) - .setNegativeButton("Cancel", null) - .show(); + etUserName.setError(null); + } + } + + @Override + public void afterTextChanged(Editable s) {} + }); + + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle("Login As Guest"); + builder.setView(v); + builder.setPositiveButton("Login", null); + builder.setNegativeButton("Cancel", null); + AlertDialog dialog = builder.create(); + dialog.show(); + Button login = dialog.getButton(AlertDialog.BUTTON_POSITIVE); + Button cancel = dialog.getButton(AlertDialog.BUTTON_NEGATIVE); + + login.setOnClickListener(view -> { + if (mRealm.isEmpty()) { + alertDialogOkay(getString(R.string.this_device_not_configured_properly_please_check_and_sync)); + return; + } + String username = etUserName.getText().toString().trim(); + Character firstChar = username.isEmpty() ? null : username.charAt(0); + boolean hasInvalidCharacters = false; + + boolean isValid = true; + + if (TextUtils.isEmpty(username)) { + etUserName.setError(getString(R.string.username_cannot_be_empty)); + isValid = false; + } + + if (firstChar != null && !Character.isDigit(firstChar) && !Character.isLetter(firstChar)) { + etUserName.setError(getString(R.string.must_start_with_letter_or_number)); + isValid = false; + } else { + for (char c : username.toCharArray()) { + if (c != '_' && c != '.' && c != '-' && !Character.isDigit(c) && !Character.isLetter(c)) { + hasInvalidCharacters = true; + break; + } + } + + if (hasInvalidCharacters) { + etUserName.setError(getString(R.string.only_letters_numbers_and_are_allowed)); + isValid = false; + } + } + + if (isValid) { + RealmUserModel existingUser = mRealm.where(RealmUserModel.class).equalTo("name", username).findFirst(); + dialog.dismiss(); + + if (existingUser != null) { + Log.d("model", String.valueOf(existingUser.get_id())); + if (existingUser.get_id().contains("guest")) { + showGuestDialog(username); + } else if (existingUser.get_id().contains("org.couchdb.user:")) { + showUserAlreadyMemberDialog(username); + } + } else { + RealmUserModel model = mRealm.copyFromRealm(RealmUserModel.createGuestUser(username, mRealm, settings)); + if (model == null) { + Utilities.toast(LoginActivity.this, getString(R.string.unable_to_login)); + } else { + saveUserInfoPref(settings, "", model); + onLogin(); + } + } + } + }); + + cancel.setOnClickListener(view -> dialog.dismiss()); } finally { if (mRealm != null && !mRealm.isClosed()) { mRealm.close(); @@ -297,6 +388,45 @@ private void showGuestLoginDialog() { } } + private void showGuestDialog(String username) { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(username + " is already a guest"); + builder.setMessage("Continue only if this is you"); + builder.setCancelable(false); + builder.setNegativeButton("cancel", (dialog, which) -> dialog.dismiss()); + + builder.setPositiveButton("continue", (dialog, which) -> { + dialog.dismiss(); + RealmUserModel model = mRealm.copyFromRealm(RealmUserModel.createGuestUser(username, mRealm, settings)); + if (model == null) { + Utilities.toast(LoginActivity.this, getString(R.string.unable_to_login)); + } else { + saveUserInfoPref(settings, "", model); + onLogin(); + } + }); + + AlertDialog dialog = builder.create(); + dialog.show(); + + } + + private void showUserAlreadyMemberDialog(String username) { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(username + " is already a member"); + builder.setMessage("Continue to login if this is you"); + builder.setCancelable(false); + builder.setNegativeButton("Cancel", (dialog, which) -> dialog.dismiss()); + + builder.setPositiveButton("login", (dialog, which) -> { + dialog.dismiss(); + inputName.setText(username); + }); + + AlertDialog dialog = builder.create(); + dialog.show(); + } + private void continueSync(MaterialDialog dialog) { processedUrl = saveConfigAndContinue(dialog); if (TextUtils.isEmpty(processedUrl)) return; @@ -729,5 +859,3 @@ public String getCustomDeviceName() { return settings.getString("customDeviceName", NetworkUtils.getDeviceName()); } } - - diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/userprofile/BecomeMemberActivity.kt b/app/src/main/java/org/ole/planet/myplanet/ui/userprofile/BecomeMemberActivity.kt index 6fb045832c..8376b1ce06 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/userprofile/BecomeMemberActivity.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/userprofile/BecomeMemberActivity.kt @@ -2,9 +2,11 @@ package org.ole.planet.myplanet.ui.userprofile import android.app.DatePickerDialog import android.content.Context +import android.content.Intent import android.content.SharedPreferences import android.os.Bundle import android.text.Editable +import android.text.TextUtils import android.text.TextWatcher import android.view.View import android.widget.ArrayAdapter @@ -20,6 +22,7 @@ import org.ole.planet.myplanet.datamanager.DatabaseService import org.ole.planet.myplanet.datamanager.Service import org.ole.planet.myplanet.model.RealmUserModel import org.ole.planet.myplanet.service.UserProfileDbHandler +import org.ole.planet.myplanet.ui.sync.LoginActivity import org.ole.planet.myplanet.ui.sync.SyncActivity import org.ole.planet.myplanet.utilities.NetworkUtils import org.ole.planet.myplanet.utilities.Utilities @@ -31,6 +34,7 @@ class BecomeMemberActivity : BaseActivity() { private lateinit var activityBecomeMemberBinding: ActivityBecomeMemberBinding var dob: String = ""; lateinit var settings: SharedPreferences + var guest: Boolean = false private fun showDatePickerDialog() { val now = Calendar.getInstance() val dpd = DatePickerDialog( @@ -58,9 +62,16 @@ class BecomeMemberActivity : BaseActivity() { showDatePickerDialog() } + val username = intent.getStringExtra("username"); + guest = intent.getBooleanExtra("guest", false); + settings = getSharedPreferences(SyncActivity.PREFS_NAME, Context.MODE_PRIVATE) textChangedListener(mRealm) + if (username != null) { + activityBecomeMemberBinding.etUsername.setText(username) + } + activityBecomeMemberBinding.etUsername.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} @@ -94,6 +105,7 @@ class BecomeMemberActivity : BaseActivity() { activityBecomeMemberBinding.btnCancel.setOnClickListener { finish() } + activityBecomeMemberBinding.btnSubmit.setOnClickListener { var username: String? = activityBecomeMemberBinding.etUsername.text.toString() var password: String? = activityBecomeMemberBinding.etPassword.text.toString() @@ -106,63 +118,62 @@ class BecomeMemberActivity : BaseActivity() { var phoneNumber: String? = activityBecomeMemberBinding.etPhone.text.toString() var birthDate: String? = dob var level: String? = activityBecomeMemberBinding.spnLevel.selectedItem.toString() - - var rb: RadioButton? = - findViewById(activityBecomeMemberBinding.rbGender.checkedRadioButtonId) as RadioButton? - var gender: String? = "" - if (rb != null) gender = rb.text.toString() - else { - Utilities.toast(this, getString(R.string.please_select_gender)) - } - + var gender: String? = null + val firstChar = if (username!!.isNotEmpty()) username[0] else null val hasInvalidCharacters = username.any { char -> char != '_' && char != '.' && char != '-' && !Character.isDigit(char) && !Character.isLetter(char) } - if (username.isEmpty()) { + + if (TextUtils.isEmpty(username)) { activityBecomeMemberBinding.etUsername.error = getString(R.string.please_enter_a_username) } else if (username.contains(" ")) { activityBecomeMemberBinding.etUsername.error = getString(R.string.invalid_username) } else if (firstChar != null && !Character.isDigit(firstChar) && !Character.isLetter(firstChar)) { activityBecomeMemberBinding.etUsername.error = getString(R.string.must_start_with_letter_or_number) } else if (hasInvalidCharacters) { - activityBecomeMemberBinding.etUsername.error = getString(R.string.only_letters_numbers_and_are_allowed) - } - - if (password!!.isEmpty()) { + activityBecomeMemberBinding.etUsername.error = getString(R.string.only_letters_numbers_and_are_allowed) + } else if (TextUtils.isEmpty(password)) { activityBecomeMemberBinding.etPassword.error = getString(R.string.please_enter_a_password) } else if (password != repassword) { activityBecomeMemberBinding.etRePassword.error = getString(R.string.password_doesn_t_match) - } - if (email!!.isNotEmpty() && !Utilities.isValidEmail(email)) { + } else if (!TextUtils.isEmpty(email) && !Utilities.isValidEmail(email)) { activityBecomeMemberBinding.etEmail.error = getString(R.string.invalid_email) - } - if (level == null) { + } else if (activityBecomeMemberBinding.rbGender.checkedRadioButtonId == -1) { + Utilities.toast(this, getString(R.string.please_select_gender)) + } else if (level == null) { Utilities.toast(this, getString(R.string.level_is_required)); - } - if (password.isEmpty() && phoneNumber!!.isNotEmpty()) { - activityBecomeMemberBinding.etRePassword.setText(phoneNumber) - password = phoneNumber - ///Add dialog that using phone as password , Agree / disagree - } + } else { + if (activityBecomeMemberBinding.male.isChecked) { + gender = "male" + } else if (activityBecomeMemberBinding.female.isChecked) { + gender = "female" + } - checkMandatoryFieldsAndAddMember( - username, - password, - repassword, - fname, - lname, - mname, - email, - language, - level, - phoneNumber, - birthDate, - gender, - mRealm - ) + if (TextUtils.isEmpty(password) && !TextUtils.isEmpty(phoneNumber)) { + activityBecomeMemberBinding.etRePassword.setText(phoneNumber) + password = phoneNumber + ///Add dialog that using phone as password , Agree / disagree + } + + checkMandatoryFieldsAndAddMember( + username, + password!!, + repassword, + fname, + lname, + mname, + email, + language, + level, + phoneNumber, + birthDate, + gender, + mRealm + ) + } } } @@ -220,6 +231,13 @@ class BecomeMemberActivity : BaseActivity() { } finish() } + + if (guest){ + val intent = Intent(this, LoginActivity::class.java) + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) + startActivity(intent) + finish() + } } } diff --git a/app/src/main/res/layout/activity_become_member.xml b/app/src/main/res/layout/activity_become_member.xml index 8b49fd2648..4e48f5011e 100644 --- a/app/src/main/res/layout/activity_become_member.xml +++ b/app/src/main/res/layout/activity_become_member.xml @@ -218,11 +218,13 @@