mirror of
https://github.com/hmalik144/Driver.git
synced 2025-12-10 02:45:20 +00:00
Merge pull request #13 from hmalik144/refactoring_base_classes
Project refactoring
This commit is contained in:
@@ -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"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package h_mal.appttude.com.objects
|
||||
|
||||
|
||||
|
||||
class ApprovalsObject {
|
||||
var driver_details_approval: Int = 0
|
||||
var driver_license_approval: Int = 0
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package h_mal.appttude.com.objects
|
||||
|
||||
|
||||
|
||||
class UserObject {
|
||||
var profileName: String? = null
|
||||
var profileEmail: String? = null
|
||||
|
||||
@@ -29,14 +29,15 @@ class MappedObject : Parcelable {
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val CREATOR: Parcelable.Creator<MappedObject?> = object : Parcelable.Creator<MappedObject?> {
|
||||
override fun createFromParcel(`in`: Parcel): MappedObject? {
|
||||
return MappedObject(`in`)
|
||||
}
|
||||
val CREATOR: Parcelable.Creator<MappedObject?> =
|
||||
object : Parcelable.Creator<MappedObject?> {
|
||||
override fun createFromParcel(`in`: Parcel): MappedObject? {
|
||||
return MappedObject(`in`)
|
||||
}
|
||||
|
||||
override fun newArray(size: Int): Array<MappedObject?> {
|
||||
return arrayOfNulls(size)
|
||||
override fun newArray(size: Int): Array<MappedObject?> {
|
||||
return arrayOfNulls(size)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ import h_mal.appttude.com.R
|
||||
class ApprovalListAdapter(
|
||||
private val activity: Activity,
|
||||
objects: Array<MappedObject?>
|
||||
): ArrayAdapter<MappedObject?>(activity, 0, objects) {
|
||||
) : ArrayAdapter<MappedObject?>(activity, 0, objects) {
|
||||
|
||||
var mappedObject: MappedObject? = objects[0]
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -70,7 +70,7 @@ class MainActivity : BaseActivity<MainViewModel>(),
|
||||
|
||||
override fun onSuccess(data: Any?) {
|
||||
super.onSuccess(data)
|
||||
when(data){
|
||||
when (data) {
|
||||
is FirebaseUser -> {
|
||||
setupDrawer(data)
|
||||
}
|
||||
@@ -84,7 +84,7 @@ class MainActivity : BaseActivity<MainViewModel>(),
|
||||
header.profileImage.setGlideImage(user.photoUrl)
|
||||
}
|
||||
|
||||
private fun setupLogoutInDrawer(){
|
||||
private fun setupLogoutInDrawer() {
|
||||
logout.setOnClickListener {
|
||||
getViewModel().logOut()
|
||||
}
|
||||
@@ -93,7 +93,7 @@ class MainActivity : BaseActivity<MainViewModel>(),
|
||||
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
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:src="@drawable/cardviewoutline"/>
|
||||
android:src="@drawable/cardviewoutline" />
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
@@ -75,7 +76,7 @@
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"/>
|
||||
android:layout_gravity="center" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/archive_icon"
|
||||
|
||||
@@ -12,6 +12,6 @@
|
||||
android:numColumns="2"
|
||||
android:rowCount="4"
|
||||
android:stretchMode="columnWidth"
|
||||
tools:listitem="@layout/approval_list_grid_item"/>
|
||||
tools:listitem="@layout/approval_list_grid_item" />
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -21,6 +21,7 @@
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:src="@drawable/choice_img_round" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/approval_iv"
|
||||
android:layout_width="10dp"
|
||||
|
||||
@@ -15,9 +15,13 @@ import org.hamcrest.CoreMatchers.anything
|
||||
open class BaseTestRobot {
|
||||
|
||||
fun fillEditText(resId: Int, text: String?): ViewInteraction =
|
||||
onView(withId(resId)).perform(ViewActions.replaceText(text), ViewActions.closeSoftKeyboard())
|
||||
onView(withId(resId)).perform(
|
||||
ViewActions.replaceText(text),
|
||||
ViewActions.closeSoftKeyboard()
|
||||
)
|
||||
|
||||
fun clickButton(resId: Int): ViewInteraction = onView((withId(resId))).perform(ViewActions.click())
|
||||
fun clickButton(resId: Int): ViewInteraction =
|
||||
onView((withId(resId))).perform(ViewActions.click())
|
||||
|
||||
fun textView(resId: Int): ViewInteraction = onView(withId(resId))
|
||||
|
||||
@@ -35,6 +39,7 @@ open class BaseTestRobot {
|
||||
fun checkErrorOnTextEntry(resId: Int, errorMessage: String): ViewInteraction =
|
||||
onView(withId(resId)).check(matches(checkErrorMessage(errorMessage)))
|
||||
|
||||
fun getStringFromResource(@StringRes resId: Int): String = Resources.getSystem().getString(resId)
|
||||
fun getStringFromResource(@StringRes resId: Int): String =
|
||||
Resources.getSystem().getString(resId)
|
||||
|
||||
}
|
||||
@@ -16,7 +16,7 @@ import org.junit.After
|
||||
import org.junit.Before
|
||||
|
||||
|
||||
open class BaseUiTest<T : BaseActivity<*>>(
|
||||
open class BaseUiTest<T : BaseActivity<*,*>>(
|
||||
private val activity: Class<T>
|
||||
) {
|
||||
|
||||
|
||||
@@ -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!"
|
||||
@@ -23,6 +23,7 @@ fun checkErrorMessage(expectedErrorText: String): Matcher<View?>? {
|
||||
val error = view.error ?: return false
|
||||
return expectedErrorText == error.toString()
|
||||
}
|
||||
|
||||
override fun describeTo(d: Description?) {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import kotlinx.coroutines.tasks.await
|
||||
import org.junit.After
|
||||
import org.junit.BeforeClass
|
||||
|
||||
open class FirebaseTest<T : BaseActivity<*>>(
|
||||
open class FirebaseTest<T : BaseActivity<*,*>>(
|
||||
activity: Class<T>,
|
||||
private val registered: Boolean = false,
|
||||
private val signedIn: Boolean = false
|
||||
@@ -62,7 +62,10 @@ open class FirebaseTest<T : BaseActivity<*>>(
|
||||
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<T : BaseActivity<*>>(
|
||||
|
||||
fun generateEmailAddress(): String {
|
||||
val suffix = (1000..50000).random()
|
||||
email ="test-${suffix}@test-account.com"
|
||||
email = "test-${suffix}@test-account.com"
|
||||
return email!!
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
)
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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>(LoginActivity::class.java, registered = true, signedIn = false) {
|
||||
class RegisteredUserAuthenticationActivityTest :
|
||||
FirebaseTest<LoginActivity>(LoginActivity::class.java, registered = true, signedIn = false) {
|
||||
|
||||
@Test
|
||||
fun verifyUserLogin_validUsernameAndPassword_loggedIn() {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
<manifest xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<application android:usesCleartextTraffic="true"
|
||||
<application
|
||||
android:usesCleartextTraffic="true"
|
||||
tools:ignore="MissingApplicationIcon" />
|
||||
|
||||
</manifest>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config>
|
||||
<domain-config cleartextTrafficPermitted="true">
|
||||
<domain>10.0.2.2</domain>
|
||||
<domain includeSubdomains="true">10.0.2.2</domain>
|
||||
</domain-config>
|
||||
</network-security-config>
|
||||
@@ -1,7 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<application android:icon="@mipmap/ic_launcher"
|
||||
<application
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:roundIcon="@mipmap/ic_launcher_round">
|
||||
<activity
|
||||
android:name="h_mal.appttude.com.ui.user.LoginActivity"
|
||||
@@ -23,6 +24,7 @@
|
||||
<activity
|
||||
android:name="h_mal.appttude.com.ui.update.UpdateActivity"
|
||||
android:theme="@style/AppTheme.NoActionBar.Update" />
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="h_mal.appttude.com.driver"
|
||||
|
||||
@@ -1,25 +1,32 @@
|
||||
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.FragmentDriverOverallBinding
|
||||
import h_mal.appttude.com.utils.navigateTo
|
||||
import kotlinx.android.synthetic.main.fragment_driver_overall.*
|
||||
|
||||
class DriverOverallFragment : Fragment(R.layout.fragment_driver_overall) {
|
||||
class DriverOverallFragment : Fragment() {
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
driver_prof.setOnClickListener {
|
||||
it.navigateTo(R.id.to_driverProfileFragment)
|
||||
}
|
||||
private_hire.setOnClickListener {
|
||||
it.navigateTo(R.id.to_privateHireLicenseFragment2)
|
||||
}
|
||||
drivers_license.setOnClickListener {
|
||||
it.navigateTo(R.id.to_driverLicenseFragment)
|
||||
}
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
return FragmentDriverOverallBinding.inflate(inflater, container, false).apply {
|
||||
driverProf.setOnClickListener {
|
||||
it.navigateTo(R.id.to_driverProfileFragment)
|
||||
}
|
||||
privateHire.setOnClickListener {
|
||||
it.navigateTo(R.id.to_privateHireLicenseFragment2)
|
||||
}
|
||||
driversLicense.setOnClickListener {
|
||||
it.navigateTo(R.id.to_driverLicenseFragment)
|
||||
}
|
||||
}.root
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,54 +5,56 @@ import android.view.View
|
||||
import h_mal.appttude.com.R
|
||||
import h_mal.appttude.com.base.DataSubmissionBaseFragment
|
||||
import h_mal.appttude.com.data.DRIVER
|
||||
import h_mal.appttude.com.databinding.FragmentHomeDriverBinding
|
||||
import h_mal.appttude.com.utils.hide
|
||||
import h_mal.appttude.com.utils.navigateTo
|
||||
import h_mal.appttude.com.utils.show
|
||||
import h_mal.appttude.com.viewmodels.RoleViewModel
|
||||
import kotlinx.android.synthetic.main.driver_profile_request.*
|
||||
import kotlinx.android.synthetic.main.fragment_home_driver.*
|
||||
import kotlinx.android.synthetic.main.home_buttons_container.*
|
||||
|
||||
|
||||
class HomeFragment : DataSubmissionBaseFragment<RoleViewModel, String>(R.layout.fragment_home_driver) {
|
||||
class HomeFragment :
|
||||
DataSubmissionBaseFragment<RoleViewModel, FragmentHomeDriverBinding, String>() {
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<MainViewModel>(),
|
||||
class MainActivity : BaseActivity<MainViewModel, ActivityMainBinding>(),
|
||||
NavigationView.OnNavigationItemSelectedListener {
|
||||
|
||||
private val vm by createLazyViewModel<MainViewModel>()
|
||||
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<MainViewModel>(),
|
||||
}
|
||||
|
||||
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<MainViewModel>(),
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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<DriverLicenseViewModel, DriversLicenseObject>(R.layout.fragment_driver_license) {
|
||||
DataSubmissionBaseFragment<DriverLicenseViewModel, FragmentDriverLicenseBinding, DriversLicense>() {
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
<DriverProfileViewModel, DriverProfileObject>(R.layout.fragment_driver_profile) {
|
||||
class DriverProfileFragment :
|
||||
DataSubmissionBaseFragment<DriverProfileViewModel, FragmentDriverProfileBinding, DriverProfile>() {
|
||||
|
||||
var localUri: Uri? = null
|
||||
override var model = DriverProfile()
|
||||
|
||||
private val viewmodel by getFragmentViewModel<DriverProfileViewModel>()
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
<PrivateHireLicenseViewModel, PrivateHireObject>(R.layout.fragment_private_hire_license) {
|
||||
<PrivateHireLicenseViewModel, FragmentPrivateHireLicenseBinding, PrivateHireLicense>() {
|
||||
|
||||
val viewmodel by getFragmentViewModel<PrivateHireLicenseViewModel>()
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<InsuranceViewModel, InsuranceObject>(R.layout.fragment_insurance) {
|
||||
class InsuranceFragment :
|
||||
DataSubmissionBaseFragment<InsuranceViewModel, FragmentInsuranceBinding, Insurance>() {
|
||||
|
||||
private var selectedImages: List<Uri>? = 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<Any?>) {
|
||||
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<Uri>?) {
|
||||
|
||||
@@ -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<LogbookViewModel, LogbookObject>(R.layout.fragment_logbook) {
|
||||
class LogbookFragment :
|
||||
DataSubmissionBaseFragment<LogbookViewModel, FragmentLogbookBinding, Logbook>() {
|
||||
|
||||
private val viewmodel by getFragmentViewModel<LogbookViewModel>()
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<MotViewModel, MotObject>(R.layout.fragment_mot){
|
||||
class MotFragment : DataSubmissionBaseFragment<MotViewModel, FragmentMotBinding, Mot>() {
|
||||
|
||||
private val viewmodel by getFragmentViewModel<MotViewModel>()
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
<PrivateHireVehicleViewModel, PrivateHireVehicleObject>(R.layout.fragment_private_hire_vehicle){
|
||||
class PrivateHireVehicleFragment :
|
||||
DataSubmissionBaseFragment<PrivateHireVehicleViewModel, FragmentPrivateHireLicenseBinding, PrivateHireVehicle>() {
|
||||
|
||||
private val viewmodel by getFragmentViewModel<PrivateHireVehicleViewModel>()
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
<VehicleProfileViewModel, VehicleProfileObject>(R.layout.fragment_vehicle_setup){
|
||||
class VehicleProfileFragment : DataSubmissionBaseFragment
|
||||
<VehicleProfileViewModel, FragmentVehicleSetupBinding, VehicleProfile>() {
|
||||
|
||||
private val viewmodel by getFragmentViewModel<VehicleProfileViewModel>()
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView4"
|
||||
@@ -66,7 +66,7 @@
|
||||
android:textSize="24sp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
android:textColor="@android:color/white"
|
||||
app:layout_constraintTop_toBottomOf="@id/textView3"/>
|
||||
app:layout_constraintTop_toBottomOf="@id/textView3" />
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@@ -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?,
|
||||
|
||||
@@ -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<String,*>?){
|
||||
private fun setUp(map: HashMap<String, *>?) {
|
||||
size = map?.size ?: 0
|
||||
map?.keys?.toTypedArray()?.let{
|
||||
map?.keys?.toTypedArray()?.let {
|
||||
mKeys = it
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,20 +15,55 @@ class ApplicationViewModelFactory(
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): 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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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<V : BaseViewModel> : AppCompatActivity(), KodeinAware {
|
||||
abstract class BaseActivity<V : BaseViewModel, VB : ViewBinding> : 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<ApplicationViewModelFactory>()
|
||||
|
||||
inline fun <reified VM : ViewModel> createLazyViewModel(): Lazy<VM> = viewModels { factory }
|
||||
inline fun <reified VM : ViewModel> createViewModel(): VM =
|
||||
ViewModelProvider(viewModelStore, factory).get(VM::class.java)
|
||||
fun createLazyViewModel(): Lazy<V> = ViewModelLazy(
|
||||
getGenericClassAt(0),
|
||||
{ viewModelStore },
|
||||
{ factory },
|
||||
{ defaultViewModelCreationExtras }
|
||||
)
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <CLASS : Any> Any.getGenericClassAt(position: Int): KClass<CLASS> =
|
||||
((javaClass.genericSuperclass as? ParameterizedType)
|
||||
?.actualTypeArguments?.getOrNull(position) as? Class<CLASS>)
|
||||
?.kotlin
|
||||
?: throw IllegalStateException("Can not find class from generic argument")
|
||||
|
||||
fun inflateBindingByType(
|
||||
genericClassAt: KClass<VB>
|
||||
): 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<V : BaseViewModel> : 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<V : BaseViewModel> : 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())
|
||||
|
||||
@@ -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<V : BaseViewModel>(@LayoutRes contentLayoutId: Int) :
|
||||
Fragment(contentLayoutId), KodeinAware {
|
||||
abstract class BaseFragment<V : BaseViewModel, VB : ViewBinding>(
|
||||
) : Fragment(), KodeinAware {
|
||||
|
||||
var mActivity: BaseActivity<V>? = 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<V, *>? = null
|
||||
|
||||
val viewModel: V by getFragmentViewModel()
|
||||
|
||||
private var multipleImage: Boolean = false
|
||||
|
||||
@@ -33,13 +42,57 @@ abstract class BaseFragment<V : BaseViewModel>(@LayoutRes contentLayoutId: Int)
|
||||
override val kodein by kodein()
|
||||
val factory by instance<ApplicationViewModelFactory>()
|
||||
|
||||
inline fun <reified VM : ViewModel> getFragmentViewModel(): Lazy<VM> = viewModels { factory }
|
||||
fun getFragmentViewModel(): Lazy<V> =
|
||||
createViewModelLazy(getGenericClassAt(0), { viewModelStore }, factoryProducer = { factory })
|
||||
|
||||
fun LayoutInflater.inflateBindingByType(
|
||||
container: ViewGroup?,
|
||||
genericClassAt: KClass<VB>
|
||||
): 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<V>
|
||||
fun <CLASS : Any> Any.getGenericClassAt(position: Int): KClass<CLASS> =
|
||||
((javaClass.genericSuperclass as? ParameterizedType)
|
||||
?.actualTypeArguments?.getOrNull(position) as? Class<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<V, *>
|
||||
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<V : BaseViewModel>(@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())
|
||||
|
||||
@@ -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<ViewState> = 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)
|
||||
|
||||
@@ -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<V : DataSubmissionBaseViewModel<T>, T: Any>
|
||||
(@LayoutRes contentLayoutId: Int) : BaseFragment<BaseViewModel>(contentLayoutId){
|
||||
|
||||
abstract class DataSubmissionBaseFragment<V : DataSubmissionBaseViewModel<T>, VB : ViewBinding, T : Any> :
|
||||
BaseFragment<V, VB>() {
|
||||
|
||||
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<V : DataSubmissionBaseViewModel<T>, T:
|
||||
requireActivity().finish()
|
||||
}
|
||||
}
|
||||
getViewModel().getDataFromDatabase()
|
||||
viewModel.getDataFromDatabase()
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
@@ -41,17 +41,17 @@ abstract class DataSubmissionBaseFragment<V : DataSubmissionBaseViewModel<T>, 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<V : DataSubmissionBaseViewModel<T>, 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<V : DataSubmissionBaseViewModel<T>, 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
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ abstract class DataSubmissionBaseViewModel<T : Any>(
|
||||
abstract fun getDataFromDatabase(): Job
|
||||
open fun setDataInDatabase(data: T, localImageUri: Uri?): Job = Job()
|
||||
open fun setDataInDatabase(data: T, localImageUris: List<Uri?>?): Job = Job()
|
||||
open fun setDataInDatabase(data: T) { }
|
||||
open fun setDataInDatabase(data: T) {}
|
||||
|
||||
inline fun <reified T : Any> getDataClass() = io {
|
||||
doTryOperation("Failed to retrieve $objectName") {
|
||||
@@ -60,7 +60,7 @@ abstract class DataSubmissionBaseViewModel<T : Any>(
|
||||
}
|
||||
|
||||
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<T : Any>(
|
||||
}
|
||||
|
||||
suspend fun getImageUrls(localImageUris: List<Uri?>?): List<String?> {
|
||||
if (localImageUris.isNullOrEmpty()){
|
||||
if (localImageUris.isNullOrEmpty()) {
|
||||
throw IOException("No images is selected")
|
||||
}
|
||||
val listOfUrls = mutableListOf<String>()
|
||||
@@ -81,10 +81,19 @@ abstract class DataSubmissionBaseViewModel<T : Any>(
|
||||
return listOfUrls
|
||||
}
|
||||
|
||||
suspend fun <T, R> Iterable<T>.mapSuspend(transform: suspend (T) -> R): List<R> =
|
||||
coroutineScope { map { t: T -> async { transform(t) } }.map { it.await() } }
|
||||
suspend fun <T, R> Iterable<T>.mapSuspend(transform: suspend (T) -> R): List<R> =
|
||||
coroutineScope { map { t: T -> async { transform(t) } }.map { it.await() } }
|
||||
|
||||
|
||||
suspend fun <T, R> Iterable<T>.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() }
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package h_mal.appttude.com.data
|
||||
|
||||
sealed class DataFieldState {
|
||||
object DefaultState : DataFieldState()
|
||||
object NonUserStateUpdated: DataFieldState()
|
||||
object UserUpdateState: DataFieldState()
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
@@ -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<Void> = auth.sendPasswordResetEmail(email)
|
||||
|
||||
override fun updateProfile(
|
||||
@@ -42,15 +42,17 @@ class FirebaseAuthSource: FirebaseAuthentication{
|
||||
}
|
||||
|
||||
override fun updateEmail(email: String): Task<Void> = getCurrentUser().updateEmail(email)
|
||||
override fun updatePassword(password: String): Task<Void> = getCurrentUser().updatePassword(password)
|
||||
override fun updatePassword(password: String): Task<Void> =
|
||||
getCurrentUser().updatePassword(password)
|
||||
|
||||
override fun deleteProfile(): Task<Void> = 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")
|
||||
}
|
||||
}
|
||||
@@ -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<UserAuthState>(){
|
||||
) : LiveData<UserAuthState>() {
|
||||
|
||||
override fun onActive() {
|
||||
super.onActive()
|
||||
@@ -24,4 +27,4 @@ class FirebaseLiveData(
|
||||
postValue(UserAuthState.LoggedIn(p0.currentUser!!))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<AuthResult>
|
||||
@@ -16,12 +16,14 @@ interface FirebaseAuthentication{
|
||||
name: String?,
|
||||
profilePic: Uri?
|
||||
): Task<Void>
|
||||
|
||||
fun reauthenticate(
|
||||
email: String,
|
||||
password: String
|
||||
): Task<Void>
|
||||
|
||||
fun updateEmail(email: String): Task<Void>
|
||||
fun updatePassword(password: String): Task<Void>
|
||||
fun deleteProfile(): Task<Void>
|
||||
fun userStateListener() : FirebaseLiveData
|
||||
fun userStateListener(): FirebaseAuthStateLiveData
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
@@ -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 <T: Any> postToDatabaseRed(ref: DatabaseReference, data: T) : T{
|
||||
/**
|
||||
* Post object to the databse on reference
|
||||
*
|
||||
* @param ref - Database reference
|
||||
* @return T returns data posted
|
||||
*/
|
||||
suspend fun <T : Any> 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)
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
@@ -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,
|
||||
@@ -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
|
||||
@@ -1,8 +1,6 @@
|
||||
package h_mal.appttude.com.model
|
||||
|
||||
|
||||
|
||||
data class InsuranceObject (
|
||||
data class Insurance(
|
||||
var photoStrings: MutableList<String?>? = null,
|
||||
var insurerName: String? = null,
|
||||
var expiryDate: String? = null
|
||||
@@ -1,8 +1,7 @@
|
||||
package h_mal.appttude.com.model
|
||||
|
||||
|
||||
|
||||
data class LogbookObject(
|
||||
data class Logbook(
|
||||
var photoString: String? = null,
|
||||
var v5cnumber: String? = null
|
||||
)
|
||||
@@ -1,8 +1,7 @@
|
||||
package h_mal.appttude.com.model
|
||||
|
||||
|
||||
|
||||
data class MotObject(
|
||||
data class Mot(
|
||||
var motImageString: String? = null,
|
||||
var motExpiry: String? = null
|
||||
)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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,
|
||||
@@ -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<UpdateUserViewModel>(R.layout.fragment_delete_profile) {
|
||||
class DeleteProfileFragment :
|
||||
BaseFragment<UpdateUserViewModel, FragmentDeleteProfileBinding>() {
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<UpdateUserViewModel>() {
|
||||
|
||||
override val layoutId: Int = R.layout.update_activity
|
||||
override fun getViewModel(): UpdateUserViewModel? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
createViewModel<UpdateUserViewModel>()
|
||||
}
|
||||
class UpdateActivity : BaseActivity<UpdateUserViewModel, UpdateActivityBinding>() {
|
||||
|
||||
override fun onSuccess(data: Any?) {
|
||||
super.onSuccess(data)
|
||||
when(data){
|
||||
when (data) {
|
||||
is FirebaseCompletion.Changed -> displayToast(data.message)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<UpdateUserViewModel>(R.layout.fragment_update_email) {
|
||||
class UpdateEmailFragment : BaseFragment<UpdateUserViewModel, FragmentUpdateEmailBinding>() {
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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<UpdateUserViewModel>(R.layout.update_overview_fragment), View.OnClickListener {
|
||||
class UpdateOverviewFragment : BaseFragment<UpdateUserViewModel, UpdateOverviewFragmentBinding>(),
|
||||
View.OnClickListener {
|
||||
|
||||
private val vm by activityViewModels<UpdateUserViewModel>()
|
||||
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<UpdateUserViewModel>(R.layout.update
|
||||
}
|
||||
}
|
||||
|
||||
override fun onClick(v: View?){
|
||||
override fun onClick(v: View?) {
|
||||
v?.submit()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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<UpdateUserViewModel>(R.layout.fragment_update_password) {
|
||||
class UpdatePasswordFragment : BaseFragment<UpdateUserViewModel, FragmentUpdatePasswordBinding>() {
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<UpdateUserViewModel>(R.layout.fragment_update_profile) {
|
||||
|
||||
private val viewmodel: UpdateUserViewModel by activityViewModels()
|
||||
override fun getViewModel(): UpdateUserViewModel = viewmodel
|
||||
class UpdateProfileFragment : BaseFragment<UpdateUserViewModel, FragmentUpdateProfileBinding>() {
|
||||
|
||||
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<UpdateUserViewModel>(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<UpdateUserViewModel>(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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<UserViewModel>(R.layout.fragment_forgot_password) {
|
||||
class ForgotPasswordFragment : BaseFragment<UserViewModel, FragmentForgotPasswordBinding>() {
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<UserViewModel>() {
|
||||
|
||||
override fun getViewModel(): UserViewModel? = null
|
||||
override val layoutId: Int = R.layout.activity_login
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
createViewModel<UserViewModel>()
|
||||
super.onCreate(savedInstanceState)
|
||||
}
|
||||
class LoginActivity : BaseActivity<UserViewModel, ActivityLoginBinding>() {
|
||||
|
||||
override fun onSuccess(data: Any?) {
|
||||
super.onSuccess(data)
|
||||
|
||||
@@ -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<UserViewModel>(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<UserViewModel, FragmentLoginBinding>() {
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<UserViewModel>(R.layout.fragment_register) {
|
||||
class RegisterFragment :
|
||||
BaseFragment<UserViewModel, FragmentRegisterBinding>() {
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
@@ -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<UserViewModel>(R.layout.fragment_splash_screen) {
|
||||
|
||||
private val userViewModel by activityViewModels<UserViewModel>()
|
||||
override fun getViewModel(): UserViewModel = userViewModel
|
||||
class SplashScreenFragment : BaseFragment<UserViewModel, SplashScreenBinding>() {
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
userViewModel.splashscreenCheckUserIsLoggedIn()
|
||||
viewModel.splashscreenCheckUserIsLoggedIn()
|
||||
}
|
||||
|
||||
override fun onSuccess(data: Any?) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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() }
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
16
app/src/main/java/h_mal/appttude/com/utils/Extensions.kt
Normal file
16
app/src/main/java/h_mal/appttude/com/utils/Extensions.kt
Normal file
@@ -0,0 +1,16 @@
|
||||
package h_mal.appttude.com.utils
|
||||
|
||||
|
||||
inline fun Boolean.isTrue(block: () -> Unit){
|
||||
if (this) {
|
||||
block()
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <T, R> T.isNotNull(block: (T) -> R): R?{
|
||||
return if (this != null) {
|
||||
block(this)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
@@ -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 <reified T: Any> DatabaseReference.getDataFromDatabaseRef(): T?{
|
||||
/**
|
||||
* Read database reference once {@link #DatabaseReference.addListenerForSingleValueEvent}
|
||||
*
|
||||
*
|
||||
* @return T
|
||||
*/
|
||||
suspend inline fun <reified T : Any> DatabaseReference.getDataFromDatabaseRef(): T? {
|
||||
return when (val response: EventResponse = singleValueEvent()) {
|
||||
is EventResponse.Changed -> {
|
||||
response.snapshot.getValue(T::class.java)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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?) {}
|
||||
})
|
||||
|
||||
@@ -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<DriversLicenseObject>(auth, database, storage) {
|
||||
) : DataSubmissionBaseViewModel<DriversLicense>(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<DriversLicenseObject>()
|
||||
override fun getDataFromDatabase() = getDataClass<DriversLicense>()
|
||||
|
||||
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)
|
||||
|
||||
@@ -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<DriverProfileObject>(auth, database, storage) {
|
||||
) : DataSubmissionBaseViewModel<DriverProfile>(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<DriverProfileObject>()
|
||||
override fun getDataFromDatabase() = getDataClass<DriverProfile>()
|
||||
|
||||
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
|
||||
|
||||
@@ -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<InsuranceObject>(auth, database, storage) {
|
||||
) : DataSubmissionBaseViewModel<Insurance>(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<InsuranceObject>()
|
||||
override fun getDataFromDatabase() = getDataClass<Insurance>()
|
||||
|
||||
override fun setDataInDatabase(data: InsuranceObject, localImageUris: List<Uri?>?) = io {
|
||||
override fun setDataInDatabase(data: Insurance, localImageUris: List<Uri?>?) = 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
|
||||
}
|
||||
|
||||
@@ -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<LogbookObject>(auth, database, storage) {
|
||||
) : DataSubmissionBaseViewModel<Logbook>(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<LogbookObject>()
|
||||
override fun getDataFromDatabase() = getDataClass<Logbook>()
|
||||
|
||||
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
|
||||
|
||||
@@ -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<String>()
|
||||
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<String>()
|
||||
role?.apply { onSuccess(this) } ?: onError("No role found")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun getUserDetails(){
|
||||
fun getUserDetails() {
|
||||
firebaseAuth.getUser()?.let {
|
||||
onSuccess(it)
|
||||
}
|
||||
}
|
||||
|
||||
fun logOut(){
|
||||
fun logOut() {
|
||||
firebaseAuth.logOut()
|
||||
}
|
||||
}
|
||||
@@ -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<MotObject>(auth, database, storage) {
|
||||
) : DataSubmissionBaseViewModel<Mot>(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<MotObject>()
|
||||
override fun getDataFromDatabase() = getDataClass<Mot>()
|
||||
|
||||
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)
|
||||
|
||||
@@ -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<PrivateHireObject>(auth, database, storage) {
|
||||
) : DataSubmissionBaseViewModel<PrivateHireLicense>(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<PrivateHireObject>()
|
||||
override fun getDataFromDatabase() = getDataClass<PrivateHireLicense>()
|
||||
|
||||
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
|
||||
|
||||
@@ -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<PrivateHireVehicleObject>(auth, database, storage) {
|
||||
) : DataSubmissionBaseViewModel<PrivateHireVehicle>(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<PrivateHireVehicleObject>()
|
||||
override fun getDataFromDatabase() = getDataClass<PrivateHireVehicle>()
|
||||
|
||||
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
|
||||
|
||||
@@ -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<VehicleProfileObject>(auth, database, storage) {
|
||||
) : DataSubmissionBaseViewModel<VehicleProfile>(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<VehicleProfileObject>()
|
||||
override fun getDataFromDatabase() = getDataClass<VehicleProfile>()
|
||||
|
||||
override fun setDataInDatabase(data: VehicleProfileObject) {
|
||||
override fun setDataInDatabase(data: VehicleProfile) {
|
||||
io {
|
||||
doTryOperation("Failed to upload $objectName"){
|
||||
doTryOperation("Failed to upload $objectName") {
|
||||
postDataToDatabase(data)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="@android:color/transparent"/>
|
||||
<stroke android:width="2dip" android:color="#03a9f4" />
|
||||
<corners android:radius="22dip"/>
|
||||
<padding android:left="0dip" android:top="0dip" android:right="0dip" android:bottom="0dip" />
|
||||
</shape>
|
||||
13
app/src/main/res/drawable/cardviewoutline.xml
Normal file
13
app/src/main/res/drawable/cardviewoutline.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="@android:color/transparent" />
|
||||
<stroke
|
||||
android:width="2dip"
|
||||
android:color="#03a9f4" />
|
||||
<corners android:radius="22dip" />
|
||||
<padding
|
||||
android:left="0dip"
|
||||
android:top="0dip"
|
||||
android:right="0dip"
|
||||
android:bottom="0dip" />
|
||||
</shape>
|
||||
@@ -1,9 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FFffffff"
|
||||
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"/>
|
||||
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" />
|
||||
</vector>
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M12,4l-1.41,1.41L16.17,11H4v2h12.17l-5.58,5.59L12,20l8,-8z"/>
|
||||
<vector android:height="24dp"
|
||||
android:tint="#FFFFFF"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24"
|
||||
android:width="24dp"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,4l-1.41,1.41L16.17,11H4v2h12.17l-5.58,5.59L12,20l8,-8z" />
|
||||
</vector>
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M19,3h-4.18C14.4,1.84 13.3,1 12,1c-1.3,0 -2.4,0.84 -2.82,2L5,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM12,3c0.55,0 1,0.45 1,1s-0.45,1 -1,1 -1,-0.45 -1,-1 0.45,-1 1,-1zM12,7c1.66,0 3,1.34 3,3s-1.34,3 -3,3 -3,-1.34 -3,-3 1.34,-3 3,-3zM18,19L6,19v-1.4c0,-2 4,-3.1 6,-3.1s6,1.1 6,3.1L18,19z"/>
|
||||
<vector android:height="24dp"
|
||||
android:tint="#FFFFFF"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24"
|
||||
android:width="24dp"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M19,3h-4.18C14.4,1.84 13.3,1 12,1c-1.3,0 -2.4,0.84 -2.82,2L5,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM12,3c0.55,0 1,0.45 1,1s-0.45,1 -1,1 -1,-0.45 -1,-1 0.45,-1 1,-1zM12,7c1.66,0 3,1.34 3,3s-1.34,3 -3,3 -3,-1.34 -3,-3 1.34,-3 3,-3zM18,19L6,19v-1.4c0,-2 4,-3.1 6,-3.1s6,1.1 6,3.1L18,19z" />
|
||||
</vector>
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M22,16L22,4c0,-1.1 -0.9,-2 -2,-2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2zM11,12l2.03,2.71L16,11l4,5L8,16l3,-4zM2,6v14c0,1.1 0.9,2 2,2h14v-2L4,20L4,6L2,6z"/>
|
||||
<vector android:height="24dp"
|
||||
android:tint="#FFFFFF"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24"
|
||||
android:width="24dp"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M22,16L22,4c0,-1.1 -0.9,-2 -2,-2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2zM11,12l2.03,2.71L16,11l4,5L8,16l3,-4zM2,6v14c0,1.1 0.9,2 2,2h14v-2L4,20L4,6L2,6z" />
|
||||
</vector>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M19,9h-4V3H9v6H5l7,7 7,-7zM5,18v2h14v-2H5z"/>
|
||||
android:pathData="M19,9h-4V3H9v6H5l7,7 7,-7zM5,18v2h14v-2H5z" />
|
||||
</vector>
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
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"/>
|
||||
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" />
|
||||
</vector>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M3,18h6v-2L3,16v2zM3,6v2h18L21,6L3,6zM3,13h12v-2L3,11v2z"/>
|
||||
android:pathData="M3,18h6v-2L3,16v2zM3,6v2h18L21,6L3,6zM3,13h12v-2L3,11v2z" />
|
||||
</vector>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user