This commit is contained in:
mohamedkaif356
2023-06-19 16:30:43 +05:30
commit 18333f0d74
88 changed files with 4278 additions and 0 deletions

View File

@@ -0,0 +1,7 @@
package com.example.hposregistration
import android.app.Application
import dagger.hilt.android.HiltAndroidApp
@HiltAndroidApp
class HPOSRegistrationApplication: Application()

View File

@@ -0,0 +1,49 @@
package com.example.hposregistration.adapters
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.AsyncListDiffer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.example.hposregistration.data.user.UserData
import com.example.hposregistration.databinding.UserItemViewBinding
class UserListOfflineAdapter(private val view: View) : RecyclerView.Adapter<UserListOfflineAdapter.CompanyViewHolder>() {
inner class CompanyViewHolder(val binding: UserItemViewBinding) :
RecyclerView.ViewHolder(binding.root)
private val differCallback = object : DiffUtil.ItemCallback<UserData>() {
override fun areItemsTheSame(oldItem: UserData, newItem: UserData): Boolean {
return oldItem.name == newItem.name
}
override fun areContentsTheSame(oldItem: UserData, newItem: UserData): Boolean {
return oldItem == newItem
}
}
val differ = AsyncListDiffer(this, differCallback)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CompanyViewHolder {
return CompanyViewHolder(
UserItemViewBinding
.inflate(LayoutInflater.from(parent.context), parent, false)
)
}
override fun getItemCount(): Int {
return differ.currentList.size
}
override fun onBindViewHolder(holder: CompanyViewHolder, position: Int) {
val userList = differ.currentList[position]
holder.binding.apply {
userName.text = userList.name
userId.text = userList._id
Glide.with(view).load(userList.userImage).into(userImage)
}
}
}

View File

@@ -0,0 +1,35 @@
package com.example.hposregistration.adapters
import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.example.hposregistration.data.user.UserData
import com.example.hposregistration.databinding.UserItemViewBinding
import com.firebase.ui.firestore.FirestoreRecyclerAdapter
import com.firebase.ui.firestore.FirestoreRecyclerOptions
class UserListOnlineAdapter(options: FirestoreRecyclerOptions<UserData>, private val view: View) :
FirestoreRecyclerAdapter<UserData, UserListOnlineAdapter.OrderItemViewHolder>(options) {
class OrderItemViewHolder(val binding: UserItemViewBinding) :
RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): OrderItemViewHolder {
return OrderItemViewHolder(
UserItemViewBinding
.inflate(LayoutInflater.from(parent.context), parent, false)
)
}
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: OrderItemViewHolder, position: Int, model: UserData) {
holder.binding.apply {
userName.text = model.name
userId.text = model._id
Glide.with(view).load(model.userImage).into(userImage)
}
}
}

View File

@@ -0,0 +1,27 @@
package com.example.hposregistration.dao
import androidx.room.TypeConverter
import com.example.hposregistration.data.user.UserData
import com.google.gson.Gson
class Converters {
private val gson = Gson()
@TypeConverter
fun fromString(value: String?): UserData.Location? {
return if (value != null) {
gson.fromJson(value, UserData.Location::class.java)
} else {
null
}
}
@TypeConverter
fun toString(location: UserData.Location?): String? {
return if (location != null) {
gson.toJson(location)
} else {
null
}
}
}

View File

@@ -0,0 +1,12 @@
package com.example.hposregistration.dao
import androidx.room.Database
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import com.example.hposregistration.data.user.UserData
@Database(entities = [UserData::class], version = 1, exportSchema = false)
@TypeConverters(Converters::class)
abstract class MyDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}

View File

@@ -0,0 +1,23 @@
package com.example.hposregistration.dao
import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import com.example.hposregistration.data.user.UserData
@Dao
interface UserDao {
@Query("SELECT * from user_table")
fun getAll(): LiveData<List<UserData>>
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertAll(userData: UserData)
@Query("SELECT * FROM user_table WHERE _id = :id")
suspend fun getUserByID(id: String): UserData
@Query("DELETE FROM user_table WHERE _id = :id")
suspend fun deleteById(id: String)
}

View File

@@ -0,0 +1,21 @@
package com.example.hposregistration.data
import com.example.hposregistration.data.user.UserData
object Constant {
fun String.fetchYOBFromDOB(): Int {
val startIndex = if (this.length >= 4) this.length - 4 else 0
return this.substring(startIndex).toInt()
}
fun String.mapToGender(): UserData.Gender {
return if (this.lowercase() == "m"|| this.lowercase() == "male") {
UserData.Gender.MALE
} else if (this.lowercase() == "f"|| this.lowercase() == "female") {
UserData.Gender.FEMALE
} else {
UserData.Gender.OTHER
}
}
}

View File

@@ -0,0 +1,58 @@
package com.example.hposregistration.data
import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import androidx.lifecycle.LiveData
class NetworkStatusLiveData(context: Context) : LiveData<Boolean>() {
private val connectivityManager: ConnectivityManager =
context.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
private val networkCallback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
postValue(true)
}
override fun onLost(network: Network) {
postValue(false)
}
}
override fun onActive() {
super.onActive()
postValue(isNetworkAvailable())
registerNetworkCallback()
}
override fun onInactive() {
super.onInactive()
unregisterNetworkCallback()
}
private fun registerNetworkCallback() {
val networkRequest = NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET)
.build()
connectivityManager.registerNetworkCallback(networkRequest, networkCallback)
}
private fun unregisterNetworkCallback() {
connectivityManager.unregisterNetworkCallback(networkCallback)
}
private fun isNetworkAvailable(): Boolean {
val network = connectivityManager.activeNetwork
val networkCapabilities = connectivityManager.getNetworkCapabilities(network)
return networkCapabilities != null &&
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
}
}

