Adding QrCode Activity and Fragment and a lot

This commit is contained in:
Mathieu Sanchez 2020-04-16 17:47:19 +02:00
parent 54d2a100d0
commit 71cb112bbe
18 changed files with 242 additions and 20 deletions

View File

@ -12,6 +12,8 @@
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=".QrCodeViewerActivity" />
<activity android:name=".PdfViewerActivity" /> <activity android:name=".PdfViewerActivity" />
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"

View File

@ -1,6 +1,7 @@
package fr.sanchezm.attestationsCovid19 package fr.sanchezm.attestationsCovid19
import android.os.Bundle import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import com.github.barteksc.pdfviewer.PDFView import com.github.barteksc.pdfviewer.PDFView
import fr.sanchezm.attestationsCovid19.utilities.InjectorUtils import fr.sanchezm.attestationsCovid19.utilities.InjectorUtils

View File

@ -0,0 +1,21 @@
package fr.sanchezm.attestationsCovid19
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import fr.sanchezm.attestationsCovid19.ui.qrcode.QrCodeFragment
class QrCodeActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.qr_code_activity)
if (savedInstanceState == null) {
val fragment = QrCodeFragment.newInstance()
fragment.arguments = intent.extras
supportFragmentManager.beginTransaction()
.replace(R.id.container, fragment)
.commitNow()
}
}
}

View File

