First version finished

This commit is contained in:
Mathieu Sanchez 2020-04-18 19:50:50 +02:00
parent 28e348c194
commit d45d9535e0
18 changed files with 325 additions and 83 deletions

View File

@ -56,6 +56,7 @@ dependencies {
implementation 'androidx.navigation:navigation-fragment-ktx: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'

View File

@ -12,8 +12,7 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme.Light">
<activity android:name=".QrCodeActivity"></activity>
<activity android:name=".QrCodeViewerActivity" />
<activity android:name=".QrCodeActivity" />
<activity android:name=".PdfViewerActivity" />
<activity
android:name=".MainActivity"

View File

@ -4,23 +4,23 @@ import android.content.Context
import fr.sanchezm.attestationsCovid19.data.db.dao.AttestationDao
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 _attestationDao: AttestationDao? = null
fun profileDao(): ProfileDao = _profileDao ?: ProfileDao(path).also { _profileDao = it }
fun profileDao(): ProfileDao = _profileDao ?: ProfileDao(savePath).also { _profileDao = it }
fun attestationDao(): AttestationDao =
_attestationDao ?: AttestationDao(path).also { _attestationDao = it }
_attestationDao ?: AttestationDao(savePath, filesPath).also { _attestationDao = it }
companion object {
@Volatile
private var instance: MyDatabase? = null
private val LOCK = Any()
operator fun invoke(context: Context) = instance ?: synchronized(LOCK) {
instance ?: MyDatabase(context.filesDir.path).also { instance = it }
operator fun invoke(context: Context, filesPath: String) = instance ?: synchronized(LOCK) {
instance ?: MyDatabase(context.filesDir.path, filesPath).also { instance = it }
}
}
}

View File

@ -1,5 +1,6 @@
package fr.sanchezm.attestationsCovid19.data.db.dao
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.google.gson.Gson
@ -8,20 +9,24 @@ import fr.sanchezm.attestationsCovid19.data.db.entity.Attestation
import fr.sanchezm.attestationsCovid19.utilities.PdfUtils
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 fileName = "attestation.db"
private val type = object : TypeToken<ArrayList<Attestation>>() {}.type
fun getAttestations() : LiveData<ArrayList<Attestation>> =
_attestations
@Suppress("UNCHECKED_CAST")
fun getAttestations(): LiveData<List<Attestation>> =
_attestations as LiveData<List<Attestation>>
fun getAttestation(id: Int): Attestation? =
_attestations.value?.elementAt(id)
fun addAttestation(attestation: Attestation) {
_attestations.value = _attestations.value ?: ArrayList()
_attestations.value?.add(attestation)
Log.d(TAG, "Add Attestation : $attestation")
save()
}
@ -33,36 +38,50 @@ class AttestationDao(private val path: String) {
return null
}
fun deleteAttestation(attestation: Attestation) {
deleteFile(attestation)
delete(attestation)
}
init {
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() {
val file = File("$path/$fileName")
val file = File("$savePath/$fileName")
val removeList = ArrayList<Attestation>()
if (file.exists()) {
_attestations.value = Gson().fromJson(file.readText(Charsets.UTF_8), type)
}
_attestations.value?.forEach {
val filePath = PdfUtils.getInstance()?.getPath(it.createAt)
val filePath = PdfUtils.getPath(filesPath, it.createAt)
if (filePath != null && !File(filePath).exists()) {
_attestations.value!!.remove(it)
if (!File(filePath).exists()) {
removeList.add(it)
}
}
}.also { _attestations.value?.removeAll(removeList) }
}
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))
}
}
//@Dao
//interface AttestationDao {
// @Insert
// fun insert(attestation: Attestation)
//
// @Query(value = "SELECT * FROM attestation WHERE id = $CURRENT_ATTESTATION_ID")
// fun getAttestation(): LiveData<Attestation>
//}
companion object {
private val TAG = AttestationDao::class.simpleName
}
}

View File

