Skip to content

Commit

Permalink
Merge pull request #409 from SwissCovid/develop
Browse files Browse the repository at this point in the history
Version 2.2.0
  • Loading branch information
gallmann-ubique committed Oct 15, 2021
2 parents b528424 + 0222ede commit 171040b
Show file tree
Hide file tree
Showing 30 changed files with 2,187 additions and 9 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ android {
applicationId "ch.admin.bag.dp3t"
minSdkVersion 23
targetSdkVersion 30
versionCode 21000
versionName "2.1.0"
versionCode 22000
versionName "2.2.0"
resConfigs "en", "fr", "de", "it", "pt", "es", "sq", "bs", "hr", "sr", "rm", "tr", "ti"

buildConfigField "long", "BUILD_TIME", readPropertyWithDefault('buildTimestamp', System.currentTimeMillis()) + 'L'
Expand Down
21 changes: 21 additions & 0 deletions app/src/main/java/ch/admin/bag/dp3t/home/HomeFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@

import org.dpppt.android.sdk.TracingStatus;

import ch.admin.bag.dp3t.vaccination.VaccinationAppointmentFragment;
import ch.admin.bag.dp3t.BuildConfig;
import ch.admin.bag.dp3t.R;
import ch.admin.bag.dp3t.checkin.CheckinOverviewFragment;
Expand Down Expand Up @@ -82,6 +83,8 @@ public class HomeFragment extends Fragment {
private View reportStatusView;
private View reportErrorView;
private View checkinCard;
private View vaccinationCardWrapper;
private View vaccinationCard;
private View loadingView;
private View covidCodeCard;

Expand Down Expand Up @@ -119,6 +122,8 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
reportStatusView = reportStatusBubble.findViewById(R.id.report_status);
reportErrorView = reportStatusBubble.findViewById(R.id.report_errors);
checkinCard = view.findViewById(R.id.card_checkin);
vaccinationCardWrapper = view.findViewById(R.id.card_vaccination_wrapper);
vaccinationCard = view.findViewById(R.id.card_vaccination);
headerView = view.findViewById(R.id.home_header_view);
scrollView = view.findViewById(R.id.home_scroll_view);
loadingView = view.findViewById(R.id.loading_view);
Expand All @@ -129,6 +134,7 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
setupTracingView();
setupNotification();
setupCheckinCard();
setupVaccinationCard();
setupNonProductionHint();
setupScrollBehavior();
setupCovidCodeCard();
Expand Down Expand Up @@ -447,6 +453,21 @@ private void setupCheckinCardNonIsolationMode() {
duration -> checkinTime.setText(StringUtil.getShortDurationString(duration)));
}

private void setupVaccinationCard(){
if(secureStorage.getShowVaccinationInfo()){
vaccinationCardWrapper.setVisibility(VISIBLE);
vaccinationCard.setOnClickListener(v -> {
requireActivity().getSupportFragmentManager().beginTransaction()
.setCustomAnimations(R.anim.slide_enter, R.anim.slide_exit, R.anim.slide_pop_enter, R.anim.slide_pop_exit)
.replace(R.id.main_fragment_container, VaccinationAppointmentFragment.newInstance())
.addToBackStack(VaccinationAppointmentFragment.class.getCanonicalName())
.commit();
});
}else {
vaccinationCardWrapper.setVisibility(View.GONE);
}
}

private void setupCovidCodeCard() {
Button covidCodeButton = covidCodeCard.findViewById(R.id.enter_covidcode_button);
TextView covidCodeTitle = covidCodeCard.findViewById(R.id.enter_covidcode_title);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ class ConfigWorker(context: Context, workerParams: WorkerParameters) : Coroutine

secureStorage.setTestInformationUrls(config.testInformationUrls)

secureStorage.setVaccinationBookingInfo(config.vaccinationBookingInfo)
secureStorage.setVaccinationBookingCantons(config.vaccinationBookingCantons)
secureStorage.setShowVaccinationInfo(config.isShowVaccinationInfo)

secureStorage.testLocations = config.testLocations
secureStorage.interopCountries = config.interOpsCountries

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ public class ConfigResponseModel {
private Map<String, String> testInformationUrls;
private boolean checkInUpdateNotificationEnabled;

private VaccinationBookingCantonCollection vaccinationBookingCantons;
private VaccinationBookingInfoCollection vaccinationBookingInfo;
private boolean showVaccinationInfo;

public boolean getDoForceUpdate() {
return forceUpdate;
}
Expand Down Expand Up @@ -60,4 +64,16 @@ public boolean isCheckInUpdateNotificationEnabled() {
return checkInUpdateNotificationEnabled;
}

public VaccinationBookingCantonCollection getVaccinationBookingCantons() {
return vaccinationBookingCantons;
}

public VaccinationBookingInfoCollection getVaccinationBookingInfo() {
return vaccinationBookingInfo;
}

public boolean isShowVaccinationInfo() {
return showVaccinationInfo;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* Copyright (c) 2021 Ubique Innovation AG <https://www.ubique.ch>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* SPDX-License-Identifier: MPL-2.0
*/
package ch.admin.bag.dp3t.networking.models;

import java.util.HashMap;
import java.util.List;

public class VaccinationBookingCantonCollection extends HashMap<String, List<VaccinationBookingCantonModel>> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* Copyright (c) 2021 Ubique Innovation AG <https://www.ubique.ch>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* SPDX-License-Identifier: MPL-2.0
*/

package ch.admin.bag.dp3t.networking.models

data class VaccinationBookingCantonModel(
val name: String,
val linkUrl: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright (c) 2021 Ubique Innovation AG <https://www.ubique.ch>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* SPDX-License-Identifier: MPL-2.0
*/
package ch.admin.bag.dp3t.networking.models;

import java.util.HashMap;

public class VaccinationBookingInfoCollection extends HashMap<String, VaccinationBookingInfoModel> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright (c) 2021 Ubique Innovation AG <https://www.ubique.ch>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* SPDX-License-Identifier: MPL-2.0
*/

package ch.admin.bag.dp3t.networking.models

data class VaccinationBookingInfoModel(
val title: String,
val text: String,
val info: String
)
47 changes: 43 additions & 4 deletions app/src/main/java/ch/admin/bag/dp3t/storage/SecureStorage.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,10 @@
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import ch.admin.bag.dp3t.networking.models.VaccinationBookingCantonModel;
import ch.admin.bag.dp3t.networking.models.VaccinationBookingInfoModel;
import ch.admin.bag.dp3t.checkin.models.CheckInState;
import ch.admin.bag.dp3t.networking.models.InfoBoxModelCollection;
import ch.admin.bag.dp3t.networking.models.TestLocationModel;
import ch.admin.bag.dp3t.networking.models.WhatToDoPositiveTestTextsCollection;
import ch.admin.bag.dp3t.networking.models.WhatToDoPositiveTestTextsModel;
import ch.admin.bag.dp3t.networking.models.*;

public class SecureStorage {

Expand Down Expand Up @@ -68,6 +67,9 @@ public class SecureStorage {
private static final String KEY_LAST_CONFIG_LOAD_SUCCESS_SDK_INT = "last_config_load_success_sdk_int";
private static final String KEY_T_DUMMY = "KEY_T_DUMMY";
private static final String KEY_WHAT_TO_DO_POSITIVE_TEST_TEXTS = "whatToDoPositiveTestTexts";
private static final String KEY_VACCINATION_BOOKING_INFO = "vaccinationBookingInfo";
private static final String KEY_VACCINATION_CANTONS = "vaccinationCantons";
private static final String KEY_SHOW_VACCINATION_INFO = "showVaccinationInfo";
private static final String KEY_TEST_LOCATIONS = "test_locations";
private static final String KEY_INTEROP_COUNTRIES = "interop_countries";
private static final String KEY_APP_OPEN_AFTER_NOTIFICATION_PENDING = "appOpenAfterNotificationPending";
Expand Down Expand Up @@ -322,6 +324,43 @@ public WhatToDoPositiveTestTextsModel getWhatToDoPositiveTestTexts(String langua
return map.get(language);
}

public void setVaccinationBookingInfo(VaccinationBookingInfoCollection vaccinationBookingInfoCollection) {
prefs.edit().putString(KEY_VACCINATION_BOOKING_INFO, gson.toJson(vaccinationBookingInfoCollection)).apply();
}

public VaccinationBookingInfoModel getVaccinationBookingInfo(String language) {
HashMap<String, VaccinationBookingInfoModel> map =
gson.fromJson(prefs.getString(KEY_VACCINATION_BOOKING_INFO, "null"),
VaccinationBookingInfoCollection.class);
if (map == null) {
return null;
}
return map.get(language);
}

public void setVaccinationBookingCantons(VaccinationBookingCantonCollection vaccinationBookingCantonCollection) {
prefs.edit().putString(KEY_VACCINATION_CANTONS, gson.toJson(vaccinationBookingCantonCollection)).apply();
}

public List<VaccinationBookingCantonModel> getVaccinationBookingCantons(String language) {
HashMap<String, List<VaccinationBookingCantonModel>> map =
gson.fromJson(prefs.getString(KEY_VACCINATION_CANTONS, "null"),
VaccinationBookingCantonCollection.class);
if (map == null) {
return null;
}
return map.get(language);
}


public void setShowVaccinationInfo(boolean showVaccinationInfo) {
prefs.edit().putBoolean(KEY_SHOW_VACCINATION_INFO, showVaccinationInfo).apply();
}

public boolean getShowVaccinationInfo(){
return prefs.getBoolean(KEY_SHOW_VACCINATION_INFO, false);
}

public void setTestLocations(Map<String, List<TestLocationModel>> testLocations) {
prefs.edit().putString(KEY_TEST_LOCATIONS, gson.toJson(testLocations)).apply();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (c) 2021 Ubique Innovation AG <https://www.ubique.ch>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* SPDX-License-Identifier: MPL-2.0
*/

package ch.admin.bag.dp3t.vaccination

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import ch.admin.bag.dp3t.networking.models.VaccinationBookingCantonModel
import ch.admin.bag.dp3t.databinding.ItemVaccinationAppointmentCantonBinding

class VaccinationAppointmentCantonAdapter(
private val onCantonClicked: (VaccinationBookingCantonModel) -> Unit
) : RecyclerView.Adapter<VaccinationAppointmentCantonViewHolder>() {

private val items = mutableListOf<VaccinationBookingCantonModel>()

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VaccinationAppointmentCantonViewHolder {
val binding = ItemVaccinationAppointmentCantonBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return VaccinationAppointmentCantonViewHolder(binding)
}

override fun onBindViewHolder(holder: VaccinationAppointmentCantonViewHolder, position: Int) {
holder.bind(items[position], onCantonClicked)
}

override fun getItemCount() = items.size

fun setItems(newItems: List<VaccinationBookingCantonModel>) {
items.clear()
items.addAll(newItems)
notifyDataSetChanged()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (c) 2021 Ubique Innovation AG <https://www.ubique.ch>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* SPDX-License-Identifier: MPL-2.0
*/

package ch.admin.bag.dp3t.vaccination

import androidx.recyclerview.widget.RecyclerView
import ch.admin.bag.dp3t.networking.models.VaccinationBookingCantonModel
import ch.admin.bag.dp3t.databinding.ItemVaccinationAppointmentCantonBinding

class VaccinationAppointmentCantonViewHolder(
private val binding: ItemVaccinationAppointmentCantonBinding
) : RecyclerView.ViewHolder(binding.root) {

fun bind(canton: VaccinationBookingCantonModel, onCantonClicked: (VaccinationBookingCantonModel) -> Unit) {
binding.root.setOnClickListener { onCantonClicked.invoke(canton) }
binding.cantonName.text = canton.name
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright (c) 2021 Ubique Innovation AG <https://www.ubique.ch>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* SPDX-License-Identifier: MPL-2.0
*/

package ch.admin.bag.dp3t.vaccination

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import ch.admin.bag.dp3t.networking.models.VaccinationBookingCantonModel
import ch.admin.bag.dp3t.networking.models.VaccinationBookingInfoModel
import ch.admin.bag.dp3t.R
import ch.admin.bag.dp3t.databinding.FragmentVaccinationAppointmentBinding
import ch.admin.bag.dp3t.storage.SecureStorage
import ch.admin.bag.dp3t.util.UrlUtil

class VaccinationAppointmentFragment : Fragment() {

companion object {
@JvmStatic
fun newInstance() = VaccinationAppointmentFragment()
}

private var _binding: FragmentVaccinationAppointmentBinding? = null
private val binding get() = _binding!!

private val adapter = VaccinationAppointmentCantonAdapter(this::onCantonClicked)

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
_binding = FragmentVaccinationAppointmentBinding.inflate(inflater, container, false)
return binding.root
}

override fun onDestroyView() {
super.onDestroyView()
_binding = null
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.toolbar.setNavigationOnClickListener { parentFragmentManager.popBackStack() }
setupCantonList()
setupMoreInformationButton()

val secureStorage = SecureStorage.getInstance(context)
secureStorage.getVaccinationBookingInfo(requireContext().getString(R.string.language_key))?.let {
setupVaccinationBookingInfo(it)
}
adapter.setItems(
secureStorage.getVaccinationBookingCantons(requireContext().getString(R.string.language_key)) ?: emptyList()
)

}

private fun setupCantonList() {
binding.vaccinationAppointmentCantonList.adapter = adapter
}

private fun setupVaccinationBookingInfo(vaccinationBookingInfo: VaccinationBookingInfoModel) {
binding.vaccinationBookingTitle.text = vaccinationBookingInfo.title
binding.vaccinationBookingText.text = vaccinationBookingInfo.text
binding.vaccinationBookingInfo.text = vaccinationBookingInfo.info
}

private fun setupMoreInformationButton() {
binding.vaccinationMoreInfoButton.setOnClickListener {
val url = getString(R.string.vaccination_booking_info_url)
UrlUtil.openUrl(requireContext(), url)
}
}

private fun onCantonClicked(canton: VaccinationBookingCantonModel) {
UrlUtil.openUrl(requireContext(), canton.linkUrl)
}

}
Loading

0 comments on commit 171040b

Please sign in to comment.