@ -5,6 +5,7 @@ import androidx.lifecycle.MutableLiveData
import com.google.gson.Gson import com.google.gson.Gson
import com.google.gson.reflect.TypeToken import com.google.gson.reflect.TypeToken
import fr.sanchezm.attestationsCovid19.data.db.entity.Attestation import fr.sanchezm.attestationsCovid19.data.db.entity.Attestation
import fr.sanchezm.attestationsCovid19.utilities.PdfUtils
import java.io.File import java.io.File
class AttestationDao(private val path: String) { class AttestationDao(private val path: String) {
@ -24,6 +25,14 @@ class AttestationDao(private val path: String) {
save() save()
} }
fun getAttestation(createAt: Long): Attestation? {
_attestations.value?.forEach {
if (it.createAt == createAt)
return@getAttestation it
}
return null
}
init { init {
load() load()
} }
@ -34,6 +43,13 @@ class AttestationDao(private val path: String) {
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 {
val filePath = PdfUtils.getInstance()?.getPath(it.createAt)
if (filePath != null && !File(filePath).exists()) {
_attestations.value!!.remove(it)
}
}
} }
private fun save() { private fun save() {

View File

@ -13,6 +13,8 @@ class AttestationRepository private constructor(private val attestationDao: Atte
fun getAttestation(id: Int) = attestationDao.getAttestation(id) fun getAttestation(id: Int) = attestationDao.getAttestation(id)
fun getAttestation(createAt: Long) = attestationDao.getAttestation(createAt)
fun addAttestation(attestation: Attestation) = attestationDao.addAttestation(attestation) fun addAttestation(attestation: Attestation) = attestationDao.addAttestation(attestation)
companion object { companion object {

View File

@ -0,0 +1,7 @@
package fr.sanchezm.attestationsCovid19.interfaces
import fr.sanchezm.attestationsCovid19.data.db.entity.Attestation
interface ItemClickListener {
fun onItemClick(item: Attestation)
}

View File

@ -1,5 +1,6 @@
package fr.sanchezm.attestationsCovid19.ui.add package fr.sanchezm.attestationsCovid19.ui.add
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@ -9,6 +10,7 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import fr.sanchezm.attestationsCovid19.QrCodeActivity
import fr.sanchezm.attestationsCovid19.R import fr.sanchezm.attestationsCovid19.R
import fr.sanchezm.attestationsCovid19.databinding.FragmentAddAttestationBinding import fr.sanchezm.attestationsCovid19.databinding.FragmentAddAttestationBinding
import fr.sanchezm.attestationsCovid19.utilities.InjectorUtils import fr.sanchezm.attestationsCovid19.utilities.InjectorUtils
@ -33,20 +35,31 @@ class AddFragment : Fragment() {
this.viewModel = addViewModel this.viewModel = addViewModel
} }
bindMessage(binding.constraintContext) bindMessage(binding.constraintContext)
return binding.root return binding.root
} }
private fun bindMessage(context: View) { private fun bindMessage(ctx: View) {
addViewModel.errorMessage.observe(viewLifecycleOwner, Observer { addViewModel.errorMessage.observe(viewLifecycleOwner, Observer {
it.getContentIfNotHandled()?.let { stringId -> it.getContentIfNotHandled()?.let { stringId ->
Snackbar.make(context, stringId, Snackbar.LENGTH_SHORT ).show() Snackbar.make(ctx, stringId, Snackbar.LENGTH_SHORT).show()
} }
}) })
addViewModel.dataMessage.observe(viewLifecycleOwner, Observer { addViewModel.dataMessage.observe(viewLifecycleOwner, Observer {
it.getContentIfNotHandled()?.let { stringId -> it.getContentIfNotHandled()?.let { stringId ->
Snackbar.make(context, stringId, Snackbar.LENGTH_SHORT).show() Snackbar.make(ctx, stringId, Snackbar.LENGTH_SHORT).show()
}
})
addViewModel.startActivity.observe(viewLifecycleOwner, Observer {
it.getContentIfNotHandled()?.let {
val intent = Intent(context, QrCodeActivity::class.java).apply {
putExtra("createAt", it)
putExtra("toCreate", true)
}
startActivity(intent)
} }
}) })
} }

View File

@ -24,6 +24,7 @@ class AddViewModel(
private val _errorMessage = MutableLiveData<Event<Int>>() private val _errorMessage = MutableLiveData<Event<Int>>()
private val _dataMessage = MutableLiveData<Event<Int>>() private val _dataMessage = MutableLiveData<Event<Int>>()
private val _startActivity = MutableLiveData<Event<Long>>()
val errorMessage: LiveData<Event<Int>> val errorMessage: LiveData<Event<Int>>
get() = _errorMessage get() = _errorMessage
@ -31,6 +32,10 @@ class AddViewModel(
val dataMessage: LiveData<Event<Int>> val dataMessage: LiveData<Event<Int>>
get() = _dataMessage get() = _dataMessage
val startActivity: LiveData<Event<Long>>
get() = _startActivity
// region ViewField
val firstName = MutableLiveData<String>() val firstName = MutableLiveData<String>()
val lastName = MutableLiveData<String>() val lastName = MutableLiveData<String>()
val birthday = MutableLiveData<String>() val birthday = MutableLiveData<String>()
@ -48,6 +53,7 @@ class AddViewModel(
val reason5 = MutableLiveData(false) val reason5 = MutableLiveData(false)
val reason6 = MutableLiveData(false) val reason6 = MutableLiveData(false)
val reason7 = MutableLiveData(false) val reason7 = MutableLiveData(false)
// endregion
private val datePattern = "dd/MM/yyyy" private val datePattern = "dd/MM/yyyy"
private val timePattern = "HH'h'mm" private val timePattern = "HH'h'mm"
@ -56,10 +62,13 @@ class AddViewModel(
fun onGenerateAttestationClick() { fun onGenerateAttestationClick() {
if (checkAllValue()) { if (checkAllValue()) {
val attestation = getAttestation() val attestation = getAttestation()
profileRepository.insertProfile(getProfileFromView()) profileRepository.insertProfile(getProfileFromView())
attestationRepository.generateAttestation(attestation)
attestationRepository.addAttestation(attestation) attestationRepository.addAttestation(attestation)
_dataMessage.value = Event(R.string.attestation_generated)
_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")
@ -113,7 +122,7 @@ class AddViewModel(
getProfileFromView(), getProfileFromView(),
exitDate.value.toString(), exitDate.value.toString(),
exitHour.value.toString(), exitHour.value.toString(),
0, Date().time,
getReasons() getReasons()
) )
} }

View File

@ -6,17 +6,22 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
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.interfaces.ItemClickListener
import kotlinx.android.synthetic.main.attestation_item.view.* import kotlinx.android.synthetic.main.attestation_item.view.*
class AttestationsAdapter(private val items: ArrayList<Attestation>) : class AttestationsAdapter(
RecyclerView.Adapter<AttestationsAdapter.ViewHolder>() { private val items: ArrayList<Attestation>,
private val itemClickListener: ItemClickListener
) : RecyclerView.Adapter<AttestationsAdapter.ViewHolder>() {
override fun getItemCount(): Int { override fun getItemCount(): Int {
return items.size return items.size
} }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder = override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder = ViewHolder(
ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.attestation_item, parent, false)) LayoutInflater.from(parent.context).inflate(R.layout.attestation_item, parent, false),
itemClickListener
)
override fun onBindViewHolder(holder: ViewHolder, position: Int) { override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(items[(items.size - 1) - position]) holder.bind(items[(items.size - 1) - position])
@ -28,7 +33,8 @@ class AttestationsAdapter(private val items: ArrayList<Attestation>) :
notifyDataSetChanged() notifyDataSetChanged()
} }
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { class ViewHolder(private var view: View, private val itemClickListener: ItemClickListener) :
RecyclerView.ViewHolder(view) {
private val peopleItem = view.people_item_data private val peopleItem = view.people_item_data
private val dateItem = view.date_item_data private val dateItem = view.date_item_data
@ -38,8 +44,10 @@ class AttestationsAdapter(private val items: ArrayList<Attestation>) :
peopleItem.text = getName(attestation) peopleItem.text = getName(attestation)
dateItem.text = attestation.getCreatedAtFormatedDate() dateItem.text = attestation.getCreatedAtFormatedDate()
reasonItem.text = attestation.getMotifsText() reasonItem.text = attestation.getMotifsText()
view.setOnClickListener { itemClickListener.onItemClick(attestation) }
} }
private fun getName(attestation: Attestation) = "${attestation.profile.firstName} ${attestation.profile.lastName}" private fun getName(attestation: Attestation) =
"${attestation.profile.firstName} ${attestation.profile.lastName}"
} }
} }

View File

@ -12,14 +12,24 @@ 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.R import fr.sanchezm.attestationsCovid19.R
import fr.sanchezm.attestationsCovid19.data.db.entity.Attestation
import fr.sanchezm.attestationsCovid19.databinding.FragmentAttestationsBinding import fr.sanchezm.attestationsCovid19.databinding.FragmentAttestationsBinding
import fr.sanchezm.attestationsCovid19.interfaces.ItemClickListener
import fr.sanchezm.attestationsCovid19.utilities.InjectorUtils import fr.sanchezm.attestationsCovid19.utilities.InjectorUtils
import kotlinx.android.synthetic.main.fragment_attestations.view.* import kotlinx.android.synthetic.main.fragment_attestations.view.*
class AttestationsFragment : Fragment() { class AttestationsFragment : Fragment() {
private lateinit var attestationsViewModel: AttestationsViewModel private lateinit var attestationsViewModel: AttestationsViewModel
private val attestationsAdapter = AttestationsAdapter(arrayListOf()) private val attestationsAdapter = AttestationsAdapter(arrayListOf(),
object : ItemClickListener {
override fun onItemClick(item: Attestation) {
val intent = Intent(context, PdfViewerActivity::class.java).apply {
putExtra("createAt", item.createAt)
}
startActivity(intent)
}
})
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,

View File

@ -7,11 +7,9 @@ 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(private val attestationRepository: AttestationRepository) : ViewModel() { class AttestationsViewModel(attestationRepository: AttestationRepository) : ViewModel() {
private var attestationCreateAt: Long
private val _startActivity = MutableLiveData<Event<Long>>() private val _startActivity = MutableLiveData<Event<Long>>()
private val _attestationName = MutableLiveData<String>()
private var _attestations = attestationRepository.getAttestations() as MutableLiveData<ArrayList<Attestation>> private var _attestations = attestationRepository.getAttestations() as MutableLiveData<ArrayList<Attestation>>
@ -22,8 +20,6 @@ class AttestationsViewModel(private val attestationRepository: AttestationReposi
_startActivity _startActivity
init { init {
val attestation = attestationRepository.getAttestations().value?.last() _attestations = attestationRepository.getAttestations() as MutableLiveData<ArrayList<Attestation>>
attestationCreateAt = attestation?.createAt!!
_attestationName.value = "${attestation.profile.firstName} ${attestation.profile.lastName}"
} }
} }

View File

@ -0,0 +1,57 @@
package fr.sanchezm.attestationsCovid19.ui.qrcode
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.lifecycle.ViewModelProvider
import fr.sanchezm.attestationsCovid19.R
import fr.sanchezm.attestationsCovid19.databinding.QrCodeFragmentBinding
import fr.sanchezm.attestationsCovid19.utilities.InjectorUtils
class QrCodeFragment : Fragment() {
companion object {
fun newInstance() = QrCodeFragment()
}
private lateinit var qrCodeViewModel: QrCodeViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
arguments?.getBoolean("toCreate", false)?.let {
arguments?.getLong("createAt", 0)?.let { it1 ->
initializeUi(
it1,
it
)
}
}
val binding = DataBindingUtil.inflate<QrCodeFragmentBinding>(
inflater,
R.layout.qr_code_fragment,
container,
false
).apply {
this.lifecycleOwner = this@QrCodeFragment
this.viewModel = qrCodeViewModel
}
return binding.root
}
private fun initializeUi(createAt: Long, toCreate: Boolean) {
val factory = context?.let { InjectorUtils.provideQrCodeViewModel(it) }
qrCodeViewModel = factory?.let {
ViewModelProvider(this, it)
.get(QrCodeViewModel::class.java)
}!!
qrCodeViewModel.addData(createAt, toCreate)
}
}

View File

@ -0,0 +1,24 @@
package fr.sanchezm.attestationsCovid19.ui.qrcode
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import fr.sanchezm.attestationsCovid19.data.db.entity.Attestation
import fr.sanchezm.attestationsCovid19.data.repository.AttestationRepository
class QrCodeViewModel(private val attestationRepository: AttestationRepository) : ViewModel() {
private val _attestation = MutableLiveData<Attestation>()
private var toCreate: Boolean = false
fun addData(createAt: Long, toCreate: Boolean) {
this.toCreate = toCreate
_attestation.value = attestationRepository.getAttestation(createAt)
if (toCreate) {
createPdf()
}
}
fun createPdf() {
}
}

View File

@ -0,0 +1,14 @@
package fr.sanchezm.attestationsCovid19.ui.qrcode
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import fr.sanchezm.attestationsCovid19.data.repository.AttestationRepository
class QrCodeViewModelFactory(private val attestationRepository: AttestationRepository) :
ViewModelProvider.NewInstanceFactory() {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return QrCodeViewModel(attestationRepository) as T
}
}

View File

@ -7,6 +7,7 @@ import fr.sanchezm.attestationsCovid19.data.repository.AttestationRepository
import fr.sanchezm.attestationsCovid19.data.repository.ProfileRepository import fr.sanchezm.attestationsCovid19.data.repository.ProfileRepository
import fr.sanchezm.attestationsCovid19.ui.add.AddViewModelFactory import fr.sanchezm.attestationsCovid19.ui.add.AddViewModelFactory
import fr.sanchezm.attestationsCovid19.ui.attestations.AttestationsViewModelFactory import fr.sanchezm.attestationsCovid19.ui.attestations.AttestationsViewModelFactory
import fr.sanchezm.attestationsCovid19.ui.qrcode.QrCodeViewModelFactory
object InjectorUtils { object InjectorUtils {
@ -26,6 +27,13 @@ object InjectorUtils {
return AttestationsViewModelFactory(attestationRepository) return AttestationsViewModelFactory(attestationRepository)
} }
fun provideQrCodeViewModel(context: Context): QrCodeViewModelFactory {
val attestationRepository =
AttestationRepository.getInstance(MyDatabase.invoke(context).attestationDao())
return QrCodeViewModelFactory(attestationRepository)
}
fun providePdfUtils(context: Context): PdfUtils { fun providePdfUtils(context: Context): PdfUtils {
return PdfUtils.getInstance(context.assets, getMyFilesDir(context)) return PdfUtils.getInstance(context.assets, getMyFilesDir(context))
} }

View File

@ -38,7 +38,6 @@ class PdfUtils private constructor(
// Adding data // Adding data
setFieldsData(acroForm, attestation) setFieldsData(acroForm, attestation)
setCheckboxFields(acroForm, attestation) setCheckboxFields(acroForm, attestation)
attestation.createAt = Date().time
addPageWithQrCode(document, attestation) addPageWithQrCode(document, attestation)
Log.v("PdfUtils", "Save File to ${getPath(attestation.createAt)}") Log.v("PdfUtils", "Save File to ${getPath(attestation.createAt)}")

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".QrCodeActivity" />

View File

@ -0,0 +1,28 @@
<?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">
<data>
<variable
name="viewModel"
type="fr.sanchezm.attestationsCovid19.ui.qrcode.QrCodeViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/qrcode"
android:layout_width="match_parent"
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>
</layout>