@ -14,12 +14,18 @@ data class Attestation(
val reasons: List<Int>
) {
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()
reasons.forEach { motifs.append(getMotifText(it), "-") }

View File

@ -6,8 +6,8 @@ import fr.sanchezm.attestationsCovid19.utilities.PdfUtils
class AttestationRepository private constructor(private val attestationDao: AttestationDao) {
fun generateAttestation(attestation: Attestation) =
PdfUtils.getInstance()?.fillForm(attestation)
fun generateAttestation(attestation: Attestation, callback: (Boolean) -> Unit) =
PdfUtils.getInstance()?.fillForm(attestation, callback)
fun getAttestations() = attestationDao.getAttestations()
@ -17,6 +17,8 @@ class AttestationRepository private constructor(private val attestationDao: Atte
fun addAttestation(attestation: Attestation) = attestationDao.addAttestation(attestation)
fun deleteAttestation(attestation: Attestation) = attestationDao.deleteAttestation(attestation)
companion object {
@Volatile
private var instance: AttestationRepository? = null

View File

@ -53,8 +53,8 @@ class AddFragment : Fragment() {
}
})
addViewModel.startActivity.observe(viewLifecycleOwner, Observer {
it.getContentIfNotHandled()?.let {
addViewModel.startActivity.observe(viewLifecycleOwner, Observer { event ->
event.getContentIfNotHandled()?.let {
val intent = Intent(context, QrCodeActivity::class.java).apply {
putExtra("createAt", it)
putExtra("toCreate", true)

View File

@ -67,8 +67,6 @@ class AddViewModel(
attestationRepository.addAttestation(attestation)
_startActivity.value = Event(attestation.createAt)
// attestationRepository.generateAttestation(attestation)
// _dataMessage.value = Event(R.string.attestation_generated)
} else {
_errorMessage.value = Event(R.string.error_cannot_create_attestation)
Log.e("onGenerateAttestationClick", "Cannot generate Attestation")

View File

@ -41,13 +41,10 @@ class AttestationsAdapter(
private val reasonItem = view.reason_item_data
fun bind(attestation: Attestation) {
peopleItem.text = getName(attestation)
dateItem.text = attestation.getCreatedAtFormatedDate()
reasonItem.text = attestation.getMotifsText()
peopleItem.text = attestation.getNameFormatted()
dateItem.text = attestation.getExitDateFormatted()
reasonItem.text = attestation.getMotifsFormatted()
view.setOnClickListener { itemClickListener.onItemClick(attestation) }
}
private fun getName(attestation: Attestation) =
"${attestation.profile.firstName} ${attestation.profile.lastName}"
}
}

View File

@ -11,6 +11,7 @@ import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import fr.sanchezm.attestationsCovid19.PdfViewerActivity
import fr.sanchezm.attestationsCovid19.QrCodeActivity
import fr.sanchezm.attestationsCovid19.R
import fr.sanchezm.attestationsCovid19.data.db.entity.Attestation
import fr.sanchezm.attestationsCovid19.databinding.FragmentAttestationsBinding
@ -24,8 +25,9 @@ class AttestationsFragment : Fragment() {
private val attestationsAdapter = AttestationsAdapter(arrayListOf(),
object : ItemClickListener {
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("toCreate", false)
}
startActivity(intent)
}
@ -56,8 +58,8 @@ class AttestationsFragment : Fragment() {
}
private fun bindMessage() {
attestationsViewModel.startActivity.observe(viewLifecycleOwner, Observer {
it.getContentIfNotHandled()?.let { createAtPdf ->
attestationsViewModel.startActivity.observe(viewLifecycleOwner, Observer { event ->
event.getContentIfNotHandled()?.let { createAtPdf ->
val intent = Intent(context, PdfViewerActivity::class.java).apply {
putExtra("createAt", createAtPdf)
}

View File

@ -4,29 +4,20 @@ import android.view.View
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import fr.sanchezm.attestationsCovid19.data.db.entity.Attestation
import fr.sanchezm.attestationsCovid19.data.repository.AttestationRepository
import fr.sanchezm.attestationsCovid19.utilities.Event
class AttestationsViewModel(attestationRepository: AttestationRepository) : ViewModel() {
private val _startActivity = MutableLiveData<Event<Long>>()
private var _attestations = attestationRepository.getAttestations() as MutableLiveData<ArrayList<Attestation>>
private var _displayNoAttestation = MutableLiveData<Int>()
val attestations: LiveData<ArrayList<Attestation>> =
_attestations
val startActivity: LiveData<Event<Long>> =
_startActivity
val displayNoAttestation: LiveData<Int> =
_displayNoAttestation
val attestations = attestationRepository.getAttestations()
val startActivity: LiveData<Event<Long>> = _startActivity
val displayNoAttestation: LiveData<Int> = _displayNoAttestation
init {
if (_attestations.value == null || _attestations.value?.size == 0) {
if (attestations.value == null || attestations.value?.size == 0) {
_displayNoAttestation.value = View.VISIBLE
} else {
_displayNoAttestation.value = View.GONE

View File

@ -1,15 +1,19 @@
package fr.sanchezm.attestationsCovid19.ui.qrcode
import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import fr.sanchezm.attestationsCovid19.PdfViewerActivity
import fr.sanchezm.attestationsCovid19.R
import fr.sanchezm.attestationsCovid19.databinding.QrCodeFragmentBinding
import fr.sanchezm.attestationsCovid19.utilities.InjectorUtils
import kotlinx.android.synthetic.main.qr_code_fragment.*
class QrCodeFragment : Fragment() {
@ -41,10 +45,11 @@ class QrCodeFragment : Fragment() {
this.viewModel = qrCodeViewModel
}
bindingData()
return binding.root
}
private fun initializeUi(createAt: Long, toCreate: Boolean) {
val factory = context?.let { InjectorUtils.provideQrCodeViewModel(it) }
qrCodeViewModel = factory?.let {
@ -54,4 +59,28 @@ class QrCodeFragment : Fragment() {
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)
}
})
}
}

View File

@ -1,24 +1,85 @@
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.ViewModel
import fr.sanchezm.attestationsCovid19.data.db.entity.Attestation
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() {
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) {
this.toCreate = toCreate
_attestation.value = attestationRepository.getAttestation(createAt)
val att = attestationRepository.getAttestation(createAt)
_attestation.value = att
if (toCreate) {
_loading.value = View.VISIBLE
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
}
}

View File

@ -13,23 +13,31 @@ object InjectorUtils {
fun provideAddViewModelFactory(context: Context): AddViewModelFactory {
val profileRepository =
ProfileRepository.getInstance(MyDatabase.invoke(context).profileDao())
ProfileRepository.getInstance(
MyDatabase.invoke(context, getMyFilesDir(context)).profileDao()
)
val attestationRepository =
AttestationRepository.getInstance(MyDatabase.invoke(context).attestationDao())
AttestationRepository.getInstance(
MyDatabase.invoke(context, getMyFilesDir(context)).attestationDao()
)
return AddViewModelFactory(profileRepository, attestationRepository)
}
fun provideAttestationViewModel(context: Context): AttestationsViewModelFactory {
val attestationRepository =
AttestationRepository.getInstance(MyDatabase.invoke(context).attestationDao())
AttestationRepository.getInstance(
MyDatabase.invoke(context, getMyFilesDir(context)).attestationDao()
)
return AttestationsViewModelFactory(attestationRepository)
}
fun provideQrCodeViewModel(context: Context): QrCodeViewModelFactory {
val attestationRepository =
AttestationRepository.getInstance(MyDatabase.invoke(context).attestationDao())
AttestationRepository.getInstance(
MyDatabase.invoke(context, getMyFilesDir(context)).attestationDao()
)
return QrCodeViewModelFactory(attestationRepository)
}

View File

@ -14,8 +14,6 @@ import com.tom_roush.pdfbox.pdmodel.interactive.form.PDTextField
import fr.sanchezm.attestationsCovid19.data.db.entity.Attestation
import java.io.File
import java.io.IOException
import java.util.*
import kotlin.collections.ArrayList
class PdfUtils private constructor(
@ -23,11 +21,10 @@ class PdfUtils private constructor(
private val path: String
) {
private val folderPath = "attestations"
private val checkboxListNames = ArrayList<String>()
private val font = PDType1Font.HELVETICA
fun fillForm(attestation: Attestation) {
fun fillForm(attestation: Attestation, callback: (Boolean) -> Unit) {
checkFolder()
try {
// Load the document and get the AcroForm
@ -43,12 +40,14 @@ class PdfUtils private constructor(
Log.v("PdfUtils", "Save File to ${getPath(attestation.createAt)}")
document.save(getPath(attestation.createAt))
document.close()
callback(true)
} catch (e: IOException) {
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) {
val size = 360
@ -100,7 +99,7 @@ class PdfUtils private constructor(
contentStream.beginText()
contentStream.setFont(font, 7f)
contentStream.newLineAtOffset(page.mediaBox.upperRightX - size - 27, 138f)
contentStream.showText(attestation.getCreatedAtFormatedDate())
contentStream.showText(attestation.getCreatedAtFormattedDate())
contentStream.endText()
}
contentStream.close()
@ -150,12 +149,16 @@ class PdfUtils private constructor(
@Volatile
private var instance: PdfUtils? = null
private val LOCK = Any()
private const val folderPath = "attestations"
fun getInstance() = instance
fun getInstance(assetManager: AssetManager, path: String) = instance ?: synchronized(LOCK) {
instance ?: PdfUtils(assetManager, path).also { instance = it; it.initList() }
}
fun getPath(path: String, createAt: Long): String = "$path/$folderPath/$createAt.pdf"
}
private fun initList() {

View File

@ -1,9 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<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>
<variable
name="viewModel"
type="fr.sanchezm.attestationsCovid19.ui.qrcode.QrCodeViewModel" />
@ -15,13 +16,132 @@
android:layout_height="match_parent"
tools:context=".ui.qrcode.QrCodeFragment">
<androidx.core.widget.ContentLoadingProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<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_height="wrap_content"
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_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -46,4 +46,10 @@
<string name="people_item">Personne :</string>
<string name="date_item">Date de sortie :</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>

View File

@ -8,7 +8,7 @@ buildscript {
}
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"
// NOTE: Do not place your application dependencies here; they belong