View File

@@ -0,0 +1,33 @@
package com.example.hposregistration.data
import androidx.lifecycle.LiveData
import com.example.hposregistration.dao.UserDao
import com.example.hposregistration.data.user.UserData
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class MainRepository @Inject constructor(
private val userDao: UserDao,
private val userFireBaseDao: com.example.hposregistration.network.UserDao
) {
val allUsers: LiveData<List<UserData>> = userDao.getAll()
suspend fun insert(userData: UserData){
userDao.insertAll(userData)
}
suspend fun getUserByID(id: String): UserData {
return userDao.getUserByID(id)
}
suspend fun deleteById(id: String) {
return userDao.deleteById(id)
}
suspend fun addDataToFirebase(userData: UserData): Response<String> {
return userFireBaseDao.addUserToDatabase(userData)
}
}

View File

@@ -0,0 +1,6 @@
package com.example.hposregistration.data
sealed class Response<out R> {
data class Success<out T>(val data: T) : Response<T>()
data class Error(val exception: Exception) : Response<Nothing>()
}

View File

@@ -0,0 +1,253 @@
package com.example.hposregistration.data
import com.example.hposregistration.data.aadhar.AadharCard
import com.example.hposregistration.data.aadhar.QrCodeException
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.IOException
import java.math.BigInteger
import java.nio.charset.StandardCharsets
import java.util.LinkedList
import java.util.zip.GZIPInputStream
/**
* Class to decode scanned QRcode
*/
open class SecureQrCode(scanData: String?) {
private var emailMobilePresent = 0
private var imageStartIndex = 0
private var imageEndIndex = 0
private var decodedData: ArrayList<String>? = null
private var signature: String? = null
private var email: String? = null
private var mobile: String? = null
var scannedAadharCard: AadharCard = AadharCard()
init {
// 1. Convert Base10 to BigInt
val bigIntScanData = scanData?.let { BigInteger(it, 10) }
// 2. Convert BigInt to Byte Array
val byteScanData = bigIntScanData?.toByteArray()
// 3. Decompress Byte Array
val decompByteScanData = byteScanData?.let { decompressData(it) }
// 4. Split the byte array using delimiter
val parts = decompByteScanData?.let { separateData(it) }
// Throw error if there are no parts
if (parts != null) {
if (parts.isEmpty()) {
throw QrCodeException("Invalid QR Code Data, no parts found after splitting by delimiter")
}
}
// 5. decode extracted data to string
if (parts != null) {
decodeData(parts)
}
// 6. Extract Signature
if (decompByteScanData != null) {
decodeSignature(decompByteScanData)
}
// 7. Email and Mobile number
if (decompByteScanData != null) {
decodeMobileEmail(decompByteScanData)
}
}
/**
* Decompress the byte array, compression used is GZIP
* @param byteScanData compressed byte array
* @return uncompressed byte array
*/
@Throws(QrCodeException::class)
protected fun decompressData(byteScanData: ByteArray): ByteArray {
val bos = ByteArrayOutputStream(byteScanData.size)
val bin = ByteArrayInputStream(byteScanData)
val gis: GZIPInputStream = try {
GZIPInputStream(bin)
} catch (e: IOException) {
throw QrCodeException("Error in opening Gzip byte stream while decompressing QRcode", e)
}
var size = 0
val buf = ByteArray(1024)
while (size >= 0) {
try {
size = gis.read(buf, 0, buf.size)
if (size > 0) {
bos.write(buf, 0, size)
}
} catch (e: IOException) {
throw QrCodeException("Error in writing byte stream while decompressing QRcode", e)
}
}
try {
gis.close()
bin.close()
} catch (e: IOException) {
throw QrCodeException("Error in closing byte stream while decompressing QRcode", e)
}
return bos.toByteArray()
}
/**
* Function to split byte array with delimiter
* @param source source byte array
* @return list of separated byte arrays
*/
private fun separateData(source: ByteArray): List<ByteArray> {
val separatedParts: MutableList<ByteArray> = LinkedList()
var begin = 0
for (i in source.indices) {
if (source[i] == SEPARATOR_BYTE) {
// skip if first or last byte is separator
if (i != 0 && i != source.size - 1) {
separatedParts.add(source.copyOfRange(begin, i))
}
begin = i + 1
// check if we have got all the parts of text data
if (separatedParts.size == VTC_INDEX + 1) {
// this is required to extract image data
imageStartIndex = begin
break
}
}
}
return separatedParts
}
private fun decodeData(encodedData: List<ByteArray>) {
val i = encodedData.iterator()
decodedData = ArrayList()
while (i.hasNext()) {
decodedData!!.add(String(i.next(), StandardCharsets.ISO_8859_1))
}
// set the value of email/mobile present flag
emailMobilePresent = decodedData!![0].toInt()
// populate decoded data
scannedAadharCard.name = decodedData!![2]
scannedAadharCard.dateOfBirth = decodedData!![3]
scannedAadharCard.gender = decodedData!![4]
scannedAadharCard.careOf = decodedData!![5]
scannedAadharCard.district = decodedData!![6]
scannedAadharCard.landmark = decodedData!![7]
scannedAadharCard.house = decodedData!![8]
scannedAadharCard.location = decodedData!![9]
scannedAadharCard.pinCode = decodedData!![10]
scannedAadharCard.postOffice = decodedData!![11]
scannedAadharCard.state = decodedData!![12]
scannedAadharCard.street = decodedData!![13]
scannedAadharCard.subDistrict = decodedData!![14]
scannedAadharCard.vtc = decodedData!![15]
}
/**
* ref : https://uidai.gov.in/2-uncategorised/11320-aadhaar-paperless-offline-e-kyc-3.html
* Hashing logic for Email ID :
* Sha256(Sha256(Email+SharePhrase))*number of times last digit of Aadhaar number
* (Ref ID field contains last 4 digits).
* Example :
* Email: abc@gm.com
* Aadhaar Number:XXXX XXXX 3632
* Passcode : Lock@487
* Hash : Sha256(Sha256(abc@gm.comLock@487))*2
* In case of Aadhaar number ends with Zero we will hashed one time.
* **********************************************************************
* **********************************************************************
* Hashing logic for Mobile Number :
* Sha256(Sha256(Mobile+SharePhrase))*number of times last digit of Aadhaar number
* (Ref ID field contains last 4 digits).
* Example :
* Mobile: 1234567890
* Aadhaar Number:XXXX XXXX 3632
* Passcode : Lock@487
* Hash: Sha256(Sha256(1234567890Lock@487))*2
* In case of Aadhaar number ends with Zero we will hashed one time.
*/
private fun decodeMobileEmail(decompressedData: ByteArray) {
val mobileStartIndex: Int
val mobileEndIndex: Int
val emailStartIndex: Int
val emailEndIndex: Int
when (emailMobilePresent) {
3 -> {
// both email mobile present
mobileStartIndex = decompressedData.size - 289 // length -1 -256 -32
mobileEndIndex = decompressedData.size - 257 // length -1 -256
emailStartIndex = decompressedData.size - 322 // length -1 -256 -32 -1 -32
emailEndIndex = decompressedData.size - 290 // length -1 -256 -32 -1
mobile = bytesToHex(
decompressedData.copyOfRange(mobileStartIndex, mobileEndIndex + 1)
)
email = bytesToHex(
decompressedData.copyOfRange(emailStartIndex, emailEndIndex + 1)
)
// set image end index, it will be used to extract image data
imageEndIndex = decompressedData.size - 323
}
2 -> {
// only mobile
email = ""
mobileStartIndex = decompressedData.size - 289 // length -1 -256 -32
mobileEndIndex = decompressedData.size - 257 // length -1 -256
mobile = bytesToHex(
decompressedData.copyOfRange(mobileStartIndex, mobileEndIndex + 1)
)
// set image end index, it will be used to extract image data
imageEndIndex = decompressedData.size - 290
}
1 -> {
// only email
mobile = ""
emailStartIndex = decompressedData.size - 289 // length -1 -256 -32
emailEndIndex = decompressedData.size - 257 // length -1 -256
email = bytesToHex(
decompressedData.copyOfRange(emailStartIndex, emailEndIndex + 1)
)
// set image end index, it will be used to extract image data
imageEndIndex = decompressedData.size - 290
}
else -> {
// no mobile or email
mobile = ""
email = ""
// set image end index, it will be used to extract image data
imageEndIndex = decompressedData.size - 257
}
}
}
private fun decodeSignature(decompressedData: ByteArray) {
// extract 256 bytes from the end of the byte array
val startIndex = decompressedData.size - 257
val noOfBytes = 256
signature = String(decompressedData, startIndex, noOfBytes, StandardCharsets.ISO_8859_1)
}
companion object {
protected const val SEPARATOR_BYTE = 255.toByte()
protected const val VTC_INDEX = 15
/**
* Convert byte array to hex string
*/
fun bytesToHex(bytes: ByteArray): String {
val hexArray = "0123456789ABCDEF".toCharArray()
val hexChars = CharArray(bytes.size * 2)
for (j in bytes.indices) {
val v = bytes[j].toInt() and 0xFF
hexChars[j * 2] = hexArray[v ushr 4]
hexChars[j * 2 + 1] = hexArray[v and 0x0F]
}
return String(hexChars)
}
}
}

