From 7c1f7b30795c339151cd59792a4ce59a1d7704f9 Mon Sep 17 00:00:00 2001 From: acomito Date: Tue, 8 Mar 2022 18:39:42 +0100 Subject: [PATCH 1/2] feat: management to add eudcc in home --- .../services/ConfigurationSettingsService.kt | 19 +- .../ministerodellasalute/immuni/koinModule.kt | 1 + .../immuni/logic/user/UserManager.kt | 6 + .../logic/user/models/GreenCertificateUser.kt | 3 +- .../logic/user/repositories/UserRepository.kt | 7 + .../ui/certificate/CertificateDGCAdapter.kt | 211 ++++++++++++++++ .../ui/certificate/CertificateDGCFragment.kt | 108 ++++++++ .../ui/certificate/CertificateDGCKnowMore.kt | 16 ++ .../countriesofinterest/CountriesFragment.kt | 2 +- .../ui/cun/ReportPositivityIndependently.kt | 2 +- .../ui/dialog/ConfirmationDialogFragment.kt | 29 ++- .../GenerateGreenCertificate.kt | 11 +- .../GreenCertificateFragment.kt | 213 ++++++++++++++-- .../ui/greencertificate/GreenPassAdapter.kt | 85 ++++++- .../immuni/ui/home/HomeFragment.kt | 21 +- .../immuni/ui/home/HomeListAdapter.kt | 51 +++- .../immuni/ui/home/HomeModels.kt | 1 + .../immuni/ui/main/MainActivity.kt | 8 +- .../immuni/ui/main/MainViewModel.kt | 32 ++- .../viewpager/ExposureNotificationFragment.kt | 2 +- .../fragments/viewpager/RegionFragment.kt | 2 +- .../immuni/ui/settings/SettingsFragment.kt | 2 +- .../immuni/ui/upload/UploadDataFragment.kt | 2 +- .../ic_certificates_selected.png | Bin 0 -> 7163 bytes .../ic_certificates_unselected.png | Bin 0 -> 2660 bytes .../ic_certificates_selected.png | Bin 0 -> 3469 bytes .../ic_certificates_unselected.png | Bin 0 -> 1494 bytes .../ic_certificates_selected.png | Bin 0 -> 11427 bytes .../ic_certificates_unselected.png | Bin 0 -> 2622 bytes .../ic_certificates_selected.png | Bin 0 -> 21831 bytes .../ic_certificates_unselected.png | Bin 0 -> 4348 bytes .../ic_certificates_selected.png | Bin 0 -> 18977 bytes .../ic_certificates_unselected.png | Bin 0 -> 2157 bytes app/src/main/res/drawable/ic_bubble_blue.xml | 9 + app/src/main/res/drawable/ic_icon_pin.xml | 44 ++++ .../main/res/drawable/ic_icon_pin_empty.xml | 26 ++ .../main/res/drawable/ic_tab_certificate.xml | 42 ++++ app/src/main/res/layout/certificate_dgc.xml | 238 ++++++++++++++++++ .../main/res/layout/certificate_dgc_item.xml | 87 +++++++ .../res/layout/certificate_dgc_know_more.xml | 68 +++++ app/src/main/res/layout/green_certificate.xml | 50 +--- .../main/res/layout/green_certificate_tab.xml | 28 ++- app/src/main/res/layout/home_activity.xml | 20 +- .../main/res/layout/home_certificate_card.xml | 74 ++++++ app/src/main/res/menu/bottom_nav_menu.xml | 5 + .../main/res/navigation/certificate_dgc.xml | 82 ++++++ .../main/res/navigation/green_certificate.xml | 30 +-- app/src/main/res/navigation/home.xml | 15 +- app/src/main/res/values/strings.xml | 27 ++ app/src/main/res/values/styles.xml | 44 +++- .../immuni/extensions/utils/DateUtils.kt | 37 +++ 51 files changed, 1596 insertions(+), 164 deletions(-) create mode 100644 app/src/main/java/it/ministerodellasalute/immuni/ui/certificate/CertificateDGCAdapter.kt create mode 100644 app/src/main/java/it/ministerodellasalute/immuni/ui/certificate/CertificateDGCFragment.kt create mode 100644 app/src/main/java/it/ministerodellasalute/immuni/ui/certificate/CertificateDGCKnowMore.kt create mode 100644 app/src/main/res/drawable-hdpi/ic_certificates_selected.png create mode 100644 app/src/main/res/drawable-hdpi/ic_certificates_unselected.png create mode 100644 app/src/main/res/drawable-mdpi/ic_certificates_selected.png create mode 100644 app/src/main/res/drawable-mdpi/ic_certificates_unselected.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_certificates_selected.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_certificates_unselected.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_certificates_selected.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_certificates_unselected.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_certificates_selected.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_certificates_unselected.png create mode 100644 app/src/main/res/drawable/ic_bubble_blue.xml create mode 100644 app/src/main/res/drawable/ic_icon_pin.xml create mode 100644 app/src/main/res/drawable/ic_icon_pin_empty.xml create mode 100644 app/src/main/res/drawable/ic_tab_certificate.xml create mode 100644 app/src/main/res/layout/certificate_dgc.xml create mode 100644 app/src/main/res/layout/certificate_dgc_item.xml create mode 100644 app/src/main/res/layout/certificate_dgc_know_more.xml create mode 100644 app/src/main/res/layout/home_certificate_card.xml create mode 100644 app/src/main/res/navigation/certificate_dgc.xml diff --git a/app/src/main/java/it/ministerodellasalute/immuni/api/services/ConfigurationSettingsService.kt b/app/src/main/java/it/ministerodellasalute/immuni/api/services/ConfigurationSettingsService.kt index 969bd8564..f951003d6 100644 --- a/app/src/main/java/it/ministerodellasalute/immuni/api/services/ConfigurationSettingsService.kt +++ b/app/src/main/java/it/ministerodellasalute/immuni/api/services/ConfigurationSettingsService.kt @@ -63,7 +63,8 @@ data class ConfigurationSettings( @field:Json(name = "dummy_analytics_waiting_time") val dummyAnalyticsWaitingTime: Int, @field:Json(name = "countries") val countries: Map>, @field:Json(name = "eudcc_expiration") val eudcc_expiration: Map>, - @field:Json(name = "risk_exposure") val risk_exposure: Map + @field:Json(name = "risk_exposure") val risk_exposure: Map, + @field:Json(name = "eudcc_validity") val days_expiration_dgc: Map ) @JsonClass(generateAdapter = true) @@ -244,6 +245,19 @@ fun risk_exposure(): Map { ) } +fun daysExpirationDgc(): Map { + return mapOf( + "cbis" to 540, + "molecular_test" to 3, + "rapid_test" to 2, + "vaccine_first_dose" to 43, + "vaccine_fully_completed" to 180, + "vaccine_booster" to 540, + "healing_certificate" to 180, + "exemption" to null + ) +} + val defaultSettings = ConfigurationSettings( minimumBuildVersion = 0, faqUrls = languageMap { "https://get.immuni.gov.it/docs/faq-${it.code}.json" }, @@ -281,5 +295,6 @@ val defaultSettings = ConfigurationSettings( dummyAnalyticsWaitingTime = 2_592_000, countries = countriesMap(), eudcc_expiration = eudccMap(), - risk_exposure = risk_exposure() + risk_exposure = risk_exposure(), + days_expiration_dgc = daysExpirationDgc() ) diff --git a/app/src/main/java/it/ministerodellasalute/immuni/koinModule.kt b/app/src/main/java/it/ministerodellasalute/immuni/koinModule.kt index 1cc21442b..23e3ac59e 100755 --- a/app/src/main/java/it/ministerodellasalute/immuni/koinModule.kt +++ b/app/src/main/java/it/ministerodellasalute/immuni/koinModule.kt @@ -397,6 +397,7 @@ val appModule = module { androidContext(), get(), get(), + get(), get() ) } diff --git a/app/src/main/java/it/ministerodellasalute/immuni/logic/user/UserManager.kt b/app/src/main/java/it/ministerodellasalute/immuni/logic/user/UserManager.kt index 0704cc3d4..5a318046c 100644 --- a/app/src/main/java/it/ministerodellasalute/immuni/logic/user/UserManager.kt +++ b/app/src/main/java/it/ministerodellasalute/immuni/logic/user/UserManager.kt @@ -75,5 +75,11 @@ class UserManager( fun setShowModalDGC(show: Boolean) { userRepository.setShowModalDGC(show) } + + val showDGCHome = userRepository.showDGCHome + + fun setShowDGCHome(show: Boolean) { + userRepository.setShowDGCHome(show) + } // END DGC } diff --git a/app/src/main/java/it/ministerodellasalute/immuni/logic/user/models/GreenCertificateUser.kt b/app/src/main/java/it/ministerodellasalute/immuni/logic/user/models/GreenCertificateUser.kt index bac97b4bb..9bfe05c83 100644 --- a/app/src/main/java/it/ministerodellasalute/immuni/logic/user/models/GreenCertificateUser.kt +++ b/app/src/main/java/it/ministerodellasalute/immuni/logic/user/models/GreenCertificateUser.kt @@ -11,5 +11,6 @@ import kotlinx.android.parcel.Parcelize data class GreenCertificateUser( @field:Json(name = "base64") val base64: String, @field:Json(name = "greenCertificate") val data: GreenCertificate?, - @field:Json(name = "fglTipoDgc") val fglTipoDgc: String? = null + @field:Json(name = "fglTipoDgc") val fglTipoDgc: String? = null, + @field:Json(name = "addedHomeDgc") var addedHomeDgc: Boolean = false ) : Parcelable diff --git a/app/src/main/java/it/ministerodellasalute/immuni/logic/user/repositories/UserRepository.kt b/app/src/main/java/it/ministerodellasalute/immuni/logic/user/repositories/UserRepository.kt index 8a66de858..c6fa71a15 100644 --- a/app/src/main/java/it/ministerodellasalute/immuni/logic/user/repositories/UserRepository.kt +++ b/app/src/main/java/it/ministerodellasalute/immuni/logic/user/repositories/UserRepository.kt @@ -27,6 +27,7 @@ class UserRepository( private val welcomeCompleteKey = KVStorage.Key("WelcomeComplete") private val onboardingCompleteKey = KVStorage.Key("OnboardingComplete") private val showModalDGCKey = KVStorage.Key("showModalDGC") + private val showDGCHomeKey = KVStorage.Key("showDGCHome") } val user = storage.stateFlow(userKey) @@ -58,4 +59,10 @@ class UserRepository( fun setShowModalDGC(show: Boolean) { storage[showModalDGCKey] = show } + + val showDGCHome = storage.stateFlow(showDGCHomeKey) + + fun setShowDGCHome(show: Boolean) { + storage[showDGCHomeKey] = show + } } diff --git a/app/src/main/java/it/ministerodellasalute/immuni/ui/certificate/CertificateDGCAdapter.kt b/app/src/main/java/it/ministerodellasalute/immuni/ui/certificate/CertificateDGCAdapter.kt new file mode 100644 index 000000000..ca6b2d71e --- /dev/null +++ b/app/src/main/java/it/ministerodellasalute/immuni/ui/certificate/CertificateDGCAdapter.kt @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2020 Presidenza del Consiglio dei Ministri. + * Please refer to the AUTHORS file for more information. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package it.ministerodellasalute.immuni.ui.certificate + +import android.annotation.SuppressLint +import android.content.Context +import android.text.format.DateFormat +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.google.android.material.card.MaterialCardView +import it.ministerodellasalute.immuni.R +import it.ministerodellasalute.immuni.extensions.utils.* +import it.ministerodellasalute.immuni.extensions.view.setSafeOnClickListener +import it.ministerodellasalute.immuni.logic.settings.ConfigurationSettingsManager +import it.ministerodellasalute.immuni.logic.user.models.GreenCertificateUser +import java.text.SimpleDateFormat +import java.util.* + +class CertificateDGCAdapter( + val context: Context, + val settingsManager: ConfigurationSettingsManager, + private val clickListener: CertificateDGCClickListener +) : + RecyclerView.Adapter() { + + private val molecolarTest = "LP6464-4" + private val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.US) + private val dateTimeFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US) + + var data: List = emptyList() + set(value) { + field = value + notifyDataSetChanged() + } + + private fun onItemClick(pos: Int) { + if (pos != RecyclerView.NO_POSITION) { + val uid = when (true) { + data[pos].data?.recoveryStatements != null -> { + data[pos].data?.recoveryStatements?.get(0)?.certificateIdentifier + } + data[pos].data?.tests != null -> { + data[pos].data?.tests?.get(0)?.certificateIdentifier + } + data[pos].data?.vaccinations != null -> { + data[pos].data?.vaccinations?.get(0)?.certificateIdentifier + } + data[pos].data?.exemptions != null -> { + data[pos].data?.exemptions?.get(0)?.certificateIdentifier + } + else -> null + } + + + clickListener.onClick(uid!!) + } + } + + inner class GreenPassVH(v: View) : RecyclerView.ViewHolder(v) { + val dateEvent: TextView = v.findViewById(R.id.dateEvent) + val nameForename: TextView = v.findViewById(R.id.nameForename) + val eventType: TextView = v.findViewById(R.id.eventType) + val validityDGC: MaterialCardView = v.findViewById(R.id.validityDGC) + val addedInHome: ImageView = v.findViewById(R.id.addedInHome) + + init { + v.setSafeOnClickListener { onItemClick(adapterPosition) } + } + } + + override fun getItemCount(): Int = data.size + + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: Int + ): CertificateDGCAdapter.GreenPassVH { + val v = LayoutInflater.from(parent.context) + .inflate(R.layout.certificate_dgc_item, parent, false) + return GreenPassVH(v) + } + + @SuppressLint("SetTextI18n") + override fun onBindViewHolder(holder: GreenPassVH, position: Int) { + val greenCertificate = data[position] + val daysExpiredDgcMap = settingsManager.settings.value.days_expiration_dgc + holder.nameForename.text = + "${greenCertificate.data?.person?.givenName} ${greenCertificate.data?.person?.familyName}" + holder.addedInHome.visibility = if (greenCertificate.addedHomeDgc) { + View.VISIBLE + } else { + View.GONE + } + when (true) { + greenCertificate.data?.recoveryStatements != null -> { + holder.dateEvent.text = when(greenCertificate.fglTipoDgc) { + "cbis" -> dateExpired( + greenCertificate.data?.recoveryStatements?.get(0)?.certificateValidFrom!!, + dateFormat, + daysExpiredDgcMap["cbis"]!!, + holder + ) + else -> dateExpired( + greenCertificate.data?.recoveryStatements?.get(0)?.certificateValidFrom!!, + dateFormat, + daysExpiredDgcMap["healing_certificate"]!!, + holder + ) + } + + holder.eventType.text = context.getString(R.string.green_certificate_card_recovery) + } + greenCertificate.data?.tests != null -> { + if (greenCertificate.data?.tests?.get(0)!!.typeOfTest == molecolarTest) { + holder.eventType.text = + context.getString(R.string.green_certificate_card_molecular_test) + holder.dateEvent.text = dateExpired( + greenCertificate.data.tests?.get(0)?.dateTimeOfTestResult!!, + dateTimeFormat, + daysExpiredDgcMap["molecular_test"]!!, + holder + ) + } else { + holder.eventType.text = + context.getString(R.string.green_certificate_card_rapid_test) + holder.dateEvent.text = dateExpired( + greenCertificate.data.tests?.get(0)?.dateTimeOfTestResult!!, + dateTimeFormat, + daysExpiredDgcMap["rapid_test"]!!, + holder + ) + } + } + greenCertificate.data?.vaccinations != null -> { + holder.dateEvent.text = if (greenCertificate.data?.vaccinations?.get(0)!!.doseNumber < greenCertificate.data.vaccinations?.get(0)!!.totalSeriesOfDoses) { + dateExpired( + greenCertificate.data.vaccinations?.get(0)?.dateOfVaccination!!, + dateFormat, + daysExpiredDgcMap["vaccine_first_dose"]!!, + holder + ) + } else if (greenCertificate.data.vaccinations?.get(0)!!.doseNumber == greenCertificate.data.vaccinations?.get(0)!!.totalSeriesOfDoses && greenCertificate.data.vaccinations?.get(0)!!.totalSeriesOfDoses < 3) { + dateExpired( + greenCertificate.data.vaccinations?.get(0)?.dateOfVaccination!!, + dateFormat, + daysExpiredDgcMap["vaccine_fully_completed"]!!, + holder + ) + } else { + dateExpired( + greenCertificate.data.vaccinations?.get(0)?.dateOfVaccination!!, + dateFormat, + daysExpiredDgcMap["vaccine_booster"]!!, + holder + ) + } + holder.eventType.text = context.getString( + R.string.green_certificate_card_vaccination, + greenCertificate.data.vaccinations?.get(0)?.doseNumber, + greenCertificate.data.vaccinations?.get(0)?.totalSeriesOfDoses + ) + } + greenCertificate.data?.exemptions != null -> { + holder.dateEvent.text = if (greenCertificate.data?.exemptions!![0].certificateValidUntil != null) { + val todayDateMill = Date().byAdding().time + val maxDateValidity = dateFormat.parse(greenCertificate.data.exemptions!![0].certificateValidUntil!!)!! + if (maxDateValidity.time > todayDateMill) { + context.getString(R.string.green_certificate_list_dgc_valid, DateFormat.getDateFormat(context).format(greenCertificate.data.exemptions!![0].certificateValidUntil)) + } else { + context.getString(R.string.green_certificate_list_dgc_expired) + } + } else { + context.getString(R.string.green_certificate_list_dgc_expired) + } + holder.eventType.text = context.getString(R.string.green_certificate_card_exemption) + } + } + } + + private fun dateExpired(dateFrom: String,simpleDateFormat: SimpleDateFormat, daysValidity: Int, holder: GreenPassVH): String { + val todayDateMill = Date().byAdding().time + val maxDateValidity = simpleDateFormat.parse(dateFrom)!!.byAdding(days = daysValidity) + return if (maxDateValidity.time > todayDateMill) { + holder.validityDGC.backgroundTintList = context.resources.getColorStateList(R.color.colorPrimary, null) + context.getString(R.string.green_certificate_list_dgc_valid, DateFormat.getDateFormat(context).format(maxDateValidity)) + } else { + holder.validityDGC.backgroundTintList = context.resources.getColorStateList(R.color.danger, null) + context.getString(R.string.green_certificate_list_dgc_expired) + } + } +} + +interface CertificateDGCClickListener { + fun onClick(uid: String) +} diff --git a/app/src/main/java/it/ministerodellasalute/immuni/ui/certificate/CertificateDGCFragment.kt b/app/src/main/java/it/ministerodellasalute/immuni/ui/certificate/CertificateDGCFragment.kt new file mode 100644 index 000000000..bda734a88 --- /dev/null +++ b/app/src/main/java/it/ministerodellasalute/immuni/ui/certificate/CertificateDGCFragment.kt @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2020 Presidenza del Consiglio dei Ministri. + * Please refer to the AUTHORS file for more information. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package it.ministerodellasalute.immuni.ui.certificate + +import android.os.Bundle +import android.view.View +import androidx.appcompat.app.AppCompatActivity +import androidx.fragment.app.Fragment +import androidx.navigation.fragment.findNavController +import com.google.android.material.appbar.AppBarLayout +import it.ministerodellasalute.immuni.R +import it.ministerodellasalute.immuni.extensions.activity.setLightStatusBar +import it.ministerodellasalute.immuni.extensions.view.setSafeOnClickListener +import it.ministerodellasalute.immuni.logic.settings.ConfigurationSettingsManager +import it.ministerodellasalute.immuni.logic.user.UserManager +import it.ministerodellasalute.immuni.logic.user.models.GreenCertificateUser +import kotlinx.android.synthetic.main.certificate_dgc.* +import org.koin.android.ext.android.get +import kotlin.math.abs + +class CertificateDGCFragment : Fragment(R.layout.certificate_dgc), CertificateDGCClickListener { + + private lateinit var certificateDGCAdapter: CertificateDGCAdapter + private lateinit var userManager: UserManager + private lateinit var listGreenCertificate: MutableList + private lateinit var settingsManager: ConfigurationSettingsManager + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + if (arguments?.containsKey("uid") == true) { + val action = CertificateDGCFragmentDirections.actionGreenCertificateTab(arguments!!["uid"] as String) + arguments!!.remove("uid") + findNavController().navigate(action) + } + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + (activity as? AppCompatActivity)?.setLightStatusBar(resources.getColor(R.color.background_darker)) + + // Fade out toolbar on scroll + appBar.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset -> + val ratio = abs(verticalOffset / appBarLayout.totalScrollRange.toFloat()) + + pageTitle?.alpha = 1 - ratio + toolbarTitle?.alpha = ratio + toolbarSeparator?.alpha = ratio + }) + + userManager = get() + settingsManager = get() + + knowMore.setSafeOnClickListener { + val action = CertificateDGCFragmentDirections.actionCertificateDgcKnowMore() + findNavController().navigate(action) + } + + listGreenCertificate = userManager.user.value?.greenPass!!.asReversed() + + if (listGreenCertificate.isEmpty()) { + emptyView.visibility = View.VISIBLE + view_fully.visibility = View.GONE + } else { + emptyView.visibility = View.GONE + view_fully.visibility = View.VISIBLE + } + + certificateDGCAdapter = CertificateDGCAdapter( + requireContext(), + settingsManager, + this + ) + certificateRecycler.adapter = certificateDGCAdapter + certificateDGCAdapter.data = listGreenCertificate + + getDGCButton.setOnClickListener { + val action = CertificateDGCFragmentDirections.actionGreenCertificateNav() + findNavController().navigate(action) + } + } + + override fun onClick(uid: String) { + val action = CertificateDGCFragmentDirections.actionGreenCertificateTab(uid) + findNavController().navigate(action) + } + + fun openGenerateGreenPass() { + val action = CertificateDGCFragmentDirections.actionGreenCertificateNav() + findNavController().navigate(action) + // close the previous dialog + // important keep here, after navigating + findNavController().popBackStack() + } + +} diff --git a/app/src/main/java/it/ministerodellasalute/immuni/ui/certificate/CertificateDGCKnowMore.kt b/app/src/main/java/it/ministerodellasalute/immuni/ui/certificate/CertificateDGCKnowMore.kt new file mode 100644 index 000000000..03f6ef528 --- /dev/null +++ b/app/src/main/java/it/ministerodellasalute/immuni/ui/certificate/CertificateDGCKnowMore.kt @@ -0,0 +1,16 @@ +package it.ministerodellasalute.immuni.ui.certificate + +import android.os.Bundle +import android.view.View +import it.ministerodellasalute.immuni.R +import it.ministerodellasalute.immuni.ui.dialog.PopupDialogFragment + +class CertificateDGCKnowMore: PopupDialogFragment() { + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + setContentLayout(R.layout.certificate_dgc_know_more) + + setTitle(getString(R.string.certificate_dgc_know_more_title)) + } +} diff --git a/app/src/main/java/it/ministerodellasalute/immuni/ui/countriesofinterest/CountriesFragment.kt b/app/src/main/java/it/ministerodellasalute/immuni/ui/countriesofinterest/CountriesFragment.kt index 3c0e573c3..af7d82483 100644 --- a/app/src/main/java/it/ministerodellasalute/immuni/ui/countriesofinterest/CountriesFragment.kt +++ b/app/src/main/java/it/ministerodellasalute/immuni/ui/countriesofinterest/CountriesFragment.kt @@ -115,7 +115,7 @@ class CountriesFragment : // Do nothing, user does not want to exit } - override fun onDialogPositive(requestCode: Int) { + override fun onDialogPositive(requestCode: Int, argument: String?) { if (requestCode == ALERT_CONFIRM_SAVE) { for (country in adapter.selectedCountries) { if (country.insertDate == null) { diff --git a/app/src/main/java/it/ministerodellasalute/immuni/ui/cun/ReportPositivityIndependently.kt b/app/src/main/java/it/ministerodellasalute/immuni/ui/cun/ReportPositivityIndependently.kt index 567f366b5..e62256ee5 100644 --- a/app/src/main/java/it/ministerodellasalute/immuni/ui/cun/ReportPositivityIndependently.kt +++ b/app/src/main/java/it/ministerodellasalute/immuni/ui/cun/ReportPositivityIndependently.kt @@ -312,7 +312,7 @@ class ReportPositivityIndependently : Fragment(R.layout.report_positivity_cun), // Do nothing, user does not want to exit } - override fun onDialogPositive(requestCode: Int) { + override fun onDialogPositive(requestCode: Int, argument: String?) { if (requestCode == ALERT_CONFIRM_SAVE) { checkboxDate.isChecked = !checkboxDate.isChecked symptomOnsetDateInput.text?.clear() diff --git a/app/src/main/java/it/ministerodellasalute/immuni/ui/dialog/ConfirmationDialogFragment.kt b/app/src/main/java/it/ministerodellasalute/immuni/ui/dialog/ConfirmationDialogFragment.kt index 9a42000f6..0c7c23c87 100644 --- a/app/src/main/java/it/ministerodellasalute/immuni/ui/dialog/ConfirmationDialogFragment.kt +++ b/app/src/main/java/it/ministerodellasalute/immuni/ui/dialog/ConfirmationDialogFragment.kt @@ -44,9 +44,17 @@ class ConfirmationDialogFragment : DialogFragment() { .setCancelable(args.getBoolean(ARG_CANCELABLE)) .setMessage(args.getString(ARG_MESSAGE)) .setPositiveButton(args.getString(ARG_POSITIVE_BUTTON)) { _, _ -> - listener.onDialogPositive( - targetRequestCode - ) + if (args.getString(ARG_ARGUMENT) != null) { + listener.onDialogPositive( + targetRequestCode, + args.getString(ARG_ARGUMENT) + ) + } else { + listener.onDialogPositive( + targetRequestCode + ) + } + } .setNegativeButton(args.getString(ARG_NEGATIVE_BUTTON)) { _, _ -> listener.onDialogNegative( @@ -64,6 +72,7 @@ class ConfirmationDialogFragment : DialogFragment() { private const val ARG_CANCELABLE = "ARG_CANCELABLE" private const val ARG_MESSAGE = "ARG_MESSAGE" private const val ARG_REQUEST_CODE = "ARG_REQUEST_CODE" + private const val ARG_ARGUMENT = "ARG_ARGUMENT" fun createInstance( positiveButton: String, @@ -71,7 +80,8 @@ class ConfirmationDialogFragment : DialogFragment() { message: String? = null, title: String, cancelable: Boolean, - requestCode: Int + requestCode: Int, + argument: String? = null ): ConfirmationDialogFragment { return ConfirmationDialogFragment().apply { arguments = bundleOf( @@ -80,7 +90,8 @@ class ConfirmationDialogFragment : DialogFragment() { ARG_MESSAGE to message, ARG_TITLE to title, ARG_CANCELABLE to cancelable, - ARG_REQUEST_CODE to requestCode + ARG_REQUEST_CODE to requestCode, + ARG_ARGUMENT to argument ) } } @@ -88,7 +99,7 @@ class ConfirmationDialogFragment : DialogFragment() { } interface ConfirmationDialogListener { - fun onDialogPositive(requestCode: Int) + fun onDialogPositive(requestCode: Int, argument: String? = null) fun onDialogNegative(requestCode: Int) } @@ -103,7 +114,8 @@ fun T.openConfirmationDialog( message: String? = null, title: String, cancelable: Boolean = true, - requestCode: Int + requestCode: Int, + argument: String? = null ) where T : Fragment, T : ConfirmationDialogListener { val fragment = ConfirmationDialogFragment.createInstance( positiveButton, @@ -111,7 +123,8 @@ fun T.openConfirmationDialog( message, title, cancelable, - requestCode + requestCode, + argument ) fragment.setTargetFragment(this, requestCode) fragment.show(parentFragmentManager, "CONFIRMATION_DIALOG_$requestCode") diff --git a/app/src/main/java/it/ministerodellasalute/immuni/ui/greencertificate/GenerateGreenCertificate.kt b/app/src/main/java/it/ministerodellasalute/immuni/ui/greencertificate/GenerateGreenCertificate.kt index 5072fbd84..bd71490a5 100644 --- a/app/src/main/java/it/ministerodellasalute/immuni/ui/greencertificate/GenerateGreenCertificate.kt +++ b/app/src/main/java/it/ministerodellasalute/immuni/ui/greencertificate/GenerateGreenCertificate.kt @@ -28,6 +28,7 @@ import android.view.MotionEvent import android.view.View import android.widget.AdapterView import android.widget.ArrayAdapter +import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import androidx.lifecycle.observe import androidx.navigation.fragment.findNavController @@ -37,6 +38,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder import it.ministerodellasalute.immuni.GreenCertificateDirections import it.ministerodellasalute.immuni.R import it.ministerodellasalute.immuni.extensions.activity.loading +import it.ministerodellasalute.immuni.extensions.activity.setLightStatusBar import it.ministerodellasalute.immuni.logic.user.UserManager import it.ministerodellasalute.immuni.ui.dialog.ConfirmationDialogListener import it.ministerodellasalute.immuni.util.ProgressDialogFragment @@ -70,7 +72,12 @@ class GenerateGreenCertificate : Fragment(R.layout.generate_green_certificate), override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - + (activity as? AppCompatActivity)?.setLightStatusBar( + resources.getColor( + R.color.background_darker, + null + ) + ) viewModel = getViewModel() userManager = get() @@ -319,7 +326,7 @@ class GenerateGreenCertificate : Fragment(R.layout.generate_green_certificate), // Do nothing, user does not want to exit } - override fun onDialogPositive(requestCode: Int) { + override fun onDialogPositive(requestCode: Int, argument: String?) { if (requestCode == ALERT_CONFIRM_SAVE) { expiredDateHealthIDDateInput.text?.clear() if (!expiredDateHealthIDDateInput.isEnabled) { diff --git a/app/src/main/java/it/ministerodellasalute/immuni/ui/greencertificate/GreenCertificateFragment.kt b/app/src/main/java/it/ministerodellasalute/immuni/ui/greencertificate/GreenCertificateFragment.kt index 507c8b023..aec987417 100644 --- a/app/src/main/java/it/ministerodellasalute/immuni/ui/greencertificate/GreenCertificateFragment.kt +++ b/app/src/main/java/it/ministerodellasalute/immuni/ui/greencertificate/GreenCertificateFragment.kt @@ -28,23 +28,24 @@ import androidx.core.content.ContextCompat import androidx.core.view.get import androidx.fragment.app.Fragment import androidx.navigation.fragment.findNavController +import androidx.navigation.fragment.navArgs import androidx.recyclerview.widget.RecyclerView import androidx.viewpager2.widget.ViewPager2 import com.google.android.material.appbar.AppBarLayout import com.google.android.material.tabs.TabLayoutMediator -import it.ministerodellasalute.immuni.GreenCertificateDirections import it.ministerodellasalute.immuni.R import it.ministerodellasalute.immuni.extensions.activity.setLightStatusBar import it.ministerodellasalute.immuni.logic.user.UserManager +import it.ministerodellasalute.immuni.logic.user.models.GreenCertificateUser import it.ministerodellasalute.immuni.logic.user.models.User import it.ministerodellasalute.immuni.ui.dialog.ConfirmationDialogListener import it.ministerodellasalute.immuni.ui.dialog.openConfirmationDialog import it.ministerodellasalute.immuni.util.ImageUtils -import kotlin.math.abs import kotlinx.android.synthetic.main.green_certificate.* import kotlinx.android.synthetic.main.green_certificate_tab.* import org.koin.android.ext.android.get import org.koin.androidx.viewmodel.ext.android.getViewModel +import kotlin.math.abs class GreenCertificateFragment : Fragment(R.layout.green_certificate), ConfirmationDialogListener { @@ -62,6 +63,9 @@ class GreenCertificateFragment : Fragment(R.layout.green_certificate), Confirmat const val DELETE_QR = 200 const val GO_TO_SETTINGS = 201 const val INFORMATION_ORDER = 202 + const val REPLACE_DGC = 203 + const val ALERT_ADD = 204 + const val ALERT_REMOVE = 205 } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -72,6 +76,7 @@ class GreenCertificateFragment : Fragment(R.layout.green_certificate), Confirmat null ) ) + val argument = navArgs() userManager = get() viewModel = getViewModel() @@ -93,14 +98,21 @@ class GreenCertificateFragment : Fragment(R.layout.green_certificate), Confirmat override fun onPageSelected(position: Int) { super.onPageSelected(position) - val currentView = (viewpager[0] as RecyclerView).layoutManager?.findViewByPosition(position) + val currentView = + (viewpager[0] as RecyclerView).layoutManager?.findViewByPosition(position) currentView?.post { - val wMeasureSpec = View.MeasureSpec.makeMeasureSpec(currentView.width, View.MeasureSpec.EXACTLY) - val hMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED) + val wMeasureSpec = View.MeasureSpec.makeMeasureSpec( + currentView.width, + View.MeasureSpec.EXACTLY + ) + val hMeasureSpec = + View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED) currentView.measure(wMeasureSpec, hMeasureSpec) if (viewpager.layoutParams.height != currentView.measuredHeight) { - viewpager.layoutParams = (viewpager.layoutParams).also { lp -> lp.height = currentView.measuredHeight } + viewpager.layoutParams = (viewpager.layoutParams).also { lp -> + lp.height = currentView.measuredHeight + } } } } @@ -109,7 +121,8 @@ class GreenCertificateFragment : Fragment(R.layout.green_certificate), Confirmat greenPassAdapter = GreenPassAdapter( context = requireContext(), fragment = this@GreenCertificateFragment, - viewModel = viewModel + viewModel = viewModel, + userManager = userManager ) greenPassAdapter.data = userManager.user.value?.greenPass!!.asReversed() @@ -121,6 +134,19 @@ class GreenCertificateFragment : Fragment(R.layout.green_certificate), Confirmat registerOnPageChangeCallback(pageChangeCallback) } + if (arguments?.containsKey("greenCertificateSelected") == true) { + if (viewpager != null) { + viewpager.post { + viewpager.setCurrentItem( + findCurrentItemFromUid(uid = argument.value.greenCertificateSelected), + true + ) + arguments!!.remove("greenCertificateSelected") + } + } + } + + TabLayoutMediator(tabLayoutDot, viewpager) { tab, position -> // Some implementation }.attach() @@ -128,19 +154,16 @@ class GreenCertificateFragment : Fragment(R.layout.green_certificate), Confirmat navigationIcon.setOnClickListener { findNavController().popBackStack() } - - getDGCButton.setOnClickListener { - val action = GreenCertificateDirections.actionGenerateGC() - findNavController().navigate(action) - } - setVisibilityLayout() informationOrder() } - override fun onDialogPositive(requestCode: Int) { + override fun onDialogPositive(requestCode: Int, argument: String?) { when (requestCode) { DELETE_QR -> { val user = userManager.user + if (user.value?.greenPass!!.asReversed()[positionToDelete!!].addedHomeDgc) { + userManager.setShowDGCHome(show = false) + } user.value?.greenPass!!.asReversed().removeAt(positionToDelete!!) userManager.save( User( @@ -150,9 +173,13 @@ class GreenCertificateFragment : Fragment(R.layout.green_certificate), Confirmat ) ) greenPassAdapter.notifyItemRemoved(positionToDelete!!) - greenPassAdapter.notifyItemRangeChanged(positionToDelete!!, greenPassAdapter.itemCount) - setVisibilityLayout() + greenPassAdapter.notifyItemRangeChanged( + positionToDelete!!, + greenPassAdapter.itemCount + ) positionToDelete = null + if (user.value?.greenPass!!.isEmpty()) + findNavController().popBackStack() } INFORMATION_ORDER -> { userManager.setShowModalDGC(show = false) @@ -164,6 +191,48 @@ class GreenCertificateFragment : Fragment(R.layout.green_certificate), Confirmat intent.data = uri startActivity(intent) } + ALERT_ADD -> { + val user = userManager.user + val listDgcUpdated = + editDGC(uid = argument!!, removeCurrent = false, removeOther = false) + userManager.setShowDGCHome(show = true) + userManager.save( + User( + region = user.value?.region!!, + province = user.value?.province!!, + greenPass = listDgcUpdated + ) + ) + greenPassAdapter.notifyDataSetChanged() + } + ALERT_REMOVE -> { + val user = userManager.user + val listDgcUpdated = + editDGC(uid = argument!!, removeCurrent = true, removeOther = false) + userManager.setShowDGCHome(show = false) + userManager.save( + User( + region = user.value?.region!!, + province = user.value?.province!!, + greenPass = listDgcUpdated + ) + ) + greenPassAdapter.notifyDataSetChanged() + } + REPLACE_DGC -> { + val user = userManager.user + val listDgcUpdated = + editDGC(uid = argument!!, removeCurrent = false, removeOther = true) + userManager.setShowDGCHome(show = true) + userManager.save( + User( + region = user.value?.region!!, + province = user.value?.province!!, + greenPass = listDgcUpdated + ) + ) + greenPassAdapter.notifyDataSetChanged() + } } } @@ -184,16 +253,6 @@ class GreenCertificateFragment : Fragment(R.layout.green_certificate), Confirmat } } - private fun setVisibilityLayout() { - if (userManager.user.value?.greenPass!!.isEmpty()) { - noQrCodeLayout.visibility = View.VISIBLE - qrCodeLayout.visibility = View.GONE - } else { - noQrCodeLayout.visibility = View.GONE - qrCodeLayout.visibility = View.VISIBLE - } - } - fun checkPermission(greenPassBase64: String, filename: String) { if (ContextCompat.checkSelfPermission( requireContext(), @@ -241,4 +300,106 @@ class GreenCertificateFragment : Fragment(R.layout.green_certificate), Confirmat ) } } + + private fun findCurrentItemFromUid(uid: String?): Int { + if (uid.isNullOrBlank()) { + return 0 + } + var i = 0; + var indexSelected = 0 + loop@ for (greenPass in userManager.user.value?.greenPass!!.asReversed()) { + when (true) { + greenPass.data?.vaccinations != null -> { + if (uid === greenPass.data?.vaccinations?.get(0)?.certificateIdentifier) { + indexSelected = i + break@loop + } + i++ + } + greenPass.data?.tests != null -> { + if (uid === greenPass.data?.tests?.get(0)?.certificateIdentifier) { + indexSelected = i + break@loop + } + i++ + } + greenPass.data?.recoveryStatements != null -> { + if (uid === greenPass.data?.recoveryStatements?.get(0)?.certificateIdentifier) { + indexSelected = i + break@loop + } + i++ + } + greenPass.data?.exemptions != null -> { + if (uid === greenPass.data?.exemptions?.get(0)?.certificateIdentifier) { + indexSelected = i + break@loop + } + i++ + } + } + } + return indexSelected + } + + private fun editDGC( + uid: String, + removeCurrent: Boolean, + removeOther: Boolean + ): MutableList { + val listDGC = userManager.user.value?.greenPass!! + loop@ for (greenPass in listDGC) { + when (true) { + greenPass.data?.vaccinations != null -> { + if (uid === greenPass.data?.vaccinations?.get(0)?.certificateIdentifier) { + greenPass.addedHomeDgc = !removeCurrent + if (!removeOther) { + break@loop + } + } else { + if (removeOther) { + greenPass.addedHomeDgc = false + } + } + } + greenPass.data?.tests != null -> { + if (uid === greenPass.data?.tests?.get(0)?.certificateIdentifier) { + greenPass.addedHomeDgc = !removeCurrent + if (!removeOther) { + break@loop + } + } else { + if (removeOther) { + greenPass.addedHomeDgc = false + } + } + } + greenPass.data?.recoveryStatements != null -> { + if (uid === greenPass.data?.recoveryStatements?.get(0)?.certificateIdentifier) { + greenPass.addedHomeDgc = !removeCurrent + if (!removeOther) { + break@loop + } + } else { + if (removeOther) { + greenPass.addedHomeDgc = false + } + } + } + greenPass.data?.exemptions != null -> { + if (uid === greenPass.data?.exemptions?.get(0)?.certificateIdentifier) { + greenPass.addedHomeDgc = !removeCurrent + if (!removeOther) { + break@loop + } + } else { + if (removeOther) { + greenPass.addedHomeDgc = false + } + } + } + } + } + return listDGC + } } diff --git a/app/src/main/java/it/ministerodellasalute/immuni/ui/greencertificate/GreenPassAdapter.kt b/app/src/main/java/it/ministerodellasalute/immuni/ui/greencertificate/GreenPassAdapter.kt index 792a8be3b..927c63328 100644 --- a/app/src/main/java/it/ministerodellasalute/immuni/ui/greencertificate/GreenPassAdapter.kt +++ b/app/src/main/java/it/ministerodellasalute/immuni/ui/greencertificate/GreenPassAdapter.kt @@ -24,19 +24,23 @@ import android.widget.Button import android.widget.ImageView import android.widget.LinearLayout import android.widget.TextView +import androidx.core.content.ContextCompat import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.RecyclerView -import it.ministerodellasalute.immuni.GreenCertificateDirections +import com.google.android.material.button.MaterialButton import it.ministerodellasalute.immuni.R import it.ministerodellasalute.immuni.extensions.view.setSafeOnClickListener +import it.ministerodellasalute.immuni.logic.user.UserManager import it.ministerodellasalute.immuni.logic.user.models.GreenCertificateUser +import it.ministerodellasalute.immuni.ui.certificate.CertificateDGCFragmentDirections import it.ministerodellasalute.immuni.ui.dialog.openConfirmationDialog import it.ministerodellasalute.immuni.util.ImageUtils class GreenPassAdapter( val context: Context, val fragment: GreenCertificateFragment, - val viewModel: GreenCertificateViewModel + val viewModel: GreenCertificateViewModel, + val userManager: UserManager ) : RecyclerView.Adapter() { @@ -51,6 +55,7 @@ class GreenPassAdapter( val qrCode: ImageView = v.findViewById(R.id.qrCode) val downloadButton: Button = v.findViewById(R.id.downloadButton) val deleteButton: Button = v.findViewById(R.id.deleteButton) + val addRemoveHomeButton: MaterialButton = v.findViewById(R.id.addRemoveHomeButton) val surnameNameText: TextView = v.findViewById(R.id.surnameNameText) val birthDateText: TextView = v.findViewById(R.id.birthDateText) @@ -104,7 +109,7 @@ class GreenPassAdapter( holder.moreDetails.setSafeOnClickListener { val action = - GreenCertificateDirections.actionMoreDetailsGreenCertificateDialog(data[position]) + CertificateDGCFragmentDirections.actionMoreDetailsGreenCertificateDialog(data[position]) fragment.findNavController().navigate(action) } @@ -123,5 +128,79 @@ class GreenPassAdapter( requestCode = GreenCertificateFragment.DELETE_QR ) } + + if (data[position].addedHomeDgc) { + holder.addRemoveHomeButton.icon = ContextCompat.getDrawable(context, R.drawable.ic_icon_pin) + holder.addRemoveHomeButton.text = context.getString(R.string.green_certificate_button_remove_home) + } else { + holder.addRemoveHomeButton.icon = ContextCompat.getDrawable(context, R.drawable.ic_icon_pin_empty) + holder.addRemoveHomeButton.text = context.getString(R.string.green_certificate_button_add_home) + } + + holder.addRemoveHomeButton.setSafeOnClickListener { + if (userManager.showDGCHome.value == null || userManager.showDGCHome.value == false) { + openDialogAddRemoveHome( + positiveButton = context.getString(R.string.green_certificate_added_home_dialog_confirm), + negativeButton = null, + message = context.getString(R.string.green_certificate_added_home_dialog_message), + title = context.getString(R.string.green_certificate_added_home_dialog_title), + requestCode = GreenCertificateFragment.ALERT_ADD, + greenCertificateUser = data[position] + ) + } else { + if (data[position].addedHomeDgc) { + openDialogAddRemoveHome( + positiveButton = context.getString(R.string.green_certificate_removed_home_dialog_confirm), + negativeButton = null, + message = context.getString(R.string.green_certificate_removed_home_dialog_message), + title = context.getString(R.string.green_certificate_removed_home_dialog_title), + requestCode = GreenCertificateFragment.ALERT_REMOVE, + greenCertificateUser = data[position] + ) + } else { + openDialogAddRemoveHome( + positiveButton = context.getString(R.string.green_certificate_replace_home_dialog_confirm), + negativeButton = context.getString(R.string.green_certificate_replace_home_dialog_cancel), + message = context.getString(R.string.green_certificate_replace_home_dialog_message), + title = context.getString(R.string.green_certificate_replace_home_dialog_title), + requestCode = GreenCertificateFragment.REPLACE_DGC, + greenCertificateUser = data[position] + ) + } + } + } + } + + private fun openDialogAddRemoveHome( + title: String, + message: String, + positiveButton: String, + negativeButton: String?, + requestCode: Int, + greenCertificateUser: GreenCertificateUser + ) { + val uid = when (true) { + greenCertificateUser.data?.recoveryStatements != null -> { + greenCertificateUser.data?.recoveryStatements?.get(0)?.certificateIdentifier + } + greenCertificateUser.data?.tests != null -> { + greenCertificateUser.data?.tests?.get(0)?.certificateIdentifier + } + greenCertificateUser.data?.vaccinations != null -> { + greenCertificateUser.data?.vaccinations?.get(0)?.certificateIdentifier + } + greenCertificateUser.data?.exemptions != null -> { + greenCertificateUser.data?.exemptions?.get(0)?.certificateIdentifier + } + else -> null + } + fragment.openConfirmationDialog( + positiveButton = positiveButton, + negativeButton = negativeButton, + message = message, + title = title, + requestCode = requestCode, + argument = uid + ) } } diff --git a/app/src/main/java/it/ministerodellasalute/immuni/ui/home/HomeFragment.kt b/app/src/main/java/it/ministerodellasalute/immuni/ui/home/HomeFragment.kt index a04bf0ebd..5f37aae1f 100644 --- a/app/src/main/java/it/ministerodellasalute/immuni/ui/home/HomeFragment.kt +++ b/app/src/main/java/it/ministerodellasalute/immuni/ui/home/HomeFragment.kt @@ -25,6 +25,7 @@ import androidx.annotation.IdRes import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import androidx.lifecycle.Observer +import androidx.lifecycle.asLiveData import androidx.navigation.fragment.findNavController import it.ministerodellasalute.immuni.R import it.ministerodellasalute.immuni.extensions.activity.setDarkStatusBarFullscreen @@ -35,8 +36,10 @@ import it.ministerodellasalute.immuni.extensions.view.setSafeOnClickListener import it.ministerodellasalute.immuni.extensions.view.visible import it.ministerodellasalute.immuni.logic.exposure.models.ExposureStatus import it.ministerodellasalute.immuni.logic.settings.ConfigurationSettingsManager +import it.ministerodellasalute.immuni.logic.user.UserManager import it.ministerodellasalute.immuni.ui.main.MainViewModel import kotlinx.android.synthetic.main.home_fragment.* +import org.koin.android.ext.android.get import org.koin.android.ext.android.inject import org.koin.androidx.viewmodel.ext.android.getSharedViewModel @@ -44,6 +47,7 @@ class HomeFragment : Fragment(), HomeClickListener { private lateinit var viewModel: MainViewModel + private lateinit var userManager: UserManager // this value varies depending on device models // so will be overridden later @@ -55,6 +59,7 @@ class HomeFragment : Fragment(), savedInstanceState: Bundle? ): View? { viewModel = getSharedViewModel() + userManager = get() return inflater.inflate(R.layout.home_fragment, container, false) } @@ -78,7 +83,8 @@ class HomeFragment : Fragment(), adapter = HomeListAdapter( requireContext(), this@HomeFragment, - settingsManager + settingsManager, + userManager ) } @@ -109,6 +115,12 @@ class HomeFragment : Fragment(), } } + userManager.showDGCHome.asLiveData().observe(viewLifecycleOwner, Observer { + (homeList.adapter as? HomeListAdapter)?.apply { + viewModel.updateHomeListModel(it) + } + }) + viewModel.homeListModel.observe(viewLifecycleOwner, Observer { newList -> (homeList.adapter as? HomeListAdapter)?.apply { update(newList) @@ -247,6 +259,9 @@ class HomeFragment : Fragment(), GreenPassCard -> { openGreenPass() } + CertificateCard -> { + openCertificate() + } is DisableExposureApi -> { openDisableExposureApi() } @@ -292,4 +307,8 @@ class HomeFragment : Fragment(), val action = HomeFragmentDirections.actionGreenCertificateNav() findNavController().navigate(action) } + + private fun openCertificate() { + + } } diff --git a/app/src/main/java/it/ministerodellasalute/immuni/ui/home/HomeListAdapter.kt b/app/src/main/java/it/ministerodellasalute/immuni/ui/home/HomeListAdapter.kt index 1222a59ba..8399c386b 100644 --- a/app/src/main/java/it/ministerodellasalute/immuni/ui/home/HomeListAdapter.kt +++ b/app/src/main/java/it/ministerodellasalute/immuni/ui/home/HomeListAdapter.kt @@ -15,11 +15,13 @@ package it.ministerodellasalute.immuni.ui.home +import android.annotation.SuppressLint import android.content.Context import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Button +import android.widget.ImageView import android.widget.TextView import androidx.annotation.IdRes import androidx.recyclerview.widget.DiffUtil @@ -30,12 +32,16 @@ import it.ministerodellasalute.immuni.extensions.utils.color import it.ministerodellasalute.immuni.extensions.view.* import it.ministerodellasalute.immuni.logic.exposure.models.ExposureStatus import it.ministerodellasalute.immuni.logic.settings.ConfigurationSettingsManager +import it.ministerodellasalute.immuni.logic.user.UserManager +import it.ministerodellasalute.immuni.logic.user.models.GreenCertificateUser +import it.ministerodellasalute.immuni.util.ImageUtils import kotlin.reflect.full.primaryConstructor class HomeListAdapter( val context: Context, private val clickListener: HomeClickListener, - val settingsManager: ConfigurationSettingsManager + val settingsManager: ConfigurationSettingsManager, + val userManager: UserManager ) : RecyclerView.Adapter() { @@ -91,6 +97,11 @@ class HomeListAdapter( inner class GreenPassVH(v: View) : RecyclerView.ViewHolder(v) + inner class CertificateVH(v: View) : RecyclerView.ViewHolder(v) { + val person: TextView = v.findViewById(R.id.person) + val qrCodeHome: ImageView = v.findViewById(R.id.qrCodeHome) + } + inner class DisableExposureApiVH(v: View) : RecyclerView.ViewHolder(v) { val disableExposureApi: Button = v.findViewById(R.id.disableExposureApi) @@ -113,12 +124,13 @@ class HomeListAdapter( val (layout, cardType) = when (viewType) { 0 -> Pair(R.layout.home_protection_state_card, ProtectionCardVH::class) 1 -> Pair(R.layout.home_section_header_item, SectionHeaderVH::class) - 2 -> Pair(R.layout.home_green_certificate_card, GreenPassVH::class) - 3 -> Pair(R.layout.home_report_positivity_card, ReportPositivityVH::class) - 4 -> Pair(R.layout.home_countries_of_interest, CountriesOfInterestVH::class) - 5 -> Pair(R.layout.home_information_how_app_works_card, InformationHowAppWorksVH::class) - 6 -> Pair(R.layout.home_information_self_care_card, InformationSelfCareVH::class) - 7 -> Pair(R.layout.home_disable_exposure_api, DisableExposureApiVH::class) + 2 -> Pair(R.layout.home_certificate_card, CertificateVH::class) + 3 -> Pair(R.layout.home_green_certificate_card, GreenPassVH::class) + 4 -> Pair(R.layout.home_report_positivity_card, ReportPositivityVH::class) + 5 -> Pair(R.layout.home_countries_of_interest, CountriesOfInterestVH::class) + 6 -> Pair(R.layout.home_information_how_app_works_card, InformationHowAppWorksVH::class) + 7 -> Pair(R.layout.home_information_self_care_card, InformationSelfCareVH::class) + 8 -> Pair(R.layout.home_disable_exposure_api, DisableExposureApiVH::class) else -> error("Unhandled viewType $viewType") } @@ -129,6 +141,7 @@ class HomeListAdapter( override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {} + @SuppressLint("SetTextI18n") override fun onBindViewHolder( holder: RecyclerView.ViewHolder, position: Int, @@ -202,6 +215,13 @@ class HomeListAdapter( holder.disableExposureApi.isEnabled = (items[position] as DisableExposureApi).isEnabled } + is CertificateVH -> { + val listGreenCertificateHome = getCertificateHome() + if (listGreenCertificateHome.isNotEmpty()) { + holder.person.text = "${listGreenCertificateHome[0].data?.person?.givenName} ${listGreenCertificateHome[0].data?.person?.familyName}" + holder.qrCodeHome.setImageBitmap(ImageUtils.convert(listGreenCertificateHome[0].base64)) + } + } } } @@ -209,16 +229,21 @@ class HomeListAdapter( return when (items[position]) { is ProtectionCard -> 0 is SectionHeader -> 1 - is GreenPassCard -> 2 - is ReportPositivityCard -> 3 - is CountriesOfInterestCard -> 4 - is HowItWorksCard -> 5 - is SelfCareCard -> 6 - is DisableExposureApi -> 7 + is CertificateCard -> 2 + is GreenPassCard -> 3 + is ReportPositivityCard -> 4 + is CountriesOfInterestCard -> 5 + is HowItWorksCard -> 6 + is SelfCareCard -> 7 + is DisableExposureApi -> 8 } } override fun getItemCount(): Int = items.size + + private fun getCertificateHome(): List { + return userManager.user.value?.greenPass!!.filter { greenCertificateUser -> greenCertificateUser.addedHomeDgc} + } } interface HomeClickListener { diff --git a/app/src/main/java/it/ministerodellasalute/immuni/ui/home/HomeModels.kt b/app/src/main/java/it/ministerodellasalute/immuni/ui/home/HomeModels.kt index d3aa79051..1045c7fdf 100644 --- a/app/src/main/java/it/ministerodellasalute/immuni/ui/home/HomeModels.kt +++ b/app/src/main/java/it/ministerodellasalute/immuni/ui/home/HomeModels.kt @@ -39,5 +39,6 @@ object SelfCareCard : InformationCard() object CountriesOfInterestCard : InformationCard() object ReportPositivityCard : InformationCard() object GreenPassCard : InformationCard() +object CertificateCard : InformationCard() data class DisableExposureApi(val isEnabled: Boolean) : HomeItemType() diff --git a/app/src/main/java/it/ministerodellasalute/immuni/ui/main/MainActivity.kt b/app/src/main/java/it/ministerodellasalute/immuni/ui/main/MainActivity.kt index c36f38c43..ddb62e213 100644 --- a/app/src/main/java/it/ministerodellasalute/immuni/ui/main/MainActivity.kt +++ b/app/src/main/java/it/ministerodellasalute/immuni/ui/main/MainActivity.kt @@ -59,11 +59,11 @@ class MainActivity : ImmuniActivity() { private fun setupBottomNavigationBar() { val bottomNavigationView = findViewById(R.id.bottom_nav) - val navGraphIds = listOf(R.navigation.home, R.navigation.settings) - val menuItemsIds = listOf(R.id.home_nav, R.id.settings_nav) + val navGraphIds = listOf(R.navigation.home, R.navigation.certificate_dgc, R.navigation.settings) + val menuItemsIds = listOf(R.id.home_nav, R.id.certificate_nav, R.id.settings_nav) val defaultIconsIds = - listOf(R.drawable.ic_home_unselected, R.drawable.ic_settings_unselected) - val selectedIconsIds = listOf(R.drawable.ic_home_selected, R.drawable.ic_settings_selected) + listOf(R.drawable.ic_home_unselected, R.drawable.ic_certificates_unselected, R.drawable.ic_settings_unselected) + val selectedIconsIds = listOf(R.drawable.ic_home_selected, R.drawable.ic_certificates_selected, R.drawable.ic_settings_selected) // Setup the bottom navigation view with a list of navigation graphs val controller = bottomNavigationView.setupWithNavController( diff --git a/app/src/main/java/it/ministerodellasalute/immuni/ui/main/MainViewModel.kt b/app/src/main/java/it/ministerodellasalute/immuni/ui/main/MainViewModel.kt index 2fe8c3b19..b24f75829 100644 --- a/app/src/main/java/it/ministerodellasalute/immuni/ui/main/MainViewModel.kt +++ b/app/src/main/java/it/ministerodellasalute/immuni/ui/main/MainViewModel.kt @@ -17,6 +17,7 @@ package it.ministerodellasalute.immuni.ui.main import android.content.Context import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.Observer import androidx.lifecycle.ViewModel import androidx.lifecycle.asLiveData import androidx.lifecycle.viewModelScope @@ -24,6 +25,8 @@ import it.ministerodellasalute.immuni.R import it.ministerodellasalute.immuni.extensions.lifecycle.AppLifecycleObserver import it.ministerodellasalute.immuni.extensions.notifications.PushNotificationManager import it.ministerodellasalute.immuni.logic.exposure.ExposureManager +import it.ministerodellasalute.immuni.logic.user.UserManager +import it.ministerodellasalute.immuni.logic.user.models.GreenCertificateUser import it.ministerodellasalute.immuni.ui.home.* import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.filter @@ -34,7 +37,8 @@ class MainViewModel( private val context: Context, private val pushNotificationManager: PushNotificationManager, private val exposureManager: ExposureManager, - appLifecycleObserver: AppLifecycleObserver + appLifecycleObserver: AppLifecycleObserver, + private val userManager: UserManager ) : ViewModel() { val homeListModel = MutableLiveData>(listOf()) @@ -61,6 +65,12 @@ class MainViewModel( protectionActive?.let { items.add(ProtectionCard(it, exposureManager.exposureStatus.value)) } + userManager.showDGCHome.value.let { + if (it == true) { + items.add(SectionHeader(context.getString(R.string.home_your_eu_dgc))) + items.add(CertificateCard) + } + } items.add(SectionHeader(context.getString(R.string.home_what_do_you_want_today))) items.add(GreenPassCard) items.add(ReportPositivityCard) @@ -71,4 +81,24 @@ class MainViewModel( items.add(DisableExposureApi(protectionActive ?: false)) return items } + + fun updateHomeListModel(addedHomeDGC: Boolean?) { + if (homeListModel.value!!.isEmpty()) return + val homeItems = homeListModel.value!!.toMutableList() + val indexTitleCertificate = homeItems.indexOf(SectionHeader(context.getString(R.string.home_your_eu_dgc))) + if (addedHomeDGC !== null && addedHomeDGC) { + if (indexTitleCertificate == -1) { + val indexTitle = homeItems.indexOf(SectionHeader(context.getString(R.string.home_what_do_you_want_today))) + homeItems.add(indexTitle, SectionHeader(context.getString(R.string.home_your_eu_dgc))) + homeItems.add(indexTitle + 1, CertificateCard) + homeListModel.postValue(homeItems) + } + } else { + if (indexTitleCertificate != -1) { + homeItems.remove(SectionHeader(context.getString(R.string.home_your_eu_dgc))) + homeItems.remove(CertificateCard) + homeListModel.postValue(homeItems) + } + } + } } diff --git a/app/src/main/java/it/ministerodellasalute/immuni/ui/onboarding/fragments/viewpager/ExposureNotificationFragment.kt b/app/src/main/java/it/ministerodellasalute/immuni/ui/onboarding/fragments/viewpager/ExposureNotificationFragment.kt index 3bc5823d3..a19c2bb6c 100644 --- a/app/src/main/java/it/ministerodellasalute/immuni/ui/onboarding/fragments/viewpager/ExposureNotificationFragment.kt +++ b/app/src/main/java/it/ministerodellasalute/immuni/ui/onboarding/fragments/viewpager/ExposureNotificationFragment.kt @@ -92,6 +92,6 @@ class ExposureNotificationFragment : } private fun canProceed(): Boolean { - return viewModel.isBroadcastingActive.value ?: false + return true //viewModel.isBroadcastingActive.value ?: false } } diff --git a/app/src/main/java/it/ministerodellasalute/immuni/ui/onboarding/fragments/viewpager/RegionFragment.kt b/app/src/main/java/it/ministerodellasalute/immuni/ui/onboarding/fragments/viewpager/RegionFragment.kt index a1a2b57e8..aa2040279 100644 --- a/app/src/main/java/it/ministerodellasalute/immuni/ui/onboarding/fragments/viewpager/RegionFragment.kt +++ b/app/src/main/java/it/ministerodellasalute/immuni/ui/onboarding/fragments/viewpager/RegionFragment.kt @@ -107,7 +107,7 @@ class RegionFragment : viewModel.onRegionSelected(item) } - override fun onDialogPositive(requestCode: Int) { + override fun onDialogPositive(requestCode: Int, argument: String?) { viewModel.onAbroadRegionConfirmed() } diff --git a/app/src/main/java/it/ministerodellasalute/immuni/ui/settings/SettingsFragment.kt b/app/src/main/java/it/ministerodellasalute/immuni/ui/settings/SettingsFragment.kt index e0ac41b26..4a0f89a59 100644 --- a/app/src/main/java/it/ministerodellasalute/immuni/ui/settings/SettingsFragment.kt +++ b/app/src/main/java/it/ministerodellasalute/immuni/ui/settings/SettingsFragment.kt @@ -140,7 +140,7 @@ class SettingsFragment : Fragment(R.layout.settings_fragment), ConfirmationDialo } } - override fun onDialogPositive(requestCode: Int) {} + override fun onDialogPositive(requestCode: Int, argument: String?) {} override fun onDialogNegative(requestCode: Int) {} } diff --git a/app/src/main/java/it/ministerodellasalute/immuni/ui/upload/UploadDataFragment.kt b/app/src/main/java/it/ministerodellasalute/immuni/ui/upload/UploadDataFragment.kt index 2baee273a..9eef522f8 100644 --- a/app/src/main/java/it/ministerodellasalute/immuni/ui/upload/UploadDataFragment.kt +++ b/app/src/main/java/it/ministerodellasalute/immuni/ui/upload/UploadDataFragment.kt @@ -133,7 +133,7 @@ class UploadDataFragment : Fragment(R.layout.upload_data_fragment), Confirmation // Do nothing, user does not want to exit } - override fun onDialogPositive(requestCode: Int) { + override fun onDialogPositive(requestCode: Int, argument: String?) { if (requestCode == ALERT_CONFIRM_EXIT) { activity?.finish() } diff --git a/app/src/main/res/drawable-hdpi/ic_certificates_selected.png b/app/src/main/res/drawable-hdpi/ic_certificates_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..ee90a05b6e314ba617a0f4388b4aa20f3663b8e0 GIT binary patch literal 7163 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_certificates_unselected.png b/app/src/main/res/drawable-mdpi/ic_certificates_unselected.png new file mode 100644 index 0000000000000000000000000000000000000000..c21e8a78451c890f94d1a249894466a6a4e1173a GIT binary patch literal 1494 zcmV;{1u6Q8P)8O7U=)BwM&lF9Z1&J|Zn5WCt7HE&mdgE4uY0Fq`C?tsqLd%U zoZ}ifERY5M2K59Ud`qnS0FM^PY^(xEcnyMJP1t%(ga%yQ*hItm~f?YmX&R zcWhD$4vw14EeCO0Is)UvQr*BP*V4S&{z+F=_ei;|%}Fg6G^w4H03o~;qD!5=gCoA` zUYV$_i!1Oa|F5b&cGc?XSh>L!UWtINa?T&aZ3rB48yZh4JZezO z>FchiHuq5PJ7;5tl~|fqm73nu3xa{CIU&}@uE6IC@a`NRF6DVts$pO(8LXO)fB0dkIO z<{Mtn*+Q)GM(;g}Mmp2Ing1?dLc6aARWN;BmNKvJ` z>mrKr^~Bn2UUUi?gVa*%XT`XAnRQQ%-QCq%>G`NFiB@!)?WLy1CsCZ|Yf+rdmgW_e z?gQJnmgd2y+`1<~4Yh98jNc4SsTf)K*lb|aWjdW9PvM}0fb%Fb_2#<42;Y1JuT^Vi z&C-3@8NPt;Xo4TR0*oErgTJr0?x`&@Jf8pdy6r}rv*Uc4BSulgn+NXOwWci5mpg{> zy(J2Duunm%087DvKPo&OPa)u!ktEkR$D}~5V`7YERPW|ui7f6>3iZa#{c``{ck;lA z@8vBGCzNbWmYLPS+QgXI9Z`Zz6lY^Geqd2H;OJUTWd z$By1osMiKJ9bN4Y#3vbG3h2o*8=T>W3P)(8$-L`D21!lL9G+`;HKnweTf$|Q=CwG1 zqEvwG=n4#wh{n&Q0}O6H`pP%weqJKh9LDpka~!~l$7Yn%lp^@sJLC3uUxJpQ)Y9}i z9u=XCf>cgTj10T|N9qgF;BjT+yfP6Tp>6Le`Gb9@@f|AdO9{~C2)$HXyqqs^f!{2z z6}~&LK9jy~{77mc(04I6oKexf<+&vom!RGaK@>$das!QD0ms<*Zz*_u*i_bD%ocXj ze_xAayP?vj$m72w2yQ^3b4RYCk%ef9zrBfq+;4mTn|BcAw$D7ttR8`j^hx_W zLTCMf*p)JC7Wy)K=lVqdZ9z}nt-#&&etAXf8~DZ+sQGFmhg|y1@^2}(wq~y{<5y~V w651q^k07*qoM6N<$f>TrVtN;K2 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_certificates_selected.png b/app/src/main/res/drawable-xhdpi/ic_certificates_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..c9e021a18a84a39d02fa8debdc76d5853073dd37 GIT binary patch literal 11427 zcmV;UEL_uxP)>d%@&0lLf7< zt?vL?9q)SD@*G5O#ov6-Ddm28JzphU)%i%u+@5)c=fj_U`}}`Hjc=q*atf0XSN>a% zexgMxOa`PvF;M}cUQdNBc!;xGsPOC=sbF$SJd7Ae0KD=CU;r41se;MLse-8~apiHj zKlj{J!GjMV&G7I!Oq>c&qMta4hnb>6lZh}6cfk%Z?t5us4kpuNK}kuQ zrnFStN9`pgqBl43y<0U+ckI-x{`={oB!GMPVJdv!0V*0BllcCHys$iv<+%tVybmC% z!13Ud1xBO2*z5Vhs*v{=TjQbWZT%tXU3)w@z0G5P`M0_||4-Sy_vVX^9iyTTe1P~` zIB8;5QlXf*I{E)-;)4Cmm>0e)>qZA&zoS2fdxh2eN!!9+XCsxa5JBu&3oCN58!nPRMT=-jq{*fkKJKQ+{! zd;P$ueDUBIi9Sjf51>zs(8c}3ba8A@zStj{dnw|&yd&V3i(@e=`s636XkdVf9>N1m zOehRcm~gEKy}OcEnI{!AH_O`b;rZ=@{i!Lw|MLCl;%JgC4kzS`gK_y{A}U`DdgfpE z*sh%F*!S}8)vFgvZGEKa?I4ZMN18}P0D1ZWDx3n45>yMs{2Gydw|T6%@uXSTQ9*Ol zw8m}u`Q6Fr+`kSda;f3|?80y&ol|;p>54wopUMr!(PODxGMc&+3(Spmb;%Xo-J}Tw zNaOL4hFS2Dj|etSOt46~t}1<@S5+2>&U4`R&YYpbpZp8yj~~qLA4#My4J-GW$9?8= z{o(msJT#Y!24-_%-)t`Aoy`T@a|?cFD&?|W`d54B%#Pu9S=YaVw0&Kqak)t2_frwT zEPCWVfC$yHWs9m_R-#t^zl|r)3SLkfI>!jH{pLVy9w4O`hWj)BD;9e7f5bztJ{u3c zruJ{ef@hzN2GIRypAGw8{aP}SzSZlc60CS}dpl`&?GzFg{C+Y-!=E zsvFs=w=2q?#SJ>F@OK`NHDms>H^+l#zsmQCpoe_Fc-HShcmMoZpYxSx-S(e9>$1M` zZNGE&jK_Xu!EL*g^*b;Bw}a!;)guF>#ay&KJ*3^alQazt3L}didWecxSF=c)TA7Kz zG7C*tT>!p9Ih!JZ*WUoUXmlWd(QE&wwmQ?!8e>JP(OB7PtUxct>q^5WqoHDRRi)wP zDwFB%s&IH(XR}cWcZY*?J9bd<_U%->V@Fog)<&8>h?U(#Me6|M$Pp@Hkd%j5azUa| zsqpsOsc?8$VT-1*Q7SST+KPcn09w=3G*wty(pFSi z*{m2vQ)RU^Z4FM#ImvCkOt!vrlEKhgXR}GAyY^DaRvYQUF)EIRNV|RwX$~GE4I4UE zDJ@%Eifgp2N>H z@yJ0sbnj7m?fw%q^U>op`_W@G`;ntGd+!mNz2^|k9y>_0c=*{P`)T&@ewsNlAy1DD zX1+2qknc>yWqo%im0&EL*F&X4{pa=_KbZT|kKIeseaDsYl#cOcP8^{bj5l-ifIM?( zT%J8JBF~Nw$ur4F>a}<{e>fD9oBKReY270k8tU8X9Ofked*6@@E)~7pV~9UGUyrthY7cx(H>?;IZzJAWlmF#!{4wf`P`? zI&9)t~-j2mcCTRV!LkoX%;)tBO=kPUSEse)x9U9BwyBWd)&~O3^8ck6m zJWqr1g*PJp^avKg6tq#*;e%2`$eWj(mdj-Ad0naiBfC4L3RvI@vzhc>H0C2rQ zF(L-1lMDc_d;sbv0v4KkN!Jd;c5p9r@ix-jdMg#3Ju6(B6&-0^p6IFWtG z*G;Ryz=nfk3m?Z=skehC#^Xgfj72#xCdN?M7n{d?<|qaLBmP+mdlsh6cT%&pk80qu ztoFNd3V{9HS?PNXQvHC94Dd${J`Yuddr9vH3qw#J9w+JIFer_UqyamNPM=2XepYp< zRsbM>7}Ql5$gv|_kD|SMC5@q?-4ymszu6y76O755b*A>Zy}PIMMq_*3#E2v*pdAq4 zF_^#m+j;u@XVD+e(dQn^(dkEW_&>ow6}-^_?%C8xBKIj@A2qq0)OcWY;gc96#b6y( zz!zhF>i6>W_~{%y_DGgK^XV*o;^P^-F93{(7`z#R^GreS;`!Y>X^qoLrsFek!GiFtac0o1vhG`@;FI4q6AG8X`ej>#?Q3?=WAPby-t? z*B__VJ}*^y++++|$$)FQ!$xJDJye1yLH9y( z(f9eGzn7yI{w7P``ZgFi!n*5iJvG#y{e7Q>*88lqe*bXpBy?u#(9(FUKUoDl|5rKs zYmD(10PoMgm8K`3Owngf&cmS1EwS$k1>Cp-z(5~ua9e1#J0P!d^v%Rw)=Q7u`Y!jo zopM9KM%69{d{H-5vKYsp2fL$G;_{LX22%^esbLm=;uAs-3U`JhviH!I*(Vk7mmhqP zis0xLwO5nY(k&I&*6!3*RJ0jPwbP|=c*{FFn1R$VK1dQjsM=ZNzV;+Qo6Mu*;a|+s zcb*3W{|q{Bn01%h(|k=0#YA z&(M?KNYj`8Bt;MZ9*jqLmO@}(zbmacebG1GpS@Gd&*;_&3NdWN0RwRCPs28)#cegoK-CNSHZYHeI|pe0Pk~O zn4z@n3`Y+8^OMM%-Mv$Yrwjypq~sNLb=-s zS0+d$$s`ryIkjM=lImjeFo`(3E<(B$w3e1u#g*ZtBbZji84Kt;EmpD^1DEhk5x15j z6so8)QvGm0O^*-3xg8RW;RlWdUZF(%pK1TtzoGw>Mh1UI0q;*0t2r12cHwxVag+W5RKdk0}`cTs3a|XUk!U7 z%g!_@`zR}FOj%BYb2Ne=zKB7D#pU!<@!i`=H{hmHh=|??H^5Xw^~vbM%YrGYlPs7s z+&>GZU7}>{B7nL=1M!T)J_Wpp0v=vx=VPJtgBXtiyk#Js{hhJF+`MXJSWk-hI|X;; zGDQLxp!3kZmnaCm=Y!r8;9Vpb3tZ=a0e0OA@YaHHEl@#C5ZhG{>pDj#)rR~K-!N5n zI;kQaBYki;mHJ?T2NR^d=N=`LQvl=;mZgxRGB&C!YoKh)87NPa2cLHTx){_Y)AHxSGI@%Yf<9J5drJAeT8(!cOvx58i#U|1(Q=E8^IYFUX69@sEGB$(W9hgi{-LXDT{GmFIC0-`F*3w{Bs9J z<(Y{QIWsXV=l2hZJ~k-lM+X-3Bgw`5aQ|X{sDB|p7+>U`27njhf!xWkTfW6(qm3@O z9}u-o@o?@@fOi4k%iw!C@tu4=8O`V8p=>@H$mYYobUx@w=L4=(-s?zZeU1!#y}1{h zy%}r3NgLtDtaW;64fNn@xJM1pgC?Jgs$pr_`WoU1(kI});I$40k^$5lf$P%rBE)u! z$VqZSf$afr$F8U;`?$(BA@8qB?9M1oH7nQS$Ds>7RBXA6N&;Te_dtw$yQnG>TIlW% z=RY+vkoziF_m}8@h5p@CPXx{Kop|7z zz?7R1jckPIt+zPk+v4HO$06QN48$_uPDC@`O@z}g#DeJ;BL4Xo!rr+T0-o6y{jQl8 zJ&u_dJhqvqJdWAN?dFu<*(cu&YrZbzp%$l~nxP9DU1nHeKh;FLsj5Fl2B(`UyaQBr z1V#}Kybf-Qmb2pz9HXKWoPk1r@Px>Y3mjHpg+L#jjzybz+3wy$Wh0bUw-`yWr=sn{H;Y4Z3L)oZ6d0b^z#t6O4$&(LpU9urcCZ*d6xedn4X_U(k~```uYf z(4Dn;of*5=nX-FrX`9cvxFZslH`#5p0SmCf>xKA&eef2V!0J^P(*)nJ+S^G+7>f!J zK_7}hkK0IxxVIQ#oQB1h!&e4x3yeqd1aEk$N!1lMvD1I%%#>n{IX0e1QsJ>`Dyl6* zWU`I4P_{a(bV;Cx^ut(D_*MohK-^kS)%8X)ZK|b)O?S}h9k!umD?#MN+V8XQ)t^_!_G)J>I`Z@Hc0 z-!3YFfhmTL*FwBC55VfSJ}6lC45ANFVR2pHiN>^@oSal#8s6BMNKO?#h`}3;h)mi^ z3rCbQ$R(Y7sm!rQ(yv`3S4N}RJH`ic_aK@$IX;+wWNdih6keYmAILv8I+*_~oaE0A z#dDt>?$3XwKa@+l`m!JNTI7uZL=JF?SZ}TOLHzvQ{M|4fzcZZ3Ju)26JvtQ2KAMbX zPA9{e$Ks*%sc0ZG=yA!Lz^si90B3{vBkI@)KXn7ZTn7WPCS;}6HVdu7BG-Y*HQoEj z=!4&y=qEkAic)~bx=&kIC;YyD{%45m8TR>pg-rB2n_73mKyKLry?91aGBmiMX0V@% z;o|7*R;hGdi?gafbZ-B#gZU?qAI?i3Juas{a*Wa^j!^oZ!<0ULh|)(7Q2OwGN*^4P z(=ar1BLmqV55^b15P<;#TQ>TbeP&u8_tN(9LHTR&Col46VVL;y>G2^sJvJbxVTk7X z!}C85`{(a>c;(F=W}X$ybJKc&xYp}|;b7MVzMr#)>Y-k0!-zZ(kyLW@ z{deF1X*qQThq|b#iT8ihQj_c23wigZ0%(FS#I6mOXWV};6(x3&cGpfg*1M@0!@#M@RgQ@{CB-RtPJ(ijqUHe^5cc!ns+^C9@^L40 z8N_!poMwb_nG|QNxeM@8N;Ja$V3HH4k$Fl)WeG0S&CXtG37Dw`EL;N+n_);+!}2x& zI1{XTjXOj}D~uf66g^_!QakUvzzCk`M%dOzMQj|OdFDFuek*UwX|B;xD&maA9d}9E z21A=^|Hzx?)NJ&zg9}$P(#z?5j**u$(F_K6X4FtTol1tYpXOwO-%d9pMm`0=QVbe{ ztb)g%6%I8=Fr3Dx^BsF>6ByX+wu5;H*}$;Xh;>)NDAdCs)dnnxI>0^{ta6CAVmRD3 zDrUDO>?6&6_fZjh7;41vz5>Xi%w=OIPl`-69BR$ht&-MYXf+)eo0iml5G4f<@IG=h zM_>Fxj=ub*9DV7DEd9ab8M^0)VBazroX?w2Cqk*y0B>`^K{pRXGmikUlmMAox&-vw z0OXA%I&aCe5nR?As)8ir|#JmE|vpyChu8q-!p>{g=kcKnu z%0@ceG~WN_een0WwQ{Oo*{$OZXs#`}^G>O_qJjZjO6f0Uk$ErU3!lr;6ib0clA?xIFdkG#6WCa;31Hh_V32+iCbEFdk|pX>(JXzNWg>(739t!fuwdhwM^ut+CZK zJ|sz;^kgf`{m}j_{mGZJ^z64Y^xvP&&{NN(>1$7>>4_)QO(3z077ZvnY3Yz}{xqE6 zTi`@*js{czr9YgShpVCh%?Sh*G_j@1Muc|;)6B}t1JU`*Sd7aU?-Is4<8{v6Yh^YD zsH(3|s;sTuX{apUTxl}xtZ-PQ;v_^ka3^V-S1GZ5(O3*&TPvcD0%1r*==N)2qu5{< zyYos#sNQ4$;r;Q@YfmI1uYUZ{#I#|=Ea|E%TTLSa)6&F40bMG-BafVMR9tT$$czVE(0KWN~gV zCeIDV<+-7LwJ**o+o~Y}tYVdyK#hmEr}Ghi?q9pR5yE+>s<%fr*?M03ZEMfVPuR^b zKQys_+7Lh--`Ay7XKCOx7jfq(i?dGLIUB#?z2J9m$_9IZ@Q>OHN=r<&vCx|@jSVbj zl94yhu5N6rbJ?eKRaLEZLy2ig_18v|!u7c4p4aIQ|7f1R_{VAb{2v0m$L8qB;nx)K z#10zoUtH$BjI`f1`9c>5RSi)wA{WZKmE{Nyjxf$)o_Wp+Sj( zi}3f=T52vV_?2}cr*K3OHYvrAr6sMVcxZZ>SDh;ps*J654jTZ(H5r?hMB;PVQpO{% z)9~OF4J7|JB@_QbiTD%+y}wujPV8a$oR>JCm-aemA9Fk9+n@v2!;rMVa<({nXnnv= z>)~Lpk08?ET|3u4x@9;npBL6!fY%?My;dFIDxbF?66qhMs>#2lhT+7bD>+UKbC&b#B?Rs+9r^(re^#oF%sn-To@Tx^NXZv4_F^O3G`Sd)Q@>ZwojPRUjgP z57*-CqvjBNJMJDcM6#Dw_jS{Tff$`%vfj#u`Z9RTY+QZv`JQfShErZWG)Sw0?gfdH zt#+=?DsQdx?Up!+pu6WDWg}h7dBE6GRn~(OqTF|CQr*tHPEi&BimFg{H2KJYTH3+N zJq92v4Xt(EJyK~;e7ZgsO@9afpI07g>4BnLX5r)gT2)**{mz>{4BAB{1o$UBVC(!Q{$Oo#_%DH4Wb9iSQj zxH{;`UoCIr`aq7|d!kf2JW4v=qQHV^kHW3-z@Ti{0C8RtWx>Mhj!r~DHw;MOrcIno z6##~O(-NoD!?^Nfx;rF&(o2@h!o^qv;5aO6f>^KStTK$uYMYfdMg!@8!Mzq#@R)VW_nTV`deT3^ zBCLzY$OM12Ddfwa7v*iQOO@-|>fHMzJ^aNo=szVR<6)!HN!pHGN}iJ|WR;Y@NTy!L zj+{Vz@@jD+#K>`5@FxmkCV~GOJL&+_e2Eu3ol*{x@Ldkam*)dU2;>{P4x)jnmvvs0HZmn z;xDE8z9?02Ne7pJI%zoZZYQkAL~8N(6WV607S^aTq0{vPHMP~8v5W|b6yY; zO1aOYY|oaoeTa%9A0%yO9ceJ;Rja&Q8?yoc)s1!Dl{&UmA854-0DaE4rn!K}>wHtH zt=YM*W6yMXzzhIgauqQIVAFZ-l6y3GPW1)3k&ew^Jo{gOQ1H(4@>@vCl z58}C=H-Qk-az>@e2B4ttRzZY0DNx7Z8Q58m@#}3}xFTdTd#K)Ol^ZOavIo$(Cs-;s zLi8KG76w|XZ)$X`w?lNfybY|M-oKw3d_Jn=O?9q|;ncq0L!|?Vk&|JBcd+$r1^xIM&^jjBh z3)|*y4_PvIcx;Pzf>~SOdwt06%6%x}m0Mv9*1@83`h6qsym1!pXFD(3Bd7vaWS`9FbxygCpdBlKP+?o$y#j0|^%Q(Q`U+lRo!y?e#^ z5hf2~AgWYXpa+?OQ&Xb2h*!a7#b6k8Vr1IrcVBu0lfL40Tp_RhvgEbT{m^Tl|3{x= z_8&dA*&ljrb3b%hXV0Mj$cd}lI{$*(n(}!$We>2x%Jnb=>mjBrW-PL6y`0B`uEKk( z;i@RC1N%(QPO9;nl}f5AtC_0Y-Bj)AcSuupbcX0O=#uAFo_Yyq(&PG2(4i>YryNfEJ{43pVxxr{wP0sZ1rF3Y8-?dFTmpnuced*Nw&-=#+& z(%Yez);Itb#HJa{YXa*yceffM30+02Y@J|T51AZb9dueXz%#}yWN`0MEG8F)mv?n3 zNzn={fYD~o+zt>Qc3Lie!(qMj6vPzwzx*`Zqo={TXSh4e7oWoYPdm-?N%XB?F6+{o zpatV2%nQPM;4N93gUaxXC3oLVx_DeEu+;K4=kNY570u7DSO*FQvgNr7AQ-r(ku>cA zD(*IuuA`GmI$d(L*OFT6>`mWdG0)uQv0eFq!#cwc^+8MD?41_J++9}7++A)<<~EN- zRdd{+brwaxRXe~qL>rZky%4Vel>H}3DY%>I_$Hg~7hlD@@ZOE(8BaxH@g z#?^prBnoIh)xRk52M19~20OSwz5i2$G%na;?4h+YY z92###a~xSV>LR_bgA85!JGD95W!A`>h-A9<){@L;K{u~=1#5phrj#?wPw%VJ?F zfpJk7s2UMII|pOBR3G>rMOZYEh2gA(TBXmX9lAlw2VwYO*m5Zk3DJU;HLyr<*(|TF z4@w#nCtkCa#F)i!qIC=+j8Rz-phN7-F+LlGN?uGm zthO=_u0*v#HQ+UXffoVY>Y~c74&}b(UO3WWs3ZrZ3hyiRfohq@=RT)a>0eh?hFREN zP+cu4p&V11cj0&=x~+|hnT41D*GZRwLFEvO3V>z^S*Vg9f`R0f#seFndyGyl>h6Yq z+ewvSd=AcQ1)SM(u!^e$SihBmT_wyiJVY^KQ7u-US+C)uCSE{*sM&*1D*+|n4C82-IzlRB5T8fVWABW{|YYc<&#RvGgy>o;o}Wj z{J$c;Y=Kzp~@e7QTc?c8cN%NsZHUMBsX>cEuHrO_Xo&<0_9)q$pcG00BIPbjWsHegt z`mr%#&@hi8uG{8w#{7A%>tp55EOPILfq|uFaF~%ihp=CXcgusAM-Tpw&x9~=0KXL9 zE2Rk0Nf4xN@Ay6J{|*+*{la9U2WP%9@KBl@0FY-%n8Y zBe*hFRo>iT)by@`GcatNa%Ygas(?Y~Q$?)&p-zguOO~1q5u~Cdx|d4gu;`HvlG<|_AI#G5eu#qk3N8L_v{gAtm~>wy|$^p1f+t<`9a>v=gBjWn5@D8o&>W1 zI;5B@SHX;84@6`8R=l<=x}}({H-CoRgl_0COkVln2^LizlhbC*y5*WYu@}8GlcjmU zxmO;HluQwShe2c}G6=h2r9&TvSO=+?4IR5atS0ynA#|b==knZmJ{+=fI$!qw;j`=+M0IH(qTBg*NeLf*;Z-x%P11fB$2OJ)Is84r^-c{i?GFiC`e zaKf*iKjVjmcqzK(KK|(w{*eijuy{N!myW!<$h>_qS*WXS%7T45}#$*)7v^pS` z@ol2_U|tcg2+`Ob;<@r%)J0_Q6z0QVw&OX)ZzWu}?)&$RX{`RN5`)N-SC2pNVH7s| z3=B_-59II!x%LE%(0~ORuI>lR6j5cLlE1^iE0bRO@f~&N@0YK-0FlL8T}-|*a~K4* z&hP4c_KA6Pz~H#~2}LA4>YF%b~g-JkfqI_SnPXJM12bAKbb2Sp6>pPi^Wv1c)YlmwyF`H-b0? z&z&I}dS~M%8)Os*hiLTmB&)W+a2C>MveNW`#OI z{+qA-H}Cw9;o(fo-Yw$%g~+q1rL^w_Jhh2B9d!%_k##5QMvfd<74V!GAXYUn3VhOv z7g2dnl_E|Oh;tyW+ZT0t#166Z-o=hysyJi)iUR{+K>)gJ%qrL=GVxjXg8 zfv%m0`kOa8ov`W*vN|6%JQKwO;%E7O!)@6@3h{n>SO0JMJ)Yn@0lOaH-r3Z#`6SV` x;`i?T?Q<3F-Hq0N%JzOv^!*(BM*Fq3{|6?6i{Qba9c};s002ovPDHLkV1mpPioXB= literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_certificates_unselected.png b/app/src/main/res/drawable-xhdpi/ic_certificates_unselected.png new file mode 100644 index 0000000000000000000000000000000000000000..23f5ba115cf9e58a55afd352ab3b6e2fe075fb98 GIT binary patch literal 2622 zcmV-E3c>Y>P);1|-+kj54}v7OjSuG84D9Vh8Z%BBMC z5~l&J(`qL)w6J_QNmo_-=olZXx(>Ba$QTT*YsK=><~vQ&WsI%e74LKHn>fe!+D;mL zlj%ItBir|$^SsY_eeOB;o@3v169)$e2L}fS2L}fS2L}fS2L}fS2S?^02s!HnLrykv zlfketDXB~z@n%-zMgdJ|v+-EMqwJMDvl_a}>xcwax@mexg`rEIRxIz`wXalRaT##0lqax%Z?P)e1!|OzeyuMGK|5jY` z)ZNr8_3Mdbe4|qgKTC!_fU&ATWQ=;jUz}p-&l)`IaD|RO>S+8t)m<^;&?3z*I9vz2 zDaIL32$G? zdKDz9uCqN`{VtCcZeP{z38sqU2UYBX)RlPv>~ z`Smnt-%79A6mm8QLUzi;3Wn@;a#^$J<#)K$lsI^gV{tQm+N6XJT8e`|AWxr4=2;hLnIW^ebielpH*Q;e?MO=6M58@{ z$Q1RQ2hnJd67W4bHW^Fsk_Znp1D_-vV=~XWK+6nfHqqTSqSjzyImuTO)r#tMs%c50`&T2%Y^&v27a+LWj21O{c$`g6U}v`! zYCS2ncb$X&h=Ewi61eK2mO#vq80awuV!Q%JM`!4=KELc9c#7&mL(zjaV#LqJYc_$H;n-Oi zw;X%+J})&t^@{ZK1FuMp%_pS5W8I6&q?^~tjABgJhZG2IVu}F(N=sw#n z6|tG_GMhl9K~;fHnYfi;&&SHlmAXO!A$A{FDux0$#+C!2v7o0O4_YqiSDBD#C+P3?G9h*5|5)AmrRqWNo;= zD$sq=9bE~Q6O$f0r!DrTBlP?$KY9W5-c)E0K8tgS<&*MSRZaKB0$cDtVFkAkG6HJ! z28+G<0jDecs;{nh)LYXt6=km~tLPk+9WdJ(_hAW4MQ<}bAMY*O(K_I(>6v8fFEAR% zPca>?@bAsG-~+kjh1FXVz~zVDV=r#_Tv_Ea_c~lH+epf8Zt#<`7`$-CVDYEusUlF21B--%oI%f5)*`MY+#bQVWxp6JH=?_3*y#%WktPs3U3$5TwCFR9e?M_n zXz3gtp}Mb{EkFC(CnAaLez9_Uk_NBQ%spIaZ>q=MRs|x%D&^-{>2Lpt zl6aQNn^-?<4no|1F?(N@ir8+Xd%nR(ZBKqxFvw$F7A2`KL^L1eSj{!}%&P@7LhV@?k6T!k-dTTC+PV9vRI{r` zUe-@YMw-vUpXda#t1(Dkxb>v;ZvVJ6F)=Hzo?O0sMLKr;uL()y2~!>_CYOyH?kt_aD{%9Y7$YB z=oCX^#L?L6F!ALg>)w0flc?rd7r=)o3<;4v=WH@3iQDE1P%?QOyK&W z;->FlgPioP)A^5CvSTg7|CZAIr7*uQtnOJC;1Vfywfu|j_vT7nt#9Kqj;kjyBE9t6 zH>Hu0g%#=X@mcAgZw)0)AoTFl42!*Sha>vawet+$@lwQ4+=O^2bajEP&#(zb+zg`a~H?NM5Ym9Nj$cj!&Q#)V?e>ChJYjvo6pwgPuW8 zB7I~YV^l(;k`WE|RCmo3+L|n+b1NH@h0>#vB{1<<6N#R6ftDFG++qugoA)nzN~EOt-qjNiy|KLEcW2TSh`>8e>m`EnQe^^Q}XKuvpqZDqWfRsP70)^+P}%?Ol)QCECmwM< z{pH-eEjeU588!DjZWPc~i8oJEUVe_~YTjC1*E=5lmA=mV#lph=?}udQQN#Knt4CP8EMu?iW)7 zQt$u9?bn)2`74$@1<-^xV#u+Q#9y`h#VPlH|Ihoia(qE0ZieD>aBy&NaBy&NaBy&N gaBy&NaIA9t50|!p^;wXjSpWb407*qoM6N<$g2UMf8UO$Q literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_certificates_selected.png b/app/src/main/res/drawable-xxhdpi/ic_certificates_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..9f6b16651b54fb7b0db56b1db708e08381d3cb33 GIT binary patch literal 21831 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_certificates_unselected.png b/app/src/main/res/drawable-xxhdpi/ic_certificates_unselected.png new file mode 100644 index 0000000000000000000000000000000000000000..be087a536fe5792f812409090da22afba139730d GIT binary patch literal 4348 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_certificates_selected.png b/app/src/main/res/drawable-xxxhdpi/ic_certificates_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..e0f8cbda9c3d104b55b56cd8de55c50ba71d4381 GIT binary patch literal 18977 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_certificates_unselected.png b/app/src/main/res/drawable-xxxhdpi/ic_certificates_unselected.png new file mode 100644 index 0000000000000000000000000000000000000000..06617064050f5fba83d8c407fcd1a4f4022b0922 GIT binary patch literal 2157 zcma)-2{hZ;9>>#0)nkGwLu)HD$|zMOs49xmP*M~nT2Zt@OTP#s+Bew98cFvqR=biV?+;i@|=l;+C`}^JHdp|eF3wjD9 zuOSZr06=b#lRlFEzO>58O4?jT#32Ac4(xW)(KjJ@kqwJDLuNT#(uKeZ9)erLA%!q$m#U z7k@^0>HMT2AzTzU;!quxoV4MC=I@cD`^zPq5p9(wm}6E`_|&&btcU&lFNj1MK6*br zmPe*p`qy*L<=@$_zp9gsX>xN~-1xQ25Qth*amkM0LXk)38VzKoX3Yhr@k!U_qCL*kXZD1XhiwZ|UVJp2@MWp?&3E@}1_kUG>3;>bnxG* z9$ya_w=lhO4@&=BML^vo(mv5NYYy9j3)*_Lv`pcpE3x$MxTwWQkl)QlD+VTOxL8{Q zLI_#-k+{C$MNr^|5k1Awx#xdcv z{^(JRv&MuZX2YYgU`y|zX{s?(?$zK{qU(F-mP~=yeLW&uu7Il2f zXR=oa(jz{5(4|*lX)~<;IU+-LkAf@K8G`)BqbqWeo{GZ$&9VEEJl=2!xpQl6Og%o$ zW@DD|gyFBW-Ko1VcE({FjS=@HS1yJQm1@o9^2K=34UJ|imUvQ!fE7<j>bKEv3Jtei(DN&zN|duysK9@CCe?&J&FT|IG&tx_bh-a7Sk-~p z1#Ej@6@~uKWQ#DDixvFV<`Az0aUOBoAW5r7QarY=CyKIB>3hHXOO9-(ZbH*F(AJvLQeM3XTnF=_3w3(;T-rqzy zLFq#7@ia8W|O?#^0gs0ICGTA17yZsj=}+T-onDcEe*m{nn@-mIWp# zpscGc;;SDk3nYI&)COltHeuZd!n>BvRIL3ed2Kw{>s$?)^rx@#{0UK){L7wCtILI< zYC9)P4Wvd_9kL1uY0jt(r#$BYSdQ<{vK${ttY0imc@yJR^ly8+pbL?jW@cPRzfgda zA!4^5KXBhQ)?lA9yNz~yntxYkIj-Ow;}xL3@|e=;6Fb4H2SMh5AbVhmS5NkVZs#L~ z-C23I<=MfuUor)3Wnj#Q){9Q_yQ~LoG&_`HWN{{m#>3$NZf{l_76M}>E?nFt6d4ie zOz`{YpR=00XS0g^FrwLI2O$ZV`gt*9Nb1}hoxh~UJnpziQ6Da%G5uk=&e$NocV(b* zFRl!~Xz+;^Uao^bWfAFV^va6sE}Hj(zqkj|fJkmP`_^k9Cd$IG)eY&ME|Ipuv)4nn zqF#G49D9OxU+hC?Hk! z9%^Ah{}fi0lApARt*IM>Pzkgl@v(1I@i8n3J*ddAx?udpb)4kEDudNaBIUOfNP$(O z=`jiKr^)`pDY&f~@8y)HJBRjxV-UKYI5%eG)k9G7N?hUgRD;;K8e{Duiq{d^ekEyD zPg(mSyX|vIlXwiUv~gX`4!oMwIFz&#mX(*H_&ZboAI8hp?L|ov-tW5>RK+$N@7#QU z7l^+betNC+AX)RWbHYC-W?Svvb=5TwV!OL`kY1=U<|862kk8fo3KKE0L08EQ_Xm3P zM-GA;-;9nzds{!HhcTX0xQ z-TT$H`_Hu&?r3KmKGCQjxlX>{xt`mSW?z4q@g6}O#K(I~d*gkP3(%D~?1j3qs1XLs jcVm5R$6tJ*byc=@Th}bsXC<^JN+oVC(32#m5Zr$NZq*!# literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/ic_bubble_blue.xml b/app/src/main/res/drawable/ic_bubble_blue.xml new file mode 100644 index 000000000..25c702878 --- /dev/null +++ b/app/src/main/res/drawable/ic_bubble_blue.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_icon_pin.xml b/app/src/main/res/drawable/ic_icon_pin.xml new file mode 100644 index 000000000..28668da05 --- /dev/null +++ b/app/src/main/res/drawable/ic_icon_pin.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_icon_pin_empty.xml b/app/src/main/res/drawable/ic_icon_pin_empty.xml new file mode 100644 index 000000000..0efd9b86d --- /dev/null +++ b/app/src/main/res/drawable/ic_icon_pin_empty.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_tab_certificate.xml b/app/src/main/res/drawable/ic_tab_certificate.xml new file mode 100644 index 000000000..f27dec814 --- /dev/null +++ b/app/src/main/res/drawable/ic_tab_certificate.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/certificate_dgc.xml b/app/src/main/res/layout/certificate_dgc.xml new file mode 100644 index 000000000..c5b175054 --- /dev/null +++ b/app/src/main/res/layout/certificate_dgc.xml @@ -0,0 +1,238 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +