mirror of
https://github.com/hmalik144/Driver.git
synced 2026-03-18 15:36:03 +00:00
- refactoring of admin app
- file structure updated Took 34 hours 38 minutes
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
|
||||
<application
|
||||
android:name="h_mal.appttude.com.driver.application.DriverApplication"
|
||||
android:name=".application.DriverApplication"
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
@@ -13,8 +13,7 @@
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity
|
||||
android:name="h_mal.appttude.com.driver.ui.user.LoginActivity"
|
||||
android:label="@string/app_name"
|
||||
android:name=".ui.user.LoginActivity"
|
||||
android:theme="@style/AppTheme.NoActionBar.User"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
@@ -25,17 +24,16 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name="h_mal.appttude.com.driver.ui.MainActivity"
|
||||
android:name=".ui.MainActivity"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme.NoActionBar" />
|
||||
<activity
|
||||
android:name="h_mal.appttude.com.driver.ui.update.UpdateActivity"
|
||||
android:name=".ui.update.UpdateActivity"
|
||||
android:theme="@style/AppTheme.NoActionBar.Update" />
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="h_mal.appttude.com.driver"
|
||||
android:authorities="${applicationId}.contentprovider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
package h_mal.appttude.com.driver.application
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import h_mal.appttude.com.driver.data.FirebaseAuthSource
|
||||
import h_mal.appttude.com.driver.data.FirebaseDatabaseSource
|
||||
import h_mal.appttude.com.driver.data.FirebaseStorageSource
|
||||
import h_mal.appttude.com.driver.viewmodels.*
|
||||
|
||||
class ApplicationViewModelFactory(
|
||||
private val auth: FirebaseAuthSource,
|
||||
private val database: FirebaseDatabaseSource,
|
||||
private val storage: FirebaseStorageSource
|
||||
) : ViewModelProvider.Factory {
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
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(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
|
||||
)
|
||||
else -> throw IllegalArgumentException("Unknown ViewModel class")
|
||||
} as T
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import android.app.Application
|
||||
import h_mal.appttude.com.driver.data.FirebaseAuthSource
|
||||
import h_mal.appttude.com.driver.data.FirebaseDatabaseSource
|
||||
import h_mal.appttude.com.driver.data.FirebaseStorageSource
|
||||
import h_mal.appttude.com.driver.data.prefs.PreferenceProvider
|
||||
import org.kodein.di.Kodein
|
||||
import org.kodein.di.KodeinAware
|
||||
import org.kodein.di.android.x.androidXModule
|
||||
@@ -20,6 +21,7 @@ class DriverApplication : Application(), KodeinAware {
|
||||
bind() from singleton { FirebaseAuthSource() }
|
||||
bind() from singleton { FirebaseDatabaseSource() }
|
||||
bind() from singleton { FirebaseStorageSource() }
|
||||
bind() from provider { ApplicationViewModelFactory(instance(), instance(), instance()) }
|
||||
bind() from singleton { PreferenceProvider(this@DriverApplication) }
|
||||
bind() from provider { ApplicationViewModelFactory(instance(), instance(), instance(), instance()) }
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package h_mal.appttude.com.driver.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
|
||||
@@ -16,12 +15,11 @@ import h_mal.appttude.com.driver.R
|
||||
import h_mal.appttude.com.driver.application.ApplicationViewModelFactory
|
||||
import h_mal.appttude.com.driver.data.ViewState
|
||||
import h_mal.appttude.com.driver.utils.*
|
||||
import h_mal.appttude.com.driver.utils.GenericsHelper.getGenericClassAt
|
||||
import h_mal.appttude.com.driver.utils.GenericsHelper.inflateBindingByType
|
||||
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, VB : ViewBinding> : AppCompatActivity(), KodeinAware {
|
||||
// The Idling Resource which will be null in production.
|
||||
@@ -47,34 +45,12 @@ abstract class BaseActivity<V : BaseViewModel, VB : ViewBinding> : AppCompatActi
|
||||
{ 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")
|
||||
|
||||
/**
|
||||
* Create a view binding out of the the generic [VB]
|
||||
*/
|
||||
private 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()
|
||||
_binding = inflateBindingByType(getGenericClassAt(1))
|
||||
_binding = inflateBindingByType(getGenericClassAt(1), layoutInflater)
|
||||
setContentView(requireNotNull(_binding).root)
|
||||
setupView(binding)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package h_mal.appttude.com.driver.base
|
||||
|
||||
import android.net.ConnectivityManager
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import com.firebase.ui.database.FirebaseRecyclerAdapter
|
||||
import com.firebase.ui.database.FirebaseRecyclerOptions
|
||||
import h_mal.appttude.com.driver.utils.GenericsHelper.getGenericClassAt
|
||||
import h_mal.appttude.com.driver.utils.GenericsHelper.inflateBindingByType
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
|
||||
open class BaseFirebaseAdapter<T: Any, VB : ViewBinding>(options: FirebaseRecyclerOptions<T>, private val layoutInflater: LayoutInflater):
|
||||
FirebaseRecyclerAdapter<T, CustomViewHolder<VB>>(options) {
|
||||
|
||||
private val connectivityManager = layoutInflater.context.getSystemService(ConnectivityManager::class.java) as ConnectivityManager
|
||||
|
||||
private var _binding: VB? = null
|
||||
val binding: VB
|
||||
get() = _binding ?: error("Must only access binding while fragment is attached.")
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder<VB> {
|
||||
_binding = inflateBindingByType(getGenericClassAt(1), layoutInflater)
|
||||
val lp = RecyclerView.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
binding.root.layoutParams = lp
|
||||
return CustomViewHolder(requireNotNull(_binding))
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: CustomViewHolder<VB>, position: Int, model: T) { }
|
||||
|
||||
override fun getItemId(position: Int): Long {
|
||||
return snapshots.getSnapshot(position).key?.toByteArray()
|
||||
?.let { ByteBuffer.wrap(it).long } ?: super.getItemId(position)
|
||||
}
|
||||
|
||||
fun getKeyAtPosition(position: Int) = snapshots.getSnapshot(position).key
|
||||
|
||||
override fun startListening() {
|
||||
super.startListening()
|
||||
// check if network is connected
|
||||
if (connectivityManager.activeNetwork == null) {
|
||||
connectionLost()
|
||||
}
|
||||
}
|
||||
|
||||
open fun connectionLost() {}
|
||||
}
|
||||
|
||||
class CustomViewHolder<VB : ViewBinding>(val viewBinding: VB): ViewHolder(viewBinding.root)
|
||||
@@ -1,29 +1,27 @@
|
||||
package h_mal.appttude.com.driver.base
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.ClipData
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.activity.result.contract.ActivityResultContract
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.createViewModelLazy
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import h_mal.appttude.com.driver.application.ApplicationViewModelFactory
|
||||
import h_mal.appttude.com.driver.data.ViewState
|
||||
import h_mal.appttude.com.driver.utils.GenericsHelper.getGenericClassAt
|
||||
import h_mal.appttude.com.driver.utils.GenericsHelper.inflateBindingByType
|
||||
import h_mal.appttude.com.driver.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, VB : ViewBinding>(
|
||||
) : Fragment(), KodeinAware {
|
||||
abstract class BaseFragment<V : BaseViewModel, VB : ViewBinding> : Fragment(), KodeinAware {
|
||||
|
||||
private var _binding: VB? = null
|
||||
private val binding: VB
|
||||
@@ -31,7 +29,12 @@ abstract class BaseFragment<V : BaseViewModel, VB : ViewBinding>(
|
||||
|
||||
var mActivity: BaseActivity<V, *>? = null
|
||||
|
||||
override val kodein by kodein()
|
||||
private val factory by instance<ApplicationViewModelFactory>()
|
||||
|
||||
val viewModel: V by getFragmentViewModel()
|
||||
private fun getFragmentViewModel(): Lazy<V> =
|
||||
createViewModelLazy(getGenericClassAt(0), { viewModelStore }, factoryProducer = { factory })
|
||||
|
||||
private var multipleImage: Boolean = false
|
||||
|
||||
@@ -39,33 +42,6 @@ abstract class BaseFragment<V : BaseViewModel, VB : ViewBinding>(
|
||||
multipleImage = true
|
||||
}
|
||||
|
||||
override val kodein by kodein()
|
||||
val factory by instance<ApplicationViewModelFactory>()
|
||||
|
||||
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")
|
||||
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,
|
||||
@@ -126,25 +102,6 @@ abstract class BaseFragment<V : BaseViewModel, VB : ViewBinding>(
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
when (requestCode) {
|
||||
IMAGE_SELECT_REQUEST_CODE -> {
|
||||
data?.clipData?.convertToList()?.let { clip ->
|
||||
val list = clip.takeIf { it.size > 10 }?.let {
|
||||
clip.subList(0, 9)
|
||||
} ?: clip
|
||||
onImageGalleryResult(list)
|
||||
return
|
||||
}
|
||||
onImageGalleryResult(data?.data)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private fun ClipData.convertToList(): List<Uri> = 0.rangeTo(itemCount).map { getItemAt(it).uri }
|
||||
|
||||
/**
|
||||
@@ -180,10 +137,33 @@ abstract class BaseFragment<V : BaseViewModel, VB : ViewBinding>(
|
||||
open fun onImageGalleryResult(imageUris: List<Uri>?) {}
|
||||
|
||||
fun openGalleryForImage() {
|
||||
val intent = Intent(Intent.ACTION_PICK)
|
||||
intent.type = "image/*"
|
||||
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, multipleImage)
|
||||
startActivityForResult(intent, IMAGE_SELECT_REQUEST_CODE)
|
||||
registerForActivityResult(getResultsContract()) { result ->
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
when (result) {
|
||||
is Uri -> onImageGalleryResult(result)
|
||||
is List<*> -> onImageGalleryResult(result as List<Uri>)
|
||||
}
|
||||
}.launch(multipleImage)
|
||||
}
|
||||
|
||||
private fun getResultsContract(): ActivityResultContract<Boolean, Any?> {
|
||||
return object : ActivityResultContract<Boolean, Any?>() {
|
||||
override fun createIntent(context: Context, input: Boolean): Intent {
|
||||
return Intent(Intent.ACTION_PICK).apply {
|
||||
type = "image/*"
|
||||
putExtra(Intent.EXTRA_ALLOW_MULTIPLE, input)
|
||||
}
|
||||
}
|
||||
|
||||
override fun parseResult(resultCode: Int, intent: Intent?): Any? {
|
||||
intent?.clipData?.convertToList()?.let { clip ->
|
||||
val list = clip.takeIf { it.size > 10 }?.let {
|
||||
clip.subList(0, 9)
|
||||
} ?: clip
|
||||
return list
|
||||
}
|
||||
return intent?.data
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,14 +29,11 @@ abstract class BaseViewModel : ViewModel() {
|
||||
operation()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
e.message?.let {
|
||||
onError(it)
|
||||
return
|
||||
}
|
||||
defaultErrorMessage?.let {
|
||||
onError(it)
|
||||
return
|
||||
}
|
||||
onError((e.message ?: "Operation failed!!"))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import java.io.IOException
|
||||
|
||||
|
||||
abstract class DataSubmissionBaseViewModel<T : Any>(
|
||||
auth: FirebaseAuthentication,
|
||||
private val database: FirebaseDatabaseSource,
|
||||
@@ -32,7 +33,7 @@ abstract class DataSubmissionBaseViewModel<T : Any>(
|
||||
open fun setDataInDatabase(data: T, localImageUris: List<Uri?>?): Job = Job()
|
||||
open fun setDataInDatabase(data: T) {}
|
||||
|
||||
inline fun <reified T : Any> getDataClass() = io {
|
||||
inline fun <reified T : Any> retrieveDataFromDatabase() = io {
|
||||
doTryOperation("Failed to retrieve $objectName") {
|
||||
val data = databaseRef.getDataFromDatabaseRef<T>()
|
||||
onSuccess(data ?: FirebaseCompletion.Default)
|
||||
|
||||
@@ -21,6 +21,7 @@ const val PRIVATE_HIRE_VEHICLE = "private_hire_vehicle"
|
||||
const val VEHICLE_DETAILS = "vehicle_details"
|
||||
const val ARCHIVE = "archive"
|
||||
|
||||
@SuppressWarnings("unused|WeakerAccess")
|
||||
class FirebaseDatabaseSource {
|
||||
private val database = FirebaseDatabase.getInstance()
|
||||
|
||||
@@ -35,7 +36,12 @@ class FirebaseDatabaseSource {
|
||||
return data
|
||||
}
|
||||
|
||||
fun getUserRef(uid: String) = database.getReference(USER_CONST).child(uid)
|
||||
fun getDatabaseReferenceFromLink(link: String) = database.getReferenceFromUrl(link)
|
||||
|
||||
val users = database.getReference(USER_CONST)
|
||||
|
||||
fun getUsersRef() = database.reference.child(USER_CONST)
|
||||
fun getUserRef(uid: String) = users.child(uid)
|
||||
fun getUserDetailsRef(uid: String) = getUserRef(uid).child(USER_DETAILS)
|
||||
fun getVehicleRef(uid: String) = getUserRef(uid).child(VEHICLE_PROFILE)
|
||||
fun getDriverRef(uid: String) = getUserRef(uid).child(DRIVER_PROFILE)
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package h_mal.appttude.com.driver.data.prefs
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import androidx.preference.PreferenceManager
|
||||
|
||||
/**
|
||||
* Shared prefs class used for storing conversion name values as pairs
|
||||
* Then retrieving as pairs
|
||||
*
|
||||
*/
|
||||
const val SORT_OPTION = "SORT_OPTION"
|
||||
class PreferenceProvider (context: Context) {
|
||||
|
||||
private val appContext = context.applicationContext
|
||||
|
||||
private val preference: SharedPreferences =
|
||||
PreferenceManager.getDefaultSharedPreferences(appContext)
|
||||
|
||||
fun setSortOption(sortLabel: String) {
|
||||
preference.edit()
|
||||
.putString(SORT_OPTION, sortLabel)
|
||||
.apply()
|
||||
}
|
||||
|
||||
fun getSortOption(): String? = preference
|
||||
.getString(SORT_OPTION, null)
|
||||
|
||||
}
|
||||
@@ -1,13 +1,22 @@
|
||||
package h_mal.appttude.com.driver.utils
|
||||
|
||||
|
||||
/**
|
||||
* Extension function that will execute high order if value is true or do nothing
|
||||
*
|
||||
* @sample #boolean.isTrue{ #Do something when its true }
|
||||
*/
|
||||
inline fun Boolean.isTrue(block: () -> Unit){
|
||||
if (this) {
|
||||
block()
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <T, R> T.isNotNull(block: (T) -> R): R?{
|
||||
/**
|
||||
* Extension function that will execute high order if value is not null or do nothing
|
||||
*
|
||||
* @sample #nullable.isNotNull{i -> i.doSomethingSinceItsNotNull() }
|
||||
*/
|
||||
inline fun <T, R> T?.isNotNull(block: (T) -> R): R?{
|
||||
return if (this != null) {
|
||||
block(this)
|
||||
} else {
|
||||
|
||||
@@ -42,4 +42,15 @@ suspend inline fun <reified T : Any> DatabaseReference.getDataFromDatabaseRef():
|
||||
throw response.error.toException()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun <T: Any> DatabaseReference.getDataFromDatabaseRef(clazz : Class<T>): T? {
|
||||
return when (val response: EventResponse = singleValueEvent()) {
|
||||
is EventResponse.Changed -> {
|
||||
response.snapshot.getValue(clazz)
|
||||
}
|
||||
is EventResponse.Cancelled -> {
|
||||
throw response.error.toException()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package h_mal.appttude.com.driver.utils
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import java.lang.reflect.ParameterizedType
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
object GenericsHelper {
|
||||
@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")
|
||||
|
||||
/**
|
||||
* Create a view binding out of the the generic [VB]
|
||||
*
|
||||
* @sample inflateBindingByType(getGenericClassAt(0), layoutInflater)
|
||||
*/
|
||||
fun <VB: ViewBinding> inflateBindingByType(
|
||||
genericClassAt: KClass<VB>,
|
||||
layoutInflater: LayoutInflater
|
||||
): 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) {
|
||||
println ("generic class failed at = $genericClassAt")
|
||||
exception.printStackTrace()
|
||||
throw IllegalStateException("Can not inflate binding from generic")
|
||||
}
|
||||
|
||||
fun <VB: ViewBinding> 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")
|
||||
}
|
||||
}
|
||||
@@ -1,28 +1,29 @@
|
||||
package h_mal.appttude.com.driver.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.view.View
|
||||
import androidx.annotation.IdRes
|
||||
import androidx.navigation.Navigation
|
||||
|
||||
const val UPLOAD_NEW = "upload_new"
|
||||
fun View.navigateTo(@IdRes navId: Int, args: Bundle? = null) {
|
||||
Navigation
|
||||
.findNavController(this)
|
||||
.navigate(navId, args)
|
||||
}
|
||||
|
||||
fun Any.toBundle(key: String): Bundle {
|
||||
return Bundle().apply {
|
||||
when (this@toBundle) {
|
||||
is String -> putString(key, this@toBundle)
|
||||
is Int -> putInt(key, this@toBundle)
|
||||
is Boolean -> putBoolean(key, this@toBundle)
|
||||
is Parcelable -> putParcelable(key, this@toBundle)
|
||||
is Double -> putDouble(key, this@toBundle)
|
||||
is Float -> putFloat(key, this@toBundle)
|
||||
}
|
||||
|
||||
fun navigateToActivity(context: Context, navigationActivity: Navigations) {
|
||||
try {
|
||||
val ourClass: Class<*> =
|
||||
Class.forName("h_mal.appttude.com.driver." + navigationActivity.value)
|
||||
val intent = Intent(context, ourClass)
|
||||
context.startActivity(intent)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
fun View.navigateTo(@IdRes navId: Int) {
|
||||
Navigation
|
||||
.findNavController(this)
|
||||
.navigate(navId)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
package h_mal.appttude.com.driver.viewmodels
|
||||
|
||||
import android.net.Uri
|
||||
import com.google.firebase.database.DatabaseReference
|
||||
import com.google.firebase.storage.StorageReference
|
||||
import h_mal.appttude.com.driver.base.DataSubmissionBaseViewModel
|
||||
import h_mal.appttude.com.driver.data.FirebaseAuthentication
|
||||
import h_mal.appttude.com.driver.data.FirebaseDatabaseSource
|
||||
import h_mal.appttude.com.driver.data.FirebaseStorageSource
|
||||
import h_mal.appttude.com.driver.model.DriversLicense
|
||||
import h_mal.appttude.com.driver.utils.Coroutines.io
|
||||
|
||||
class DriverLicenseViewModel(
|
||||
auth: FirebaseAuthentication,
|
||||
database: FirebaseDatabaseSource,
|
||||
storage: FirebaseStorageSource
|
||||
) : 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<DriversLicense>()
|
||||
|
||||
override fun setDataInDatabase(data: DriversLicense, localImageUri: Uri?) = io {
|
||||
doTryOperation("Failed to upload $objectName") {
|
||||
val imageUrl = getImageUrl(localImageUri, data.licenseImageString)
|
||||
data.licenseImageString = imageUrl
|
||||
postDataToDatabase(data)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package h_mal.appttude.com.driver.viewmodels
|
||||
|
||||
import android.net.Uri
|
||||
import com.google.firebase.database.DatabaseReference
|
||||
import com.google.firebase.storage.StorageReference
|
||||
import h_mal.appttude.com.driver.base.DataSubmissionBaseViewModel
|
||||
import h_mal.appttude.com.driver.data.FirebaseAuthentication
|
||||
import h_mal.appttude.com.driver.data.FirebaseDatabaseSource
|
||||
import h_mal.appttude.com.driver.data.FirebaseStorageSource
|
||||
import h_mal.appttude.com.driver.model.DriverProfile
|
||||
import h_mal.appttude.com.driver.utils.Coroutines.io
|
||||
|
||||
class DriverProfileViewModel(
|
||||
auth: FirebaseAuthentication,
|
||||
database: FirebaseDatabaseSource,
|
||||
storage: FirebaseStorageSource
|
||||
) : 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<DriverProfile>()
|
||||
|
||||
override fun setDataInDatabase(data: DriverProfile, localImageUri: Uri?) = io {
|
||||
doTryOperation("Failed to upload $objectName") {
|
||||
|
||||
val imageUrl = getImageUrl(localImageUri, data.driverPic)
|
||||
data.driverPic = imageUrl
|
||||
|
||||
postDataToDatabase(data)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package h_mal.appttude.com.driver.viewmodels
|
||||
|
||||
import android.net.Uri
|
||||
import com.google.firebase.database.DatabaseReference
|
||||
import com.google.firebase.storage.StorageReference
|
||||
import h_mal.appttude.com.driver.base.DataSubmissionBaseViewModel
|
||||
import h_mal.appttude.com.driver.data.FirebaseAuthentication
|
||||
import h_mal.appttude.com.driver.data.FirebaseDatabaseSource
|
||||
import h_mal.appttude.com.driver.data.FirebaseStorageSource
|
||||
import h_mal.appttude.com.driver.model.Insurance
|
||||
import h_mal.appttude.com.driver.utils.Coroutines.io
|
||||
|
||||
class InsuranceViewModel(
|
||||
auth: FirebaseAuthentication,
|
||||
database: FirebaseDatabaseSource,
|
||||
storage: FirebaseStorageSource
|
||||
) : 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<Insurance>()
|
||||
|
||||
override fun setDataInDatabase(data: Insurance, localImageUris: List<Uri?>?) = io {
|
||||
doTryOperation("Failed to upload $objectName") {
|
||||
val imageUrls = if (!localImageUris.isNullOrEmpty()) {
|
||||
getImageUrls(localImageUris).toMutableList()
|
||||
} else {
|
||||
data.photoStrings
|
||||
}
|
||||
if (imageUrls.isNullOrEmpty()) {
|
||||
onError("no images selected")
|
||||
return@doTryOperation
|
||||
}
|
||||
|
||||
data.photoStrings = imageUrls
|
||||
postDataToDatabase(data)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package h_mal.appttude.com.driver.viewmodels
|
||||
|
||||
import android.net.Uri
|
||||
import com.google.firebase.database.DatabaseReference
|
||||
import com.google.firebase.storage.StorageReference
|
||||
import h_mal.appttude.com.driver.base.DataSubmissionBaseViewModel
|
||||
import h_mal.appttude.com.driver.data.FirebaseAuthentication
|
||||
import h_mal.appttude.com.driver.data.FirebaseDatabaseSource
|
||||
import h_mal.appttude.com.driver.data.FirebaseStorageSource
|
||||
import h_mal.appttude.com.driver.model.Logbook
|
||||
import h_mal.appttude.com.driver.utils.Coroutines.io
|
||||
|
||||
class LogbookViewModel(
|
||||
auth: FirebaseAuthentication,
|
||||
database: FirebaseDatabaseSource,
|
||||
storage: FirebaseStorageSource
|
||||
) : 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<Logbook>()
|
||||
|
||||
override fun setDataInDatabase(data: Logbook, localImageUri: Uri?) = io {
|
||||
doTryOperation("Failed to upload $objectName") {
|
||||
val imageUrl = getImageUrl(localImageUri, data.photoString)
|
||||
data.photoString = imageUrl
|
||||
postDataToDatabase(data)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package h_mal.appttude.com.driver.viewmodels
|
||||
|
||||
import android.net.Uri
|
||||
import com.google.firebase.database.DatabaseReference
|
||||
import com.google.firebase.storage.StorageReference
|
||||
import h_mal.appttude.com.driver.base.DataSubmissionBaseViewModel
|
||||
import h_mal.appttude.com.driver.data.FirebaseAuthentication
|
||||
import h_mal.appttude.com.driver.data.FirebaseDatabaseSource
|
||||
import h_mal.appttude.com.driver.data.FirebaseStorageSource
|
||||
import h_mal.appttude.com.driver.model.Mot
|
||||
import h_mal.appttude.com.driver.utils.Coroutines.io
|
||||
|
||||
class MotViewModel(
|
||||
auth: FirebaseAuthentication,
|
||||
database: FirebaseDatabaseSource,
|
||||
storage: FirebaseStorageSource
|
||||
) : 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<Mot>()
|
||||
|
||||
override fun setDataInDatabase(data: Mot, localImageUri: Uri?) = io {
|
||||
doTryOperation("Failed to upload $objectName") {
|
||||
val imageUrl = getImageUrl(localImageUri, data.motImageString)
|
||||
data.motImageString = imageUrl
|
||||
postDataToDatabase(data)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package h_mal.appttude.com.driver.viewmodels
|
||||
|
||||
import android.net.Uri
|
||||
import com.google.firebase.database.DatabaseReference
|
||||
import com.google.firebase.storage.StorageReference
|
||||
import h_mal.appttude.com.driver.base.DataSubmissionBaseViewModel
|
||||
import h_mal.appttude.com.driver.data.FirebaseAuthentication
|
||||
import h_mal.appttude.com.driver.data.FirebaseDatabaseSource
|
||||
import h_mal.appttude.com.driver.data.FirebaseStorageSource
|
||||
import h_mal.appttude.com.driver.model.PrivateHireLicense
|
||||
import h_mal.appttude.com.driver.utils.Coroutines.io
|
||||
|
||||
class PrivateHireLicenseViewModel(
|
||||
auth: FirebaseAuthentication,
|
||||
database: FirebaseDatabaseSource,
|
||||
storage: FirebaseStorageSource
|
||||
) : 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<PrivateHireLicense>()
|
||||
|
||||
override fun setDataInDatabase(data: PrivateHireLicense, localImageUri: Uri?) = io {
|
||||
doTryOperation("Failed to upload private hire license") {
|
||||
val imageUrl = getImageUrl(localImageUri, data.phImageString)
|
||||
val driverLicense = PrivateHireLicense(
|
||||
phExpiry = data.phExpiry,
|
||||
phNumber = data.phNumber,
|
||||
phImageString = imageUrl
|
||||
)
|
||||
|
||||
postDataToDatabase(driverLicense)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package h_mal.appttude.com.driver.viewmodels
|
||||
|
||||
import android.net.Uri
|
||||
import com.google.firebase.database.DatabaseReference
|
||||
import com.google.firebase.storage.StorageReference
|
||||
import h_mal.appttude.com.driver.base.DataSubmissionBaseViewModel
|
||||
import h_mal.appttude.com.driver.data.FirebaseAuthentication
|
||||
import h_mal.appttude.com.driver.data.FirebaseDatabaseSource
|
||||
import h_mal.appttude.com.driver.data.FirebaseStorageSource
|
||||
import h_mal.appttude.com.driver.model.PrivateHireVehicle
|
||||
import h_mal.appttude.com.driver.utils.Coroutines.io
|
||||
|
||||
class PrivateHireVehicleViewModel(
|
||||
auth: FirebaseAuthentication,
|
||||
database: FirebaseDatabaseSource,
|
||||
storage: FirebaseStorageSource
|
||||
) : 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<PrivateHireVehicle>()
|
||||
|
||||
override fun setDataInDatabase(data: PrivateHireVehicle, localImageUri: Uri?) = io {
|
||||
doTryOperation("Failed to upload $objectName") {
|
||||
val imageUrl = getImageUrl(localImageUri, data.phCarImageString)
|
||||
data.phCarImageString = imageUrl
|
||||
postDataToDatabase(data)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ class RoleViewModel(
|
||||
override val storageRef: StorageReference? = null
|
||||
override val objectName: String = "role"
|
||||
|
||||
override fun getDataFromDatabase() = getDataClass<String>()
|
||||
override fun getDataFromDatabase() = retrieveDataFromDatabase<String>()
|
||||
|
||||
override fun setDataInDatabase(data: String) {
|
||||
io {
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
package h_mal.appttude.com.driver.viewmodels
|
||||
|
||||
import com.google.firebase.database.DatabaseReference
|
||||
import com.google.firebase.storage.StorageReference
|
||||
import h_mal.appttude.com.driver.base.DataSubmissionBaseViewModel
|
||||
import h_mal.appttude.com.driver.data.FirebaseAuthentication
|
||||
import h_mal.appttude.com.driver.data.FirebaseDatabaseSource
|
||||
import h_mal.appttude.com.driver.data.FirebaseStorageSource
|
||||
import h_mal.appttude.com.driver.model.VehicleProfile
|
||||
import h_mal.appttude.com.driver.utils.Coroutines.io
|
||||
|
||||
class VehicleProfileViewModel(
|
||||
auth: FirebaseAuthentication,
|
||||
database: FirebaseDatabaseSource,
|
||||
storage: FirebaseStorageSource
|
||||
) : 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<VehicleProfile>()
|
||||
|
||||
override fun setDataInDatabase(data: VehicleProfile) {
|
||||
io {
|
||||
doTryOperation("Failed to upload $objectName") {
|
||||
postDataToDatabase(data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/drawer_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:openDrawer="start">
|
||||
|
||||
<include
|
||||
android:id="@+id/app_bar_layout"
|
||||
layout="@layout/app_bar_main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<com.google.android.material.navigation.NavigationView
|
||||
android:id="@+id/nav_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="start"
|
||||
android:fitsSystemWindows="true"
|
||||
app:itemTextColor="@android:color/white"
|
||||
app:headerLayout="@layout/nav_header_main"
|
||||
app:menu="@menu/activity_main_drawer">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/logout"
|
||||
style="@style/headerStyle"
|
||||
android:background="@color/colour_nine"
|
||||
android:textSize="14sp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/logout"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
</com.google.android.material.navigation.NavigationView>
|
||||
|
||||
</androidx.drawerlayout.widget.DrawerLayout>
|
||||
@@ -18,22 +18,9 @@
|
||||
android:layout_marginBottom="24dp"
|
||||
android:text="@string/not_a_driver_message" />
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/request_driver_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:backgroundTint="@color/colour_one"
|
||||
android:selectAllOnFocus="true"
|
||||
app:cardCornerRadius="8dp">
|
||||
style="@style/TextButton"
|
||||
android:text="@string/request_driver_profile" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/request_driver_profile"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
</androidx.cardview.widget.CardView>
|
||||
</LinearLayout>
|
||||
@@ -46,7 +46,8 @@
|
||||
tools:src="@drawable/choice_img_round" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout style="@style/text_input_layout">
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
style="@style/text_input_layout">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/names_input"
|
||||
|
||||
@@ -4,9 +4,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
style="@style/parent_constraint_layout"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
tools:context=".ui.vehicleprofile.LogbookFragment">
|
||||
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
style="@style/parent_constraint_layout"
|
||||
tools:context=".ui.vehicleprofile.PrivateHireVehicleFragment">
|
||||
style="@style/parent_constraint_layout">
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="vertical"
|
||||
tools:context=".ui.vehicleprofile.VehicleProfileFragment">
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
<item
|
||||
android:id="@+id/archive"
|
||||
android:icon="@drawable/ic_sort_black_24dp"
|
||||
android:title="sort"
|
||||
app:showAsAction="ifRoom"></item>
|
||||
android:title="@string/sort"
|
||||
app:showAsAction="ifRoom" />
|
||||
</menu>
|
||||
@@ -14,5 +14,6 @@
|
||||
<color name="colour_seven">#91ddff</color>
|
||||
|
||||
<color name="colour_eight">#9958BE3F</color>
|
||||
<color name="colour_ten">#604D4A51</color>
|
||||
<color name="colour_nine">#303030</color>
|
||||
</resources>
|
||||
|
||||
@@ -4,4 +4,5 @@
|
||||
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||
<dimen name="nav_header_vertical_spacing">8dp</dimen>
|
||||
<dimen name="nav_header_height">200dp</dimen>
|
||||
<dimen name="status_size">16dp</dimen>
|
||||
</resources>
|
||||
@@ -1,5 +1,4 @@
|
||||
<resources>
|
||||
<string name="app_name">Choice Minicabs</string>
|
||||
<string name="nav_header_title">Driver Name</string>
|
||||
<string name="nav_header_subtitle">driver@example.com</string>
|
||||
<string name="nav_header_desc">Navigation header</string>
|
||||
@@ -83,7 +82,7 @@
|
||||
<string name="insurance">Insurance</string>
|
||||
<string name="m_o_t">M.O.T</string>
|
||||
<string name="log_book">Log book</string>
|
||||
<string name="private_hire_vehicle_license">Private hire Vehicle License</string>
|
||||
<string name="private_hire_vehicle_license">Private Hire Vehicle License</string>
|
||||
<string name="upload_insurance_documents">Upload Insurance Documents</string>
|
||||
<string name="insurer">Insurer</string>
|
||||
<string name="insurance_expiry">Insurance expiry</string>
|
||||
@@ -95,4 +94,11 @@
|
||||
<string name="request_driver_profile">Request driver profile</string>
|
||||
<string name="or">OR</string>
|
||||
<string name="floating_action_button">Floating action button</string>
|
||||
<string name="sort">sort</string>
|
||||
<string name="denied">Approval denied</string>
|
||||
<string name="pending">Pending approval</string>
|
||||
<string name="approved">Approved</string>
|
||||
<string name="not_submitted">Not submitted</string>
|
||||
<string name="empty_view_message">You have no drivers</string>
|
||||
<string name="approval_status">approval status</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user