View File

@@ -0,0 +1,20 @@
package com.example.hposregistration.data.aadhar
class AadharCard {
var name = ""
var dateOfBirth = ""
var gender = ""
var careOf = ""
var district = ""
var landmark = ""
var house = ""
var location = ""
var pinCode = ""
var postOffice = ""
var state = ""
var street = ""
var subDistrict = ""
var vtc = ""
}

View File

@@ -0,0 +1,6 @@
package com.example.hposregistration.data.aadhar
class QrCodeException : Exception {
constructor(message: String?) : super(message) {}
constructor(message: String?, cause: Throwable?) : super(message, cause) {}
}

View File

@@ -0,0 +1,49 @@
package com.example.hposregistration.data.user
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "user_table")
data class UserData(
@PrimaryKey
var _id: String = "",
var AbhaId: String = "",
var AadharId: String = "",
var name: String = "",
var birthYear: String = "",
var gender: String = "",
var phoneNumber: String = "",
var careOf: String = "",
var maritalStatus: String = "",
var caste: String = "",
var subCaste: String = "",
var house: String = "",
var city: String = "",
var district: String = "",
var state: String = "",
var pinCode: String = "",
var bloodGroup: String = "",
var isUnderMedication: Boolean? = false,
var isUnderTransfusion: Boolean? = false,
var sickleCellHistory: String? = "",
var userImage: String = "",
var location: Location? = null,
var uploadTime: String? = "",
var testStatus: Boolean? = false,
var mobileId: String = "",
var deviceId: String = "",
var kitSerial: String = "",
var csvPath: String = "",
var reportPath: String = ""
){
enum class Gender {
MALE,
FEMALE,
OTHER
}
data class Location(
var latitude: Double? = null,
var longitude: Double? = null
)
}

View File

