diff --git a/app/build.gradle b/app/build.gradle index 88a2a22..f6e470e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -6,7 +6,9 @@ apply plugin: 'kotlin-kapt' apply plugin: 'kotlin-android-extensions' -apply plugin: 'io.fabric' +apply plugin: 'com.google.gms.google-services' + +apply plugin: 'com.google.firebase.crashlytics' android { compileSdkVersion 29 @@ -20,6 +22,10 @@ android { testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' } + viewBinding { + enabled = true + } + compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 @@ -121,14 +127,14 @@ android { dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.2' + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1' implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.core:core-ktx:1.3.2' - implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation 'androidx.constraintlayout:constraintlayout:2.0.4' implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation "androidx.preference:preference-ktx:1.1.1" implementation 'com.google.android.material:material:1.2.1' - testImplementation 'junit:junit:4.12' + testImplementation 'junit:junit:4.13.1' testImplementation 'org.mockito:mockito-core:2.28.2' androidTestImplementation 'androidx.test:runner:1.3.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' @@ -149,14 +155,15 @@ dependencies { implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0" //---- GOOGLE JSON SERIALIZER/DESERIALIZER ---- - implementation 'com.google.code.gson:gson:2.8.5' + implementation 'com.google.code.gson:gson:2.8.6' //---- MixPanel ---- implementation 'com.mixpanel.android:mixpanel-android:5.6.1' //---- Firebase ---- - implementation 'com.google.firebase:firebase-core:18.0.0' - implementation 'com.google.firebase:firebase-analytics:18.0.0' - implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1' - implementation 'org.jetbrains.kotlin:kotlin-reflect:1.3.61' + implementation platform('com.google.firebase:firebase-bom:26.1.0') + implementation 'com.google.firebase:firebase-core:18.0.2' + implementation 'com.google.firebase:firebase-analytics-ktx' + implementation 'com.google.firebase:firebase-crashlytics-ktx' + implementation 'org.jetbrains.kotlin:kotlin-reflect:1.4.10' //---- Image ---- implementation group: 'com.github.bumptech.glide', name: 'glide', version: '4.10.0' //---- Network ---- @@ -169,5 +176,3 @@ dependencies { //---- Linters ---- ktlint "com.pinterest:ktlint:0.35.0" } - -apply plugin: 'com.google.gms.google-services' diff --git a/app/src/main/java/com/rootstrap/android/ui/activity/main/ProfileActivity.kt b/app/src/main/java/com/rootstrap/android/ui/activity/main/ProfileActivity.kt index 696b34a..c8e85c2 100644 --- a/app/src/main/java/com/rootstrap/android/ui/activity/main/ProfileActivity.kt +++ b/app/src/main/java/com/rootstrap/android/ui/activity/main/ProfileActivity.kt @@ -1,7 +1,7 @@ package com.rootstrap.android.ui.activity.main import android.os.Bundle -import androidx.lifecycle.ViewModelProviders +import androidx.lifecycle.ViewModelProvider import com.rootstrap.android.R import com.rootstrap.android.metrics.Analytics import com.rootstrap.android.metrics.PageEvents @@ -22,7 +22,7 @@ class ProfileActivity : BaseActivity(), ProfileView { setContentView(R.layout.activity_profile) val factory = ProfileActivityViewModelFactory(viewModelListener) - viewModel = ViewModelProviders.of(this, factory) + viewModel = ViewModelProvider(this, factory) .get(ProfileActivityViewModel::class.java) Analytics.track(PageEvents.visit(VISIT_PROFILE)) diff --git a/app/src/main/java/com/rootstrap/android/ui/activity/main/ProfileActivityViewModel.kt b/app/src/main/java/com/rootstrap/android/ui/activity/main/ProfileActivityViewModel.kt index 626c949..18d680c 100644 --- a/app/src/main/java/com/rootstrap/android/ui/activity/main/ProfileActivityViewModel.kt +++ b/app/src/main/java/com/rootstrap/android/ui/activity/main/ProfileActivityViewModel.kt @@ -4,6 +4,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.viewModelScope import com.rootstrap.android.network.managers.IUserManager +import com.rootstrap.android.network.managers.SessionManager import com.rootstrap.android.network.managers.UserManager import com.rootstrap.android.ui.base.BaseViewModel import com.rootstrap.android.util.NetworkState @@ -23,6 +24,7 @@ open class ProfileActivityViewModel(listener: ViewModelListener?) : BaseViewMode if (result.isSuccess) { networkState = NetworkState.idle state = ProfileState.signOutSuccess + SessionManager.signOut() } else { handleError(result.exceptionOrNull()) } diff --git a/app/src/main/java/com/rootstrap/android/ui/activity/main/SignInActivity.kt b/app/src/main/java/com/rootstrap/android/ui/activity/main/SignInActivity.kt index fa0c9b6..cb7f323 100644 --- a/app/src/main/java/com/rootstrap/android/ui/activity/main/SignInActivity.kt +++ b/app/src/main/java/com/rootstrap/android/ui/activity/main/SignInActivity.kt @@ -2,8 +2,9 @@ package com.rootstrap.android.ui.activity.main import android.Manifest import android.os.Bundle -import androidx.lifecycle.ViewModelProviders +import androidx.lifecycle.ViewModelProvider import com.rootstrap.android.R +import com.rootstrap.android.databinding.ActivitySignInBinding import com.rootstrap.android.metrics.Analytics import com.rootstrap.android.metrics.PageEvents import com.rootstrap.android.metrics.VISIT_SIGN_IN @@ -14,22 +15,24 @@ import com.rootstrap.android.util.ViewModelListener import com.rootstrap.android.util.extensions.value import com.rootstrap.android.util.permissions.PermissionActivity import com.rootstrap.android.util.permissions.PermissionResponse -import kotlinx.android.synthetic.main.activity_sign_in.* class SignInActivity : PermissionActivity(), AuthView { private lateinit var viewModel: SignInActivityViewModel + private lateinit var binding: ActivitySignInBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + binding = ActivitySignInBinding.inflate(layoutInflater) + setContentView(R.layout.activity_sign_in) Analytics.track(PageEvents.visit(VISIT_SIGN_IN)) val factory = SignInActivityViewModelFactory(viewModelListener) - viewModel = ViewModelProviders.of(this, factory) + viewModel = ViewModelProvider(this, factory) .get(SignInActivityViewModel::class.java) - sign_in_button.setOnClickListener { signIn() } + binding.signInButton.setOnClickListener { signIn() } lifecycle.addObserver(viewModel) @@ -41,11 +44,13 @@ class SignInActivity : PermissionActivity(), AuthView { } private fun signIn() { - val user = User( - email = email_edit_text.value(), - password = password_edit_text.value() - ) - viewModel.signIn(user) + with(binding) { + val user = User( + email = emailEditText.value(), + password = passwordEditText.value() + ) + viewModel.signIn(user) + } } // ViewModelListener @@ -68,7 +73,7 @@ class SignInActivity : PermissionActivity(), AuthView { } } - fun sampleAskForPermission() { + private fun sampleAskForPermission() { requestPermission(arrayOf(Manifest.permission.CAMERA), object : PermissionResponse { override fun granted() { // TODO.. diff --git a/app/src/main/java/com/rootstrap/android/ui/activity/main/SignUpActivity.kt b/app/src/main/java/com/rootstrap/android/ui/activity/main/SignUpActivity.kt index 9a131be..9f9f01f 100644 --- a/app/src/main/java/com/rootstrap/android/ui/activity/main/SignUpActivity.kt +++ b/app/src/main/java/com/rootstrap/android/ui/activity/main/SignUpActivity.kt @@ -2,8 +2,9 @@ package com.rootstrap.android.ui.activity.main import android.content.Intent import android.os.Bundle -import androidx.lifecycle.ViewModelProviders +import androidx.lifecycle.ViewModelProvider import com.rootstrap.android.R +import com.rootstrap.android.databinding.ActivitySignUpBinding import com.rootstrap.android.metrics.Analytics import com.rootstrap.android.metrics.PageEvents import com.rootstrap.android.metrics.VISIT_SIGN_UP @@ -13,24 +14,27 @@ import com.rootstrap.android.ui.view.AuthView import com.rootstrap.android.util.NetworkState import com.rootstrap.android.util.ViewModelListener import com.rootstrap.android.util.extensions.value -import kotlinx.android.synthetic.main.activity_sign_up.* class SignUpActivity : BaseActivity(), AuthView { private lateinit var viewModel: SignUpActivityViewModel + private lateinit var binding: ActivitySignUpBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_sign_up) + binding = ActivitySignUpBinding.inflate(layoutInflater) + + setContentView(binding.root) Analytics.track(PageEvents.visit(VISIT_SIGN_UP)) val factory = SignUpActivityViewModelFactory(viewModelListener) - viewModel = ViewModelProviders.of(this, factory) + viewModel = ViewModelProvider(this, factory) .get(SignUpActivityViewModel::class.java) - sign_up_button.setOnClickListener { signUp() } - sign_in_text_view.setOnClickListener { startActivity(Intent(this, SignInActivity::class.java)) } - + with(binding) { + signUpButton.setOnClickListener { signUp() } + signInTextView.setOnClickListener { signIn() } + } lifecycle.addObserver(viewModel) } @@ -38,14 +42,20 @@ class SignUpActivity : BaseActivity(), AuthView { startActivityClearTask(ProfileActivity()) } + private fun signIn() { + startActivity(Intent(this, SignInActivity::class.java)) + } + private fun signUp() { - val user = User( - email = email_edit_text.value(), - firstName = first_name_edit_text.value(), - lastName = last_name_edit_text.value(), - password = password_edit_text.value() - ) - viewModel.signUp(user) + with(binding) { + val user = User( + email = emailEditText.value(), + firstName = firstNameEditText.value(), + lastName = lastNameEditText.value(), + password = passwordEditText.value() + ) + viewModel.signUp(user) + } } // ViewModelListener diff --git a/app/src/main/java/com/rootstrap/android/ui/base/BaseActivity.kt b/app/src/main/java/com/rootstrap/android/ui/base/BaseActivity.kt index b0cf488..4b3765a 100644 --- a/app/src/main/java/com/rootstrap/android/ui/base/BaseActivity.kt +++ b/app/src/main/java/com/rootstrap/android/ui/base/BaseActivity.kt @@ -2,47 +2,23 @@ package com.rootstrap.android.ui.base import android.annotation.SuppressLint import android.app.Activity -import android.app.AlertDialog import android.content.Intent import androidx.appcompat.app.AppCompatActivity -import com.rootstrap.android.R -import com.rootstrap.android.ui.custom.LoadingDialog +import com.rootstrap.android.util.LoadingDialogUtil @SuppressLint("Registered") open class BaseActivity : AppCompatActivity(), BaseView { - private var loadingDialog: LoadingDialog? = null - override fun showProgress() { - if (loadingDialog == null) { - loadingDialog = LoadingDialog(this, null) - } - - loadingDialog!!.show() + LoadingDialogUtil.showProgress(this) } override fun hideProgress() { - if (loadingDialog != null) { - loadingDialog!!.dismiss() - } + LoadingDialogUtil.hideProgress() } override fun showError(message: String?) { - val builder = AlertDialog.Builder(this) - builder.setTitle(getString(R.string.error)) - - when (message) { - "" -> builder.setMessage(getString(R.string.generic_error)) - null -> builder.setMessage(getString(R.string.generic_error)) - else -> builder.setMessage(message) - } - - builder.setPositiveButton(getString(R.string.ok)) { dialog, _ -> - dialog.cancel() - } - - val dialog: AlertDialog = builder.create() - dialog.show() + LoadingDialogUtil.showError(message, this) } protected fun startActivityClearTask(activity: Activity) { diff --git a/app/src/main/java/com/rootstrap/android/ui/base/BaseFragment.kt b/app/src/main/java/com/rootstrap/android/ui/base/BaseFragment.kt index aa6c60d..863b49e 100644 --- a/app/src/main/java/com/rootstrap/android/ui/base/BaseFragment.kt +++ b/app/src/main/java/com/rootstrap/android/ui/base/BaseFragment.kt @@ -1,18 +1,19 @@ package com.rootstrap.android.ui.base import androidx.fragment.app.Fragment +import com.rootstrap.android.util.LoadingDialogUtil open class BaseFragment : Fragment(), BaseView { override fun showProgress() { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. + LoadingDialogUtil.showProgress(requireContext()) } override fun hideProgress() { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. + LoadingDialogUtil.hideProgress() } override fun showError(message: String?) { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. + LoadingDialogUtil.showError(message, requireContext()) } } diff --git a/app/src/main/java/com/rootstrap/android/util/LoadingDialogUtil.kt b/app/src/main/java/com/rootstrap/android/util/LoadingDialogUtil.kt new file mode 100644 index 0000000..810851f --- /dev/null +++ b/app/src/main/java/com/rootstrap/android/util/LoadingDialogUtil.kt @@ -0,0 +1,42 @@ +package com.rootstrap.android.util + +import android.app.AlertDialog +import android.content.Context +import com.rootstrap.android.R +import com.rootstrap.android.ui.custom.LoadingDialog + +object LoadingDialogUtil { + + private var loadingDialog: LoadingDialog? = null + + fun showProgress(context: Context) { + if (loadingDialog == null) { + loadingDialog = LoadingDialog(context, null) + } + + loadingDialog?.show() + } + + fun hideProgress() { + loadingDialog?.run { dismiss() } + } + + fun showError(message: String?, context: Context) { + val builder = AlertDialog.Builder(context) + with(builder) { + setTitle(context.getString(R.string.error)) + + val showMessage = if (message.isNullOrEmpty()) + context.getString(R.string.generic_error) + else message + + setMessage(showMessage) + + setPositiveButton(context.getString(R.string.ok)) { dialog, _ -> + dialog.cancel() + } + val dialog: AlertDialog = create() + dialog.show() + } + } +} diff --git a/build.gradle b/build.gradle index eba192c..991aa38 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.3.61' + ext.kotlin_version = '1.3.72' repositories { google() jcenter() @@ -11,10 +11,10 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.5.3' + classpath 'com.android.tools.build:gradle:4.1.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath 'com.google.gms:google-services:4.3.3' - classpath 'io.fabric.tools:gradle:1.31.2' // Crashlytics plugin + classpath 'com.google.gms:google-services:4.3.4' + classpath 'com.google.firebase:firebase-crashlytics-gradle:2.4.1' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 62f7a0c..e7b189d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Apr 22 13:26:09 UYT 2020 +#Mon Jan 18 09:20:52 ART 2021 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.2.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip