From 1b00d7d40dd413eaa71fecbf90e0d1313cb13bcf Mon Sep 17 00:00:00 2001 From: hmalik144 Date: Fri, 24 Mar 2023 19:15:48 +0000 Subject: [PATCH] - android bumblebee gradle migration - lint driverDebug - view binding migration Took 12 hours 10 minutes --- app/build.gradle | 31 ++--- .../appttude/com/objects/ApprovalsObject.kt | 1 - .../h_mal/appttude/com/objects/UserObject.kt | 1 - .../com/objects/wholeObject/MappedObject.kt | 15 ++- .../appttude/com/ui/ApprovalListAdapter.kt | 2 +- .../appttude/com/ui/HomeSuperUserFragment.kt | 4 +- .../h_mal/appttude/com/ui/MainActivity.kt | 6 +- .../res/layout/approval_list_grid_item.xml | 5 +- .../admin/res/layout/fragment_user_main.xml | 2 +- app/src/admin/res/layout/list_item_layout.xml | 1 + .../java/h_mal/appttude/com/BaseTestRobot.kt | 11 +- .../java/h_mal/appttude/com/BaseUiTest.kt | 2 +- .../java/h_mal/appttude/com/Constants.kt | 3 +- .../h_mal/appttude/com/CustomViewMatchers.kt | 1 + .../java/h_mal/appttude/com/FirebaseTest.kt | 9 +- .../appttude/com/firebase/SignUpResponse.kt | 12 +- .../h_mal/appttude/com/robots/HomeRobot.kt | 2 +- .../h_mal/appttude/com/robots/LoginRobot.kt | 2 +- .../appttude/com/robots/RegisterRobot.kt | 2 +- ...egisteredUserAuthenticationActivityTest.kt | 4 +- app/src/debug/AndroidManifest.xml | 4 +- .../debug/res/xml/network_security_config.xml | 2 +- app/src/driver/AndroidManifest.xml | 4 +- .../appttude/com/ui/DriverOverallFragment.kt | 35 +++-- .../h_mal/appttude/com/ui/HomeFragment.kt | 46 +++---- .../h_mal/appttude/com/ui/MainActivity.kt | 75 ++++++----- .../appttude/com/ui/VehicleOverallFragment.kt | 29 +++-- .../h_mal/appttude/com/ui/WelcomeFragment.kt | 22 ++-- .../ui/driverprofile/DriverLicenseFragment.kt | 63 +++++---- .../ui/driverprofile/DriverProfileFragment.kt | 91 +++++++------ .../PrivateHireLicenseFragment.kt | 52 ++++---- .../ui/vehicleprofile/InsuranceFragment.kt | 65 ++++----- .../com/ui/vehicleprofile/LogbookFragment.kt | 49 ++++--- .../com/ui/vehicleprofile/MotFragment.kt | 46 +++---- .../PrivateHireVehicleFragment.kt | 53 ++++---- .../vehicleprofile/VehicleProfileFragment.kt | 75 +++++------ .../driver/res/layout/fragment_welcome.xml | 4 +- .../appttude/com/Archive/ArchiveFragment.kt | 23 +--- .../com/Archive/ArchiveObjectListAdapter.kt | 7 +- .../ApplicationViewModelFactory.kt | 57 ++++++-- .../com/application/DriverApplication.kt | 2 +- .../h_mal/appttude/com/base/BaseActivity.kt | 63 +++++++-- .../h_mal/appttude/com/base/BaseFragment.kt | 77 +++++++++-- .../h_mal/appttude/com/base/BaseViewModel.kt | 6 +- .../com/base/DataSubmissionBaseFragment.kt | 28 ++-- .../com/base/DataSubmissionBaseViewModel.kt | 21 ++- .../h_mal/appttude/com/data/DataFieldState.kt | 7 - .../h_mal/appttude/com/data/EventResponse.kt | 4 +- .../appttude/com/data/FirebaseAuthSource.kt | 16 ++- ...veData.kt => FirebaseAuthStateLiveData.kt} | 9 +- .../com/data/FirebaseAuthentication.kt | 6 +- .../appttude/com/data/FirebaseCompletion.kt | 8 +- .../com/data/FirebaseDatabaseSource.kt | 15 ++- .../com/data/FirebaseStorageSource.kt | 8 +- .../h_mal/appttude/com/dialogs/DateDialog.kt | 17 ++- .../h_mal/appttude/com/dialogs/ExitDialog.kt | 27 ++-- ...riverProfileObject.kt => DriverProfile.kt} | 4 +- ...versLicenseObject.kt => DriversLicense.kt} | 2 +- .../{InsuranceObject.kt => Insurance.kt} | 4 +- .../model/{LogbookObject.kt => Logbook.kt} | 3 +- .../com/model/{MotObject.kt => Mot.kt} | 3 +- ...ateHireObject.kt => PrivateHireLicense.kt} | 3 +- ...VehicleObject.kt => PrivateHireVehicle.kt} | 3 +- ...icleProfileObject.kt => VehicleProfile.kt} | 3 +- .../com/ui/update/DeleteProfileFragment.kt | 28 ++-- .../appttude/com/ui/update/UpdateActivity.kt | 15 +-- .../com/ui/update/UpdateEmailFragment.kt | 32 ++--- .../com/ui/update/UpdateOverviewFragment.kt | 30 ++--- .../com/ui/update/UpdatePasswordFragment.kt | 32 ++--- .../com/ui/update/UpdateProfileFragment.kt | 50 ++++--- .../com/ui/user/ForgotPasswordFragment.kt | 21 +-- .../appttude/com/ui/user/LoginActivity.kt | 13 +- .../appttude/com/ui/user/LoginFragment.kt | 33 ++--- .../appttude/com/ui/user/RegisterFragment.kt | 43 +++--- .../com/ui/user/SplashScreenFragment.kt | 9 +- .../appttude/com/utils/AnimationUtils.kt | 2 +- .../h_mal/appttude/com/utils/Coroutines.kt | 2 +- .../h_mal/appttude/com/utils/DateUtils.kt | 4 +- .../h_mal/appttude/com/utils/Extensions.kt | 16 +++ .../h_mal/appttude/com/utils/FirebaseUtils.kt | 18 ++- .../appttude/com/utils/NavigationUtils.kt | 2 +- .../h_mal/appttude/com/utils/ViewUtils.kt | 1 + .../com/viewmodels/DriverLicenseViewModel.kt | 10 +- .../com/viewmodels/DriverProfileViewModel.kt | 10 +- .../com/viewmodels/InsuranceViewModel.kt | 16 +-- .../com/viewmodels/LogbookViewModel.kt | 10 +- .../appttude/com/viewmodels/MainViewModel.kt | 18 +-- .../appttude/com/viewmodels/MotViewModel.kt | 12 +- .../viewmodels/PrivateHireLicenseViewModel.kt | 12 +- .../viewmodels/PrivateHireVehicleViewModel.kt | 10 +- .../com/viewmodels/VehicleProfileViewModel.kt | 12 +- .../main/res/drawable-v21/cardviewoutline.xml | 7 - app/src/main/res/drawable/cardviewoutline.xml | 13 ++ .../res/drawable/ic_archive_black_24dp.xml | 10 +- .../drawable/ic_baseline_arrow_forward_24.xml | 13 +- .../ic_baseline_assignment_ind_24.xml | 13 +- .../drawable/ic_baseline_photo_library_24.xml | 13 +- .../drawable/ic_file_download_black_24dp.xml | 10 +- .../res/drawable/ic_settings_black_24dp.xml | 12 +- .../main/res/drawable/ic_sort_black_24dp.xml | 10 +- .../round_edit_text.xml | 5 +- app/src/main/res/layout/activity_login.xml | 8 +- app/src/main/res/layout/activity_main.xml | 6 +- app/src/main/res/layout/address_dialog.xml | 16 ++- .../main/res/layout/carousal_image_cell.xml | 2 +- .../res/layout/driver_profile_request.xml | 5 +- .../res/layout/fragment_driver_license.xml | 123 +++++++++--------- .../main/res/layout/fragment_image_viewer.xml | 10 +- app/src/main/res/layout/fragment_mot.xml | 2 +- .../res/layout/fragment_splash_screen.xml | 1 - .../main/res/layout/fragment_update_email.xml | 6 +- .../res/layout/fragment_vehicle_setup.xml | 26 ++-- .../res/layout/home_buttons_container.xml | 6 +- .../main/res/layout/multi_image_selector.xml | 1 + app/src/main/res/layout/splash_screen.xml | 18 +++ app/src/main/res/layout/update_activity.xml | 3 +- .../res/layout/update_overview_fragment.xml | 8 +- .../main/res/navigation/auth_navigation.xml | 8 +- .../main/res/navigation/main_navigation.xml | 28 ++-- .../main/res/navigation/update_navigation.xml | 12 +- app/src/main/res/values/strings.xml | 6 + app/src/main/res/values/styles.xml | 4 +- app/src/main/res/xml/file_paths.xml | 4 +- build.gradle | 31 ++--- settings.gradle | 18 +++ 125 files changed, 1163 insertions(+), 1013 deletions(-) delete mode 100644 app/src/main/java/h_mal/appttude/com/data/DataFieldState.kt rename app/src/main/java/h_mal/appttude/com/data/{FirebaseLiveData.kt => FirebaseAuthStateLiveData.kt} (82%) rename app/src/main/java/h_mal/appttude/com/model/{DriverProfileObject.kt => DriverProfile.kt} (87%) rename app/src/main/java/h_mal/appttude/com/model/{DriversLicenseObject.kt => DriversLicense.kt} (82%) rename app/src/main/java/h_mal/appttude/com/model/{InsuranceObject.kt => Insurance.kt} (83%) rename app/src/main/java/h_mal/appttude/com/model/{LogbookObject.kt => Logbook.kt} (80%) rename app/src/main/java/h_mal/appttude/com/model/{MotObject.kt => Mot.kt} (81%) rename app/src/main/java/h_mal/appttude/com/model/{PrivateHireObject.kt => PrivateHireLicense.kt} (81%) rename app/src/main/java/h_mal/appttude/com/model/{PrivateHireVehicleObject.kt => PrivateHireVehicle.kt} (81%) rename app/src/main/java/h_mal/appttude/com/model/{VehicleProfileObject.kt => VehicleProfile.kt} (90%) create mode 100644 app/src/main/java/h_mal/appttude/com/utils/Extensions.kt delete mode 100644 app/src/main/res/drawable-v21/cardviewoutline.xml create mode 100644 app/src/main/res/drawable/cardviewoutline.xml rename app/src/main/res/{drawable-v21 => drawable}/round_edit_text.xml (65%) create mode 100644 app/src/main/res/layout/splash_screen.xml diff --git a/app/build.gradle b/app/build.gradle index f78d18f..04cbb6a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,16 +1,9 @@ -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' -apply plugin: 'kotlin-android-extensions' - -apply plugin: 'com.google.gms.google-services' - -// kotlin kapt -apply plugin: 'kotlin-kapt' -// Android navigation -apply plugin: 'androidx.navigation.safeargs' - -repositories { - mavenCentral() +plugins { + id 'com.android.application' + id 'org.jetbrains.kotlin.android' + id 'com.google.gms.google-services' + id 'kotlin-kapt' + id 'androidx.navigation.safeargs' } def relStorePassword = System.getenv("RELEASE_STORE_PASSWORD") @@ -59,10 +52,16 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } - + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } kotlinOptions { jvmTarget = "1.8" } + buildFeatures { + viewBinding true + } flavorDimensions "Default" productFlavors { @@ -139,7 +138,7 @@ dependencies { / * coroutines support for firebase operations */ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.6.1" / * Circle Image View */ - implementation "com.mikhaellopez:circularimageview:4.2.0" + implementation "com.mikhaellopez:circularimageview:4.3.0" / * Kodein Dependency Injection */ def kodein_version = "6.2.1" implementation "org.kodein.di:kodein-di-generic-jvm:$kodein_version" @@ -151,4 +150,6 @@ dependencies { annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0' / * OKHttp */ implementation 'com.squareup.okhttp3:okhttp:4.10.0' + / * Kotlin Reflect */ + implementation "org.jetbrains.kotlin:kotlin-reflect:1.8.10" } diff --git a/app/src/admin/java/h_mal/appttude/com/objects/ApprovalsObject.kt b/app/src/admin/java/h_mal/appttude/com/objects/ApprovalsObject.kt index a43fc28..bd9cadd 100644 --- a/app/src/admin/java/h_mal/appttude/com/objects/ApprovalsObject.kt +++ b/app/src/admin/java/h_mal/appttude/com/objects/ApprovalsObject.kt @@ -1,7 +1,6 @@ package h_mal.appttude.com.objects - class ApprovalsObject { var driver_details_approval: Int = 0 var driver_license_approval: Int = 0 diff --git a/app/src/admin/java/h_mal/appttude/com/objects/UserObject.kt b/app/src/admin/java/h_mal/appttude/com/objects/UserObject.kt index cf4c542..49f47a6 100644 --- a/app/src/admin/java/h_mal/appttude/com/objects/UserObject.kt +++ b/app/src/admin/java/h_mal/appttude/com/objects/UserObject.kt @@ -1,7 +1,6 @@ package h_mal.appttude.com.objects - class UserObject { var profileName: String? = null var profileEmail: String? = null diff --git a/app/src/admin/java/h_mal/appttude/com/objects/wholeObject/MappedObject.kt b/app/src/admin/java/h_mal/appttude/com/objects/wholeObject/MappedObject.kt index 096d8ef..8a5cef2 100644 --- a/app/src/admin/java/h_mal/appttude/com/objects/wholeObject/MappedObject.kt +++ b/app/src/admin/java/h_mal/appttude/com/objects/wholeObject/MappedObject.kt @@ -29,14 +29,15 @@ class MappedObject : Parcelable { companion object { @JvmField - val CREATOR: Parcelable.Creator = object : Parcelable.Creator { - override fun createFromParcel(`in`: Parcel): MappedObject? { - return MappedObject(`in`) - } + val CREATOR: Parcelable.Creator = + object : Parcelable.Creator { + override fun createFromParcel(`in`: Parcel): MappedObject? { + return MappedObject(`in`) + } - override fun newArray(size: Int): Array { - return arrayOfNulls(size) + override fun newArray(size: Int): Array { + return arrayOfNulls(size) + } } - } } } \ No newline at end of file diff --git a/app/src/admin/java/h_mal/appttude/com/ui/ApprovalListAdapter.kt b/app/src/admin/java/h_mal/appttude/com/ui/ApprovalListAdapter.kt index e54e2c3..a4bf99f 100644 --- a/app/src/admin/java/h_mal/appttude/com/ui/ApprovalListAdapter.kt +++ b/app/src/admin/java/h_mal/appttude/com/ui/ApprovalListAdapter.kt @@ -12,7 +12,7 @@ import h_mal.appttude.com.R class ApprovalListAdapter( private val activity: Activity, objects: Array -): ArrayAdapter(activity, 0, objects) { +) : ArrayAdapter(activity, 0, objects) { var mappedObject: MappedObject? = objects[0] diff --git a/app/src/admin/java/h_mal/appttude/com/ui/HomeSuperUserFragment.kt b/app/src/admin/java/h_mal/appttude/com/ui/HomeSuperUserFragment.kt index 4fb061e..257e620 100644 --- a/app/src/admin/java/h_mal/appttude/com/ui/HomeSuperUserFragment.kt +++ b/app/src/admin/java/h_mal/appttude/com/ui/HomeSuperUserFragment.kt @@ -125,7 +125,9 @@ class HomeSuperUserFragment : Fragment() { } return s1!!.compareTo((s2)!!) } - else -> { throw IOException("dfdfs") } + else -> { + throw IOException("dfdfs") + } // 2 -> return MainActivity.approvalsClass.getOverApprovalStatusCode(o1.wholeDriverObject) - // MainActivity.approvalsClass.getOverApprovalStatusCode(o2.wholeDriverObject) // else -> return MainActivity.approvalsClass.getOverApprovalStatusCode( diff --git a/app/src/admin/java/h_mal/appttude/com/ui/MainActivity.kt b/app/src/admin/java/h_mal/appttude/com/ui/MainActivity.kt index 07d6abe..2a3ac76 100644 --- a/app/src/admin/java/h_mal/appttude/com/ui/MainActivity.kt +++ b/app/src/admin/java/h_mal/appttude/com/ui/MainActivity.kt @@ -70,7 +70,7 @@ class MainActivity : BaseActivity(), override fun onSuccess(data: Any?) { super.onSuccess(data) - when(data){ + when (data) { is FirebaseUser -> { setupDrawer(data) } @@ -84,7 +84,7 @@ class MainActivity : BaseActivity(), header.profileImage.setGlideImage(user.photoUrl) } - private fun setupLogoutInDrawer(){ + private fun setupLogoutInDrawer() { logout.setOnClickListener { getViewModel().logOut() } @@ -93,7 +93,7 @@ class MainActivity : BaseActivity(), override fun onNavigationItemSelected(item: MenuItem): Boolean { // Handle navigation view item clicks here. when (item.itemId) { - R.id.nav_user_settings -> { } + R.id.nav_user_settings -> {} } drawer_layout.closeDrawer(GravityCompat.START) return true diff --git a/app/src/admin/res/layout/approval_list_grid_item.xml b/app/src/admin/res/layout/approval_list_grid_item.xml index 078971c..3eef1e4 100644 --- a/app/src/admin/res/layout/approval_list_grid_item.xml +++ b/app/src/admin/res/layout/approval_list_grid_item.xml @@ -18,7 +18,8 @@ + android:src="@drawable/cardviewoutline" /> + @@ -75,7 +76,7 @@ + android:layout_gravity="center" /> + tools:listitem="@layout/approval_list_grid_item" /> \ No newline at end of file diff --git a/app/src/admin/res/layout/list_item_layout.xml b/app/src/admin/res/layout/list_item_layout.xml index a123bb7..c7446e5 100644 --- a/app/src/admin/res/layout/list_item_layout.xml +++ b/app/src/admin/res/layout/list_item_layout.xml @@ -21,6 +21,7 @@ app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" tools:src="@drawable/choice_img_round" /> + >( +open class BaseUiTest>( private val activity: Class ) { diff --git a/app/src/androidTest/java/h_mal/appttude/com/Constants.kt b/app/src/androidTest/java/h_mal/appttude/com/Constants.kt index c450d71..f13c1c1 100644 --- a/app/src/androidTest/java/h_mal/appttude/com/Constants.kt +++ b/app/src/androidTest/java/h_mal/appttude/com/Constants.kt @@ -3,7 +3,8 @@ package h_mal.appttude.com private const val apiKey = "test_key" const val signUpFirebase = "http://identitytoolkit.googleapis.com/v1/accounts:signUp?key=$apiKey" -const val deleteAccountFirebase = "http://10.0.2.2:9099/identitytoolkit.googleapis.com/v1/accounts:delete?key=$apiKey" +const val deleteAccountFirebase = + "http://10.0.2.2:9099/identitytoolkit.googleapis.com/v1/accounts:delete?key=$apiKey" const val USER_PASSWORD = "LetMeIn123!" \ No newline at end of file diff --git a/app/src/androidTest/java/h_mal/appttude/com/CustomViewMatchers.kt b/app/src/androidTest/java/h_mal/appttude/com/CustomViewMatchers.kt index 1ab7048..46f9c13 100644 --- a/app/src/androidTest/java/h_mal/appttude/com/CustomViewMatchers.kt +++ b/app/src/androidTest/java/h_mal/appttude/com/CustomViewMatchers.kt @@ -23,6 +23,7 @@ fun checkErrorMessage(expectedErrorText: String): Matcher? { val error = view.error ?: return false return expectedErrorText == error.toString() } + override fun describeTo(d: Description?) {} } } diff --git a/app/src/androidTest/java/h_mal/appttude/com/FirebaseTest.kt b/app/src/androidTest/java/h_mal/appttude/com/FirebaseTest.kt index 3204a87..95d0888 100644 --- a/app/src/androidTest/java/h_mal/appttude/com/FirebaseTest.kt +++ b/app/src/androidTest/java/h_mal/appttude/com/FirebaseTest.kt @@ -10,7 +10,7 @@ import kotlinx.coroutines.tasks.await import org.junit.After import org.junit.BeforeClass -open class FirebaseTest>( +open class FirebaseTest>( activity: Class, private val registered: Boolean = false, private val signedIn: Boolean = false @@ -62,7 +62,10 @@ open class FirebaseTest>( suspend fun removeUser() { try { getEmail()?.let { - if (firebaseAuthSource.getUser() == null) firebaseAuthSource.signIn(email = it, password = USER_PASSWORD).await() + if (firebaseAuthSource.getUser() == null) firebaseAuthSource.signIn( + email = it, + password = USER_PASSWORD + ).await() firebaseAuthSource.reauthenticate(it, USER_PASSWORD).await() firebaseAuthSource.deleteProfile().await() } @@ -74,7 +77,7 @@ open class FirebaseTest>( fun generateEmailAddress(): String { val suffix = (1000..50000).random() - email ="test-${suffix}@test-account.com" + email = "test-${suffix}@test-account.com" return email!! } diff --git a/app/src/androidTest/java/h_mal/appttude/com/firebase/SignUpResponse.kt b/app/src/androidTest/java/h_mal/appttude/com/firebase/SignUpResponse.kt index 1fe472b..5e0d8f8 100644 --- a/app/src/androidTest/java/h_mal/appttude/com/firebase/SignUpResponse.kt +++ b/app/src/androidTest/java/h_mal/appttude/com/firebase/SignUpResponse.kt @@ -1,10 +1,10 @@ package h_mal.appttude.com.firebase data class SignUpResponse( - val expiresIn: String? = null, - val kind: String? = null, - val idToken: String? = null, - val localId: String? = null, - val email: String? = null, - val refreshToken: String? = null + val expiresIn: String? = null, + val kind: String? = null, + val idToken: String? = null, + val localId: String? = null, + val email: String? = null, + val refreshToken: String? = null ) \ No newline at end of file diff --git a/app/src/androidTestDriver/java/h_mal/appttude/com/robots/HomeRobot.kt b/app/src/androidTestDriver/java/h_mal/appttude/com/robots/HomeRobot.kt index 9352c53..feff2b9 100644 --- a/app/src/androidTestDriver/java/h_mal/appttude/com/robots/HomeRobot.kt +++ b/app/src/androidTestDriver/java/h_mal/appttude/com/robots/HomeRobot.kt @@ -4,7 +4,7 @@ import h_mal.appttude.com.BaseTestRobot import h_mal.appttude.com.R fun home(func: HomeRobot.() -> Unit) = HomeRobot().apply { func() } -class HomeRobot: BaseTestRobot() { +class HomeRobot : BaseTestRobot() { fun checkTitleExists(title: String) = matchText(R.id.prova_title_tv, title) diff --git a/app/src/androidTestDriver/java/h_mal/appttude/com/robots/LoginRobot.kt b/app/src/androidTestDriver/java/h_mal/appttude/com/robots/LoginRobot.kt index 5eb19bb..74ce0b1 100644 --- a/app/src/androidTestDriver/java/h_mal/appttude/com/robots/LoginRobot.kt +++ b/app/src/androidTestDriver/java/h_mal/appttude/com/robots/LoginRobot.kt @@ -5,7 +5,7 @@ import h_mal.appttude.com.R fun login(func: LoginRobot.() -> Unit) = LoginRobot().apply { func() } -class LoginRobot: BaseTestRobot() { +class LoginRobot : BaseTestRobot() { fun setEmail(email: String?) = fillEditText(R.id.email, email) diff --git a/app/src/androidTestDriver/java/h_mal/appttude/com/robots/RegisterRobot.kt b/app/src/androidTestDriver/java/h_mal/appttude/com/robots/RegisterRobot.kt index b714199..ee28670 100644 --- a/app/src/androidTestDriver/java/h_mal/appttude/com/robots/RegisterRobot.kt +++ b/app/src/androidTestDriver/java/h_mal/appttude/com/robots/RegisterRobot.kt @@ -4,7 +4,7 @@ import h_mal.appttude.com.BaseTestRobot import h_mal.appttude.com.R fun register(func: RegisterRobot.() -> Unit) = RegisterRobot().apply { func() } -class RegisterRobot: BaseTestRobot() { +class RegisterRobot : BaseTestRobot() { fun setName(name: String) = fillEditText(R.id.name_register, name) diff --git a/app/src/androidTestDriver/java/h_mal/appttude/com/tests/RegisteredUserAuthenticationActivityTest.kt b/app/src/androidTestDriver/java/h_mal/appttude/com/tests/RegisteredUserAuthenticationActivityTest.kt index 2133703..a0668e3 100644 --- a/app/src/androidTestDriver/java/h_mal/appttude/com/tests/RegisteredUserAuthenticationActivityTest.kt +++ b/app/src/androidTestDriver/java/h_mal/appttude/com/tests/RegisteredUserAuthenticationActivityTest.kt @@ -8,7 +8,6 @@ import h_mal.appttude.com.R import h_mal.appttude.com.USER_PASSWORD import h_mal.appttude.com.robots.home import h_mal.appttude.com.robots.login -import h_mal.appttude.com.robots.register import h_mal.appttude.com.ui.user.LoginActivity import org.junit.* import org.junit.runner.RunWith @@ -16,7 +15,8 @@ import org.junit.runner.RunWith @LargeTest @RunWith(AndroidJUnit4::class) -class RegisteredUserAuthenticationActivityTest : FirebaseTest(LoginActivity::class.java, registered = true, signedIn = false) { +class RegisteredUserAuthenticationActivityTest : + FirebaseTest(LoginActivity::class.java, registered = true, signedIn = false) { @Test fun verifyUserLogin_validUsernameAndPassword_loggedIn() { diff --git a/app/src/debug/AndroidManifest.xml b/app/src/debug/AndroidManifest.xml index 118af13..8451b0c 100644 --- a/app/src/debug/AndroidManifest.xml +++ b/app/src/debug/AndroidManifest.xml @@ -1,7 +1,9 @@ + - \ No newline at end of file diff --git a/app/src/debug/res/xml/network_security_config.xml b/app/src/debug/res/xml/network_security_config.xml index 17abf3a..eb7159c 100644 --- a/app/src/debug/res/xml/network_security_config.xml +++ b/app/src/debug/res/xml/network_security_config.xml @@ -1,6 +1,6 @@ - 10.0.2.2 + 10.0.2.2 \ No newline at end of file diff --git a/app/src/driver/AndroidManifest.xml b/app/src/driver/AndroidManifest.xml index 7f36feb..813f6df 100644 --- a/app/src/driver/AndroidManifest.xml +++ b/app/src/driver/AndroidManifest.xml @@ -1,7 +1,8 @@ - + (R.layout.fragment_home_driver) { +class HomeFragment : + DataSubmissionBaseFragment() { - private val viewmodel: RoleViewModel by getFragmentViewModel() - override fun getViewModel(): RoleViewModel = viewmodel override var model = String() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - viewmodel.getDataFromDatabase() + viewModel.getDataFromDatabase() } override fun onSuccess(data: Any?) { super.onSuccess(data) - if (data == DRIVER){ + if (data == DRIVER) { loadDriver() return } loadNonDriver() } - private fun loadNonDriver(){ - home_buttons_container.hide() - profile_request_container.show() + private fun loadNonDriver() { + applyBinding { + homeButtonsContainer.root.hide() + profileRequestContainer.root.show() - request_driver_button.setOnClickListener { - viewmodel.setDataInDatabase(DRIVER) + profileRequestContainer.requestDriverButton.setOnClickListener { + viewModel.setDataInDatabase(DRIVER) + } } } - private fun loadDriver(){ - home_buttons_container.show() - profile_request_container.hide() - - driver.setOnClickListener { - view?.navigateTo(R.id.to_driverOverallFragment) - } - car.setOnClickListener { - view?.navigateTo(R.id.to_vehicleOverallFragment) + private fun loadDriver() { + applyBinding { + homeButtonsContainer.apply { + driver.setOnClickListener { + view?.navigateTo(R.id.to_driverOverallFragment) + } + car.setOnClickListener { + view?.navigateTo(R.id.to_vehicleOverallFragment) + } + root.show() + } + profileRequestContainer.root.hide() } } diff --git a/app/src/driver/java/h_mal/appttude/com/ui/MainActivity.kt b/app/src/driver/java/h_mal/appttude/com/ui/MainActivity.kt index 07d6abe..7b49ae5 100644 --- a/app/src/driver/java/h_mal/appttude/com/ui/MainActivity.kt +++ b/app/src/driver/java/h_mal/appttude/com/ui/MainActivity.kt @@ -1,9 +1,7 @@ package h_mal.appttude.com.ui -import android.os.Bundle import android.view.MenuItem -import android.view.View import androidx.core.view.GravityCompat import androidx.navigation.NavController import androidx.navigation.findNavController @@ -15,36 +13,30 @@ import com.google.android.material.navigation.NavigationView import com.google.firebase.auth.FirebaseUser import h_mal.appttude.com.R import h_mal.appttude.com.base.BaseActivity +import h_mal.appttude.com.databinding.ActivityMainBinding +import h_mal.appttude.com.databinding.NavHeaderMainBinding import h_mal.appttude.com.dialogs.ExitDialog.displayExitDialog +import h_mal.appttude.com.utils.isTrue import h_mal.appttude.com.utils.setGlideImage import h_mal.appttude.com.viewmodels.MainViewModel -import kotlinx.android.synthetic.main.activity_main.* -import kotlinx.android.synthetic.main.app_bar_main.* -import kotlinx.android.synthetic.main.nav_header_main.view.* -class MainActivity : BaseActivity(), +class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedListener { - private val vm by createLazyViewModel() - override fun getViewModel(): MainViewModel = vm - override val layoutId: Int = R.layout.activity_main - lateinit var navController: NavController lateinit var appBarConfiguration: AppBarConfiguration - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - setSupportActionBar(toolbar) + override fun setupView(binding: ActivityMainBinding) = binding.run { + setSupportActionBar(appBarLayout.toolbar) supportActionBar?.setDisplayShowTitleEnabled(false) navController = findNavController(R.id.container) - appBarConfiguration = AppBarConfiguration(navController.graph, drawer_layout) - nav_view.setupWithNavController(navController) + appBarConfiguration = AppBarConfiguration(navController.graph, drawerLayout) + navView.setupWithNavController(navController) setupActionBarWithNavController(navController, appBarConfiguration) - getViewModel().getUserDetails() + viewModel.getUserDetails() setupLogoutInDrawer() } @@ -53,24 +45,29 @@ class MainActivity : BaseActivity(), } override fun setTitle(title: CharSequence) { - toolbar.title = title + applyBinding { + appBarLayout.toolbar.title = title + } + } override fun onBackPressed() { - if (drawer_layout.isDrawerOpen(GravityCompat.START)) { - drawer_layout.closeDrawer(GravityCompat.START) - } else { - val navHostFragment = supportFragmentManager.findFragmentById(R.id.container) - navHostFragment?.childFragmentManager?.backStackEntryCount?.takeIf { it >= 1 }?.let { - return super.onBackPressed() + applyBinding { + if (drawerLayout.isDrawerOpen(GravityCompat.START)) { + drawerLayout.closeDrawer(GravityCompat.START) + } else { + val navHostFragment = supportFragmentManager.findFragmentById(R.id.container) + navHostFragment?.childFragmentManager?.backStackEntryCount?.let { it >= 1 }?.isTrue { + super.onBackPressed() + } + displayExitDialog() } - displayExitDialog() } } override fun onSuccess(data: Any?) { super.onSuccess(data) - when(data){ + when (data) { is FirebaseUser -> { setupDrawer(data) } @@ -78,24 +75,32 @@ class MainActivity : BaseActivity(), } private fun setupDrawer(user: FirebaseUser) { - val header: View = nav_view.getHeaderView(0) - header.driver_email.text = user.email - header.driver_name.text = user.displayName - header.profileImage.setGlideImage(user.photoUrl) + applyBinding { + NavHeaderMainBinding.inflate(layoutInflater).apply { + driverEmail.text = user.email + driverName.text = user.displayName + profileImage.setGlideImage(user.photoUrl) + } + } } - private fun setupLogoutInDrawer(){ - logout.setOnClickListener { - getViewModel().logOut() + private fun setupLogoutInDrawer() { + applyBinding { + logout.setOnClickListener { + viewModel.logOut() + } } } override fun onNavigationItemSelected(item: MenuItem): Boolean { // Handle navigation view item clicks here. when (item.itemId) { - R.id.nav_user_settings -> { } + R.id.nav_user_settings -> {} } - drawer_layout.closeDrawer(GravityCompat.START) + applyBinding { + drawerLayout.closeDrawer(GravityCompat.START) + } + return true } } \ No newline at end of file diff --git a/app/src/driver/java/h_mal/appttude/com/ui/VehicleOverallFragment.kt b/app/src/driver/java/h_mal/appttude/com/ui/VehicleOverallFragment.kt index b870659..7df8870 100644 --- a/app/src/driver/java/h_mal/appttude/com/ui/VehicleOverallFragment.kt +++ b/app/src/driver/java/h_mal/appttude/com/ui/VehicleOverallFragment.kt @@ -1,23 +1,30 @@ package h_mal.appttude.com.ui import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.fragment.app.Fragment import h_mal.appttude.com.R +import h_mal.appttude.com.databinding.FragmentVehicleOverallBinding import h_mal.appttude.com.utils.navigateTo -import kotlinx.android.synthetic.main.fragment_vehicle_overall.* -class VehicleOverallFragment : Fragment(R.layout.fragment_vehicle_overall) { +class VehicleOverallFragment : Fragment() { - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - vehicle_prof.setOnClickListener { it.navigateTo(R.id.to_vehicleSetupFragment) } - insurance.setOnClickListener { it.navigateTo(R.id.to_insuranceFragment) } - mot.setOnClickListener { it.navigateTo(R.id.to_motFragment) } - logbook.setOnClickListener { it.navigateTo(R.id.to_logbookFragment) } - private_hire_vehicle_license.setOnClickListener { it.navigateTo(R.id.to_privateHireVehicleFragment) } + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + return FragmentVehicleOverallBinding.inflate(inflater, container, false).apply { + vehicleProf.setOnClickListener { + it.navigateTo(R.id.to_vehicleSetupFragment) + } + insurance.setOnClickListener { it.navigateTo(R.id.to_insuranceFragment) } + mot.setOnClickListener { it.navigateTo(R.id.to_motFragment) } + logbook.setOnClickListener { it.navigateTo(R.id.to_logbookFragment) } + privateHireVehicleLicense.setOnClickListener { it.navigateTo(R.id.to_privateHireVehicleFragment) } + }.root } } \ No newline at end of file diff --git a/app/src/driver/java/h_mal/appttude/com/ui/WelcomeFragment.kt b/app/src/driver/java/h_mal/appttude/com/ui/WelcomeFragment.kt index a3863a7..a1dce70 100644 --- a/app/src/driver/java/h_mal/appttude/com/ui/WelcomeFragment.kt +++ b/app/src/driver/java/h_mal/appttude/com/ui/WelcomeFragment.kt @@ -1,20 +1,26 @@ package h_mal.appttude.com.ui import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.fragment.app.Fragment import h_mal.appttude.com.R +import h_mal.appttude.com.databinding.FragmentWelcomeBinding import h_mal.appttude.com.utils.navigateTo -import kotlinx.android.synthetic.driver.fragment_welcome.* -class WelcomeFragment : Fragment(R.layout.fragment_welcome) { +class WelcomeFragment : Fragment() { - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - email_sign_in_button.setOnClickListener { - view.navigateTo(R.id.to_driverOverallFragment) - } + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + return FragmentWelcomeBinding.inflate(inflater, container, false).apply { + emailSignInButton.setOnClickListener { + it.navigateTo(R.id.to_driverOverallFragment) + } + }.root } } \ No newline at end of file diff --git a/app/src/driver/java/h_mal/appttude/com/ui/driverprofile/DriverLicenseFragment.kt b/app/src/driver/java/h_mal/appttude/com/ui/driverprofile/DriverLicenseFragment.kt index a050cf6..7757c4a 100644 --- a/app/src/driver/java/h_mal/appttude/com/ui/driverprofile/DriverLicenseFragment.kt +++ b/app/src/driver/java/h_mal/appttude/com/ui/driverprofile/DriverLicenseFragment.kt @@ -1,59 +1,54 @@ package h_mal.appttude.com.ui.driverprofile import android.net.Uri -import android.os.Bundle -import android.view.View -import h_mal.appttude.com.R import h_mal.appttude.com.base.DataSubmissionBaseFragment +import h_mal.appttude.com.databinding.FragmentDriverLicenseBinding import h_mal.appttude.com.dialogs.DateDialog -import h_mal.appttude.com.model.DriversLicenseObject +import h_mal.appttude.com.model.DriversLicense +import h_mal.appttude.com.utils.isTrue import h_mal.appttude.com.utils.setGlideImage import h_mal.appttude.com.viewmodels.DriverLicenseViewModel -import kotlinx.android.synthetic.main.fragment_driver_license.* class DriverLicenseFragment : - DataSubmissionBaseFragment(R.layout.fragment_driver_license) { + DataSubmissionBaseFragment() { - private val viewmodel: DriverLicenseViewModel by getFragmentViewModel() - override fun getViewModel(): DriverLicenseViewModel = viewmodel - override var model = DriversLicenseObject() + override var model = DriversLicense() - private var imageUri: Uri? = null + override fun setupView(binding: FragmentDriverLicenseBinding) { + binding.apply { + licExpiry.apply { + setTextOnChange { model.licenseExpiry = it } + setOnClickListener { + DateDialog(this) { date -> + model.licenseExpiry = date + } + } + } + licNo.setTextOnChange { model.licenseNumber = it } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - lic_expiry.apply { - setTextOnChange { model.licenseExpiry = it } - setOnClickListener { - DateDialog(this) { date -> - model.licenseExpiry = date + searchImage.setOnClickListener { openGalleryWithPermissionRequest() } + submit.setOnClickListener { + validateEditTexts(licExpiry, licNo).isTrue { + viewModel.setDataInDatabase(model, picUri) } } } - lic_no.setTextOnChange { model.licenseNumber = it } - - search_image.setOnClickListener { openGalleryWithPermissionRequest() } - submit.setOnClickListener { submit() } } - override fun submit() { - validateEditTexts(lic_expiry, lic_no).takeIf { !it }?.let { return } - - viewmodel.setDataInDatabase(model, imageUri) - } - - override fun setFields(data: DriversLicenseObject) { + override fun setFields(data: DriversLicense) { super.setFields(data) - driversli_img.setGlideImage(data.licenseImageString) - lic_no.setText(data.licenseNumber) - lic_expiry.setText(data.licenseExpiry) + applyBinding { + driversliImg.setGlideImage(data.licenseImageString) + licNo.setText(data.licenseNumber) + licExpiry.setText(data.licenseExpiry) + } } override fun onImageGalleryResult(imageUri: Uri?) { super.onImageGalleryResult(imageUri) - this.imageUri = imageUri - driversli_img.setGlideImage(imageUri) + applyBinding { + driversliImg.setGlideImage(imageUri) + } } } \ No newline at end of file diff --git a/app/src/driver/java/h_mal/appttude/com/ui/driverprofile/DriverProfileFragment.kt b/app/src/driver/java/h_mal/appttude/com/ui/driverprofile/DriverProfileFragment.kt index 8d64174..d07a498 100644 --- a/app/src/driver/java/h_mal/appttude/com/ui/driverprofile/DriverProfileFragment.kt +++ b/app/src/driver/java/h_mal/appttude/com/ui/driverprofile/DriverProfileFragment.kt @@ -1,77 +1,74 @@ package h_mal.appttude.com.ui.driverprofile import android.net.Uri -import android.os.Bundle -import android.view.View -import h_mal.appttude.com.R import h_mal.appttude.com.base.DataSubmissionBaseFragment +import h_mal.appttude.com.databinding.FragmentDriverProfileBinding import h_mal.appttude.com.dialogs.DateDialog -import h_mal.appttude.com.model.DriverProfileObject +import h_mal.appttude.com.model.DriverProfile +import h_mal.appttude.com.utils.isTrue import h_mal.appttude.com.utils.setGlideImage import h_mal.appttude.com.viewmodels.DriverProfileViewModel -import kotlinx.android.synthetic.main.fragment_driver_profile.* -class DriverProfileFragment: DataSubmissionBaseFragment -(R.layout.fragment_driver_profile) { +class DriverProfileFragment : + DataSubmissionBaseFragment() { - var localUri: Uri? = null + override var model = DriverProfile() - private val viewmodel by getFragmentViewModel() - override fun getViewModel(): DriverProfileViewModel = viewmodel - override var model = DriverProfileObject() - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - names_input.setTextOnChange{ model.forenames = it } - address_input.setTextOnChange{ model.address = it } - postcode_input.setTextOnChange{ model.postcode = it } - dob_input.apply { - setTextOnChange{ model.dob = it } - setOnClickListener { - DateDialog(this){ date -> - model.dob = date - } + override fun setupView(binding: FragmentDriverProfileBinding) = binding.run { + namesInput.setTextOnChange { model.forenames = it } + addressInput.setTextOnChange { model.address = it } + postcodeInput.setTextOnChange { model.postcode = it } + dobInput.apply { + setTextOnChange { model.dob = it } + setOnClickListener { + DateDialog(this) { date -> + model.dob = date } } - ni_number.setTextOnChange{ model.ni = it } - date_first.apply { - setTextOnChange{ model.dateFirst = it } + } + niNumber.setTextOnChange { model.ni = it } + dateFirst.apply { + setTextOnChange { model.dateFirst = it } setOnClickListener { - DateDialog(this){ date -> + DateDialog(this) { date -> model.dateFirst = date } } } - add_photo.setOnClickListener { openGalleryWithPermissionRequest() } - submit_driver.setOnClickListener{ submit() } + addPhoto.setOnClickListener { openGalleryWithPermissionRequest() } + submitDriver.setOnClickListener { submit() } } - override fun submit(){ - validateEditTexts(names_input, address_input, postcode_input, - dob_input, ni_number, date_first) - .takeIf { !it } - ?.let { return } - - viewmodel.setDataInDatabase(model, localUri) + override fun submit() { + applyBinding { + validateEditTexts( + namesInput, addressInput, postcodeInput, + dobInput, niNumber, dateFirst + ).isTrue { + viewModel.setDataInDatabase(model, picUri) + } + } } - override fun setFields(data: DriverProfileObject) { + override fun setFields(data: DriverProfile) { super.setFields(data) - driver_pic.setGlideImage(data.driverPic) - names_input.setText(data.forenames) - address_input.setText(data.address) - postcode_input.setText(data.postcode) - dob_input.setText(data.dob) - ni_number.setText(data.ni) - date_first.setText(data.dateFirst) + applyBinding { + driverPic.setGlideImage(data.driverPic) + namesInput.setText(data.forenames) + addressInput.setText(data.address) + postcodeInput.setText(data.postcode) + dobInput.setText(data.dob) + niNumber.setText(data.ni) + dateFirst.setText(data.dateFirst) + } } override fun onImageGalleryResult(imageUri: Uri?) { super.onImageGalleryResult(imageUri) - localUri = imageUri - driver_pic.setGlideImage(imageUri) + applyBinding { + driverPic.setGlideImage(imageUri) + } } } \ No newline at end of file diff --git a/app/src/driver/java/h_mal/appttude/com/ui/driverprofile/PrivateHireLicenseFragment.kt b/app/src/driver/java/h_mal/appttude/com/ui/driverprofile/PrivateHireLicenseFragment.kt index 49c1076..5bb4343 100644 --- a/app/src/driver/java/h_mal/appttude/com/ui/driverprofile/PrivateHireLicenseFragment.kt +++ b/app/src/driver/java/h_mal/appttude/com/ui/driverprofile/PrivateHireLicenseFragment.kt @@ -1,57 +1,57 @@ package h_mal.appttude.com.ui.driverprofile import android.net.Uri -import android.os.Bundle -import android.view.View -import h_mal.appttude.com.R import h_mal.appttude.com.base.DataSubmissionBaseFragment +import h_mal.appttude.com.databinding.FragmentPrivateHireLicenseBinding import h_mal.appttude.com.dialogs.DateDialog -import h_mal.appttude.com.model.PrivateHireObject +import h_mal.appttude.com.model.PrivateHireLicense +import h_mal.appttude.com.utils.isTrue import h_mal.appttude.com.utils.setGlideImage import h_mal.appttude.com.viewmodels.PrivateHireLicenseViewModel -import kotlinx.android.synthetic.main.fragment_private_hire_license.* class PrivateHireLicenseFragment : DataSubmissionBaseFragment -(R.layout.fragment_private_hire_license) { +() { - val viewmodel by getFragmentViewModel() - override fun getViewModel(): PrivateHireLicenseViewModel = viewmodel - override var model = PrivateHireObject() + override var model = PrivateHireLicense() - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - ph_no.setTextOnChange{ model.phNumber = it } - ph_expiry.apply { - setTextOnChange{ model.phExpiry = it } + override fun setupView(binding: FragmentPrivateHireLicenseBinding) = binding.run { + phNo.setTextOnChange { model.phNumber = it } + phExpiry.apply { + setTextOnChange { model.phExpiry = it } setOnClickListener { - DateDialog(this){ date -> + DateDialog(this) { date -> model.phExpiry = date } } } uploadphlic.setOnClickListener { openGalleryWithPermissionRequest() } - submit.setOnClickListener{ submit() } + submit.setOnClickListener { submit() } } - override fun submit(){ - validateEditTexts(ph_no,ph_expiry).takeIf { !it }?.let { return } - - viewmodel.setDataInDatabase(model, picUri) + override fun submit() { + applyBinding { + validateEditTexts(phNo, phExpiry).isTrue { + viewModel.setDataInDatabase(model, picUri) + } + } } - override fun setFields(data: PrivateHireObject) { + override fun setFields(data: PrivateHireLicense) { super.setFields(data) - imageView2.setGlideImage(data.phImageString) - ph_no.setText(data.phNumber) - ph_expiry.setText(data.phExpiry) + applyBinding { + imageView2.setGlideImage(data.phImageString) + phNo.setText(data.phNumber) + phExpiry.setText(data.phExpiry) + } } override fun onImageGalleryResult(imageUri: Uri?) { super.onImageGalleryResult(imageUri) - imageView2.setGlideImage(imageUri) + applyBinding { + imageView2.setGlideImage(imageUri) + } } } \ No newline at end of file diff --git a/app/src/driver/java/h_mal/appttude/com/ui/vehicleprofile/InsuranceFragment.kt b/app/src/driver/java/h_mal/appttude/com/ui/vehicleprofile/InsuranceFragment.kt index dba3688..d4a71ed 100644 --- a/app/src/driver/java/h_mal/appttude/com/ui/vehicleprofile/InsuranceFragment.kt +++ b/app/src/driver/java/h_mal/appttude/com/ui/vehicleprofile/InsuranceFragment.kt @@ -4,66 +4,71 @@ import android.net.Uri import android.os.Bundle import android.view.View import android.widget.ImageView -import h_mal.appttude.com.R import h_mal.appttude.com.base.DataSubmissionBaseFragment +import h_mal.appttude.com.databinding.FragmentInsuranceBinding import h_mal.appttude.com.dialogs.DateDialog -import h_mal.appttude.com.model.InsuranceObject +import h_mal.appttude.com.model.Insurance +import h_mal.appttude.com.utils.isTrue import h_mal.appttude.com.utils.setGlideImage import h_mal.appttude.com.viewmodels.InsuranceViewModel -import kotlinx.android.synthetic.main.fragment_insurance.* -class InsuranceFragment : DataSubmissionBaseFragment(R.layout.fragment_insurance) { +class InsuranceFragment : + DataSubmissionBaseFragment() { private var selectedImages: List? = listOf() - private val viewmodel: InsuranceViewModel by getFragmentViewModel() - override fun getViewModel(): InsuranceViewModel = viewmodel - override var model = InsuranceObject() + override var model = Insurance() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setImageSelectionAsMultiple() - insurer.setTextOnChange { model.insurerName = it } - insurance_exp.apply { - setOnClickListener { - DateDialog(this) { date -> - model.expiryDate = date + applyBinding { + insurer.setTextOnChange { model.insurerName = it } + insuranceExp.apply { + setOnClickListener { + DateDialog(this) { date -> + model.expiryDate = date + } } } + uploadInsurance.setOnClickListener { openGalleryWithPermissionRequest() } + submitIns.setOnClickListener { submit() } } - - uploadInsurance.setOnClickListener { openGalleryWithPermissionRequest() } - submit_ins.setOnClickListener { submit() } } private fun updateImageCarousal(list: List) { - carouselView.setImageClickListener(null) - carouselView.setImageListener { i: Int, imageView: ImageView -> - when (list[i]) { - is Uri -> { - imageView.setGlideImage(list[i] as Uri) + applyBinding { + carouselView.setImageClickListener(null) + carouselView.setImageListener { i: Int, imageView: ImageView -> + when (list[i]) { + is Uri -> { + imageView.setGlideImage(list[i] as Uri) + } + is String -> imageView.setGlideImage(list[i] as String) } - is String -> imageView.setGlideImage(list[i] as String) } + carouselView.pageCount = list.size } - carouselView.pageCount = list.size - } override fun submit() { super.submit() - validateEditTexts(insurer, insurance_exp).takeIf { !it }?.let { return } - viewmodel.setDataInDatabase(model, selectedImages) + applyBinding { + validateEditTexts(insurer, insuranceExp).isTrue { + viewModel.setDataInDatabase(model, selectedImages) + } + } } - override fun setFields(data: InsuranceObject) { + override fun setFields(data: Insurance) { super.setFields(data) - - insurer.setText(model.insurerName) - insurance_exp.setText(model.expiryDate) - model.photoStrings?.let { updateImageCarousal(it) } + applyBinding { + insurer.setText(model.insurerName) + insuranceExp.setText(model.expiryDate) + model.photoStrings?.let { updateImageCarousal(it) } + } } override fun onImageGalleryResult(imageUris: List?) { diff --git a/app/src/driver/java/h_mal/appttude/com/ui/vehicleprofile/LogbookFragment.kt b/app/src/driver/java/h_mal/appttude/com/ui/vehicleprofile/LogbookFragment.kt index 3d906b9..3c0a9da 100644 --- a/app/src/driver/java/h_mal/appttude/com/ui/vehicleprofile/LogbookFragment.kt +++ b/app/src/driver/java/h_mal/appttude/com/ui/vehicleprofile/LogbookFragment.kt @@ -1,50 +1,47 @@ package h_mal.appttude.com.ui.vehicleprofile import android.net.Uri -import android.os.Bundle -import android.view.View -import h_mal.appttude.com.R import h_mal.appttude.com.base.DataSubmissionBaseFragment -import h_mal.appttude.com.model.LogbookObject +import h_mal.appttude.com.databinding.FragmentLogbookBinding +import h_mal.appttude.com.model.Logbook +import h_mal.appttude.com.utils.isTrue import h_mal.appttude.com.utils.setGlideImage import h_mal.appttude.com.viewmodels.LogbookViewModel -import kotlinx.android.synthetic.main.fragment_logbook.* -class LogbookFragment : DataSubmissionBaseFragment(R.layout.fragment_logbook) { +class LogbookFragment : + DataSubmissionBaseFragment() { - private val viewmodel by getFragmentViewModel() - override fun getViewModel(): LogbookViewModel = viewmodel - override var model = LogbookObject() + override var model = Logbook() - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - v5c_no.setTextOnChange{ model.v5cnumber = it } - upload_lb.setOnClickListener { openGalleryWithPermissionRequest() } - submit_lb.setOnClickListener { submit() } + override fun setupView(binding: FragmentLogbookBinding) = binding.run { + v5cNo.setTextOnChange { model.v5cnumber = it } + uploadLb.setOnClickListener { openGalleryWithPermissionRequest() } + submitLb.setOnClickListener { submit() } } override fun submit() { super.submit() - validateEditTexts(v5c_no) - .takeIf { !it } - ?.let { return } - - viewmodel.setDataInDatabase(model, picUri) + applyBinding { + validateEditTexts(v5cNo).isTrue { + viewModel.setDataInDatabase(model, picUri) + } + } } - override fun setFields(data: LogbookObject) { + override fun setFields(data: Logbook) { super.setFields(data) + applyBinding { + logBookImg.setGlideImage(data.photoString) + v5cNo.setText(data.v5cnumber) + } - log_book_img.setGlideImage(data.photoString) - v5c_no.setText(data.v5cnumber) } override fun onImageGalleryResult(imageUri: Uri?) { super.onImageGalleryResult(imageUri) - - picUri = imageUri - log_book_img.setGlideImage(picUri) + applyBinding { + logBookImg.setGlideImage(picUri) + } } } \ No newline at end of file diff --git a/app/src/driver/java/h_mal/appttude/com/ui/vehicleprofile/MotFragment.kt b/app/src/driver/java/h_mal/appttude/com/ui/vehicleprofile/MotFragment.kt index a0db309..4ea534b 100644 --- a/app/src/driver/java/h_mal/appttude/com/ui/vehicleprofile/MotFragment.kt +++ b/app/src/driver/java/h_mal/appttude/com/ui/vehicleprofile/MotFragment.kt @@ -1,52 +1,48 @@ package h_mal.appttude.com.ui.vehicleprofile import android.net.Uri -import android.os.Bundle -import android.view.View -import h_mal.appttude.com.R import h_mal.appttude.com.base.DataSubmissionBaseFragment +import h_mal.appttude.com.databinding.FragmentMotBinding import h_mal.appttude.com.dialogs.DateDialog -import h_mal.appttude.com.model.MotObject +import h_mal.appttude.com.model.Mot +import h_mal.appttude.com.utils.isTrue import h_mal.appttude.com.utils.setGlideImage import h_mal.appttude.com.viewmodels.MotViewModel -import kotlinx.android.synthetic.main.fragment_mot.* -class MotFragment: DataSubmissionBaseFragment(R.layout.fragment_mot){ +class MotFragment : DataSubmissionBaseFragment() { - private val viewmodel by getFragmentViewModel() - override fun getViewModel(): MotViewModel = viewmodel - override var model = MotObject() + override var model = Mot() - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - mot_expiry.apply { + override fun setupView(binding: FragmentMotBinding) = binding.run { + motExpiry.apply { setOnClickListener { - DateDialog(this){ date -> + DateDialog(this) { date -> model.motExpiry = date } } } uploadmot.setOnClickListener { openGalleryWithPermissionRequest() } - submit_mot.setOnClickListener { submit() } + submitMot.setOnClickListener { + validateEditTexts(motExpiry).isTrue { + viewModel.setDataInDatabase(model, picUri) + } + } } - override fun submit() { - super.submit() - validateEditTexts(mot_expiry).takeIf { !it }?.let { return } - viewmodel.setDataInDatabase(model, picUri) - } - - override fun setFields(data: MotObject) { + override fun setFields(data: Mot) { super.setFields(data) - mot_img.setGlideImage(data.motImageString) - mot_expiry.setText(data.motExpiry) + applyBinding { + motImg.setGlideImage(data.motImageString) + motExpiry.setText(data.motExpiry) + } } override fun onImageGalleryResult(imageUri: Uri?) { super.onImageGalleryResult(imageUri) - mot_img.setGlideImage(imageUri) + applyBinding { + motImg.setGlideImage(imageUri) + } } } \ No newline at end of file diff --git a/app/src/driver/java/h_mal/appttude/com/ui/vehicleprofile/PrivateHireVehicleFragment.kt b/app/src/driver/java/h_mal/appttude/com/ui/vehicleprofile/PrivateHireVehicleFragment.kt index 5039676..3af05a6 100644 --- a/app/src/driver/java/h_mal/appttude/com/ui/vehicleprofile/PrivateHireVehicleFragment.kt +++ b/app/src/driver/java/h_mal/appttude/com/ui/vehicleprofile/PrivateHireVehicleFragment.kt @@ -1,55 +1,52 @@ package h_mal.appttude.com.ui.vehicleprofile import android.net.Uri -import android.os.Bundle -import android.view.View -import h_mal.appttude.com.R import h_mal.appttude.com.base.DataSubmissionBaseFragment +import h_mal.appttude.com.databinding.FragmentPrivateHireLicenseBinding import h_mal.appttude.com.dialogs.DateDialog -import h_mal.appttude.com.model.PrivateHireVehicleObject +import h_mal.appttude.com.model.PrivateHireVehicle +import h_mal.appttude.com.utils.isTrue import h_mal.appttude.com.utils.setGlideImage import h_mal.appttude.com.viewmodels.PrivateHireVehicleViewModel -import kotlinx.android.synthetic.main.fragment_private_hire_vehicle.* -class PrivateHireVehicleFragment: DataSubmissionBaseFragment -(R.layout.fragment_private_hire_vehicle){ +class PrivateHireVehicleFragment : + DataSubmissionBaseFragment() { - private val viewmodel by getFragmentViewModel() - override fun getViewModel(): PrivateHireVehicleViewModel = viewmodel - override var model = PrivateHireVehicleObject() + override var model = PrivateHireVehicle() - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - ph_no.setTextOnChange{ model.phCarNumber = it } - ph_expiry.apply { + override fun setupView(binding: FragmentPrivateHireLicenseBinding) = binding.run { + phNo.setTextOnChange { model.phCarNumber = it } + phExpiry.apply { setOnClickListener { - DateDialog(this){ date -> + DateDialog(this) { date -> model.phCarExpiry = date } } } uploadphlic.setOnClickListener { openGalleryWithPermissionRequest() } - submit.setOnClickListener { submit() } + submit.setOnClickListener { + validateEditTexts(phNo, phExpiry).isTrue { + viewModel.setDataInDatabase(model, picUri) + } + } } - override fun submit() { - super.submit() - validateEditTexts(ph_no, ph_expiry).takeIf { !it }?.let { return } - viewmodel.setDataInDatabase(model, picUri) - } - - override fun setFields(data: PrivateHireVehicleObject) { + override fun setFields(data: PrivateHireVehicle) { super.setFields(data) - imageView2.setGlideImage(data.phCarImageString) - ph_no.setText(data.phCarNumber) - ph_expiry.setText(data.phCarExpiry) + applyBinding { + imageView2.setGlideImage(data.phCarImageString) + phNo.setText(data.phCarNumber) + phExpiry.setText(data.phCarExpiry) + } + } override fun onImageGalleryResult(imageUri: Uri?) { super.onImageGalleryResult(imageUri) - imageView2.setGlideImage(imageUri) + applyBinding { + imageView2.setGlideImage(imageUri) + } } } \ No newline at end of file diff --git a/app/src/driver/java/h_mal/appttude/com/ui/vehicleprofile/VehicleProfileFragment.kt b/app/src/driver/java/h_mal/appttude/com/ui/vehicleprofile/VehicleProfileFragment.kt index c3748fe..6fc99d1 100644 --- a/app/src/driver/java/h_mal/appttude/com/ui/vehicleprofile/VehicleProfileFragment.kt +++ b/app/src/driver/java/h_mal/appttude/com/ui/vehicleprofile/VehicleProfileFragment.kt @@ -1,62 +1,63 @@ package h_mal.appttude.com.ui.vehicleprofile -import android.os.Bundle -import android.view.View -import h_mal.appttude.com.R import h_mal.appttude.com.base.DataSubmissionBaseFragment +import h_mal.appttude.com.databinding.FragmentVehicleSetupBinding import h_mal.appttude.com.dialogs.DateDialog -import h_mal.appttude.com.model.VehicleProfileObject +import h_mal.appttude.com.model.VehicleProfile +import h_mal.appttude.com.utils.isTrue import h_mal.appttude.com.viewmodels.VehicleProfileViewModel -import kotlinx.android.synthetic.main.fragment_vehicle_setup.* -class VehicleProfileFragment: DataSubmissionBaseFragment -(R.layout.fragment_vehicle_setup){ +class VehicleProfileFragment : DataSubmissionBaseFragment +() { - private val viewmodel by getFragmentViewModel() - override fun getViewModel(): VehicleProfileViewModel = viewmodel - override var model = VehicleProfileObject() - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) + override var model = VehicleProfile() + override fun setupView(binding: FragmentVehicleSetupBinding) = binding.run { reg.setTextOnChange { model.reg = it } make.setTextOnChange { model.make = it } - car_model.setTextOnChange { model.model = it } + carModel.setTextOnChange { model.model = it } colour.setTextOnChange { model.colour = it } - keeper_name.setTextOnChange { model.keeperName = it } + keeperName.setTextOnChange { model.keeperName = it } address.setTextOnChange { model.keeperAddress = it } postcode.setTextOnChange { model.keeperPostCode = it } - start_date.apply { + startDate.apply { setOnClickListener { - DateDialog(this){ date -> + DateDialog(this) { date -> model.startDate = date } } } - seized_checkbox.setOnCheckedChangeListener { _, res -> model.isSeized = res} + seizedCheckbox.setOnCheckedChangeListener { _, res -> model.isSeized = res } - submit_vehicle.setOnClickListener { submit() } + submitVehicle.setOnClickListener { + validateEditTexts( + reg, + make, + carModel, + colour, + keeperName, + address, + postcode, + startDate + ).isTrue { + viewModel.setDataInDatabase(model) + } + } } - override fun submit() { - validateEditTexts(reg, make, car_model, colour, keeper_name, address, postcode, start_date) - .takeIf { !it } - ?.let { return } - - viewmodel.setDataInDatabase(model) - } - - override fun setFields(data: VehicleProfileObject) { + override fun setFields(data: VehicleProfile) { super.setFields(data) - reg.setText(data.reg) - make.setText(data.make) - car_model.setText(data.model) - colour.setText(data.colour) - keeper_name.setText(data.keeperName) - address.setText(data.keeperAddress) - postcode.setText(data.keeperPostCode) - start_date.setText(data.startDate) - seized_checkbox.isChecked = data.isSeized + applyBinding { + reg.setText(data.reg) + make.setText(data.make) + carModel.setText(data.model) + colour.setText(data.colour) + keeperName.setText(data.keeperName) + address.setText(data.keeperAddress) + postcode.setText(data.keeperPostCode) + startDate.setText(data.startDate) + seizedCheckbox.isChecked = data.isSeized + } } } \ No newline at end of file diff --git a/app/src/driver/res/layout/fragment_welcome.xml b/app/src/driver/res/layout/fragment_welcome.xml index 21b0e30..82ad7ac 100644 --- a/app/src/driver/res/layout/fragment_welcome.xml +++ b/app/src/driver/res/layout/fragment_welcome.xml @@ -54,7 +54,7 @@ android:textColor="@android:color/white" app:layout_constraintTop_toTopOf="parent" app:layout_constraintLeft_toLeftOf="parent" - android:layout_marginTop="32dp"/> + android:layout_marginTop="32dp" /> + app:layout_constraintTop_toBottomOf="@id/textView3" /> diff --git a/app/src/main/java/h_mal/appttude/com/Archive/ArchiveFragment.kt b/app/src/main/java/h_mal/appttude/com/Archive/ArchiveFragment.kt index af3143a..5dce8ec 100644 --- a/app/src/main/java/h_mal/appttude/com/Archive/ArchiveFragment.kt +++ b/app/src/main/java/h_mal/appttude/com/Archive/ArchiveFragment.kt @@ -10,31 +10,10 @@ import com.google.firebase.database.DatabaseReference import h_mal.appttude.com.R class ArchiveFragment : Fragment() { -// var archive: ArchiveObject? = null + // var archive: ArchiveObject? = null private var reference: DatabaseReference? = null private var listView: ListView? = null var archiveString: String? = null - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) -// reference = -// MainActivity.mDatabase!!.child(FirebaseClass.USER_FIREBASE).child( -// requireArguments().getString("user_id") -// ) -// .child(FirebaseClass.ARCHIVE_FIREBASE) - -// archiveString = requireArguments().getString("archive") -// var s: String = "" -// when (archiveString) { -// FirebaseClass.PRIVATE_HIRE_FIREBASE -> s = "Private Hire" -// FirebaseClass.DRIVERS_LICENSE_FIREBASE -> s = "License" -// FirebaseClass.VEHICLE_DETAILS_FIREBASE -> s = "Vehicle" -// FirebaseClass.MOT_FIREBASE -> s = "M.O.T" -// FirebaseClass.INSURANCE_FIREBASE -> s = "Insurance" -// FirebaseClass.LOG_BOOK_FIREBASE -> s = "Logbook" -// FirebaseClass.PRIVATE_HIRE_VEHICLE_LICENSE -> s = "Private Hire Vehicle" -// } -// requireActivity().title = s + " Archive" - } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, diff --git a/app/src/main/java/h_mal/appttude/com/Archive/ArchiveObjectListAdapter.kt b/app/src/main/java/h_mal/appttude/com/Archive/ArchiveObjectListAdapter.kt index acd1e72..ecaca7b 100644 --- a/app/src/main/java/h_mal/appttude/com/Archive/ArchiveObjectListAdapter.kt +++ b/app/src/main/java/h_mal/appttude/com/Archive/ArchiveObjectListAdapter.kt @@ -174,7 +174,8 @@ class ArchiveObjectListAdapter( private fun dateString(position: Int) { var success: Boolean = true try { - dateArchivedText!!.text = mKeys[position].convertDateStringDatePattern("yyyyMMdd_HHmmss", "dd/MM/yyyy") + dateArchivedText!!.text = + mKeys[position].convertDateStringDatePattern("yyyyMMdd_HHmmss", "dd/MM/yyyy") } catch (e: ParseException) { e.printStackTrace() success = false @@ -206,9 +207,9 @@ class ArchiveObjectListAdapter( // // } - private fun setUp(map: HashMap?){ + private fun setUp(map: HashMap?) { size = map?.size ?: 0 - map?.keys?.toTypedArray()?.let{ + map?.keys?.toTypedArray()?.let { mKeys = it } } diff --git a/app/src/main/java/h_mal/appttude/com/application/ApplicationViewModelFactory.kt b/app/src/main/java/h_mal/appttude/com/application/ApplicationViewModelFactory.kt index 5195e15..9189179 100644 --- a/app/src/main/java/h_mal/appttude/com/application/ApplicationViewModelFactory.kt +++ b/app/src/main/java/h_mal/appttude/com/application/ApplicationViewModelFactory.kt @@ -15,20 +15,55 @@ class ApplicationViewModelFactory( @Suppress("UNCHECKED_CAST") override fun create(modelClass: Class): T { - with(modelClass){ - return when{ + with(modelClass) { + return when { isAssignableFrom(UserViewModel::class.java) -> UserViewModel(auth) isAssignableFrom(MainViewModel::class.java) -> MainViewModel(auth, database) - isAssignableFrom(UpdateUserViewModel::class.java) -> UpdateUserViewModel(auth, storage) - isAssignableFrom(DriverLicenseViewModel::class.java) -> DriverLicenseViewModel(auth, database, storage) - isAssignableFrom(DriverProfileViewModel::class.java) -> DriverProfileViewModel(auth, database, storage) - isAssignableFrom(PrivateHireLicenseViewModel::class.java) -> PrivateHireLicenseViewModel(auth, database, storage) - isAssignableFrom(VehicleProfileViewModel::class.java) -> VehicleProfileViewModel(auth, database, storage) - isAssignableFrom(InsuranceViewModel::class.java) -> InsuranceViewModel(auth, database, storage) + isAssignableFrom(UpdateUserViewModel::class.java) -> UpdateUserViewModel( + auth, + storage + ) + isAssignableFrom(DriverLicenseViewModel::class.java) -> DriverLicenseViewModel( + auth, + database, + storage + ) + isAssignableFrom(DriverProfileViewModel::class.java) -> DriverProfileViewModel( + auth, + database, + storage + ) + isAssignableFrom(PrivateHireLicenseViewModel::class.java) -> PrivateHireLicenseViewModel( + auth, + database, + storage + ) + isAssignableFrom(VehicleProfileViewModel::class.java) -> VehicleProfileViewModel( + auth, + database, + storage + ) + isAssignableFrom(InsuranceViewModel::class.java) -> InsuranceViewModel( + auth, + database, + storage + ) isAssignableFrom(MotViewModel::class.java) -> MotViewModel(auth, database, storage) - isAssignableFrom(LogbookViewModel::class.java) -> LogbookViewModel(auth, database, storage) - isAssignableFrom(PrivateHireVehicleViewModel::class.java) -> PrivateHireVehicleViewModel(auth, database, storage) - isAssignableFrom(RoleViewModel::class.java) -> RoleViewModel(auth, database, storage) + isAssignableFrom(LogbookViewModel::class.java) -> LogbookViewModel( + auth, + database, + storage + ) + isAssignableFrom(PrivateHireVehicleViewModel::class.java) -> PrivateHireVehicleViewModel( + auth, + database, + storage + ) + isAssignableFrom(RoleViewModel::class.java) -> RoleViewModel( + auth, + database, + storage + ) else -> throw IllegalArgumentException("Unknown ViewModel class") } as T } diff --git a/app/src/main/java/h_mal/appttude/com/application/DriverApplication.kt b/app/src/main/java/h_mal/appttude/com/application/DriverApplication.kt index da47352..723dedb 100644 --- a/app/src/main/java/h_mal/appttude/com/application/DriverApplication.kt +++ b/app/src/main/java/h_mal/appttude/com/application/DriverApplication.kt @@ -12,7 +12,7 @@ import org.kodein.di.generic.instance import org.kodein.di.generic.provider import org.kodein.di.generic.singleton -class DriverApplication : Application(), KodeinAware{ +class DriverApplication : Application(), KodeinAware { // Kodein aware to initialise the classes used for DI override val kodein = Kodein.lazy { diff --git a/app/src/main/java/h_mal/appttude/com/base/BaseActivity.kt b/app/src/main/java/h_mal/appttude/com/base/BaseActivity.kt index 94305cd..79b7dba 100644 --- a/app/src/main/java/h_mal/appttude/com/base/BaseActivity.kt +++ b/app/src/main/java/h_mal/appttude/com/base/BaseActivity.kt @@ -2,15 +2,16 @@ package h_mal.appttude.com.base import android.content.Intent import android.os.Bundle +import android.view.LayoutInflater import android.view.View import android.view.ViewGroup.LayoutParams import android.view.ViewGroup.LayoutParams.MATCH_PARENT -import androidx.activity.viewModels +import android.view.ViewGroup.inflate import androidx.annotation.VisibleForTesting import androidx.appcompat.app.AppCompatActivity -import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.ViewModelLazy import androidx.test.espresso.IdlingResource +import androidx.viewbinding.ViewBinding import h_mal.appttude.com.R import h_mal.appttude.com.application.ApplicationViewModelFactory import h_mal.appttude.com.data.ViewState @@ -18,30 +19,65 @@ import h_mal.appttude.com.utils.* import org.kodein.di.KodeinAware import org.kodein.di.android.kodein import org.kodein.di.generic.instance +import java.lang.reflect.ParameterizedType +import kotlin.reflect.KClass -abstract class BaseActivity : AppCompatActivity(), KodeinAware { +abstract class BaseActivity : AppCompatActivity(), KodeinAware { // The Idling Resource which will be null in production. private var mIdlingResource: BasicIdlingResource? = null private lateinit var loadingView: View - abstract fun getViewModel(): V? - abstract val layoutId: Int + private var _binding: VB? = null + private val binding: VB + get() = _binding ?: error("Must only access binding while fragment is attached.") + + + val viewModel: V by createLazyViewModel() override val kodein by kodein() val factory by instance() - inline fun createLazyViewModel(): Lazy = viewModels { factory } - inline fun createViewModel(): VM = - ViewModelProvider(viewModelStore, factory).get(VM::class.java) + fun createLazyViewModel(): Lazy = ViewModelLazy( + getGenericClassAt(0), + { viewModelStore }, + { factory }, + { defaultViewModelCreationExtras } + ) + @Suppress("UNCHECKED_CAST") + fun Any.getGenericClassAt(position: Int): KClass = + ((javaClass.genericSuperclass as? ParameterizedType) + ?.actualTypeArguments?.getOrNull(position) as? Class) + ?.kotlin + ?: throw IllegalStateException("Can not find class from generic argument") + + fun inflateBindingByType( + genericClassAt: KClass + ): VB = try { + @Suppress("UNCHECKED_CAST") + genericClassAt.java.methods.first { viewBinding -> + viewBinding.parameterTypes.size == 1 + && viewBinding.parameterTypes.getOrNull(0) == LayoutInflater::class.java + }.invoke(null, layoutInflater) as VB + } catch (exception: Exception) { + throw IllegalStateException("Can not inflate binding from generic") + } private var loading: Boolean = false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) configureObserver() - setContentView(layoutId) + _binding = inflateBindingByType(getGenericClassAt(1)) + setContentView(requireNotNull(_binding).root) + setupView(binding) + } + + open fun setupView(binding: VB) {} + + fun applyBinding(block: VB.() -> Unit) { + block(binding) } /** @@ -50,9 +86,8 @@ abstract class BaseActivity : AppCompatActivity(), KodeinAwar * #setOnClickListener(null) is an ugly work around to prevent under being clicked during * loading */ - private fun instantiateLoadingView(){ -// loadingView = View.inflate(this, R.layout.progress_layout, null) - loadingView = layoutInflater.inflate(R.layout.progress_layout, null) + private fun instantiateLoadingView() { + loadingView = inflate(this, R.layout.progress_layout, null) loadingView.setOnClickListener(null) addContentView(loadingView, LayoutParams(MATCH_PARENT, MATCH_PARENT)) loadingView.hide() @@ -97,7 +132,7 @@ abstract class BaseActivity : AppCompatActivity(), KodeinAwar } private fun configureObserver() { - getViewModel()?.uiState?.observe(this) { + viewModel.uiState.observe(this) { when (it) { is ViewState.HasStarted -> onStarted() is ViewState.HasData<*> -> onSuccess(it.data.getContentIfNotHandled()) diff --git a/app/src/main/java/h_mal/appttude/com/base/BaseFragment.kt b/app/src/main/java/h_mal/appttude/com/base/BaseFragment.kt index 84183c9..ad21ec4 100644 --- a/app/src/main/java/h_mal/appttude/com/base/BaseFragment.kt +++ b/app/src/main/java/h_mal/appttude/com/base/BaseFragment.kt @@ -5,24 +5,33 @@ import android.content.ClipData import android.content.Intent import android.net.Uri import android.os.Bundle -import androidx.annotation.LayoutRes +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup import androidx.fragment.app.Fragment -import androidx.fragment.app.viewModels -import androidx.lifecycle.ViewModel +import androidx.fragment.app.createViewModelLazy +import androidx.viewbinding.ViewBinding import h_mal.appttude.com.application.ApplicationViewModelFactory import h_mal.appttude.com.data.ViewState import h_mal.appttude.com.utils.PermissionsUtils import org.kodein.di.KodeinAware import org.kodein.di.android.x.kodein import org.kodein.di.generic.instance +import java.lang.reflect.ParameterizedType +import kotlin.reflect.KClass const val IMAGE_SELECT_REQUEST_CODE = 401 -abstract class BaseFragment(@LayoutRes contentLayoutId: Int) : - Fragment(contentLayoutId), KodeinAware { +abstract class BaseFragment( +) : Fragment(), KodeinAware { - var mActivity: BaseActivity? = null - abstract fun getViewModel(): V + private var _binding: VB? = null + private val binding: VB + get() = _binding ?: error("Must only access binding while fragment is attached.") + + var mActivity: BaseActivity? = null + + val viewModel: V by getFragmentViewModel() private var multipleImage: Boolean = false @@ -33,13 +42,57 @@ abstract class BaseFragment(@LayoutRes contentLayoutId: Int) override val kodein by kodein() val factory by instance() - inline fun getFragmentViewModel(): Lazy = viewModels { factory } + fun getFragmentViewModel(): Lazy = + createViewModelLazy(getGenericClassAt(0), { viewModelStore }, factoryProducer = { factory }) + + fun LayoutInflater.inflateBindingByType( + container: ViewGroup?, + genericClassAt: KClass + ): VB = try { + @Suppress("UNCHECKED_CAST") + genericClassAt.java.methods.first { inflateFun -> + inflateFun.parameterTypes.size == 3 + && inflateFun.parameterTypes.getOrNull(0) == LayoutInflater::class.java + && inflateFun.parameterTypes.getOrNull(1) == ViewGroup::class.java + && inflateFun.parameterTypes.getOrNull(2) == Boolean::class.java + }.invoke(null, this, container, false) as VB + } catch (exception: Exception) { + throw IllegalStateException("Can not inflate binding from generic") + } @Suppress("UNCHECKED_CAST") - override fun onActivityCreated(savedInstanceState: Bundle?) { - super.onActivityCreated(savedInstanceState) - mActivity = activity as BaseActivity + fun Any.getGenericClassAt(position: Int): KClass = + ((javaClass.genericSuperclass as? ParameterizedType) + ?.actualTypeArguments?.getOrNull(position) as? Class) + ?.kotlin + ?: throw IllegalStateException("Can not find class from generic argument") + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + _binding = inflater.inflateBindingByType(container, getGenericClassAt(1)) + return requireNotNull(_binding).root + } + + @Suppress("UNCHECKED_CAST") + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + mActivity = activity as BaseActivity configureObserver() + setupView(binding) + } + + open fun setupView(binding: VB) {} + + fun applyBinding(block: VB.() -> Unit) { + block(binding) + } + + override fun onDestroy() { + super.onDestroy() + _binding = null } /** @@ -64,7 +117,7 @@ abstract class BaseFragment(@LayoutRes contentLayoutId: Int) } private fun configureObserver() { - getViewModel().uiState.observe(viewLifecycleOwner) { + viewModel.uiState.observe(viewLifecycleOwner) { when (it) { is ViewState.HasStarted -> onStarted() is ViewState.HasData<*> -> onSuccess(it.data.getContentIfNotHandled()) diff --git a/app/src/main/java/h_mal/appttude/com/base/BaseViewModel.kt b/app/src/main/java/h_mal/appttude/com/base/BaseViewModel.kt index 99e8db2..274ab0b 100644 --- a/app/src/main/java/h_mal/appttude/com/base/BaseViewModel.kt +++ b/app/src/main/java/h_mal/appttude/com/base/BaseViewModel.kt @@ -5,7 +5,7 @@ import androidx.lifecycle.ViewModel import h_mal.appttude.com.data.ViewState import h_mal.appttude.com.utils.Event -abstract class BaseViewModel: ViewModel(){ +abstract class BaseViewModel : ViewModel() { open val uiState: MutableLiveData = MutableLiveData() fun onStart() { @@ -23,11 +23,11 @@ abstract class BaseViewModel: ViewModel(){ suspend fun doTryOperation( defaultErrorMessage: String?, operation: suspend () -> Unit - ){ + ) { try { onStart() operation() - }catch (e: Exception){ + } catch (e: Exception) { e.printStackTrace() e.message?.let { onError(it) diff --git a/app/src/main/java/h_mal/appttude/com/base/DataSubmissionBaseFragment.kt b/app/src/main/java/h_mal/appttude/com/base/DataSubmissionBaseFragment.kt index 426e503..5ead99f 100644 --- a/app/src/main/java/h_mal/appttude/com/base/DataSubmissionBaseFragment.kt +++ b/app/src/main/java/h_mal/appttude/com/base/DataSubmissionBaseFragment.kt @@ -6,25 +6,25 @@ import android.net.Uri import android.os.Bundle import android.view.View import android.widget.EditText -import androidx.annotation.LayoutRes import androidx.core.widget.doAfterTextChanged +import androidx.viewbinding.ViewBinding import h_mal.appttude.com.data.UserAuthState import h_mal.appttude.com.ui.user.LoginActivity import h_mal.appttude.com.utils.PermissionsUtils.askForPermissions import h_mal.appttude.com.utils.TextValidationUtils.validateEditText private const val IMAGE_PERMISSION_RESULT = 402 -abstract class DataSubmissionBaseFragment, T: Any> - (@LayoutRes contentLayoutId: Int) : BaseFragment(contentLayoutId){ + +abstract class DataSubmissionBaseFragment, VB : ViewBinding, T : Any> : + BaseFragment() { var picUri: Uri? = null - abstract override fun getViewModel(): V abstract var model: T override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - getViewModel().stateLiveData.observe(viewLifecycleOwner) { + viewModel.stateLiveData.observe(viewLifecycleOwner) { if (it is UserAuthState.LoggedOut) { val intent = Intent(requireContext(), LoginActivity::class.java) intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK) @@ -32,7 +32,7 @@ abstract class DataSubmissionBaseFragment, T: requireActivity().finish() } } - getViewModel().getDataFromDatabase() + viewModel.getDataFromDatabase() } @Suppress("UNCHECKED_CAST") @@ -41,17 +41,17 @@ abstract class DataSubmissionBaseFragment, T: data?.let { if (it::class.java == model::class.java) - setFields(data as T) + setFields(data as T) } } - open fun setFields(data: T){ + open fun setFields(data: T) { model = data } - open fun submit(){} + open fun submit() {} - fun openGalleryWithPermissionRequest(){ + fun openGalleryWithPermissionRequest() { if (askForPermissions(Manifest.permission.READ_EXTERNAL_STORAGE, IMAGE_PERMISSION_RESULT)) { openGalleryForImage() } @@ -65,9 +65,9 @@ abstract class DataSubmissionBaseFragment, T: openGalleryForImage() } - fun validateEditTexts(vararg editTexts: EditText): Boolean{ + fun validateEditTexts(vararg editTexts: EditText): Boolean { editTexts.forEach { - if (it.text.isNullOrBlank()){ + if (it.text.isNullOrBlank()) { it.validateEditText() return false } @@ -75,13 +75,13 @@ abstract class DataSubmissionBaseFragment, T: return true } - fun EditText.setTextOnChange(output: (m: String) -> Unit){ + fun EditText.setTextOnChange(output: (m: String) -> Unit) { doAfterTextChanged { output(text.toString()) } } - override fun onImageGalleryResult(imageUri: Uri?){ + override fun onImageGalleryResult(imageUri: Uri?) { super.onImageGalleryResult(imageUri) picUri = imageUri } diff --git a/app/src/main/java/h_mal/appttude/com/base/DataSubmissionBaseViewModel.kt b/app/src/main/java/h_mal/appttude/com/base/DataSubmissionBaseViewModel.kt index f05af76..cea7e46 100644 --- a/app/src/main/java/h_mal/appttude/com/base/DataSubmissionBaseViewModel.kt +++ b/app/src/main/java/h_mal/appttude/com/base/DataSubmissionBaseViewModel.kt @@ -30,7 +30,7 @@ abstract class DataSubmissionBaseViewModel( abstract fun getDataFromDatabase(): Job open fun setDataInDatabase(data: T, localImageUri: Uri?): Job = Job() open fun setDataInDatabase(data: T, localImageUris: List?): Job = Job() - open fun setDataInDatabase(data: T) { } + open fun setDataInDatabase(data: T) {} inline fun getDataClass() = io { doTryOperation("Failed to retrieve $objectName") { @@ -60,7 +60,7 @@ abstract class DataSubmissionBaseViewModel( } suspend fun getImageUrl(localImageUri: Uri?, imageUrl: String?): String { - if (localImageUri == null && imageUrl.isNullOrBlank()){ + if (localImageUri == null && imageUrl.isNullOrBlank()) { throw IOException("No image is selected") } @@ -68,7 +68,7 @@ abstract class DataSubmissionBaseViewModel( } suspend fun getImageUrls(localImageUris: List?): List { - if (localImageUris.isNullOrEmpty()){ + if (localImageUris.isNullOrEmpty()) { throw IOException("No images is selected") } val listOfUrls = mutableListOf() @@ -81,10 +81,19 @@ abstract class DataSubmissionBaseViewModel( return listOfUrls } - suspend fun Iterable.mapSuspend(transform: suspend (T) -> R): List = - coroutineScope { map { t: T -> async { transform(t) } }.map { it.await() } } + suspend fun Iterable.mapSuspend(transform: suspend (T) -> R): List = + coroutineScope { map { t: T -> async { transform(t) } }.map { it.await() } } suspend fun Iterable.mapIndexSuspend(transform: suspend (index: Int, T) -> R) = - coroutineScope { mapIndexed { index: Int, t: T -> async { transform(index, t) } }.map { it.await() } } + coroutineScope { + mapIndexed { index: Int, t: T -> + async { + transform( + index, + t + ) + } + }.map { it.await() } + } } \ No newline at end of file diff --git a/app/src/main/java/h_mal/appttude/com/data/DataFieldState.kt b/app/src/main/java/h_mal/appttude/com/data/DataFieldState.kt deleted file mode 100644 index f98db94..0000000 --- a/app/src/main/java/h_mal/appttude/com/data/DataFieldState.kt +++ /dev/null @@ -1,7 +0,0 @@ -package h_mal.appttude.com.data - -sealed class DataFieldState { - object DefaultState : DataFieldState() - object NonUserStateUpdated: DataFieldState() - object UserUpdateState: DataFieldState() -} \ No newline at end of file diff --git a/app/src/main/java/h_mal/appttude/com/data/EventResponse.kt b/app/src/main/java/h_mal/appttude/com/data/EventResponse.kt index 20c0e05..5c73313 100644 --- a/app/src/main/java/h_mal/appttude/com/data/EventResponse.kt +++ b/app/src/main/java/h_mal/appttude/com/data/EventResponse.kt @@ -4,6 +4,6 @@ import com.google.firebase.database.DataSnapshot import com.google.firebase.database.DatabaseError sealed class EventResponse { - data class Changed(val snapshot: DataSnapshot): EventResponse() - data class Cancelled(val error: DatabaseError): EventResponse() + data class Changed(val snapshot: DataSnapshot) : EventResponse() + data class Cancelled(val error: DatabaseError) : EventResponse() } \ No newline at end of file diff --git a/app/src/main/java/h_mal/appttude/com/data/FirebaseAuthSource.kt b/app/src/main/java/h_mal/appttude/com/data/FirebaseAuthSource.kt index 6cd0682..c438059 100644 --- a/app/src/main/java/h_mal/appttude/com/data/FirebaseAuthSource.kt +++ b/app/src/main/java/h_mal/appttude/com/data/FirebaseAuthSource.kt @@ -5,8 +5,8 @@ import com.google.android.gms.tasks.Task import com.google.firebase.auth.* import java.io.IOException -class FirebaseAuthSource: FirebaseAuthentication{ - private val auth = FirebaseAuth.getInstance() +class FirebaseAuthSource : FirebaseAuthentication { + private val auth = FirebaseAuth.getInstance() override fun getUid(): String? = auth.uid @@ -19,7 +19,7 @@ class FirebaseAuthSource: FirebaseAuthentication{ auth.createUserWithEmailAndPassword(email, password) override fun logOut() = auth.signOut() - + override fun forgotPassword(email: String): Task = auth.sendPasswordResetEmail(email) override fun updateProfile( @@ -42,15 +42,17 @@ class FirebaseAuthSource: FirebaseAuthentication{ } override fun updateEmail(email: String): Task = getCurrentUser().updateEmail(email) - override fun updatePassword(password: String): Task = getCurrentUser().updatePassword(password) + override fun updatePassword(password: String): Task = + getCurrentUser().updatePassword(password) + override fun deleteProfile(): Task = getCurrentUser().delete() - override fun userStateListener() : FirebaseLiveData { - return FirebaseLiveData(auth) + override fun userStateListener(): FirebaseAuthStateLiveData { + return FirebaseAuthStateLiveData(auth) } - private fun getCurrentUser(): FirebaseUser{ + private fun getCurrentUser(): FirebaseUser { return getUser() ?: throw IOException("User not signed in") } } \ No newline at end of file diff --git a/app/src/main/java/h_mal/appttude/com/data/FirebaseLiveData.kt b/app/src/main/java/h_mal/appttude/com/data/FirebaseAuthStateLiveData.kt similarity index 82% rename from app/src/main/java/h_mal/appttude/com/data/FirebaseLiveData.kt rename to app/src/main/java/h_mal/appttude/com/data/FirebaseAuthStateLiveData.kt index 48962bb..a4fe5cc 100644 --- a/app/src/main/java/h_mal/appttude/com/data/FirebaseLiveData.kt +++ b/app/src/main/java/h_mal/appttude/com/data/FirebaseAuthStateLiveData.kt @@ -3,9 +3,12 @@ package h_mal.appttude.com.data import androidx.lifecycle.LiveData import com.google.firebase.auth.FirebaseAuth -class FirebaseLiveData( +/** + * Creates #LiveDate out of {UserAuthState} for firebase user state + */ +class FirebaseAuthStateLiveData( private val firebaseAuth: FirebaseAuth -): LiveData(){ +) : LiveData() { override fun onActive() { super.onActive() @@ -24,4 +27,4 @@ class FirebaseLiveData( postValue(UserAuthState.LoggedIn(p0.currentUser!!)) } } -} +} \ No newline at end of file diff --git a/app/src/main/java/h_mal/appttude/com/data/FirebaseAuthentication.kt b/app/src/main/java/h_mal/appttude/com/data/FirebaseAuthentication.kt index 1b2ee5d..db56d30 100644 --- a/app/src/main/java/h_mal/appttude/com/data/FirebaseAuthentication.kt +++ b/app/src/main/java/h_mal/appttude/com/data/FirebaseAuthentication.kt @@ -5,7 +5,7 @@ import com.google.android.gms.tasks.Task import com.google.firebase.auth.AuthResult import com.google.firebase.auth.FirebaseUser -interface FirebaseAuthentication{ +interface FirebaseAuthentication { fun getUid(): String? fun getUser(): FirebaseUser? fun signIn(email: String, password: String): Task @@ -16,12 +16,14 @@ interface FirebaseAuthentication{ name: String?, profilePic: Uri? ): Task + fun reauthenticate( email: String, password: String ): Task + fun updateEmail(email: String): Task fun updatePassword(password: String): Task fun deleteProfile(): Task - fun userStateListener() : FirebaseLiveData + fun userStateListener(): FirebaseAuthStateLiveData } \ No newline at end of file diff --git a/app/src/main/java/h_mal/appttude/com/data/FirebaseCompletion.kt b/app/src/main/java/h_mal/appttude/com/data/FirebaseCompletion.kt index 4c0ebaf..131142b 100644 --- a/app/src/main/java/h_mal/appttude/com/data/FirebaseCompletion.kt +++ b/app/src/main/java/h_mal/appttude/com/data/FirebaseCompletion.kt @@ -1,7 +1,7 @@ package h_mal.appttude.com.data -sealed class FirebaseCompletion{ - object Default: FirebaseCompletion() - data class Changed(val message: String): FirebaseCompletion() - data class ProfileDeleted(val message: String): FirebaseCompletion() +sealed class FirebaseCompletion { + object Default : FirebaseCompletion() + data class Changed(val message: String) : FirebaseCompletion() + data class ProfileDeleted(val message: String) : FirebaseCompletion() } \ No newline at end of file diff --git a/app/src/main/java/h_mal/appttude/com/data/FirebaseDatabaseSource.kt b/app/src/main/java/h_mal/appttude/com/data/FirebaseDatabaseSource.kt index 964be45..3d01044 100644 --- a/app/src/main/java/h_mal/appttude/com/data/FirebaseDatabaseSource.kt +++ b/app/src/main/java/h_mal/appttude/com/data/FirebaseDatabaseSource.kt @@ -5,7 +5,7 @@ import com.google.firebase.database.FirebaseDatabase import kotlinx.coroutines.tasks.await const val USER_CONST = "user" -const val PROFILE_ROLE ="role" +const val PROFILE_ROLE = "role" const val DRIVER_NUMBER = "driver_number" const val USER_DETAILS = "user_details" const val VEHICLE_PROFILE = "vehicle_profile" @@ -20,10 +20,17 @@ const val MOT = "mot_details" const val PRIVATE_HIRE_VEHICLE = "private_hire_vehicle" const val VEHICLE_DETAILS = "vehicle_details" const val ARCHIVE = "archive" + class FirebaseDatabaseSource { private val database = FirebaseDatabase.getInstance() - suspend fun postToDatabaseRed(ref: DatabaseReference, data: T) : T{ + /** + * Post object to the databse on reference + * + * @param ref - Database reference + * @return T returns data posted + */ + suspend fun postToDatabaseRed(ref: DatabaseReference, data: T): T { ref.setValue(data).await() return data } @@ -52,6 +59,8 @@ class FirebaseDatabaseSource { fun getArchiveLogbookRef(uid: String) = getArchiveRef(uid).child(LOG_BOOK) fun getArchiveMotDetailsRef(uid: String) = getArchiveRef(uid).child(MOT) fun getArchivePrivateHireLicenseRef(uid: String) = getArchiveRef(uid).child(PRIVATE_HIRE) - fun getArchivePrivateHireVehicleRef(uid: String) = getArchiveRef(uid).child(PRIVATE_HIRE_VEHICLE) + fun getArchivePrivateHireVehicleRef(uid: String) = + getArchiveRef(uid).child(PRIVATE_HIRE_VEHICLE) + fun getArchiveVehicleDetailsRef(uid: String) = getArchiveRef(uid).child(VEHICLE_DETAILS) } \ No newline at end of file diff --git a/app/src/main/java/h_mal/appttude/com/data/FirebaseStorageSource.kt b/app/src/main/java/h_mal/appttude/com/data/FirebaseStorageSource.kt index 323f247..8608f05 100644 --- a/app/src/main/java/h_mal/appttude/com/data/FirebaseStorageSource.kt +++ b/app/src/main/java/h_mal/appttude/com/data/FirebaseStorageSource.kt @@ -13,6 +13,7 @@ const val LOG_BOOK_SREF = "log_book" const val MOT_SREF = "mot_Details" const val PRIVATE_HIRE_SREF = "private_hire" const val PRIVATE_HIRE_VEHICLE_SREF = "private_hire_vehicle" + class FirebaseStorageSource { private val storage = FirebaseStorage.getInstance() private val storageRef: StorageReference by lazy { storage.reference } @@ -26,10 +27,13 @@ class FirebaseStorageSource { private fun usersImagesStorageRef(uid: String) = storageRef.child(IMAGE_CONST).child(uid) fun profileImageStorageRef(uid: String) = usersImagesStorageRef(uid).child(PROFILE_SREF) - fun driversLicenseStorageRef(uid: String) = usersImagesStorageRef(uid).child(DRIVERS_LICENSE_SREF) + fun driversLicenseStorageRef(uid: String) = + usersImagesStorageRef(uid).child(DRIVERS_LICENSE_SREF) + fun insuranceStorageRef(uid: String) = usersImagesStorageRef(uid).child(INSURANCE_SREF) fun logBookStorageRef(uid: String) = usersImagesStorageRef(uid).child(LOG_BOOK_SREF) fun motStorageRef(uid: String) = usersImagesStorageRef(uid).child(MOT_SREF) fun privateHireStorageRef(uid: String) = usersImagesStorageRef(uid).child(PRIVATE_HIRE_SREF) - fun privateHireVehicleStorageRef(uid: String) = usersImagesStorageRef(uid).child(PRIVATE_HIRE_VEHICLE_SREF) + fun privateHireVehicleStorageRef(uid: String) = + usersImagesStorageRef(uid).child(PRIVATE_HIRE_VEHICLE_SREF) } \ No newline at end of file diff --git a/app/src/main/java/h_mal/appttude/com/dialogs/DateDialog.kt b/app/src/main/java/h_mal/appttude/com/dialogs/DateDialog.kt index f938000..5bec251 100644 --- a/app/src/main/java/h_mal/appttude/com/dialogs/DateDialog.kt +++ b/app/src/main/java/h_mal/appttude/com/dialogs/DateDialog.kt @@ -1,7 +1,6 @@ package h_mal.appttude.com.dialogs -import android.app.AlertDialog import android.app.DatePickerDialog import android.app.DatePickerDialog.OnDateSetListener import android.icu.util.Calendar @@ -11,11 +10,12 @@ import h_mal.appttude.com.utils.DateUtils private const val DATE_FORMAT = "dd/MM/yyyy" + @Suppress("DEPRECATION") class DateDialog( private val editText: EditText, - dateSelected:(String?) -> Unit -) : DatePickerDialog(editText.context, AlertDialog.THEME_HOLO_LIGHT) { + dateSelected: (String?) -> Unit +) : DatePickerDialog(editText.context) { private val dateSetListener: OnDateSetListener = OnDateSetListener { _, year, month, dayOfMonth -> @@ -29,11 +29,15 @@ class DateDialog( } init { + datePicker.apply { + spinnersShown = true + calendarViewShown = false + } val dateString = editText.text?.toString() - val date = if (dateString.isNullOrBlank()){ + val date = if (dateString.isNullOrBlank()) { // Set time to now Calendar.getInstance() - }else{ + } else { // Parse current edit text string and set value DateUtils.parseDateStringIntoCalender(dateString, DATE_FORMAT) ?: Calendar.getInstance() @@ -44,7 +48,7 @@ class DateDialog( show() } - private fun setDateFromCalender(calendar: Calendar){ + private fun setDateFromCalender(calendar: Calendar) { val mYear = calendar.get(Calendar.YEAR) val mMonth = calendar.get(Calendar.MONTH) val mDay = calendar.get(Calendar.DAY_OF_MONTH) @@ -52,5 +56,4 @@ class DateDialog( updateDate(mYear, mMonth, mDay) } - } \ No newline at end of file diff --git a/app/src/main/java/h_mal/appttude/com/dialogs/ExitDialog.kt b/app/src/main/java/h_mal/appttude/com/dialogs/ExitDialog.kt index 075def3..15bda6b 100644 --- a/app/src/main/java/h_mal/appttude/com/dialogs/ExitDialog.kt +++ b/app/src/main/java/h_mal/appttude/com/dialogs/ExitDialog.kt @@ -2,23 +2,22 @@ package h_mal.appttude.com.dialogs import android.app.Activity import android.app.AlertDialog -import androidx.fragment.app.Fragment +import h_mal.appttude.com.R import kotlin.system.exitProcess -object ExitDialog{ +object ExitDialog { fun Activity.displayExitDialog() = AlertDialog.Builder(this) - .setTitle("Leave?") - .setMessage("Are you sure you want to exit?") - .setNegativeButton(android.R.string.cancel, null) - .setPositiveButton( - android.R.string.ok - ) { _, _ -> - finish() - exitProcess(0) - } - .create() - .show() + .setTitle(getString(R.string.leave_header)) + .setMessage(getString(R.string.leave_message)) + .setNegativeButton(android.R.string.cancel, null) + .setPositiveButton( + android.R.string.ok + ) { _, _ -> + finish() + exitProcess(0) + } + .create() + .show() - fun Fragment.displayExitDialog() = requireActivity().displayExitDialog() } \ No newline at end of file diff --git a/app/src/main/java/h_mal/appttude/com/model/DriverProfileObject.kt b/app/src/main/java/h_mal/appttude/com/model/DriverProfile.kt similarity index 87% rename from app/src/main/java/h_mal/appttude/com/model/DriverProfileObject.kt rename to app/src/main/java/h_mal/appttude/com/model/DriverProfile.kt index b1d70a4..c48c2b2 100644 --- a/app/src/main/java/h_mal/appttude/com/model/DriverProfileObject.kt +++ b/app/src/main/java/h_mal/appttude/com/model/DriverProfile.kt @@ -1,8 +1,6 @@ package h_mal.appttude.com.model - - -data class DriverProfileObject( +data class DriverProfile( var driverPic: String? = null, var forenames: String? = null, var address: String? = null, diff --git a/app/src/main/java/h_mal/appttude/com/model/DriversLicenseObject.kt b/app/src/main/java/h_mal/appttude/com/model/DriversLicense.kt similarity index 82% rename from app/src/main/java/h_mal/appttude/com/model/DriversLicenseObject.kt rename to app/src/main/java/h_mal/appttude/com/model/DriversLicense.kt index d1cb240..6ef594b 100644 --- a/app/src/main/java/h_mal/appttude/com/model/DriversLicenseObject.kt +++ b/app/src/main/java/h_mal/appttude/com/model/DriversLicense.kt @@ -1,7 +1,7 @@ package h_mal.appttude.com.model -data class DriversLicenseObject( +data class DriversLicense( var licenseImageString: String? = null, var licenseNumber: String? = null, var licenseExpiry: String? = null diff --git a/app/src/main/java/h_mal/appttude/com/model/InsuranceObject.kt b/app/src/main/java/h_mal/appttude/com/model/Insurance.kt similarity index 83% rename from app/src/main/java/h_mal/appttude/com/model/InsuranceObject.kt rename to app/src/main/java/h_mal/appttude/com/model/Insurance.kt index be7d563..d418585 100644 --- a/app/src/main/java/h_mal/appttude/com/model/InsuranceObject.kt +++ b/app/src/main/java/h_mal/appttude/com/model/Insurance.kt @@ -1,8 +1,6 @@ package h_mal.appttude.com.model - - -data class InsuranceObject ( +data class Insurance( var photoStrings: MutableList? = null, var insurerName: String? = null, var expiryDate: String? = null diff --git a/app/src/main/java/h_mal/appttude/com/model/LogbookObject.kt b/app/src/main/java/h_mal/appttude/com/model/Logbook.kt similarity index 80% rename from app/src/main/java/h_mal/appttude/com/model/LogbookObject.kt rename to app/src/main/java/h_mal/appttude/com/model/Logbook.kt index 3559d66..73f0904 100644 --- a/app/src/main/java/h_mal/appttude/com/model/LogbookObject.kt +++ b/app/src/main/java/h_mal/appttude/com/model/Logbook.kt @@ -1,8 +1,7 @@ package h_mal.appttude.com.model - -data class LogbookObject( +data class Logbook( var photoString: String? = null, var v5cnumber: String? = null ) diff --git a/app/src/main/java/h_mal/appttude/com/model/MotObject.kt b/app/src/main/java/h_mal/appttude/com/model/Mot.kt similarity index 81% rename from app/src/main/java/h_mal/appttude/com/model/MotObject.kt rename to app/src/main/java/h_mal/appttude/com/model/Mot.kt index e0b42ee..fcf519d 100644 --- a/app/src/main/java/h_mal/appttude/com/model/MotObject.kt +++ b/app/src/main/java/h_mal/appttude/com/model/Mot.kt @@ -1,8 +1,7 @@ package h_mal.appttude.com.model - -data class MotObject( +data class Mot( var motImageString: String? = null, var motExpiry: String? = null ) \ No newline at end of file diff --git a/app/src/main/java/h_mal/appttude/com/model/PrivateHireObject.kt b/app/src/main/java/h_mal/appttude/com/model/PrivateHireLicense.kt similarity index 81% rename from app/src/main/java/h_mal/appttude/com/model/PrivateHireObject.kt rename to app/src/main/java/h_mal/appttude/com/model/PrivateHireLicense.kt index ea27ec6..11b554a 100644 --- a/app/src/main/java/h_mal/appttude/com/model/PrivateHireObject.kt +++ b/app/src/main/java/h_mal/appttude/com/model/PrivateHireLicense.kt @@ -1,8 +1,7 @@ package h_mal.appttude.com.model - -data class PrivateHireObject ( +data class PrivateHireLicense( var phImageString: String? = null, var phNumber: String? = null, var phExpiry: String? = null diff --git a/app/src/main/java/h_mal/appttude/com/model/PrivateHireVehicleObject.kt b/app/src/main/java/h_mal/appttude/com/model/PrivateHireVehicle.kt similarity index 81% rename from app/src/main/java/h_mal/appttude/com/model/PrivateHireVehicleObject.kt rename to app/src/main/java/h_mal/appttude/com/model/PrivateHireVehicle.kt index f6defbc..0da565f 100644 --- a/app/src/main/java/h_mal/appttude/com/model/PrivateHireVehicleObject.kt +++ b/app/src/main/java/h_mal/appttude/com/model/PrivateHireVehicle.kt @@ -1,8 +1,7 @@ package h_mal.appttude.com.model - -class PrivateHireVehicleObject( +class PrivateHireVehicle( var phCarImageString: String? = null, var phCarNumber: String? = null, var phCarExpiry: String? = null diff --git a/app/src/main/java/h_mal/appttude/com/model/VehicleProfileObject.kt b/app/src/main/java/h_mal/appttude/com/model/VehicleProfile.kt similarity index 90% rename from app/src/main/java/h_mal/appttude/com/model/VehicleProfileObject.kt rename to app/src/main/java/h_mal/appttude/com/model/VehicleProfile.kt index fddf3a8..e5fa101 100644 --- a/app/src/main/java/h_mal/appttude/com/model/VehicleProfileObject.kt +++ b/app/src/main/java/h_mal/appttude/com/model/VehicleProfile.kt @@ -1,8 +1,7 @@ package h_mal.appttude.com.model - -data class VehicleProfileObject( +data class VehicleProfile( var reg: String? = null, var make: String? = null, var model: String? = null, diff --git a/app/src/main/java/h_mal/appttude/com/ui/update/DeleteProfileFragment.kt b/app/src/main/java/h_mal/appttude/com/ui/update/DeleteProfileFragment.kt index 35e1a63..545141d 100644 --- a/app/src/main/java/h_mal/appttude/com/ui/update/DeleteProfileFragment.kt +++ b/app/src/main/java/h_mal/appttude/com/ui/update/DeleteProfileFragment.kt @@ -1,33 +1,25 @@ package h_mal.appttude.com.ui.update -import android.os.Bundle -import android.view.View -import androidx.fragment.app.activityViewModels -import h_mal.appttude.com.R import h_mal.appttude.com.base.BaseFragment +import h_mal.appttude.com.databinding.FragmentDeleteProfileBinding import h_mal.appttude.com.utils.TextValidationUtils.validatePasswordEditText import h_mal.appttude.com.utils.setEnterPressedListener import h_mal.appttude.com.viewmodels.UpdateUserViewModel -import kotlinx.android.synthetic.main.fragment_delete_profile.* -class DeleteProfileFragment : BaseFragment(R.layout.fragment_delete_profile) { +class DeleteProfileFragment : + BaseFragment() { - private val viewmodel: UpdateUserViewModel by activityViewModels() - override fun getViewModel(): UpdateUserViewModel = viewmodel - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - password_top.setEnterPressedListener { deleteUser() } - submission_button_label.setOnClickListener { deleteUser() } + override fun setupView(binding: FragmentDeleteProfileBinding) = binding.run { + passwordTop.setEnterPressedListener { deleteUser() } + submissionButtonLabel.setOnClickListener { deleteUser() } } - private fun deleteUser(){ - val emailString = email_update.validatePasswordEditText() ?: return - val passwordText = password_top.validatePasswordEditText() ?: return + private fun deleteUser() = applyBinding { + val emailString = emailUpdate.validatePasswordEditText() ?: return@applyBinding + val passwordText = passwordTop.validatePasswordEditText() ?: return@applyBinding - getViewModel().deleteProfile(emailString, passwordText) + viewModel.deleteProfile(emailString, passwordText) } } \ No newline at end of file diff --git a/app/src/main/java/h_mal/appttude/com/ui/update/UpdateActivity.kt b/app/src/main/java/h_mal/appttude/com/ui/update/UpdateActivity.kt index 56d820d..3b2dc7f 100644 --- a/app/src/main/java/h_mal/appttude/com/ui/update/UpdateActivity.kt +++ b/app/src/main/java/h_mal/appttude/com/ui/update/UpdateActivity.kt @@ -1,25 +1,16 @@ package h_mal.appttude.com.ui.update -import android.os.Bundle -import h_mal.appttude.com.R import h_mal.appttude.com.base.BaseActivity import h_mal.appttude.com.data.FirebaseCompletion +import h_mal.appttude.com.databinding.UpdateActivityBinding import h_mal.appttude.com.utils.displayToast import h_mal.appttude.com.viewmodels.UpdateUserViewModel -class UpdateActivity : BaseActivity() { - - override val layoutId: Int = R.layout.update_activity - override fun getViewModel(): UpdateUserViewModel? = null - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - createViewModel() - } +class UpdateActivity : BaseActivity() { override fun onSuccess(data: Any?) { super.onSuccess(data) - when(data){ + when (data) { is FirebaseCompletion.Changed -> displayToast(data.message) } } diff --git a/app/src/main/java/h_mal/appttude/com/ui/update/UpdateEmailFragment.kt b/app/src/main/java/h_mal/appttude/com/ui/update/UpdateEmailFragment.kt index 3adcc71..020edc8 100644 --- a/app/src/main/java/h_mal/appttude/com/ui/update/UpdateEmailFragment.kt +++ b/app/src/main/java/h_mal/appttude/com/ui/update/UpdateEmailFragment.kt @@ -1,36 +1,28 @@ package h_mal.appttude.com.ui.update -import android.os.Bundle -import android.view.View -import androidx.fragment.app.activityViewModels -import h_mal.appttude.com.R import h_mal.appttude.com.base.BaseFragment +import h_mal.appttude.com.databinding.FragmentUpdateEmailBinding import h_mal.appttude.com.utils.TextValidationUtils.validateEmailEditText import h_mal.appttude.com.utils.TextValidationUtils.validatePasswordEditText import h_mal.appttude.com.utils.setEnterPressedListener import h_mal.appttude.com.viewmodels.UpdateUserViewModel -import kotlinx.android.synthetic.main.fragment_update_email.* -class UpdateEmailFragment : BaseFragment(R.layout.fragment_update_email) { +class UpdateEmailFragment : BaseFragment() { - private val viewmodel: UpdateUserViewModel by activityViewModels() - override fun getViewModel(): UpdateUserViewModel = viewmodel - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - new_email.setEnterPressedListener { registerUser() } - submission_button_label.setOnClickListener { registerUser() } + override fun setupView(binding: FragmentUpdateEmailBinding) = binding.run { + newEmail.setEnterPressedListener { registerUser() } + submissionButtonLabel.setOnClickListener { registerUser() } } - private fun registerUser(){ - val emailString = email_update.validatePasswordEditText() ?: return - val passwordText = password_top.validatePasswordEditText() ?: return - val newEmail = new_email.validateEmailEditText() ?: return + private fun registerUser() { + applyBinding { + val emailString = emailUpdate.validatePasswordEditText() ?: return@applyBinding + val passwordText = passwordTop.validatePasswordEditText() ?: return@applyBinding + val newEmail = newEmail.validateEmailEditText() ?: return@applyBinding - getViewModel().updateEmail(emailString, passwordText, newEmail) + viewModel.updateEmail(emailString, passwordText, newEmail) + } } - } \ No newline at end of file diff --git a/app/src/main/java/h_mal/appttude/com/ui/update/UpdateOverviewFragment.kt b/app/src/main/java/h_mal/appttude/com/ui/update/UpdateOverviewFragment.kt index fe79287..9d39319 100644 --- a/app/src/main/java/h_mal/appttude/com/ui/update/UpdateOverviewFragment.kt +++ b/app/src/main/java/h_mal/appttude/com/ui/update/UpdateOverviewFragment.kt @@ -1,30 +1,25 @@ package h_mal.appttude.com.ui.update -import android.os.Bundle import android.view.View -import androidx.fragment.app.activityViewModels import h_mal.appttude.com.R import h_mal.appttude.com.base.BaseFragment +import h_mal.appttude.com.databinding.UpdateOverviewFragmentBinding import h_mal.appttude.com.utils.navigateTo import h_mal.appttude.com.viewmodels.UpdateUserViewModel -import kotlinx.android.synthetic.main.update_overview_fragment.* -class UpdateOverviewFragment : BaseFragment(R.layout.update_overview_fragment), View.OnClickListener { +class UpdateOverviewFragment : BaseFragment(), + View.OnClickListener { - private val vm by activityViewModels() - override fun getViewModel(): UpdateUserViewModel = vm - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - update_email_button.setOnClickListener(this) - update_password_button.setOnClickListener(this) - update_profile_button.setOnClickListener(this) - delete_profile.setOnClickListener(this) + override fun setupView(binding: UpdateOverviewFragmentBinding) = binding.run { + updateEmailButton.setOnClickListener(this@UpdateOverviewFragment) + updatePasswordButton.setOnClickListener(this@UpdateOverviewFragment) + updateProfileButton.setOnClickListener(this@UpdateOverviewFragment) + deleteProfile.setOnClickListener(this@UpdateOverviewFragment) } - private fun View.submit(){ - when(id){ + + private fun View.submit() { + when (id) { R.id.update_email_button -> navigateTo(R.id.to_updateEmailFragment) R.id.update_password_button -> navigateTo(R.id.to_updatePasswordFragment) R.id.update_profile_button -> navigateTo(R.id.to_updateProfileFragment) @@ -32,9 +27,8 @@ class UpdateOverviewFragment : BaseFragment(R.layout.update } } - override fun onClick(v: View?){ + override fun onClick(v: View?) { v?.submit() } - } \ No newline at end of file diff --git a/app/src/main/java/h_mal/appttude/com/ui/update/UpdatePasswordFragment.kt b/app/src/main/java/h_mal/appttude/com/ui/update/UpdatePasswordFragment.kt index 6abedb8..63970b3 100644 --- a/app/src/main/java/h_mal/appttude/com/ui/update/UpdatePasswordFragment.kt +++ b/app/src/main/java/h_mal/appttude/com/ui/update/UpdatePasswordFragment.kt @@ -1,36 +1,30 @@ package h_mal.appttude.com.ui.update -import android.os.Bundle -import android.view.View -import androidx.fragment.app.activityViewModels -import h_mal.appttude.com.R import h_mal.appttude.com.base.BaseFragment +import h_mal.appttude.com.databinding.FragmentUpdatePasswordBinding import h_mal.appttude.com.utils.TextValidationUtils.validateEmailEditText import h_mal.appttude.com.utils.TextValidationUtils.validatePasswordEditText import h_mal.appttude.com.utils.setEnterPressedListener import h_mal.appttude.com.viewmodels.UpdateUserViewModel -import kotlinx.android.synthetic.main.fragment_update_password.* -class UpdatePasswordFragment : - BaseFragment(R.layout.fragment_update_password) { +class UpdatePasswordFragment : BaseFragment() { - private val viewmodel: UpdateUserViewModel by activityViewModels() - override fun getViewModel(): UpdateUserViewModel = viewmodel - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - email_update.setEnterPressedListener { registerUser() } - email_sign_up.setOnClickListener { registerUser() } + override fun setupView(binding: FragmentUpdatePasswordBinding) { + applyBinding { + emailUpdate.setEnterPressedListener { registerUser() } + emailSignUp.setOnClickListener { registerUser() } + } } private fun registerUser() { - val emailString = email_update.validatePasswordEditText() ?: return - val passwordText = password_top.validatePasswordEditText() ?: return - val newPassword = password_bottom.validateEmailEditText() ?: return + applyBinding { + val emailString = emailUpdate.validatePasswordEditText() ?: return@applyBinding + val passwordText = passwordTop.validatePasswordEditText() ?: return@applyBinding + val newPassword = passwordBottom.validateEmailEditText() ?: return@applyBinding - getViewModel().updatePassword(emailString, passwordText, newPassword) + viewModel.updatePassword(emailString, passwordText, newPassword) + } } } \ No newline at end of file diff --git a/app/src/main/java/h_mal/appttude/com/ui/update/UpdateProfileFragment.kt b/app/src/main/java/h_mal/appttude/com/ui/update/UpdateProfileFragment.kt index 6d01701..6f71e78 100644 --- a/app/src/main/java/h_mal/appttude/com/ui/update/UpdateProfileFragment.kt +++ b/app/src/main/java/h_mal/appttude/com/ui/update/UpdateProfileFragment.kt @@ -2,39 +2,29 @@ package h_mal.appttude.com.ui.update import android.Manifest.permission.READ_EXTERNAL_STORAGE import android.net.Uri -import android.os.Bundle -import android.view.View import androidx.core.widget.doAfterTextChanged -import androidx.fragment.app.activityViewModels import com.google.firebase.auth.FirebaseUser -import h_mal.appttude.com.R import h_mal.appttude.com.base.BaseFragment +import h_mal.appttude.com.databinding.FragmentUpdateProfileBinding import h_mal.appttude.com.utils.PermissionsUtils.askForPermissions import h_mal.appttude.com.utils.setEnterPressedListener import h_mal.appttude.com.utils.setGlideImage - import h_mal.appttude.com.viewmodels.UpdateUserViewModel -import kotlinx.android.synthetic.main.fragment_update_profile.* const val TAG_CONST = "non-user" private const val IMAGE_PERMISSION_RESULT = 402 -class UpdateProfileFragment : BaseFragment(R.layout.fragment_update_profile) { - - private val viewmodel: UpdateUserViewModel by activityViewModels() - override fun getViewModel(): UpdateUserViewModel = viewmodel +class UpdateProfileFragment : BaseFragment() { private var imageChangeListener: Boolean = false private var nameChangeListener: Boolean = false private var imageUri: Uri? = null - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) + override fun setupView(binding: FragmentUpdateProfileBinding) = binding.run { + viewModel.getUser() - viewmodel.getUser() - - update_name.apply { + updateName.apply { doAfterTextChanged { if (tag == TAG_CONST) { tag = null @@ -45,20 +35,22 @@ class UpdateProfileFragment : BaseFragment(R.layout.fragmen setEnterPressedListener { submitProfileUpdate() } } - profile_img.setOnClickListener { + profileImg.setOnClickListener { if (askForPermissions(READ_EXTERNAL_STORAGE, IMAGE_PERMISSION_RESULT)) { openGalleryForImage() } } - submit_update_profile.setOnClickListener { submitProfileUpdate() } + submitUpdateProfile.setOnClickListener { submitProfileUpdate() } } private fun submitProfileUpdate() { - val name: String? = takeIf { nameChangeListener }?.update_name?.text?.toString() - val imgUri = takeIf { imageChangeListener }?.let { imageUri } + applyBinding { + val name: String? = takeIf { nameChangeListener }?.updateName?.text?.toString() + val imgUri = takeIf { imageChangeListener }?.let { imageUri } - viewmodel.updateProfile(name, imgUri) + viewModel.updateProfile(name, imgUri) + } } override fun onRequestPermissionsResult( @@ -76,18 +68,24 @@ class UpdateProfileFragment : BaseFragment(R.layout.fragmen } private fun setFields(firebaseUser: FirebaseUser) { - profile_img.setGlideImage(firebaseUser.photoUrl) - update_name.apply { - setText(firebaseUser.displayName) - tag = TAG_CONST + applyBinding { + profileImg.setGlideImage(firebaseUser.photoUrl) + updateName.apply { + setText(firebaseUser.displayName) + tag = TAG_CONST + } } + } override fun onImageGalleryResult(imageUri: Uri?) { super.onImageGalleryResult(imageUri) this.imageUri = imageUri - profile_img.setGlideImage(imageUri) - imageChangeListener = true + applyBinding { + profileImg.setGlideImage(imageUri) + imageChangeListener = true + } + } } \ No newline at end of file diff --git a/app/src/main/java/h_mal/appttude/com/ui/user/ForgotPasswordFragment.kt b/app/src/main/java/h_mal/appttude/com/ui/user/ForgotPasswordFragment.kt index 4b74413..7d458ed 100644 --- a/app/src/main/java/h_mal/appttude/com/ui/user/ForgotPasswordFragment.kt +++ b/app/src/main/java/h_mal/appttude/com/ui/user/ForgotPasswordFragment.kt @@ -1,26 +1,17 @@ package h_mal.appttude.com.ui.user -import android.os.Bundle -import android.view.View -import androidx.fragment.app.activityViewModels -import h_mal.appttude.com.R import h_mal.appttude.com.base.BaseFragment +import h_mal.appttude.com.databinding.FragmentForgotPasswordBinding import h_mal.appttude.com.utils.TextValidationUtils.validateEmailEditText import h_mal.appttude.com.viewmodels.UserViewModel -import kotlinx.android.synthetic.main.fragment_forgot_password.* -class ForgotPasswordFragment : BaseFragment(R.layout.fragment_forgot_password) { +class ForgotPasswordFragment : BaseFragment() { - private val userViewModel: UserViewModel by activityViewModels() - override fun getViewModel(): UserViewModel = userViewModel - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - submission_button.setOnClickListener { - val emailString = submission_et.validateEmailEditText() ?: return@setOnClickListener - userViewModel.forgotPassword(emailString) + override fun setupView(binding: FragmentForgotPasswordBinding) = binding.run { + submissionButton.setOnClickListener { + val emailString = submissionEt.validateEmailEditText() ?: return@setOnClickListener + viewModel.forgotPassword(emailString) } } diff --git a/app/src/main/java/h_mal/appttude/com/ui/user/LoginActivity.kt b/app/src/main/java/h_mal/appttude/com/ui/user/LoginActivity.kt index c9a1647..32f8249 100644 --- a/app/src/main/java/h_mal/appttude/com/ui/user/LoginActivity.kt +++ b/app/src/main/java/h_mal/appttude/com/ui/user/LoginActivity.kt @@ -2,11 +2,10 @@ package h_mal.appttude.com.ui.user import android.content.Intent -import android.os.Bundle import com.google.firebase.auth.AuthResult import com.google.firebase.auth.FirebaseUser -import h_mal.appttude.com.R import h_mal.appttude.com.base.BaseActivity +import h_mal.appttude.com.databinding.ActivityLoginBinding import h_mal.appttude.com.ui.MainActivity import h_mal.appttude.com.viewmodels.UserViewModel @@ -14,15 +13,7 @@ import h_mal.appttude.com.viewmodels.UserViewModel /** * A login screen that offers login via email/password. */ -class LoginActivity : BaseActivity() { - - override fun getViewModel(): UserViewModel? = null - override val layoutId: Int = R.layout.activity_login - - override fun onCreate(savedInstanceState: Bundle?) { - createViewModel() - super.onCreate(savedInstanceState) - } +class LoginActivity : BaseActivity() { override fun onSuccess(data: Any?) { super.onSuccess(data) diff --git a/app/src/main/java/h_mal/appttude/com/ui/user/LoginFragment.kt b/app/src/main/java/h_mal/appttude/com/ui/user/LoginFragment.kt index 2c8109d..551514d 100644 --- a/app/src/main/java/h_mal/appttude/com/ui/user/LoginFragment.kt +++ b/app/src/main/java/h_mal/appttude/com/ui/user/LoginFragment.kt @@ -1,39 +1,32 @@ package h_mal.appttude.com.ui.user -import android.os.Bundle -import android.view.View -import androidx.fragment.app.activityViewModels import h_mal.appttude.com.R import h_mal.appttude.com.base.BaseFragment +import h_mal.appttude.com.databinding.FragmentLoginBinding import h_mal.appttude.com.utils.TextValidationUtils.validateEmailEditText import h_mal.appttude.com.utils.TextValidationUtils.validatePasswordEditText import h_mal.appttude.com.utils.navigateTo import h_mal.appttude.com.utils.setEnterPressedListener import h_mal.appttude.com.viewmodels.UserViewModel -import kotlinx.android.synthetic.main.fragment_login.* -class LoginFragment : BaseFragment(R.layout.fragment_login) { - - private val userViewModel: UserViewModel by activityViewModels() - override fun getViewModel(): UserViewModel = userViewModel - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) +class LoginFragment : BaseFragment() { + override fun setupView(binding: FragmentLoginBinding) = binding.run { password.setEnterPressedListener { attemptLogin() } - - email_sign_in_button.setOnClickListener { attemptLogin() } - register_button.setOnClickListener { it.navigateTo(R.id.to_register) } + emailSignInButton.setOnClickListener { attemptLogin() } + registerButton.setOnClickListener { it.navigateTo(R.id.to_register) } forgot.setOnClickListener { it.navigateTo(R.id.to_forgotPassword) } } - private fun attemptLogin(){ - // Store values at the time of the login attempt. - val emailString = email.validateEmailEditText() ?: return - val passwordString = password.validatePasswordEditText() ?: return + private fun attemptLogin() { + applyBinding { + // Store values at the time of the login attempt. + val emailString = email.validateEmailEditText() ?: return@applyBinding + val passwordString = password.validatePasswordEditText() ?: return@applyBinding - // attempt to login user - getViewModel().signInUser(emailString, passwordString) + // attempt to login user + viewModel.signInUser(emailString, passwordString) + } } } \ No newline at end of file diff --git a/app/src/main/java/h_mal/appttude/com/ui/user/RegisterFragment.kt b/app/src/main/java/h_mal/appttude/com/ui/user/RegisterFragment.kt index f890728..dd98732 100644 --- a/app/src/main/java/h_mal/appttude/com/ui/user/RegisterFragment.kt +++ b/app/src/main/java/h_mal/appttude/com/ui/user/RegisterFragment.kt @@ -1,42 +1,37 @@ package h_mal.appttude.com.ui.user -import android.os.Bundle -import android.view.View -import androidx.fragment.app.activityViewModels import h_mal.appttude.com.R import h_mal.appttude.com.base.BaseFragment +import h_mal.appttude.com.databinding.FragmentRegisterBinding import h_mal.appttude.com.utils.TextValidationUtils.validateEmailEditText import h_mal.appttude.com.utils.TextValidationUtils.validatePasswordEditText import h_mal.appttude.com.utils.setEnterPressedListener import h_mal.appttude.com.viewmodels.UserViewModel -import kotlinx.android.synthetic.main.fragment_register.* -class RegisterFragment : BaseFragment(R.layout.fragment_register) { +class RegisterFragment : + BaseFragment() { - override fun getViewModel(): UserViewModel { - val userViewModel: UserViewModel by activityViewModels() - return userViewModel + override fun setupView(binding: FragmentRegisterBinding) = binding.run { + passwordBottom.setEnterPressedListener { registerUser() } + emailSignUp.setOnClickListener { registerUser() } } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) + private fun registerUser() { + applyBinding { + val nameString = nameRegister.validatePasswordEditText() ?: return@applyBinding + val emailText = emailRegister.validateEmailEditText() ?: return@applyBinding + val passwordText = passwordTop.validatePasswordEditText() ?: return@applyBinding + val passwordTextBottom = + passwordBottom.validatePasswordEditText() ?: return@applyBinding - password_bottom.setEnterPressedListener { registerUser() } - email_sign_up.setOnClickListener { registerUser() } - } + if ((passwordText != passwordTextBottom)) { + passwordBottom.error = getString(R.string.no_match_password) + passwordBottom.requestFocus() + return@applyBinding + } - private fun registerUser(){ - val nameString = name_register.validatePasswordEditText() ?: return - val emailText = email_register.validateEmailEditText() ?: return - val passwordText = password_top.validatePasswordEditText() ?: return - val passwordTextBottom = password_bottom.validatePasswordEditText() ?: return - - if ((passwordText != passwordTextBottom)) { - password_bottom.error = getString(R.string.no_match_password) - password_bottom.requestFocus() - return + viewModel.registerUser(nameString, emailText, passwordText) } - getViewModel().registerUser(nameString, emailText, passwordText) } } \ No newline at end of file diff --git a/app/src/main/java/h_mal/appttude/com/ui/user/SplashScreenFragment.kt b/app/src/main/java/h_mal/appttude/com/ui/user/SplashScreenFragment.kt index 0f96cee..cb4b696 100644 --- a/app/src/main/java/h_mal/appttude/com/ui/user/SplashScreenFragment.kt +++ b/app/src/main/java/h_mal/appttude/com/ui/user/SplashScreenFragment.kt @@ -2,23 +2,20 @@ package h_mal.appttude.com.ui.user import android.os.Bundle import android.view.View -import androidx.fragment.app.activityViewModels import h_mal.appttude.com.R import h_mal.appttude.com.base.BaseFragment import h_mal.appttude.com.data.FirebaseCompletion +import h_mal.appttude.com.databinding.SplashScreenBinding import h_mal.appttude.com.utils.navigateTo import h_mal.appttude.com.viewmodels.UserViewModel -class SplashScreenFragment : BaseFragment(R.layout.fragment_splash_screen) { - - private val userViewModel by activityViewModels() - override fun getViewModel(): UserViewModel = userViewModel +class SplashScreenFragment : BaseFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - userViewModel.splashscreenCheckUserIsLoggedIn() + viewModel.splashscreenCheckUserIsLoggedIn() } override fun onSuccess(data: Any?) { diff --git a/app/src/main/java/h_mal/appttude/com/utils/AnimationUtils.kt b/app/src/main/java/h_mal/appttude/com/utils/AnimationUtils.kt index 513fc1e..e092c30 100644 --- a/app/src/main/java/h_mal/appttude/com/utils/AnimationUtils.kt +++ b/app/src/main/java/h_mal/appttude/com/utils/AnimationUtils.kt @@ -5,7 +5,7 @@ import android.view.animation.Animation import android.view.animation.AnimationUtils import androidx.annotation.AnimRes -fun View.triggerAnimation(@AnimRes id:Int, complete:(View) -> Unit){ +fun View.triggerAnimation(@AnimRes id: Int, complete: (View) -> Unit) { val animation = AnimationUtils.loadAnimation(context, id) animation.setAnimationListener(object : Animation.AnimationListener { override fun onAnimationEnd(animation: Animation?) = complete(this@triggerAnimation) diff --git a/app/src/main/java/h_mal/appttude/com/utils/Coroutines.kt b/app/src/main/java/h_mal/appttude/com/utils/Coroutines.kt index 834fbcd..6ee55dd 100644 --- a/app/src/main/java/h_mal/appttude/com/utils/Coroutines.kt +++ b/app/src/main/java/h_mal/appttude/com/utils/Coroutines.kt @@ -4,7 +4,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -object Coroutines{ +object Coroutines { fun io(work: suspend () -> Unit) = CoroutineScope(Dispatchers.IO).launch { work() } fun main(work: suspend () -> Unit) = CoroutineScope(Dispatchers.Main).launch { work() } diff --git a/app/src/main/java/h_mal/appttude/com/utils/DateUtils.kt b/app/src/main/java/h_mal/appttude/com/utils/DateUtils.kt index f0b01d1..d2fa568 100644 --- a/app/src/main/java/h_mal/appttude/com/utils/DateUtils.kt +++ b/app/src/main/java/h_mal/appttude/com/utils/DateUtils.kt @@ -11,7 +11,7 @@ object DateUtils { return sdf.format(Date()) } - fun getDateTimeStamp(): String{ + fun getDateTimeStamp(): String { val sdf: SimpleDateFormat = getSimpleDateFormat("yyyyMMdd_HHmmss") return sdf.format(Date()) } @@ -23,7 +23,7 @@ object DateUtils { val sdfOut = getSimpleDateFormat(formatOut) val newDate: Date = sdfIn.parse(this) sdfOut.format(newDate) - }catch (e: Exception){ + } catch (e: Exception) { e.printStackTrace() this } diff --git a/app/src/main/java/h_mal/appttude/com/utils/Extensions.kt b/app/src/main/java/h_mal/appttude/com/utils/Extensions.kt new file mode 100644 index 0000000..0f94d5e --- /dev/null +++ b/app/src/main/java/h_mal/appttude/com/utils/Extensions.kt @@ -0,0 +1,16 @@ +package h_mal.appttude.com.utils + + +inline fun Boolean.isTrue(block: () -> Unit){ + if (this) { + block() + } +} + +inline fun T.isNotNull(block: (T) -> R): R?{ + return if (this != null) { + block(this) + } else { + null + } +} \ No newline at end of file diff --git a/app/src/main/java/h_mal/appttude/com/utils/FirebaseUtils.kt b/app/src/main/java/h_mal/appttude/com/utils/FirebaseUtils.kt index 8ac5ac8..2b333c4 100644 --- a/app/src/main/java/h_mal/appttude/com/utils/FirebaseUtils.kt +++ b/app/src/main/java/h_mal/appttude/com/utils/FirebaseUtils.kt @@ -8,10 +8,14 @@ import h_mal.appttude.com.data.EventResponse import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine - - +/** + * Read database reference once {@link #DatabaseReference.addListenerForSingleValueEvent} + * + * + * @return EventResponse + */ suspend fun DatabaseReference.singleValueEvent(): EventResponse = suspendCoroutine { continuation -> - val valueEventListener = object: ValueEventListener { + val valueEventListener = object : ValueEventListener { override fun onCancelled(error: DatabaseError) { continuation.resume(EventResponse.Cancelled(error)) } @@ -23,7 +27,13 @@ suspend fun DatabaseReference.singleValueEvent(): EventResponse = suspendCorouti addListenerForSingleValueEvent(valueEventListener) } -suspend inline fun DatabaseReference.getDataFromDatabaseRef(): T?{ +/** + * Read database reference once {@link #DatabaseReference.addListenerForSingleValueEvent} + * + * + * @return T + */ +suspend inline fun DatabaseReference.getDataFromDatabaseRef(): T? { return when (val response: EventResponse = singleValueEvent()) { is EventResponse.Changed -> { response.snapshot.getValue(T::class.java) diff --git a/app/src/main/java/h_mal/appttude/com/utils/NavigationUtils.kt b/app/src/main/java/h_mal/appttude/com/utils/NavigationUtils.kt index da3df41..102f2d1 100644 --- a/app/src/main/java/h_mal/appttude/com/utils/NavigationUtils.kt +++ b/app/src/main/java/h_mal/appttude/com/utils/NavigationUtils.kt @@ -19,7 +19,7 @@ fun navigateToActivity(context: Context, navigationActivity: Navigations) { } } -fun View.navigateTo(@IdRes navId: Int){ +fun View.navigateTo(@IdRes navId: Int) { Navigation .findNavController(this) .navigate(navId) diff --git a/app/src/main/java/h_mal/appttude/com/utils/ViewUtils.kt b/app/src/main/java/h_mal/appttude/com/utils/ViewUtils.kt index 20dc409..7efeb5f 100644 --- a/app/src/main/java/h_mal/appttude/com/utils/ViewUtils.kt +++ b/app/src/main/java/h_mal/appttude/com/utils/ViewUtils.kt @@ -103,6 +103,7 @@ fun ImageView.setPicassoImage( context?.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url))) } } + override fun onBitmapFailed(e: Exception?, errorDrawable: Drawable?) {} override fun onPrepareLoad(placeHolderDrawable: Drawable?) {} }) diff --git a/app/src/main/java/h_mal/appttude/com/viewmodels/DriverLicenseViewModel.kt b/app/src/main/java/h_mal/appttude/com/viewmodels/DriverLicenseViewModel.kt index f7fc0f7..3d4886d 100644 --- a/app/src/main/java/h_mal/appttude/com/viewmodels/DriverLicenseViewModel.kt +++ b/app/src/main/java/h_mal/appttude/com/viewmodels/DriverLicenseViewModel.kt @@ -7,23 +7,23 @@ import h_mal.appttude.com.base.DataSubmissionBaseViewModel import h_mal.appttude.com.data.FirebaseAuthentication import h_mal.appttude.com.data.FirebaseDatabaseSource import h_mal.appttude.com.data.FirebaseStorageSource -import h_mal.appttude.com.model.DriversLicenseObject +import h_mal.appttude.com.model.DriversLicense import h_mal.appttude.com.utils.Coroutines.io class DriverLicenseViewModel( auth: FirebaseAuthentication, database: FirebaseDatabaseSource, storage: FirebaseStorageSource -) : DataSubmissionBaseViewModel(auth, database, storage) { +) : DataSubmissionBaseViewModel(auth, database, storage) { override val databaseRef: DatabaseReference = database.getDriverLicenseRef(uid) override val storageRef: StorageReference = storage.driversLicenseStorageRef(uid) override val objectName: String = "drivers license" - override fun getDataFromDatabase() = getDataClass() + override fun getDataFromDatabase() = getDataClass() - override fun setDataInDatabase(data: DriversLicenseObject, localImageUri: Uri?) = io { - doTryOperation("Failed to upload $objectName"){ + override fun setDataInDatabase(data: DriversLicense, localImageUri: Uri?) = io { + doTryOperation("Failed to upload $objectName") { val imageUrl = getImageUrl(localImageUri, data.licenseImageString) data.licenseImageString = imageUrl postDataToDatabase(data) diff --git a/app/src/main/java/h_mal/appttude/com/viewmodels/DriverProfileViewModel.kt b/app/src/main/java/h_mal/appttude/com/viewmodels/DriverProfileViewModel.kt index 98d6852..0a7ed53 100644 --- a/app/src/main/java/h_mal/appttude/com/viewmodels/DriverProfileViewModel.kt +++ b/app/src/main/java/h_mal/appttude/com/viewmodels/DriverProfileViewModel.kt @@ -7,23 +7,23 @@ import h_mal.appttude.com.base.DataSubmissionBaseViewModel import h_mal.appttude.com.data.FirebaseAuthentication import h_mal.appttude.com.data.FirebaseDatabaseSource import h_mal.appttude.com.data.FirebaseStorageSource -import h_mal.appttude.com.model.DriverProfileObject +import h_mal.appttude.com.model.DriverProfile import h_mal.appttude.com.utils.Coroutines.io class DriverProfileViewModel( auth: FirebaseAuthentication, database: FirebaseDatabaseSource, storage: FirebaseStorageSource -) : DataSubmissionBaseViewModel(auth, database, storage) { +) : DataSubmissionBaseViewModel(auth, database, storage) { override val databaseRef: DatabaseReference = database.getDriverDetailsRef(uid) override val storageRef: StorageReference = storage.profileImageStorageRef(uid) override val objectName: String = "drivers profile" - override fun getDataFromDatabase() = getDataClass() + override fun getDataFromDatabase() = getDataClass() - override fun setDataInDatabase(data: DriverProfileObject, localImageUri: Uri?) = io { - doTryOperation("Failed to upload $objectName"){ + override fun setDataInDatabase(data: DriverProfile, localImageUri: Uri?) = io { + doTryOperation("Failed to upload $objectName") { val imageUrl = getImageUrl(localImageUri, data.driverPic) data.driverPic = imageUrl diff --git a/app/src/main/java/h_mal/appttude/com/viewmodels/InsuranceViewModel.kt b/app/src/main/java/h_mal/appttude/com/viewmodels/InsuranceViewModel.kt index 2082fb4..3717f14 100644 --- a/app/src/main/java/h_mal/appttude/com/viewmodels/InsuranceViewModel.kt +++ b/app/src/main/java/h_mal/appttude/com/viewmodels/InsuranceViewModel.kt @@ -7,29 +7,29 @@ import h_mal.appttude.com.base.DataSubmissionBaseViewModel import h_mal.appttude.com.data.FirebaseAuthentication import h_mal.appttude.com.data.FirebaseDatabaseSource import h_mal.appttude.com.data.FirebaseStorageSource -import h_mal.appttude.com.model.InsuranceObject +import h_mal.appttude.com.model.Insurance import h_mal.appttude.com.utils.Coroutines.io -class InsuranceViewModel ( +class InsuranceViewModel( auth: FirebaseAuthentication, database: FirebaseDatabaseSource, storage: FirebaseStorageSource -) : DataSubmissionBaseViewModel(auth, database, storage) { +) : DataSubmissionBaseViewModel(auth, database, storage) { override val databaseRef: DatabaseReference = database.getInsuranceDetailsRef(uid) override val storageRef: StorageReference = storage.insuranceStorageRef(uid) override val objectName: String = "insurance" - override fun getDataFromDatabase() = getDataClass() + override fun getDataFromDatabase() = getDataClass() - override fun setDataInDatabase(data: InsuranceObject, localImageUris: List?) = io { + override fun setDataInDatabase(data: Insurance, localImageUris: List?) = io { doTryOperation("Failed to upload $objectName") { - val imageUrls = if (!localImageUris.isNullOrEmpty()){ + val imageUrls = if (!localImageUris.isNullOrEmpty()) { getImageUrls(localImageUris).toMutableList() - }else{ + } else { data.photoStrings } - if (imageUrls.isNullOrEmpty()){ + if (imageUrls.isNullOrEmpty()) { onError("no images selected") return@doTryOperation } diff --git a/app/src/main/java/h_mal/appttude/com/viewmodels/LogbookViewModel.kt b/app/src/main/java/h_mal/appttude/com/viewmodels/LogbookViewModel.kt index cc1f74c..09d89be 100644 --- a/app/src/main/java/h_mal/appttude/com/viewmodels/LogbookViewModel.kt +++ b/app/src/main/java/h_mal/appttude/com/viewmodels/LogbookViewModel.kt @@ -7,22 +7,22 @@ import h_mal.appttude.com.base.DataSubmissionBaseViewModel import h_mal.appttude.com.data.FirebaseAuthentication import h_mal.appttude.com.data.FirebaseDatabaseSource import h_mal.appttude.com.data.FirebaseStorageSource -import h_mal.appttude.com.model.LogbookObject +import h_mal.appttude.com.model.Logbook import h_mal.appttude.com.utils.Coroutines.io -class LogbookViewModel ( +class LogbookViewModel( auth: FirebaseAuthentication, database: FirebaseDatabaseSource, storage: FirebaseStorageSource -) : DataSubmissionBaseViewModel(auth, database, storage) { +) : DataSubmissionBaseViewModel(auth, database, storage) { override val databaseRef: DatabaseReference = database.getLogbookRef(uid) override val storageRef: StorageReference = storage.logBookStorageRef(uid) override val objectName: String = "Log book" - override fun getDataFromDatabase() = getDataClass() + override fun getDataFromDatabase() = getDataClass() - override fun setDataInDatabase(data: LogbookObject, localImageUri: Uri?) = io { + override fun setDataInDatabase(data: Logbook, localImageUri: Uri?) = io { doTryOperation("Failed to upload $objectName") { val imageUrl = getImageUrl(localImageUri, data.photoString) data.photoString = imageUrl diff --git a/app/src/main/java/h_mal/appttude/com/viewmodels/MainViewModel.kt b/app/src/main/java/h_mal/appttude/com/viewmodels/MainViewModel.kt index d850e4c..4099f72 100644 --- a/app/src/main/java/h_mal/appttude/com/viewmodels/MainViewModel.kt +++ b/app/src/main/java/h_mal/appttude/com/viewmodels/MainViewModel.kt @@ -9,25 +9,25 @@ import h_mal.appttude.com.utils.getDataFromDatabaseRef class MainViewModel( private val firebaseAuth: FirebaseAuthentication, private val firebaseDatabase: FirebaseDatabaseSource -) : BaseViewModel(){ +) : BaseViewModel() { fun getRole() = io { - doTryOperation("failed to retrieve data") { - val uid = firebaseAuth.getUid() ?: return@doTryOperation - val ref = firebaseDatabase.getUserRoleRef(uid) - val role = ref.getDataFromDatabaseRef() - role?.apply { onSuccess(this) } ?: onError("No role found") - } + doTryOperation("failed to retrieve data") { + val uid = firebaseAuth.getUid() ?: return@doTryOperation + val ref = firebaseDatabase.getUserRoleRef(uid) + val role = ref.getDataFromDatabaseRef() + role?.apply { onSuccess(this) } ?: onError("No role found") } + } - fun getUserDetails(){ + fun getUserDetails() { firebaseAuth.getUser()?.let { onSuccess(it) } } - fun logOut(){ + fun logOut() { firebaseAuth.logOut() } } \ No newline at end of file diff --git a/app/src/main/java/h_mal/appttude/com/viewmodels/MotViewModel.kt b/app/src/main/java/h_mal/appttude/com/viewmodels/MotViewModel.kt index a93b2c3..c9c86fb 100644 --- a/app/src/main/java/h_mal/appttude/com/viewmodels/MotViewModel.kt +++ b/app/src/main/java/h_mal/appttude/com/viewmodels/MotViewModel.kt @@ -7,23 +7,23 @@ import h_mal.appttude.com.base.DataSubmissionBaseViewModel import h_mal.appttude.com.data.FirebaseAuthentication import h_mal.appttude.com.data.FirebaseDatabaseSource import h_mal.appttude.com.data.FirebaseStorageSource -import h_mal.appttude.com.model.MotObject +import h_mal.appttude.com.model.Mot import h_mal.appttude.com.utils.Coroutines.io -class MotViewModel ( +class MotViewModel( auth: FirebaseAuthentication, database: FirebaseDatabaseSource, storage: FirebaseStorageSource -) : DataSubmissionBaseViewModel(auth, database, storage) { +) : DataSubmissionBaseViewModel(auth, database, storage) { override val databaseRef: DatabaseReference = database.getMotDetailsRef(uid) override val storageRef: StorageReference? = storage.motStorageRef(uid) override val objectName: String = "vehicle profile" - override fun getDataFromDatabase() = getDataClass() + override fun getDataFromDatabase() = getDataClass() - override fun setDataInDatabase(data: MotObject, localImageUri: Uri?) = io { - doTryOperation("Failed to upload $objectName"){ + override fun setDataInDatabase(data: Mot, localImageUri: Uri?) = io { + doTryOperation("Failed to upload $objectName") { val imageUrl = getImageUrl(localImageUri, data.motImageString) data.motImageString = imageUrl postDataToDatabase(data) diff --git a/app/src/main/java/h_mal/appttude/com/viewmodels/PrivateHireLicenseViewModel.kt b/app/src/main/java/h_mal/appttude/com/viewmodels/PrivateHireLicenseViewModel.kt index d47e929..a6dfb23 100644 --- a/app/src/main/java/h_mal/appttude/com/viewmodels/PrivateHireLicenseViewModel.kt +++ b/app/src/main/java/h_mal/appttude/com/viewmodels/PrivateHireLicenseViewModel.kt @@ -7,25 +7,25 @@ import h_mal.appttude.com.base.DataSubmissionBaseViewModel import h_mal.appttude.com.data.FirebaseAuthentication import h_mal.appttude.com.data.FirebaseDatabaseSource import h_mal.appttude.com.data.FirebaseStorageSource -import h_mal.appttude.com.model.PrivateHireObject +import h_mal.appttude.com.model.PrivateHireLicense import h_mal.appttude.com.utils.Coroutines.io class PrivateHireLicenseViewModel( auth: FirebaseAuthentication, database: FirebaseDatabaseSource, storage: FirebaseStorageSource -) : DataSubmissionBaseViewModel(auth, database, storage) { +) : DataSubmissionBaseViewModel(auth, database, storage) { override val databaseRef: DatabaseReference = database.getPrivateHireRef(uid) override val storageRef: StorageReference = storage.privateHireStorageRef(uid) override val objectName: String = "private hire license" - override fun getDataFromDatabase() = getDataClass() + override fun getDataFromDatabase() = getDataClass() - override fun setDataInDatabase(data: PrivateHireObject, localImageUri: Uri?) = io { - doTryOperation("Failed to upload private hire license"){ + override fun setDataInDatabase(data: PrivateHireLicense, localImageUri: Uri?) = io { + doTryOperation("Failed to upload private hire license") { val imageUrl = getImageUrl(localImageUri, data.phImageString) - val driverLicense = PrivateHireObject( + val driverLicense = PrivateHireLicense( phExpiry = data.phExpiry, phNumber = data.phNumber, phImageString = imageUrl diff --git a/app/src/main/java/h_mal/appttude/com/viewmodels/PrivateHireVehicleViewModel.kt b/app/src/main/java/h_mal/appttude/com/viewmodels/PrivateHireVehicleViewModel.kt index 335bfcf..df4a870 100644 --- a/app/src/main/java/h_mal/appttude/com/viewmodels/PrivateHireVehicleViewModel.kt +++ b/app/src/main/java/h_mal/appttude/com/viewmodels/PrivateHireVehicleViewModel.kt @@ -7,22 +7,22 @@ import h_mal.appttude.com.base.DataSubmissionBaseViewModel import h_mal.appttude.com.data.FirebaseAuthentication import h_mal.appttude.com.data.FirebaseDatabaseSource import h_mal.appttude.com.data.FirebaseStorageSource -import h_mal.appttude.com.model.PrivateHireVehicleObject +import h_mal.appttude.com.model.PrivateHireVehicle import h_mal.appttude.com.utils.Coroutines.io -class PrivateHireVehicleViewModel ( +class PrivateHireVehicleViewModel( auth: FirebaseAuthentication, database: FirebaseDatabaseSource, storage: FirebaseStorageSource -) : DataSubmissionBaseViewModel(auth, database, storage) { +) : DataSubmissionBaseViewModel(auth, database, storage) { override val databaseRef: DatabaseReference = database.getPrivateHireVehicleRef(uid) override val storageRef: StorageReference = storage.privateHireVehicleStorageRef(uid) override val objectName: String = "private hire vehicle license" - override fun getDataFromDatabase() = getDataClass() + override fun getDataFromDatabase() = getDataClass() - override fun setDataInDatabase(data: PrivateHireVehicleObject, localImageUri: Uri?) = io { + override fun setDataInDatabase(data: PrivateHireVehicle, localImageUri: Uri?) = io { doTryOperation("Failed to upload $objectName") { val imageUrl = getImageUrl(localImageUri, data.phCarImageString) data.phCarImageString = imageUrl diff --git a/app/src/main/java/h_mal/appttude/com/viewmodels/VehicleProfileViewModel.kt b/app/src/main/java/h_mal/appttude/com/viewmodels/VehicleProfileViewModel.kt index 215891c..4bb4036 100644 --- a/app/src/main/java/h_mal/appttude/com/viewmodels/VehicleProfileViewModel.kt +++ b/app/src/main/java/h_mal/appttude/com/viewmodels/VehicleProfileViewModel.kt @@ -6,24 +6,24 @@ import h_mal.appttude.com.base.DataSubmissionBaseViewModel import h_mal.appttude.com.data.FirebaseAuthentication import h_mal.appttude.com.data.FirebaseDatabaseSource import h_mal.appttude.com.data.FirebaseStorageSource -import h_mal.appttude.com.model.VehicleProfileObject +import h_mal.appttude.com.model.VehicleProfile import h_mal.appttude.com.utils.Coroutines.io -class VehicleProfileViewModel ( +class VehicleProfileViewModel( auth: FirebaseAuthentication, database: FirebaseDatabaseSource, storage: FirebaseStorageSource -) : DataSubmissionBaseViewModel(auth, database, storage) { +) : DataSubmissionBaseViewModel(auth, database, storage) { override val databaseRef: DatabaseReference = database.getVehicleDetailsRef(uid) override val storageRef: StorageReference? = null override val objectName: String = "vehicle profile" - override fun getDataFromDatabase() = getDataClass() + override fun getDataFromDatabase() = getDataClass() - override fun setDataInDatabase(data: VehicleProfileObject) { + override fun setDataInDatabase(data: VehicleProfile) { io { - doTryOperation("Failed to upload $objectName"){ + doTryOperation("Failed to upload $objectName") { postDataToDatabase(data) } } diff --git a/app/src/main/res/drawable-v21/cardviewoutline.xml b/app/src/main/res/drawable-v21/cardviewoutline.xml deleted file mode 100644 index d2640f1..0000000 --- a/app/src/main/res/drawable-v21/cardviewoutline.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/cardviewoutline.xml b/app/src/main/res/drawable/cardviewoutline.xml new file mode 100644 index 0000000..9cdbe25 --- /dev/null +++ b/app/src/main/res/drawable/cardviewoutline.xml @@ -0,0 +1,13 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_archive_black_24dp.xml b/app/src/main/res/drawable/ic_archive_black_24dp.xml index 025a961..abe9604 100644 --- a/app/src/main/res/drawable/ic_archive_black_24dp.xml +++ b/app/src/main/res/drawable/ic_archive_black_24dp.xml @@ -1,9 +1,9 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M20.54,5.23l-1.39,-1.68C18.88,3.21 18.47,3 18,3H6c-0.47,0 -0.88,0.21 -1.16,0.55L3.46,5.23C3.17,5.57 3,6.02 3,6.5V19c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2V6.5c0,-0.48 -0.17,-0.93 -0.46,-1.27zM12,17.5L6.5,12H10v-2h4v2h3.5L12,17.5zM5.12,5l0.81,-1h12l0.94,1H5.12z" /> diff --git a/app/src/main/res/drawable/ic_baseline_arrow_forward_24.xml b/app/src/main/res/drawable/ic_baseline_arrow_forward_24.xml index 045d385..02671e8 100644 --- a/app/src/main/res/drawable/ic_baseline_arrow_forward_24.xml +++ b/app/src/main/res/drawable/ic_baseline_arrow_forward_24.xml @@ -1,5 +1,10 @@ - - + + diff --git a/app/src/main/res/drawable/ic_baseline_assignment_ind_24.xml b/app/src/main/res/drawable/ic_baseline_assignment_ind_24.xml index 7fe791f..a0f1ea9 100644 --- a/app/src/main/res/drawable/ic_baseline_assignment_ind_24.xml +++ b/app/src/main/res/drawable/ic_baseline_assignment_ind_24.xml @@ -1,5 +1,10 @@ - - + + diff --git a/app/src/main/res/drawable/ic_baseline_photo_library_24.xml b/app/src/main/res/drawable/ic_baseline_photo_library_24.xml index b2b971d..4f7eb78 100644 --- a/app/src/main/res/drawable/ic_baseline_photo_library_24.xml +++ b/app/src/main/res/drawable/ic_baseline_photo_library_24.xml @@ -1,5 +1,10 @@ - - + + diff --git a/app/src/main/res/drawable/ic_file_download_black_24dp.xml b/app/src/main/res/drawable/ic_file_download_black_24dp.xml index 8073476..a243261 100644 --- a/app/src/main/res/drawable/ic_file_download_black_24dp.xml +++ b/app/src/main/res/drawable/ic_file_download_black_24dp.xml @@ -1,9 +1,9 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M19,9h-4V3H9v6H5l7,7 7,-7zM5,18v2h14v-2H5z" /> diff --git a/app/src/main/res/drawable/ic_settings_black_24dp.xml b/app/src/main/res/drawable/ic_settings_black_24dp.xml index ace746c..5cc6e23 100644 --- a/app/src/main/res/drawable/ic_settings_black_24dp.xml +++ b/app/src/main/res/drawable/ic_settings_black_24dp.xml @@ -1,9 +1,11 @@ + xmlns:tools="http://schemas.android.com/tools" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98s-0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.12,-0.22 -0.39,-0.3 -0.61,-0.22l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.23,-0.09 -0.49,0 -0.61,0.22l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98s0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.12,0.22 0.39,0.3 0.61,0.22l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.23,0.09 0.49,0 0.61,-0.22l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z" + tools:ignore="VectorPath" /> diff --git a/app/src/main/res/drawable/ic_sort_black_24dp.xml b/app/src/main/res/drawable/ic_sort_black_24dp.xml index 449c263..0be05e6 100644 --- a/app/src/main/res/drawable/ic_sort_black_24dp.xml +++ b/app/src/main/res/drawable/ic_sort_black_24dp.xml @@ -1,9 +1,9 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M3,18h6v-2L3,16v2zM3,6v2h18L21,6L3,6zM3,13h12v-2L3,11v2z" /> diff --git a/app/src/main/res/drawable-v21/round_edit_text.xml b/app/src/main/res/drawable/round_edit_text.xml similarity index 65% rename from app/src/main/res/drawable-v21/round_edit_text.xml rename to app/src/main/res/drawable/round_edit_text.xml index fa2415d..744ceb1 100644 --- a/app/src/main/res/drawable-v21/round_edit_text.xml +++ b/app/src/main/res/drawable/round_edit_text.xml @@ -1,6 +1,7 @@ - + - - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index b5820d2..498e7f4 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,6 +1,5 @@ - @@ -22,7 +22,7 @@ android:fitsSystemWindows="true" app:itemTextColor="@android:color/white" app:headerLayout="@layout/nav_header_main" - app:menu="@menu/activity_main_drawer" > + app:menu="@menu/activity_main_drawer"> - + @@ -35,14 +37,14 @@ android:layout_height="wrap_content" android:layout_centerInParent="true" android:layout_margin="4dp" - android:text="OR" /> + android:text="@string/or" /> @@ -60,4 +62,4 @@ android:textColor="@android:color/black" android:textStyle="bold" /> - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/carousal_image_cell.xml b/app/src/main/res/layout/carousal_image_cell.xml index b827e55..e4024d0 100644 --- a/app/src/main/res/layout/carousal_image_cell.xml +++ b/app/src/main/res/layout/carousal_image_cell.xml @@ -13,5 +13,5 @@ app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" - app:layout_constraintRight_toRightOf="parent"/> + app:layout_constraintRight_toRightOf="parent" /> \ No newline at end of file diff --git a/app/src/main/res/layout/driver_profile_request.xml b/app/src/main/res/layout/driver_profile_request.xml index 8d9d2da..ad3ff8d 100644 --- a/app/src/main/res/layout/driver_profile_request.xml +++ b/app/src/main/res/layout/driver_profile_request.xml @@ -1,7 +1,6 @@ + android:text="@string/not_a_driver_message" /> diff --git a/app/src/main/res/layout/fragment_driver_license.xml b/app/src/main/res/layout/fragment_driver_license.xml index 5816ec4..cb92003 100644 --- a/app/src/main/res/layout/fragment_driver_license.xml +++ b/app/src/main/res/layout/fragment_driver_license.xml @@ -1,79 +1,78 @@ - - + + + android:layout_height="200dp" + android:layout_alignParentStart="true" + android:adjustViewBounds="true" + android:scaleType="centerCrop" + tools:src="@drawable/choice_img_round" + android:contentDescription="@string/image_description" /> - + - + - + - + - + - + - + - - - + + app:layout_constraintVertical_bias="0.8" /> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_image_viewer.xml b/app/src/main/res/layout/fragment_image_viewer.xml index 8fa1b4e..c5e989b 100644 --- a/app/src/main/res/layout/fragment_image_viewer.xml +++ b/app/src/main/res/layout/fragment_image_viewer.xml @@ -10,19 +10,19 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:background="#000000" - tools:src="@drawable/cars"/> + tools:src="@drawable/cars" /> - + android:src="@drawable/ic_file_download_black_24dp" + android:contentDescription="@string/floating_action_button" /> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mot.xml b/app/src/main/res/layout/fragment_mot.xml index 002810c..82194d3 100644 --- a/app/src/main/res/layout/fragment_mot.xml +++ b/app/src/main/res/layout/fragment_mot.xml @@ -35,7 +35,7 @@ android:text="@string/upload_mot" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintBottom_toTopOf="@+id/til_submission"/> + app:layout_constraintBottom_toTopOf="@+id/til_submission" /> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_update_email.xml b/app/src/main/res/layout/fragment_update_email.xml index 554e2e6..55153aa 100644 --- a/app/src/main/res/layout/fragment_update_email.xml +++ b/app/src/main/res/layout/fragment_update_email.xml @@ -16,7 +16,7 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" - app:layout_constraintStart_toStartOf="parent"/> + app:layout_constraintStart_toStartOf="parent" /> + app:layout_constraintStart_toStartOf="parent" /> + app:layout_constraintTop_toBottomOf="@+id/til_password_top" /> diff --git a/app/src/main/res/layout/fragment_vehicle_setup.xml b/app/src/main/res/layout/fragment_vehicle_setup.xml index ebf449d..e574fe4 100644 --- a/app/src/main/res/layout/fragment_vehicle_setup.xml +++ b/app/src/main/res/layout/fragment_vehicle_setup.xml @@ -12,8 +12,7 @@ android:layout_margin="12dp" android:orientation="vertical"> - + - + - + - + - + - + - + - + + android:textSize="18sp" /> + android:layout_marginBottom="12dp" /> + + android:text="@string/vehicle_profile" /> \ No newline at end of file diff --git a/app/src/main/res/layout/multi_image_selector.xml b/app/src/main/res/layout/multi_image_selector.xml index 3f47b7d..f382903 100644 --- a/app/src/main/res/layout/multi_image_selector.xml +++ b/app/src/main/res/layout/multi_image_selector.xml @@ -17,6 +17,7 @@ android:layout_width="200dp" android:layout_height="200dp" android:adjustViewBounds="true"> + diff --git a/app/src/main/res/layout/splash_screen.xml b/app/src/main/res/layout/splash_screen.xml new file mode 100644 index 0000000..4faea89 --- /dev/null +++ b/app/src/main/res/layout/splash_screen.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/update_activity.xml b/app/src/main/res/layout/update_activity.xml index 1c3ac2d..451bc4f 100644 --- a/app/src/main/res/layout/update_activity.xml +++ b/app/src/main/res/layout/update_activity.xml @@ -1,6 +1,5 @@ - + android:text="@string/update_email" /> + android:text="@string/update_password" /> + android:text="@string/update_profile" /> + app:layout_constraintStart_toStartOf="parent" /> diff --git a/app/src/main/res/navigation/auth_navigation.xml b/app/src/main/res/navigation/auth_navigation.xml index 1d79ce2..76eecc9 100644 --- a/app/src/main/res/navigation/auth_navigation.xml +++ b/app/src/main/res/navigation/auth_navigation.xml @@ -16,20 +16,20 @@ app:enterAnim="@anim/nav_default_enter_anim" app:exitAnim="@anim/nav_default_exit_anim" app:popEnterAnim="@anim/nav_default_enter_anim" - app:popExitAnim="@anim/nav_default_exit_anim"/> + app:popExitAnim="@anim/nav_default_exit_anim" /> + app:popExitAnim="@anim/nav_default_exit_anim" /> + tools:layout="@layout/fragment_register" /> + tools:layout="@layout/fragment_splash_screen"> + tools:layout="@layout/fragment_home_driver"> + app:popExitAnim="@anim/nav_default_exit_anim" /> + app:popExitAnim="@anim/nav_default_exit_anim" /> + app:popExitAnim="@anim/nav_default_exit_anim" /> + app:popExitAnim="@anim/nav_default_exit_anim" /> + app:popExitAnim="@anim/nav_default_exit_anim" /> + app:popExitAnim="@anim/nav_default_exit_anim" /> + app:popExitAnim="@anim/nav_default_exit_anim" /> + app:popExitAnim="@anim/nav_default_exit_anim" /> + app:popExitAnim="@anim/nav_default_exit_anim" /> + app:popExitAnim="@anim/nav_default_exit_anim" /> + tools:layout="@layout/fragment_vehicle_setup" /> + tools:layout="@layout/fragment_insurance" /> + tools:layout="@layout/fragment_mot" /> + app:popExitAnim="@anim/nav_default_exit_anim" /> + app:popExitAnim="@anim/nav_default_exit_anim" /> + app:popExitAnim="@anim/nav_default_exit_anim" /> + app:popExitAnim="@anim/nav_default_exit_anim" /> + tools:layout="@layout/fragment_update_email" /> + tools:layout="@layout/fragment_update_password" /> Insurance expiry Logout Forgot password? + Leave? + Are you sure you want to exit? + You are not a driver, request a driver profile to use this app + Request driver profile + OR + Floating action button diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 77dd2f6..e9dc07f 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -35,7 +35,7 @@ - @@ -115,7 +115,7 @@ @android:color/white -