@@ -0,0 +1,44 @@
package com.example.hposregistration.di
import android.app.Application
import android.content.Context
import androidx.room.Room
import com.example.hposregistration.dao.MyDatabase
import com.example.hposregistration.dao.UserDao
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Provides
@Singleton
fun provideMyDatabase(@ApplicationContext context: Context): MyDatabase {
return Room.databaseBuilder(
context, MyDatabase::class.java, "my_database"
).build()
}
@Provides
@Singleton
fun provideMyDao(myDatabase: MyDatabase): UserDao {
return myDatabase.userDao()
}
@Provides
@Singleton
fun provideMyNetworkDao(): com.example.hposregistration.network.UserDao {
return com.example.hposregistration.network.UserDao()
}
@Provides
@Singleton
fun provideContext(application: Application): Context {
return application.applicationContext
}
}

View File

@@ -0,0 +1,30 @@
package com.example.hposregistration.network
import com.example.hposregistration.data.Response
import com.example.hposregistration.data.user.UserData
import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
import kotlinx.coroutines.tasks.await
class UserDao {
private val db: FirebaseFirestore = Firebase.firestore
private val patientCollection = db.collection("patientData")
suspend fun addUserToDatabase(data: UserData): Response<String> {
return try {
patientCollection.document()
.set(data)
.await()
Response.Success(data._id)
} catch (e: Exception) {
Response.Error(e)
}
}
// suspend fun getPatientList(): List<UserData> {
// return patientCollection.get().await().toObjects(UserData::class.java)
// }
}

View File

@@ -0,0 +1,18 @@
package com.example.hposregistration.ui.activities
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.example.hposregistration.databinding.ActivityMainBinding
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
}
}

View File

@@ -0,0 +1,50 @@
package com.example.hposregistration.ui.fragments
import android.view.View
import android.widget.Button
import android.widget.TextView
import androidx.fragment.app.Fragment
import com.journeyapps.barcodescanner.ScanOptions
open class BaseFragment: Fragment() {
fun hideProgressBar(view: View) {
view.visibility = View.GONE
}
fun showProgressBar(view: View) {
view.visibility = View.VISIBLE
}
// fun hideErrorMessage(view: View) {
// view.visibility = View.GONE
// }
//
// fun showErrorMessage(message: String, errorView: View, errorMessageView: TextView) {
// errorView.visibility = View.VISIBLE
// errorMessageView.text = message
// }
//
// fun markButtonDisable(button: Button) {
// button.isEnabled = false
// }
//
// fun markButtonEnable(button: Button) {
// button.isEnabled = true
// }
fun scanQR(scannerMessage: String): ScanOptions {
val options = ScanOptions()
options.setDesiredBarcodeFormats(ScanOptions.QR_CODE)
options.setPrompt("Scan a barcode")
options.setCameraId(0)
options.setBeepEnabled(true)
options.setBarcodeImageEnabled(true)
options.setPrompt(scannerMessage)
options.setOrientationLocked(false)
return options
}
}

View File

@@ -0,0 +1,26 @@
package com.example.hposregistration.ui.fragments
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.example.hposregistration.databinding.FragmentProfileBinding
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class ProfileFragment : Fragment() {
private lateinit var _binding: FragmentProfileBinding
private val binding get() = _binding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentProfileBinding.inflate(layoutInflater, container, false)
return binding.root
}
}

View File

@@ -0,0 +1,161 @@
package com.example.hposregistration.ui.fragments
import android.app.AlertDialog
import android.content.Context
import android.content.DialogInterface
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import com.example.hposregistration.R
import com.example.hposregistration.adapters.UserListOfflineAdapter
import com.example.hposregistration.adapters.UserListOnlineAdapter
import com.example.hposregistration.data.user.UserData
import com.example.hposregistration.databinding.FragmentUserListBinding
import com.example.hposregistration.ui.viewmodels.RegistrationViewModel
import com.firebase.ui.firestore.FirestoreRecyclerOptions
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class UserListFragment : BaseFragment() {
private var _binding: FragmentUserListBinding? = null
private val binding get() = _binding!!
private val viewModel by viewModels<RegistrationViewModel>()
private var isOnline = false
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
_binding = FragmentUserListBinding.inflate(inflater, container, false)
setupViews()
return binding.root
}
override fun onResume() {
super.onResume()
init()
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
private fun setupViews() {
binding.btnRegisterUser.setOnClickListener {
findNavController().navigate(R.id.action_userListFragment_to_registrationFragment)
}
}
private fun init() {
viewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable ->
if (isNetworkAvailable) {
isOnline = isNetworkAvailable
fetchFromServer()
checkForLocalDBData()
} else {
isOnline = isNetworkAvailable
fetchFromLocalDB()
}
}
binding.uploadData.setOnClickListener {
showUploadDialog(requireContext())
}
}
private fun showUploadDialog(context: Context) {
val builder = AlertDialog.Builder(context)
builder.setTitle("Upload DB Registration")
builder.setMessage("Do you want to upload the local DB Registration to the cloud?")
// Positive button
builder.setPositiveButton("Upload") { dialog, _ ->
uploadLoadDBData(dialog)
}
// Negative button
builder.setNegativeButton("Cancel") { dialog, _ ->
dialog.dismiss()
}
val dialog = builder.create()
dialog.show()
}
private fun uploadLoadDBData(dialog: DialogInterface) {
viewModel.allUserData.observe(viewLifecycleOwner) {
if (it.isEmpty()) {
dialog.dismiss()
} else {
it.forEach { userData ->
viewModel.addUserToDatabase(userData)
viewModel.deleteById(userData._id)
}
dialog.dismiss()
Toast.makeText(requireContext(), "Upload done successfully", Toast.LENGTH_SHORT)
.show()
}
}
}
private fun checkForLocalDBData() {
viewModel.allUserData.observe(viewLifecycleOwner) { userDataList ->
if (userDataList.isEmpty()) {
binding.uploadData.visibility = View.GONE
} else {
binding.uploadData.visibility = View.VISIBLE
}
}
}
private fun fetchFromServer() {
binding.noList.visibility = View.GONE
binding.rvOrder.visibility = View.VISIBLE
val query = Firebase.firestore.collection("patientData")
val recyclerViewOptions =
FirestoreRecyclerOptions.Builder<UserData>().setQuery(query, UserData::class.java)
.build()
val adapter = UserListOnlineAdapter(recyclerViewOptions, binding.root)
binding.rvOrder.adapter = adapter
adapter.startListening()
}
private fun fetchFromLocalDB() {
binding.uploadData.visibility = View.GONE
viewModel.allUserData.observe(viewLifecycleOwner) { userDataList ->
if (isOnline) {
binding.noList.visibility = View.GONE
binding.rvOrder.visibility = View.VISIBLE
} else {
if (userDataList.isEmpty()) {
binding.noList.visibility = View.VISIBLE
binding.rvOrder.visibility = View.GONE
} else {
binding.noList.visibility = View.GONE
binding.rvOrder.visibility = View.VISIBLE
deteleIncompleteRegistration(userDataList)
val adapter = UserListOfflineAdapter(binding.root)
adapter.differ.submitList(userDataList)
binding.rvOrder.adapter = adapter
}
}
}
}
private fun deteleIncompleteRegistration(userDataList: List<UserData>) {
userDataList.forEach {
if (it.userImage.isEmpty()) {
viewModel.deleteById(it._id)
}
}
}
}

