First version finished
This commit is contained in:
parent
28e348c194
commit
d45d9535e0
@ -56,6 +56,7 @@ dependencies {
|
|||||||
|
|
||||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.2.1'
|
implementation 'androidx.navigation:navigation-fragment-ktx:2.2.1'
|
||||||
implementation 'androidx.navigation:navigation-fragment:2.2.1'
|
implementation 'androidx.navigation:navigation-fragment:2.2.1'
|
||||||
|
implementation 'androidx.navigation:navigation-ui-ktx:2.2.1'
|
||||||
implementation 'androidx.navigation:navigation-ui:2.2.1'
|
implementation 'androidx.navigation:navigation-ui:2.2.1'
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,8 +12,7 @@
|
|||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme.Light">
|
android:theme="@style/AppTheme.Light">
|
||||||
<activity android:name=".QrCodeActivity"></activity>
|
<activity android:name=".QrCodeActivity" />
|
||||||
<activity android:name=".QrCodeViewerActivity" />
|
|
||||||
<activity android:name=".PdfViewerActivity" />
|
<activity android:name=".PdfViewerActivity" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
|
@ -4,23 +4,23 @@ import android.content.Context
|
|||||||
import fr.sanchezm.attestationsCovid19.data.db.dao.AttestationDao
|
import fr.sanchezm.attestationsCovid19.data.db.dao.AttestationDao
|
||||||
import fr.sanchezm.attestationsCovid19.data.db.dao.ProfileDao
|
import fr.sanchezm.attestationsCovid19.data.db.dao.ProfileDao
|
||||||
|
|
||||||
class MyDatabase private constructor(private val path: String) {
|
class MyDatabase private constructor(private val savePath: String, private val filesPath: String) {
|
||||||
|
|
||||||
private var _profileDao: ProfileDao? = null
|
private var _profileDao: ProfileDao? = null
|
||||||
private var _attestationDao: AttestationDao? = null
|
private var _attestationDao: AttestationDao? = null
|
||||||
|
|
||||||
fun profileDao(): ProfileDao = _profileDao ?: ProfileDao(path).also { _profileDao = it }
|
fun profileDao(): ProfileDao = _profileDao ?: ProfileDao(savePath).also { _profileDao = it }
|
||||||
|
|
||||||
fun attestationDao(): AttestationDao =
|
fun attestationDao(): AttestationDao =
|
||||||
_attestationDao ?: AttestationDao(path).also { _attestationDao = it }
|
_attestationDao ?: AttestationDao(savePath, filesPath).also { _attestationDao = it }
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@Volatile
|
@Volatile
|
||||||
private var instance: MyDatabase? = null
|
private var instance: MyDatabase? = null
|
||||||
private val LOCK = Any()
|
private val LOCK = Any()
|
||||||
|
|
||||||
operator fun invoke(context: Context) = instance ?: synchronized(LOCK) {
|
operator fun invoke(context: Context, filesPath: String) = instance ?: synchronized(LOCK) {
|
||||||
instance ?: MyDatabase(context.filesDir.path).also { instance = it }
|
instance ?: MyDatabase(context.filesDir.path, filesPath).also { instance = it }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package fr.sanchezm.attestationsCovid19.data.db.dao
|
package fr.sanchezm.attestationsCovid19.data.db.dao
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
@ -8,20 +9,24 @@ import fr.sanchezm.attestationsCovid19.data.db.entity.Attestation
|
|||||||
import fr.sanchezm.attestationsCovid19.utilities.PdfUtils
|
import fr.sanchezm.attestationsCovid19.utilities.PdfUtils
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class AttestationDao(private val path: String) {
|
class AttestationDao(private val savePath: String, private val filesPath: String) {
|
||||||
|
|
||||||
private var _attestations = MutableLiveData<ArrayList<Attestation>>()
|
private var _attestations = MutableLiveData<ArrayList<Attestation>>()
|
||||||
private var fileName = "attestation.db"
|
private var fileName = "attestation.db"
|
||||||
private val type = object : TypeToken<ArrayList<Attestation>>() {}.type
|
private val type = object : TypeToken<ArrayList<Attestation>>() {}.type
|
||||||
|
|
||||||
fun getAttestations() : LiveData<ArrayList<Attestation>> =
|
@Suppress("UNCHECKED_CAST")
|
||||||
_attestations
|
fun getAttestations(): LiveData<List<Attestation>> =
|
||||||
|
_attestations as LiveData<List<Attestation>>
|
||||||
|
|
||||||
fun getAttestation(id: Int): Attestation? =
|
fun getAttestation(id: Int): Attestation? =
|
||||||
_attestations.value?.elementAt(id)
|
_attestations.value?.elementAt(id)
|
||||||
|
|
||||||
fun addAttestation(attestation: Attestation) {
|
fun addAttestation(attestation: Attestation) {
|
||||||
|
_attestations.value = _attestations.value ?: ArrayList()
|
||||||
|
|
||||||
_attestations.value?.add(attestation)
|
_attestations.value?.add(attestation)
|
||||||
|
Log.d(TAG, "Add Attestation : $attestation")
|
||||||
save()
|
save()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,36 +38,50 @@ class AttestationDao(private val path: String) {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun deleteAttestation(attestation: Attestation) {
|
||||||
|
deleteFile(attestation)
|
||||||
|
delete(attestation)
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
load()
|
load()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun delete(attestation: Attestation) {
|
||||||
|
_attestations.value?.remove(attestation)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun deleteFile(attestation: Attestation) {
|
||||||
|
File(PdfUtils.getPath(filesPath, attestation.createAt)).also {
|
||||||
|
if (it.exists())
|
||||||
|
it.delete()
|
||||||
|
}
|
||||||
|
_attestations.value = _attestations.value
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private fun load() {
|
private fun load() {
|
||||||
val file = File("$path/$fileName")
|
val file = File("$savePath/$fileName")
|
||||||
|
val removeList = ArrayList<Attestation>()
|
||||||
|
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
_attestations.value = Gson().fromJson(file.readText(Charsets.UTF_8), type)
|
_attestations.value = Gson().fromJson(file.readText(Charsets.UTF_8), type)
|
||||||
}
|
}
|
||||||
_attestations.value?.forEach {
|
_attestations.value?.forEach {
|
||||||
val filePath = PdfUtils.getInstance()?.getPath(it.createAt)
|
val filePath = PdfUtils.getPath(filesPath, it.createAt)
|
||||||
|
|
||||||
if (filePath != null && !File(filePath).exists()) {
|
if (!File(filePath).exists()) {
|
||||||
_attestations.value!!.remove(it)
|
removeList.add(it)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}.also { _attestations.value?.removeAll(removeList) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun save() {
|
private fun save() {
|
||||||
File("$path/$fileName").writeText(Gson().toJson(_attestations.value))
|
Log.d(TAG, "Save : ${Gson().toJson(_attestations.value)}")
|
||||||
|
File("$savePath/$fileName").writeText(Gson().toJson(_attestations.value))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val TAG = AttestationDao::class.simpleName
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//@Dao
|
|
||||||
//interface AttestationDao {
|
|
||||||
// @Insert
|
|
||||||
// fun insert(attestation: Attestation)
|
|
||||||
//
|
|
||||||
// @Query(value = "SELECT * FROM attestation WHERE id = $CURRENT_ATTESTATION_ID")
|
|
||||||
// fun getAttestation(): LiveData<Attestation>
|
|
||||||
//}
|
|
@ -14,12 +14,18 @@ data class Attestation(
|
|||||||
val reasons: List<Int>
|
val reasons: List<Int>
|
||||||
) {
|
) {
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "Cree le: ${getDate(createAt)}; $profile; Sortie: $exitDate a $exitHour; Motifs: ${getMotifsText()}"
|
return "Cree le: ${getDate(createAt)}; $profile; Sortie: ${getExitDateFormatted()}; Motifs: ${getMotifsText()}"
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCreatedAtFormatedDate(): String = getDate(createAt)
|
fun getNameFormatted(): String = "${profile.firstName} ${profile.lastName}"
|
||||||
|
|
||||||
fun getMotifsText(): String {
|
fun getCreatedAtFormattedDate(): String = getDate(createAt)
|
||||||
|
|
||||||
|
fun getExitDateFormatted(): String = "$exitDate a $exitHour"
|
||||||
|
|
||||||
|
fun getMotifsFormatted(): String = getMotifsText().replace("-", " ")
|
||||||
|
|
||||||
|
private fun getMotifsText(): String {
|
||||||
val motifs = StringBuilder()
|
val motifs = StringBuilder()
|
||||||
|
|
||||||
reasons.forEach { motifs.append(getMotifText(it), "-") }
|
reasons.forEach { motifs.append(getMotifText(it), "-") }
|
||||||
|
@ -6,8 +6,8 @@ import fr.sanchezm.attestationsCovid19.utilities.PdfUtils
|
|||||||
|
|
||||||
class AttestationRepository private constructor(private val attestationDao: AttestationDao) {
|
class AttestationRepository private constructor(private val attestationDao: AttestationDao) {
|
||||||
|
|
||||||
fun generateAttestation(attestation: Attestation) =
|
fun generateAttestation(attestation: Attestation, callback: (Boolean) -> Unit) =
|
||||||
PdfUtils.getInstance()?.fillForm(attestation)
|
PdfUtils.getInstance()?.fillForm(attestation, callback)
|
||||||
|
|
||||||
fun getAttestations() = attestationDao.getAttestations()
|
fun getAttestations() = attestationDao.getAttestations()
|
||||||
|
|
||||||
@ -17,6 +17,8 @@ class AttestationRepository private constructor(private val attestationDao: Atte
|
|||||||
|
|
||||||
fun addAttestation(attestation: Attestation) = attestationDao.addAttestation(attestation)
|
fun addAttestation(attestation: Attestation) = attestationDao.addAttestation(attestation)
|
||||||
|
|
||||||
|
fun deleteAttestation(attestation: Attestation) = attestationDao.deleteAttestation(attestation)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@Volatile
|
@Volatile
|
||||||
private var instance: AttestationRepository? = null
|
private var instance: AttestationRepository? = null
|
||||||
|
@ -53,8 +53,8 @@ class AddFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
addViewModel.startActivity.observe(viewLifecycleOwner, Observer {
|
addViewModel.startActivity.observe(viewLifecycleOwner, Observer { event ->
|
||||||
it.getContentIfNotHandled()?.let {
|
event.getContentIfNotHandled()?.let {
|
||||||
val intent = Intent(context, QrCodeActivity::class.java).apply {
|
val intent = Intent(context, QrCodeActivity::class.java).apply {
|
||||||
putExtra("createAt", it)
|
putExtra("createAt", it)
|
||||||
putExtra("toCreate", true)
|
putExtra("toCreate", true)
|
||||||
|
@ -67,8 +67,6 @@ class AddViewModel(
|
|||||||
attestationRepository.addAttestation(attestation)
|
attestationRepository.addAttestation(attestation)
|
||||||
|
|
||||||
_startActivity.value = Event(attestation.createAt)
|
_startActivity.value = Event(attestation.createAt)
|
||||||
// attestationRepository.generateAttestation(attestation)
|
|
||||||
// _dataMessage.value = Event(R.string.attestation_generated)
|
|
||||||
} else {
|
} else {
|
||||||
_errorMessage.value = Event(R.string.error_cannot_create_attestation)
|
_errorMessage.value = Event(R.string.error_cannot_create_attestation)
|
||||||
Log.e("onGenerateAttestationClick", "Cannot generate Attestation")
|
Log.e("onGenerateAttestationClick", "Cannot generate Attestation")
|
||||||
|
@ -41,13 +41,10 @@ class AttestationsAdapter(
|
|||||||
private val reasonItem = view.reason_item_data
|
private val reasonItem = view.reason_item_data
|
||||||
|
|
||||||
fun bind(attestation: Attestation) {
|
fun bind(attestation: Attestation) {
|
||||||
peopleItem.text = getName(attestation)
|
peopleItem.text = attestation.getNameFormatted()
|
||||||
dateItem.text = attestation.getCreatedAtFormatedDate()
|
dateItem.text = attestation.getExitDateFormatted()
|
||||||
reasonItem.text = attestation.getMotifsText()
|
reasonItem.text = attestation.getMotifsFormatted()
|
||||||
view.setOnClickListener { itemClickListener.onItemClick(attestation) }
|
view.setOnClickListener { itemClickListener.onItemClick(attestation) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getName(attestation: Attestation) =
|
|
||||||
"${attestation.profile.firstName} ${attestation.profile.lastName}"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -11,6 +11,7 @@ import androidx.lifecycle.Observer
|
|||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import fr.sanchezm.attestationsCovid19.PdfViewerActivity
|
import fr.sanchezm.attestationsCovid19.PdfViewerActivity
|
||||||
|
import fr.sanchezm.attestationsCovid19.QrCodeActivity
|
||||||
import fr.sanchezm.attestationsCovid19.R
|
import fr.sanchezm.attestationsCovid19.R
|
||||||
import fr.sanchezm.attestationsCovid19.data.db.entity.Attestation
|
import fr.sanchezm.attestationsCovid19.data.db.entity.Attestation
|
||||||
import fr.sanchezm.attestationsCovid19.databinding.FragmentAttestationsBinding
|
import fr.sanchezm.attestationsCovid19.databinding.FragmentAttestationsBinding
|
||||||
@ -24,8 +25,9 @@ class AttestationsFragment : Fragment() {
|
|||||||
private val attestationsAdapter = AttestationsAdapter(arrayListOf(),
|
private val attestationsAdapter = AttestationsAdapter(arrayListOf(),
|
||||||
object : ItemClickListener {
|
object : ItemClickListener {
|
||||||
override fun onItemClick(item: Attestation) {
|
override fun onItemClick(item: Attestation) {
|
||||||
val intent = Intent(context, PdfViewerActivity::class.java).apply {
|
val intent = Intent(context, QrCodeActivity::class.java).apply {
|
||||||
putExtra("createAt", item.createAt)
|
putExtra("createAt", item.createAt)
|
||||||
|
putExtra("toCreate", false)
|
||||||
}
|
}
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
@ -56,8 +58,8 @@ class AttestationsFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun bindMessage() {
|
private fun bindMessage() {
|
||||||
attestationsViewModel.startActivity.observe(viewLifecycleOwner, Observer {
|
attestationsViewModel.startActivity.observe(viewLifecycleOwner, Observer { event ->
|
||||||
it.getContentIfNotHandled()?.let { createAtPdf ->
|
event.getContentIfNotHandled()?.let { createAtPdf ->
|
||||||
val intent = Intent(context, PdfViewerActivity::class.java).apply {
|
val intent = Intent(context, PdfViewerActivity::class.java).apply {
|
||||||
putExtra("createAt", createAtPdf)
|
putExtra("createAt", createAtPdf)
|
||||||
}
|
}
|
||||||
|
@ -4,29 +4,20 @@ import android.view.View
|
|||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import fr.sanchezm.attestationsCovid19.data.db.entity.Attestation
|
|
||||||
import fr.sanchezm.attestationsCovid19.data.repository.AttestationRepository
|
import fr.sanchezm.attestationsCovid19.data.repository.AttestationRepository
|
||||||
import fr.sanchezm.attestationsCovid19.utilities.Event
|
import fr.sanchezm.attestationsCovid19.utilities.Event
|
||||||
|
|
||||||
class AttestationsViewModel(attestationRepository: AttestationRepository) : ViewModel() {
|
class AttestationsViewModel(attestationRepository: AttestationRepository) : ViewModel() {
|
||||||
|
|
||||||
private val _startActivity = MutableLiveData<Event<Long>>()
|
private val _startActivity = MutableLiveData<Event<Long>>()
|
||||||
|
|
||||||
private var _attestations = attestationRepository.getAttestations() as MutableLiveData<ArrayList<Attestation>>
|
|
||||||
|
|
||||||
private var _displayNoAttestation = MutableLiveData<Int>()
|
private var _displayNoAttestation = MutableLiveData<Int>()
|
||||||
|
|
||||||
val attestations: LiveData<ArrayList<Attestation>> =
|
val attestations = attestationRepository.getAttestations()
|
||||||
_attestations
|
val startActivity: LiveData<Event<Long>> = _startActivity
|
||||||
|
val displayNoAttestation: LiveData<Int> = _displayNoAttestation
|
||||||
val startActivity: LiveData<Event<Long>> =
|
|
||||||
_startActivity
|
|
||||||
|
|
||||||
val displayNoAttestation: LiveData<Int> =
|
|
||||||
_displayNoAttestation
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (_attestations.value == null || _attestations.value?.size == 0) {
|
if (attestations.value == null || attestations.value?.size == 0) {
|
||||||
_displayNoAttestation.value = View.VISIBLE
|
_displayNoAttestation.value = View.VISIBLE
|
||||||
} else {
|
} else {
|
||||||
_displayNoAttestation.value = View.GONE
|
_displayNoAttestation.value = View.GONE
|
||||||
|
@ -1,15 +1,19 @@
|
|||||||
package fr.sanchezm.attestationsCovid19.ui.qrcode
|
package fr.sanchezm.attestationsCovid19.ui.qrcode
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.databinding.DataBindingUtil
|
import androidx.databinding.DataBindingUtil
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import fr.sanchezm.attestationsCovid19.PdfViewerActivity
|
||||||
import fr.sanchezm.attestationsCovid19.R
|
import fr.sanchezm.attestationsCovid19.R
|
||||||
import fr.sanchezm.attestationsCovid19.databinding.QrCodeFragmentBinding
|
import fr.sanchezm.attestationsCovid19.databinding.QrCodeFragmentBinding
|
||||||
import fr.sanchezm.attestationsCovid19.utilities.InjectorUtils
|
import fr.sanchezm.attestationsCovid19.utilities.InjectorUtils
|
||||||
|
import kotlinx.android.synthetic.main.qr_code_fragment.*
|
||||||
|
|
||||||
class QrCodeFragment : Fragment() {
|
class QrCodeFragment : Fragment() {
|
||||||
|
|
||||||
@ -41,10 +45,11 @@ class QrCodeFragment : Fragment() {
|
|||||||
this.viewModel = qrCodeViewModel
|
this.viewModel = qrCodeViewModel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bindingData()
|
||||||
|
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun initializeUi(createAt: Long, toCreate: Boolean) {
|
private fun initializeUi(createAt: Long, toCreate: Boolean) {
|
||||||
val factory = context?.let { InjectorUtils.provideQrCodeViewModel(it) }
|
val factory = context?.let { InjectorUtils.provideQrCodeViewModel(it) }
|
||||||
qrCodeViewModel = factory?.let {
|
qrCodeViewModel = factory?.let {
|
||||||
@ -54,4 +59,28 @@ class QrCodeFragment : Fragment() {
|
|||||||
qrCodeViewModel.addData(createAt, toCreate)
|
qrCodeViewModel.addData(createAt, toCreate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun bindingData() {
|
||||||
|
qrCodeViewModel.qrCodeBitmap.observe(viewLifecycleOwner, Observer {
|
||||||
|
qrcode_image.setImageBitmap(it)
|
||||||
|
})
|
||||||
|
|
||||||
|
qrCodeViewModel.finish.observe(viewLifecycleOwner, Observer { event ->
|
||||||
|
event.getContentIfNotHandled()?.let {
|
||||||
|
if (it) {
|
||||||
|
activity?.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
qrCodeViewModel.startActivity.observe(viewLifecycleOwner, Observer { event ->
|
||||||
|
event.getContentIfNotHandled()?.let {
|
||||||
|
val intent = Intent(context, PdfViewerActivity::class.java).apply {
|
||||||
|
putExtra("createAt", it)
|
||||||
|
putExtra("toCreate", true)
|
||||||
|
}
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,85 @@
|
|||||||
package fr.sanchezm.attestationsCovid19.ui.qrcode
|
package fr.sanchezm.attestationsCovid19.ui.qrcode
|
||||||
|
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.view.View
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import fr.sanchezm.attestationsCovid19.data.db.entity.Attestation
|
import fr.sanchezm.attestationsCovid19.data.db.entity.Attestation
|
||||||
import fr.sanchezm.attestationsCovid19.data.repository.AttestationRepository
|
import fr.sanchezm.attestationsCovid19.data.repository.AttestationRepository
|
||||||
|
import fr.sanchezm.attestationsCovid19.utilities.Event
|
||||||
|
import fr.sanchezm.attestationsCovid19.utilities.QRCodeUtils
|
||||||
|
|
||||||
class QrCodeViewModel(private val attestationRepository: AttestationRepository) : ViewModel() {
|
class QrCodeViewModel(private val attestationRepository: AttestationRepository) : ViewModel() {
|
||||||
|
|
||||||
private val _attestation = MutableLiveData<Attestation>()
|
private val _attestation = MutableLiveData<Attestation>()
|
||||||
private var toCreate: Boolean = false
|
|
||||||
|
private val _loading = MutableLiveData(View.GONE)
|
||||||
|
private val _displayQrCode = MutableLiveData(View.GONE)
|
||||||
|
private val _qrCodeBitmap = MutableLiveData<Bitmap>()
|
||||||
|
private val _peopleItem = MutableLiveData<String>()
|
||||||
|
private val _dateItem = MutableLiveData<String>()
|
||||||
|
private val _reasonItem = MutableLiveData<String>()
|
||||||
|
|
||||||
|
private val _startActivity = MutableLiveData<Event<Long>>()
|
||||||
|
private val _finish = MutableLiveData<Event<Boolean>>()
|
||||||
|
|
||||||
|
val attestation: LiveData<Attestation> = _attestation
|
||||||
|
|
||||||
|
val loading: LiveData<Int> = _loading
|
||||||
|
val displayQrCode: LiveData<Int> = _displayQrCode
|
||||||
|
val qrCodeBitmap: LiveData<Bitmap> = _qrCodeBitmap
|
||||||
|
val peopleItem: LiveData<String> = _peopleItem
|
||||||
|
val dateItem: LiveData<String> = _dateItem
|
||||||
|
val reasonItem: LiveData<String> = _reasonItem
|
||||||
|
|
||||||
|
val startActivity: LiveData<Event<Long>> = _startActivity
|
||||||
|
val finish: LiveData<Event<Boolean>> = _finish
|
||||||
|
|
||||||
fun addData(createAt: Long, toCreate: Boolean) {
|
fun addData(createAt: Long, toCreate: Boolean) {
|
||||||
this.toCreate = toCreate
|
val att = attestationRepository.getAttestation(createAt)
|
||||||
_attestation.value = attestationRepository.getAttestation(createAt)
|
|
||||||
|
_attestation.value = att
|
||||||
if (toCreate) {
|
if (toCreate) {
|
||||||
|
_loading.value = View.VISIBLE
|
||||||
createPdf()
|
createPdf()
|
||||||
|
} else {
|
||||||
|
displayQrCode()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createPdf() {
|
fun displayAttestation() {
|
||||||
|
_startActivity.value = Event(_attestation.value!!.createAt)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deleteAttestation() {
|
||||||
|
attestationRepository.deleteAttestation(_attestation.value!!)
|
||||||
|
_finish.value = Event(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createPdf() {
|
||||||
|
_attestation.value?.let { attesattion ->
|
||||||
|
attestationRepository.generateAttestation(
|
||||||
|
attesattion
|
||||||
|
) { success ->
|
||||||
|
if (success)
|
||||||
|
displayQrCode()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun displayQrCode() {
|
||||||
|
_qrCodeBitmap.value = _attestation.value?.let { QRCodeUtils.getQrCode(it, 300) }
|
||||||
|
|
||||||
|
_peopleItem.value = attestation.value?.getNameFormatted()
|
||||||
|
_dateItem.value = attestation.value?.getExitDateFormatted()
|
||||||
|
_reasonItem.value = attestation.value?.getMotifsFormatted()
|
||||||
|
|
||||||
|
_loading.value = View.GONE
|
||||||
|
_displayQrCode.value = View.VISIBLE
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val TAG = QrCodeViewModel::class.simpleName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,23 +13,31 @@ object InjectorUtils {
|
|||||||
|
|
||||||
fun provideAddViewModelFactory(context: Context): AddViewModelFactory {
|
fun provideAddViewModelFactory(context: Context): AddViewModelFactory {
|
||||||
val profileRepository =
|
val profileRepository =
|
||||||
ProfileRepository.getInstance(MyDatabase.invoke(context).profileDao())
|
ProfileRepository.getInstance(
|
||||||
|
MyDatabase.invoke(context, getMyFilesDir(context)).profileDao()
|
||||||
|
)
|
||||||
val attestationRepository =
|
val attestationRepository =
|
||||||
AttestationRepository.getInstance(MyDatabase.invoke(context).attestationDao())
|
AttestationRepository.getInstance(
|
||||||
|
MyDatabase.invoke(context, getMyFilesDir(context)).attestationDao()
|
||||||
|
)
|
||||||
|
|
||||||
return AddViewModelFactory(profileRepository, attestationRepository)
|
return AddViewModelFactory(profileRepository, attestationRepository)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun provideAttestationViewModel(context: Context): AttestationsViewModelFactory {
|
fun provideAttestationViewModel(context: Context): AttestationsViewModelFactory {
|
||||||
val attestationRepository =
|
val attestationRepository =
|
||||||
AttestationRepository.getInstance(MyDatabase.invoke(context).attestationDao())
|
AttestationRepository.getInstance(
|
||||||
|
MyDatabase.invoke(context, getMyFilesDir(context)).attestationDao()
|
||||||
|
)
|
||||||
|
|
||||||
return AttestationsViewModelFactory(attestationRepository)
|
return AttestationsViewModelFactory(attestationRepository)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun provideQrCodeViewModel(context: Context): QrCodeViewModelFactory {
|
fun provideQrCodeViewModel(context: Context): QrCodeViewModelFactory {
|
||||||
val attestationRepository =
|
val attestationRepository =
|
||||||
AttestationRepository.getInstance(MyDatabase.invoke(context).attestationDao())
|
AttestationRepository.getInstance(
|
||||||
|
MyDatabase.invoke(context, getMyFilesDir(context)).attestationDao()
|
||||||
|
)
|
||||||
|
|
||||||
return QrCodeViewModelFactory(attestationRepository)
|
return QrCodeViewModelFactory(attestationRepository)
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,6 @@ import com.tom_roush.pdfbox.pdmodel.interactive.form.PDTextField
|
|||||||
import fr.sanchezm.attestationsCovid19.data.db.entity.Attestation
|
import fr.sanchezm.attestationsCovid19.data.db.entity.Attestation
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.util.*
|
|
||||||
import kotlin.collections.ArrayList
|
|
||||||
|
|
||||||
|
|
||||||
class PdfUtils private constructor(
|
class PdfUtils private constructor(
|
||||||
@ -23,11 +21,10 @@ class PdfUtils private constructor(
|
|||||||
private val path: String
|
private val path: String
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private val folderPath = "attestations"
|
|
||||||
private val checkboxListNames = ArrayList<String>()
|
private val checkboxListNames = ArrayList<String>()
|
||||||
private val font = PDType1Font.HELVETICA
|
private val font = PDType1Font.HELVETICA
|
||||||
|
|
||||||
fun fillForm(attestation: Attestation) {
|
fun fillForm(attestation: Attestation, callback: (Boolean) -> Unit) {
|
||||||
checkFolder()
|
checkFolder()
|
||||||
try {
|
try {
|
||||||
// Load the document and get the AcroForm
|
// Load the document and get the AcroForm
|
||||||
@ -43,12 +40,14 @@ class PdfUtils private constructor(
|
|||||||
Log.v("PdfUtils", "Save File to ${getPath(attestation.createAt)}")
|
Log.v("PdfUtils", "Save File to ${getPath(attestation.createAt)}")
|
||||||
document.save(getPath(attestation.createAt))
|
document.save(getPath(attestation.createAt))
|
||||||
document.close()
|
document.close()
|
||||||
|
callback(true)
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
callback(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getPath(createAt: Long): String = "$path/$folderPath/$createAt.pdf"
|
fun getPath(createAt: Long): String = getPath(path, createAt)
|
||||||
|
|
||||||
private fun addPageWithQrCode(document: PDDocument, attestation: Attestation) {
|
private fun addPageWithQrCode(document: PDDocument, attestation: Attestation) {
|
||||||
val size = 360
|
val size = 360
|
||||||
@ -100,7 +99,7 @@ class PdfUtils private constructor(
|
|||||||
contentStream.beginText()
|
contentStream.beginText()
|
||||||
contentStream.setFont(font, 7f)
|
contentStream.setFont(font, 7f)
|
||||||
contentStream.newLineAtOffset(page.mediaBox.upperRightX - size - 27, 138f)
|
contentStream.newLineAtOffset(page.mediaBox.upperRightX - size - 27, 138f)
|
||||||
contentStream.showText(attestation.getCreatedAtFormatedDate())
|
contentStream.showText(attestation.getCreatedAtFormattedDate())
|
||||||
contentStream.endText()
|
contentStream.endText()
|
||||||
}
|
}
|
||||||
contentStream.close()
|
contentStream.close()
|
||||||
@ -150,12 +149,16 @@ class PdfUtils private constructor(
|
|||||||
@Volatile
|
@Volatile
|
||||||
private var instance: PdfUtils? = null
|
private var instance: PdfUtils? = null
|
||||||
private val LOCK = Any()
|
private val LOCK = Any()
|
||||||
|
private const val folderPath = "attestations"
|
||||||
|
|
||||||
fun getInstance() = instance
|
fun getInstance() = instance
|
||||||
|
|
||||||
fun getInstance(assetManager: AssetManager, path: String) = instance ?: synchronized(LOCK) {
|
fun getInstance(assetManager: AssetManager, path: String) = instance ?: synchronized(LOCK) {
|
||||||
instance ?: PdfUtils(assetManager, path).also { instance = it; it.initList() }
|
instance ?: PdfUtils(assetManager, path).also { instance = it; it.initList() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getPath(path: String, createAt: Long): String = "$path/$folderPath/$createAt.pdf"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initList() {
|
private fun initList() {
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
<data>
|
<data>
|
||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="viewModel"
|
name="viewModel"
|
||||||
type="fr.sanchezm.attestationsCovid19.ui.qrcode.QrCodeViewModel" />
|
type="fr.sanchezm.attestationsCovid19.ui.qrcode.QrCodeViewModel" />
|
||||||
@ -15,14 +16,133 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".ui.qrcode.QrCodeFragment">
|
tools:context=".ui.qrcode.QrCodeFragment">
|
||||||
|
|
||||||
<androidx.core.widget.ContentLoadingProgressBar
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:visibility="@{viewModel.loading}">
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/progress_circular"
|
||||||
|
android:layout_width="60dp"
|
||||||
|
android:layout_height="60dp"
|
||||||
|
android:visibility="@{viewModel.loading}"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
android:layout_marginTop="20dp"
|
||||||
|
android:text="@string/generating_attestation"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:visibility="@{viewModel.loading}"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/progress_circular" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:visibility="@{viewModel.displayQrCode}">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/qrcode_image"
|
||||||
|
android:layout_width="300dp"
|
||||||
|
android:layout_height="300dp"
|
||||||
|
android:layout_marginTop="60dp"
|
||||||
|
android:contentDescription="@string/qrcode_attestation"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/people_item"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="60dp"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:text="@string/people_item"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/qrcode_image" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/date_item"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="60dp"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:text="@string/date_item"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/people_item" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/reason_item"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="60dp"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:text="@string/reason_item"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/date_item" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/people_item_data"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:layout_marginEnd="60dp"
|
||||||
|
android:text="@{viewModel.peopleItem}"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/qrcode_image" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/date_item_data"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:layout_marginEnd="60dp"
|
||||||
|
android:text="@{viewModel.dateItem}"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/people_item_data" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/reason_item_data"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:layout_marginEnd="60dp"
|
||||||
|
android:text="@{viewModel.reasonItem}"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/date_item_data" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:layout_width="300dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="10dp"
|
||||||
|
android:onClick="@{() -> viewModel.displayAttestation()}"
|
||||||
|
android:text="@string/display_attestation"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/delete"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/delete"
|
||||||
|
style="?attr/materialButtonOutlinedStyle"
|
||||||
|
android:layout_width="300dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="40dp"
|
||||||
|
android:onClick="@{() -> viewModel.deleteAttestation()}"
|
||||||
|
android:text="@string/delete_attestation"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
</layout>
|
</layout>
|
@ -46,4 +46,10 @@
|
|||||||
<string name="people_item">Personne :</string>
|
<string name="people_item">Personne :</string>
|
||||||
<string name="date_item">Date de sortie :</string>
|
<string name="date_item">Date de sortie :</string>
|
||||||
<string name="reason_item">Raison(s) :</string>
|
<string name="reason_item">Raison(s) :</string>
|
||||||
|
|
||||||
|
<!-- QR Fragment -->
|
||||||
|
<string name="generating_attestation">Création de votre attesation</string>
|
||||||
|
<string name="qrcode_attestation">QrCode Attestation</string>
|
||||||
|
<string name="display_attestation">Afficher l\'attestation</string>
|
||||||
|
<string name="delete_attestation">Supprimer l\'attestation</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -8,7 +8,7 @@ buildscript {
|
|||||||
|
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.6.2'
|
classpath 'com.android.tools.build:gradle:3.6.3'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
|
Loading…
Reference in New Issue
Block a user