View File

@@ -0,0 +1,204 @@
package com.example.hposregistration.ui.fragments.registration
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import com.example.hposregistration.data.Constant.fetchYOBFromDOB
import com.example.hposregistration.data.Constant.mapToGender
import com.example.hposregistration.data.SecureQrCode
import com.example.hposregistration.data.user.UserData
import com.example.hposregistration.databinding.FragmentAbhaRegistrationBinding
import com.example.hposregistration.ui.fragments.BaseFragment
import com.example.hposregistration.ui.viewmodels.RegistrationViewModel
import com.journeyapps.barcodescanner.ScanContract
import com.journeyapps.barcodescanner.ScanIntentResult
import dagger.hilt.android.AndroidEntryPoint
import org.json.JSONObject
@AndroidEntryPoint
class AbhaRegistrationFragment : BaseFragment() {
private var _binding: FragmentAbhaRegistrationBinding? = null
private val binding get() = _binding!!
private val viewModel by viewModels<RegistrationViewModel>()
private val args: AbhaRegistrationFragmentArgs by navArgs()
private var userData = UserData()
private val barcodeLauncher =
registerForActivityResult(ScanContract()) { result: ScanIntentResult ->
if (result.contents == null) {
Toast.makeText(
requireContext(), "Cancelled: Unable to scan, Try Again!!", Toast.LENGTH_LONG
).show()
} else {
processScannedData(result.contents)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
_binding = FragmentAbhaRegistrationBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
init()
}
private fun init() {
binding.btnScanNow.setOnClickListener {
barcodeLauncher.launch(scanQR("Please Scan the Abha ID/Aadhar ID"))
}
if (args.userId != "null") {
viewModel.getUserByID(args.userId)
}
viewModel.userData.observe(viewLifecycleOwner) { user ->
userData = user
with(binding) {
aadharID.setText(user.AadharId)
etAbhaId.setText(user.AbhaId)
etName.setText(user.name)
}
}
binding.btnProceed.setOnClickListener {
val abhaId = binding.etAbhaId.text.toString()
val userName = binding.etName.text.toString()
val aadharId = binding.aadharID.text.toString()
if (validateInputs(abhaId, aadharId, userName)) {
userData.apply {
name = userName
AadharId = aadharId
AbhaId = abhaId
_id = aadharId + userName.substring(0, 3).uppercase()
}
viewModel.insert(userData)
navigateToUserDetailsFragment(userData._id)
}
}
}
private fun processScannedData(contents: String) {
try {
val obj = JSONObject(contents)
userData.apply {
AbhaId = obj.getString("hidn").replace("-", "")
name = obj.getString("name")
birthYear = obj.getString("dob").fetchYOBFromDOB().toString()
gender = obj.getString("gender").mapToGender().toString()
phoneNumber = obj.getString("mobile")
state = obj.getString("state name")
district = obj.getString("district_name")
house = obj.getString("address")
}
if (userData.AbhaId.isNotEmpty()) {
saveUserDataAsPerAbhaId()
} else {
saveUserDataAsPerAadharId()
}
} catch (e: Exception) {
try {
val decodedData = SecureQrCode(contents)
val aadharData = decodedData.scannedAadharCard
userData.apply {
name = aadharData.name
birthYear = aadharData.dateOfBirth.fetchYOBFromDOB().toString()
gender = aadharData.gender.mapToGender().toString()
state = aadharData.state
district = aadharData.district
house = aadharData.house
}
saveUserDataAsPerAadharId()
} catch (e: Exception) {
Toast.makeText(
requireContext(),
"The QR Code you have scanned is not valid, enter the data manually",
Toast.LENGTH_SHORT
).show()
}
}
}
private fun saveUserDataAsPerAbhaId() {
with(binding) {
tvScanMessage.visibility = View.VISIBLE
tvScanMessage.text = "You have scanned the Abha ID, need to enter Aadhar ID manually"
etAbhaId.setText(userData.AbhaId)
etName.setText(userData.name)
}
Toast.makeText(
requireContext(), "You have scanned the Abha ID", Toast.LENGTH_SHORT
).show()
}
private fun saveUserDataAsPerAadharId() {
with(binding) {
tvScanMessage.text =
"You have scanned the Aadhar ID, need to enter Aadhar ID number you have scan and Abha ID manually"
etName.setText(userData.name)
}
Toast.makeText(
requireContext(), "You have scanned the Aadhar ID", Toast.LENGTH_SHORT
).show()
}
private fun validateInputs(abhaId: String, aadharId: String, userName: String): Boolean {
with(binding) {
if (!checkAbhaIDNumber(abhaId)) {
etAbhaId.error = "Invalid Abha ID"
return false
}
if (!checkAadharIDNumber(aadharId)) {
aadharID.error = "Invalid Aadhar ID"
return false
}
if (!checkUserName(userName)) {
etName.error = "Name field can't be empty or less than 3 characters"
return false
}
}
return true
}
private fun checkAbhaIDNumber(abhaId: String): Boolean {
return abhaId.isNotEmpty() || abhaId.length == 14
}
private fun checkAadharIDNumber(aadharId: String): Boolean {
return aadharId.isNotEmpty() || aadharId.length == 12
}
private fun checkUserName(userName: String): Boolean {
return userName.isNotEmpty() && userName.length >= 3
}
private fun navigateToUserDetailsFragment(userId: String) {
val action =
AbhaRegistrationFragmentDirections.actionRegistrationFragmentToUserDetailsRegistrationFragment(
userId
)
findNavController().navigate(action)
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@@ -0,0 +1,181 @@
package com.example.hposregistration.ui.fragments.registration
import android.Manifest
import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import com.bumptech.glide.Glide
import com.example.hposregistration.data.user.UserData
import com.example.hposregistration.databinding.FragmentCaptureUserImageBinding
import com.example.hposregistration.ui.viewmodels.RegistrationViewModel
import dagger.hilt.android.AndroidEntryPoint
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.OutputStream
import java.util.UUID
@AndroidEntryPoint
class CaptureUserImageFragment : Fragment() {
private var _binding: FragmentCaptureUserImageBinding? = null
private val binding get() = _binding!!
private val viewModel by viewModels<RegistrationViewModel>()
private var userData = UserData()
private lateinit var cameraLauncher: ActivityResultLauncher<Intent>
private val args: CaptureUserImageFragmentArgs by navArgs()
private lateinit var requestPermissionLauncher: ActivityResultLauncher<Array<String>>
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentCaptureUserImageBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
init()
}
private fun init() {
setupViewModel()
setupCameraLauncher()
setupRequestPermissionLauncher()
checkPermissionsAndPerformCameraOperation()
}
private fun setupViewModel() {
viewModel.getUserByID(args.userId)
viewModel.userData.observe(viewLifecycleOwner) { user ->
userData = user
if (userData.userImage.isNotEmpty()) {
binding.userImage.loadImageFromUri(Uri.parse(user.userImage))
}
}
}
private fun setupCameraLauncher() {
cameraLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK && result.data != null) {
val thumbnail: Bitmap = result.data!!.extras!!.get("data") as Bitmap
val uri: Uri = saveImageToInternalStorage(thumbnail)
uri.let {
binding.btnSubmit.isEnabled = true
Glide.with(requireActivity()).load(it).into(binding.userImage)
binding.btnSubmit.setOnClickListener {
submitImage(uri)
}
}
}
}
}
private fun setupRequestPermissionLauncher() {
requestPermissionLauncher =
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
val grantedPermissions = permissions.filterValues { it }
val deniedPermissions = permissions.filterValues { !it }
if (grantedPermissions.isNotEmpty()) {
binding.userImage.setOnClickListener {
takePicture()
}
}
if (deniedPermissions.isNotEmpty()) {
requestPermissions()
}
}
}
private fun takePicture() {
Intent(MediaStore.ACTION_IMAGE_CAPTURE).also {
cameraLauncher.launch(it)
}
}
private fun submitImage(uri: Uri) {
userData.userImage = uri.toString()
viewModel.insert(userData)
val action = CaptureUserImageFragmentDirections
.actionCaptureUserImageFragment2ToReviewDetailsRegistrationFragment(args.userId)
findNavController().navigate(action)
}
private fun saveImageToInternalStorage(bitmap: Bitmap): Uri {
val file = File(context?.filesDir, "${UUID.randomUUID()}.jpg")
try {
val stream: OutputStream = FileOutputStream(file)
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, stream)
stream.flush()
stream.close()
} catch (e: IOException) {
e.printStackTrace()
}
return Uri.fromFile(file)
}
private fun checkPermissionsAndPerformCameraOperation() {
val cameraPermission = ContextCompat.checkSelfPermission(
requireContext(),
Manifest.permission.CAMERA
)
val storagePermission = ContextCompat.checkSelfPermission(
requireContext(),
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
if (cameraPermission == PackageManager.PERMISSION_GRANTED &&
storagePermission == PackageManager.PERMISSION_GRANTED
) {
binding.userImage.setOnClickListener {
takePicture()
}
} else {
requestPermissions()
}
}
private fun requestPermissions() {
val permissions = arrayOf(
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
requestPermissionLauncher.launch(permissions)
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
private fun ImageView.loadImageFromUri(uri: Uri) {
Glide.with(this)
.load(uri)
.into(this)
}

View File

@@ -0,0 +1,154 @@
package com.example.hposregistration.ui.fragments.registration
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import com.bumptech.glide.Glide
import com.example.hposregistration.R
import com.example.hposregistration.data.user.UserData
import com.example.hposregistration.databinding.FragmentReviewDetailsRegistrationBinding
import com.example.hposregistration.ui.fragments.BaseFragment
import com.example.hposregistration.ui.viewmodels.RegistrationViewModel
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class ReviewDetailsRegistrationFragment : BaseFragment() {
private var _binding: FragmentReviewDetailsRegistrationBinding? = null
private val binding get() = _binding!!
private val viewModel by viewModels<RegistrationViewModel>()
private val args: ReviewDetailsRegistrationFragmentArgs by navArgs()
private var userData = UserData()
private var isOnline = false
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
_binding = FragmentReviewDetailsRegistrationBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
init()
}
private fun init() {
viewModel.getUserByID(args.userId)
viewModel.userData.observe(viewLifecycleOwner) { user ->
userData = user
setUserData(user)
}
viewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable ->
isOnline = isNetworkAvailable
}
binding.btnSubmit.setOnClickListener {
if (isOnline) {
showProgressBar(binding.progressBarCL)
addDataToFirebase()
} else {
Toast.makeText(
requireContext(),
"Internet not available, Data stored in local DB",
Toast.LENGTH_SHORT
).show()
navigateToUserListFragment()
}
}
binding.btnEdit.setOnClickListener {
val action =
ReviewDetailsRegistrationFragmentDirections.actionReviewDetailsRegistrationFragmentToRegistrationFragment(
args.userId
)
findNavController().navigate(action)
}
viewModel.fireBaseUpload.observe(viewLifecycleOwner) {
if (it == "Success") {
Toast.makeText(requireContext(), "Registration Done Successfully", Toast.LENGTH_SHORT)
.show()
navigateToUserListFragment()
}
}
}
private fun addDataToFirebase() {
viewModel.addUserToDatabase(userData)
viewModel.deleteById(args.userId)
}
private fun setUserData(userData: UserData) {
with(binding) {
Glide.with(requireActivity()).load(Uri.parse(userData.userImage)).into(userImage)
binding.tvUserID.text = requireContext().getString(R.string.user_id, userData._id)
binding.tvAbhaId.text =
requireContext().getString(R.string.abha_number, userData.AbhaId)
binding.tvAadharId.text =
requireContext().getString(R.string.aadhar_number_details, userData.AadharId)
binding.tvUserName.text = requireContext().getString(R.string.user_name, userData.name)
binding.tvBirthYear.text =
requireContext().getString(R.string.birth_year_details, userData.birthYear)
binding.tvGender.text =
requireContext().getString(R.string.gender_details, userData.gender)
binding.tvPhoneNumber.text =
requireContext().getString(R.string.phone_number_details, userData.phoneNumber)
binding.tvCareOf.text =
requireContext().getString(R.string.care_of_details, userData.careOf)
binding.tvMaritalStatus.text =
requireContext().getString(R.string.marital_status_details, userData.maritalStatus)
binding.tvCaste.text =
requireContext().getString(R.string.caste_details, userData.caste)
binding.tvSubCaste.text =
requireContext().getString(R.string.sub_caste_details, userData.subCaste)
binding.tvHouse.text =
requireContext().getString(R.string.house_details, userData.house)
binding.tvCity.text =
requireContext().getString(R.string.city_town_details, userData.city)
binding.tvDistrict.text =
requireContext().getString(R.string.district_details, userData.district)
binding.tvState.text =
requireContext().getString(R.string.state_details, userData.state)
binding.tvPincode.text =
requireContext().getString(R.string.pincode_details, userData.pinCode)
if (userData.isUnderMedication!!) {
binding.tvIsUnderMedication.text = requireContext().getString(
R.string.is_patient_under_any_medication_details, "Yes"
)
}
if (userData.isUnderTransfusion!!) {
binding.tvIsUnderTransfusion.text = requireContext().getString(
R.string.is_patient_undergoing_any_blood_transfusion_details, "Yes"
)
}
if (userData.sickleCellHistory != "") {
binding.tvSickleCellFamilyHistory.text = requireContext().getString(
R.string.sickle_cell_family_history, userData.sickleCellHistory
)
}
}
}
private fun navigateToUserListFragment() {
hideProgressBar(binding.progressBarCL)
val action =
ReviewDetailsRegistrationFragmentDirections.actionReviewDetailsRegistrationFragmentToUserListFragment()
findNavController().navigate(action)
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@@ -0,0 +1,221 @@
package com.example.hposregistration.ui.fragments.registration
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import com.example.hposregistration.data.user.UserData
import com.example.hposregistration.databinding.FragmentUserDetailsRegistrationBinding
import com.example.hposregistration.ui.viewmodels.RegistrationViewModel
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class UserDetailsRegistrationFragment : Fragment() {
private var _binding: FragmentUserDetailsRegistrationBinding? = null
private val binding get() = _binding!!
private val viewModel by viewModels<RegistrationViewModel>()
private lateinit var userData: UserData
private val args: UserDetailsRegistrationFragmentArgs by navArgs()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
_binding = FragmentUserDetailsRegistrationBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
init()
}
private fun init() {
setupViewModel()
setupSubmitButton()
}
private fun setupViewModel() {
viewModel.getUserByID(args.userId)
viewModel.userData.observe(viewLifecycleOwner) {
userData = it
autoFillUserData(userData)
}
}
private fun autoFillUserData(user: UserData) {
with(binding) {
user.birthYear.let { etYob.setText(it) }
user.gender.let { etGenderBlock.setText(it, false) }
user.phoneNumber.let { etMobile.setText(it) }
user.careOf.let { etCareof.setText(it) }
user.maritalStatus.let { etIsMarried.setText(it, false) }
user.caste.let { etCategory.setText(it, false) }
user.subCaste.let { etSubCaste.setText(it) }
user.house.let { etHouse.setText(it) }
user.city.let { etCity.setText(it) }
user.district.let { etDistrict.setText(it) }
user.state.let { etState.setText(it) }
user.pinCode.let { etPincode.setText(it) }
user.bloodGroup.let { etBloodGroup.setText(it, false) }
cbItem1.isChecked = user.isUnderMedication ?: false
cbItem2.isChecked = user.isUnderTransfusion ?: false
}
}
private fun setupSubmitButton() {
binding.btnSubmit.setOnClickListener {
if (verifyUserDetails()) {
userData._id = args.userId
viewModel.insert(userData)
navigateToCaptureUserImageFragment()
} else {
showToast("Please enter all the details properly")
}
}
}
private fun navigateToCaptureUserImageFragment() {
val action = UserDetailsRegistrationFragmentDirections
.actionUserDetailsRegistrationFragmentToCaptureUserImageFragment2(args.userId)
findNavController().navigate(action)
}
private fun verifyUserDetails(): Boolean {
with(binding) {
val yob = etYob.text.toString()
if (yob.isEmpty() || yob.toInt() <= 1900 || yob.toInt() > 2023) {
etYob.error = "Please enter a valid birth year between 1900 and 2023"
return false
} else {
userData.birthYear = yob
}
val gender = etGenderBlock.text.toString()
if (gender.isEmpty()) {
etGenderBlock.error = "Please enter your gender"
return false
} else {
userData.gender = gender
}
val mobile = etMobile.text.toString()
if (mobile.isEmpty() || mobile.length != 10) {
etMobile.error = "Please enter a valid 10-digit mobile number"
return false
} else {
userData.phoneNumber = mobile
}
val careOf = etCareof.text.toString()
if (careOf.isEmpty()) {
etCareof.error = "Please enter your name"
return false
} else {
userData.careOf = careOf
}
val maritalStatus = etIsMarried.text.toString()
if (maritalStatus.isEmpty()) {
etIsMarried.error = "Please enter your marital status"
return false
} else {
userData.maritalStatus = maritalStatus
}
val category = etCategory.text.toString()
if (category.isEmpty()) {
etCategory.error = "Please enter your caste"
return false
} else {
userData.caste = category
}
val subCaste = etSubCaste.text.toString()
if (subCaste.isEmpty()) {
etSubCaste.error = "Please enter your sub caste"
return false
} else {
userData.subCaste = subCaste
}
val house = etHouse.text.toString()
if (house.isEmpty()) {
etHouse.error = "Please enter your house address"
return false
} else {
userData.house = house
}
val city = etCity.text.toString()
if (city.isEmpty()) {
etCity.error = "Please enter your city"
return false
} else {
userData.city = city
}
val district = etDistrict.text.toString()
if (district.isEmpty()) {
etDistrict.error = "Please enter your district"
return false
} else {
userData.district = district
}
val state = etState.text.toString()
if (state.isEmpty()) {
etState.error = "Please enter your state"
return false
} else {
userData.state = state
}
val pincode = etPincode.text.toString()
if (pincode.isEmpty() || pincode.length != 6) {
etPincode.error = "Please enter a valid 6-digit pin code"
return false
} else {
userData.pinCode = pincode
}
val bloodGroup = etBloodGroup.text.toString()
if (bloodGroup.isEmpty()) {
etBloodGroup.error = "Please enter your blood group"
return false
} else {
userData.bloodGroup = bloodGroup
}
userData.isUnderMedication = cbItem1.isChecked
userData.isUnderTransfusion = cbItem2.isChecked
val familyHistory = etFamilyHistory.text.toString()
if (familyHistory.isEmpty()) {
etFamilyHistory.error = "Please enter your family history"
return false
} else {
userData.sickleCellHistory = familyHistory
}
return true
}
}
private fun showToast(message: String) {
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@@ -0,0 +1,76 @@
package com.example.hposregistration.ui.viewmodels
import android.content.Context
import android.net.Uri
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.hposregistration.data.MainRepository
import com.example.hposregistration.data.NetworkStatusLiveData
import com.example.hposregistration.data.Response
import com.example.hposregistration.data.user.UserData
import com.google.firebase.storage.FirebaseStorage
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
class RegistrationViewModel @Inject constructor(
private val mainRepository: MainRepository,
context: Context
) : ViewModel() {
val userData = MutableLiveData<UserData>()
val allUserData = mainRepository.allUsers
val fireBaseUpload = MutableLiveData<String>()
fun addUserToDatabase(userData: UserData) = viewModelScope.launch {
val file = Uri.parse(userData.userImage)
val storageRef = FirebaseStorage.getInstance().reference
val imageRef = storageRef.child("${userData._id}/${file.lastPathSegment}")
val uploadTask = file.let { imageRef.putFile(it) }
uploadTask.continueWithTask { task ->
if (!task.isSuccessful) {
throw task.exception!!
}
imageRef.downloadUrl
}.addOnSuccessListener { uri ->
userData.userImage = uri.toString()
addDataToFirebase(userData)
}.addOnFailureListener { exception ->
}
}
private fun addDataToFirebase(userData: UserData) = viewModelScope.launch {
when (mainRepository.addDataToFirebase(userData)) {
is Response.Success -> {
fireBaseUpload.postValue("Success")
}
else -> {
}
}
}
private val _networkStatusLiveData = NetworkStatusLiveData(context)
val networkStatusLiveData: LiveData<Boolean>
get() = _networkStatusLiveData
fun insert(userData: UserData) = viewModelScope.launch {
mainRepository.insert(userData)
}
fun getUserByID(userId: String) = viewModelScope.launch {
userData.postValue(mainRepository.getUserByID(id = userId))
}
fun deleteById(userId: String) = viewModelScope.launch {
mainRepository.deleteById(id = userId)
}
}