From b13b25f34f3b6790e0de39639a13cbba6f53ce28 Mon Sep 17 00:00:00 2001 From: Stefan Mitterrutzner Date: Wed, 7 Jul 2021 08:28:53 +0200 Subject: [PATCH 01/27] update disclaimer --- .../Resources/Disclaimer/DE_App_Datenschutzerklaerung.html | 4 ++-- DP3TApp/Resources/Disclaimer/DE_App_Nutzungsbedingungen.html | 4 ++-- .../Resources/Disclaimer/EN_App_Datenschutzerklaerung.html | 4 ++-- DP3TApp/Resources/Disclaimer/EN_App_Nutzungsbedingungen.html | 4 ++-- .../Resources/Disclaimer/FR_App_Datenschutzerklaerung.html | 4 ++-- DP3TApp/Resources/Disclaimer/FR_App_Nutzungsbedingungen.html | 4 ++-- .../Resources/Disclaimer/IT_App_Datenschutzerklaerung.html | 4 ++-- DP3TApp/Resources/Disclaimer/IT_App_Nutzungsbedingungen.html | 4 ++-- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/DP3TApp/Resources/Disclaimer/DE_App_Datenschutzerklaerung.html b/DP3TApp/Resources/Disclaimer/DE_App_Datenschutzerklaerung.html index 85e39310..ee35749f 100644 --- a/DP3TApp/Resources/Disclaimer/DE_App_Datenschutzerklaerung.html +++ b/DP3TApp/Resources/Disclaimer/DE_App_Datenschutzerklaerung.html @@ -18,7 +18,7 @@

Das Datenschutzrecht regelt die Bearbeitung von Personendaten. Die Bundesgesetzgebung über den Datenschutz ist auf die Bearbeitung von Personendaten anwendbar. Die Datenschutzerklärung steht zudem im Einklang mit dem Epidemiengesetz vom 28. September 2012 (EpG; SR 818.101), der Verordnung vom 24. Juni 2020 über das Proximity-Tracing-System für das Coronavirus SARS-CoV-2 (VPTS; SR 818.101.25), - dem Bundesgesetz über die gesetzlichen Grundlagen für Verordnungen des Bundesrates zur Bewältigung der Covid-19-Epidemie vom 25. September 2020 (Covid-19-Gesetz; SR 818.102) sowie der Verordnung über ein Warnsystem zu Covid-19 für Veranstaltungen vom 1. Juli 2021. + dem Bundesgesetz über die gesetzlichen Grundlagen für Verordnungen des Bundesrates zur Bewältigung der Covid-19-Epidemie vom 25. September 2020 (Covid-19-Gesetz; SR 818.102) sowie der Verordnung vom 30. Juni 2021 über ein System zur Benachrichtigung über eine mögliche Ansteckung mit dem Coronavirus Sars-CoV-2 an Veranstaltungen (VBV; SR 818.102.4).

Unter Personendaten werden alle Angaben verstanden, die sich auf eine bestimmte oder bestimmbare Person beziehen. Bearbeiten meint jeden Umgang mit Personendaten, unabhängig von den angewandten Mitteln und Verfahren, insbesondere das Beschaffen, Aufbewahren, Verwenden, Umarbeiten, Bekanntgeben, Archivieren oder Vernichten der Daten. @@ -264,4 +264,4 @@

***** -

\ No newline at end of file +

diff --git a/DP3TApp/Resources/Disclaimer/DE_App_Nutzungsbedingungen.html b/DP3TApp/Resources/Disclaimer/DE_App_Nutzungsbedingungen.html index 5b7da35b..f33e4191 100644 --- a/DP3TApp/Resources/Disclaimer/DE_App_Nutzungsbedingungen.html +++ b/DP3TApp/Resources/Disclaimer/DE_App_Nutzungsbedingungen.html @@ -17,7 +17,7 @@

1.2 - Die App des Bundesamtes für Gesundheit (BAG) stützt sich auf das Epidemiengesetz vom 28. September 2012 (EpG; SR 818.101), die Verordnung vom 24. Juni 2020 über das Proximity-Tracing-System für das Coronavirus SARS-CoV-2 (VPTS; SR 818.101.25), dem Bundesgesetz über die gesetzlichen Grundlagen für Verordnungen des Bundesrates zur Bewältigung der Covid-19-Epidemie vom 25. September 2020 (Covid-19-Gesetz; SR 818.102) sowie der Verordnung über ein Warnsystem zu Covid-19 für Veranstaltungen vom 1. Juli 2021. + Die App des Bundesamtes für Gesundheit (BAG) stützt sich auf das Epidemiengesetz vom 28. September 2012 (EpG; SR 818.101), die Verordnung vom 24. Juni 2020 über das Proximity-Tracing-System für das Coronavirus SARS-CoV-2 (VPTS; SR 818.101.25), dem Bundesgesetz über die gesetzlichen Grundlagen für Verordnungen des Bundesrates zur Bewältigung der Covid-19-Epidemie vom 25. September 2020 (Covid-19-Gesetz; SR 818.102) sowie der Verordnung vom 30. Juni 2021 über ein System zur Benachrichtigung über eine mögliche Ansteckung mit dem Coronavirus Sars-CoV-2 an Veranstaltungen (VBV; SR 818.102.4).

1.3 @@ -228,4 +228,4 @@

9.5 Anwendbar ist schweizerisches Recht, unter Vorbehalt abweichender zwingender Bestimmungen. Ausschliesslicher Gerichtsstand für alle Streitigkeiten ist das zuständige schweizerische Gericht. -

\ No newline at end of file +

diff --git a/DP3TApp/Resources/Disclaimer/EN_App_Datenschutzerklaerung.html b/DP3TApp/Resources/Disclaimer/EN_App_Datenschutzerklaerung.html index 57c7db91..99822d11 100644 --- a/DP3TApp/Resources/Disclaimer/EN_App_Datenschutzerklaerung.html +++ b/DP3TApp/Resources/Disclaimer/EN_App_Datenschutzerklaerung.html @@ -18,7 +18,7 @@

The processing of personal data is governed by data protection legislation. The federal legislation on data protection is applicable to the processing of personal data. In addition, the Data Protection Statement is in line with the Epidemics Act of 28 September 2012 (EpG; CC 818.101), the Ordinance of 24 June 2020 on the Proximity Tracing System for the Coronavirus SARS-CoV-2 (VPTS; CC 818.101.25), - the Federal Act on the Statutory Principles for Federal Council Ordinances on Combating the COVID-19 Epidemic of 25 September 2020 (COVID-19 Act; CC 818.102) and the Ordinance on a COVID-19 Warning System for Events of 1 July 2021. + the Federal Act on the Statutory Principles for Federal Council Ordinances on Combating the COVID-19 Epidemic of 25 September 2020 (COVID-19 Act; CC 818.102) and the Ordinance of 30 June 2021 on a system for notification of possible infection with the Coronavirus Sars-CoV-2 at events (VBV; CC 818.102.4).

“Personal data” means all information relating to an identified or identifiable person. “Processing” means any operation with personal data, irrespective of the means applied and the procedure, and in particular the collection, storage, use, revision, disclosure, archiving or destruction of data. @@ -266,4 +266,4 @@

***** -

\ No newline at end of file +

diff --git a/DP3TApp/Resources/Disclaimer/EN_App_Nutzungsbedingungen.html b/DP3TApp/Resources/Disclaimer/EN_App_Nutzungsbedingungen.html index f5bc6e64..4c34e971 100644 --- a/DP3TApp/Resources/Disclaimer/EN_App_Nutzungsbedingungen.html +++ b/DP3TApp/Resources/Disclaimer/EN_App_Nutzungsbedingungen.html @@ -17,7 +17,7 @@

1.2 - The Federal Office of Public Health (FOPH) app is based on the Epidemics Act of 28 September 2012 (EpG; SR 818.101) and the Ordinance of 24 June 2020 on the Proximity Tracing System for the Coronavirus SARS-CoV-2 (VPTS; SR 818.101.25), the Federal Act on the Statutory Principles for Federal Council Ordinances on Combating the COVID-19 Epidemic (COVID-19 Act; CC 818.102) and the Ordinance on a COVID-19 Warning System for Events of 24 June 2021. + The Federal Office of Public Health (FOPH) app is based on the Epidemics Act of 28 September 2012 (EpG; SR 818.101) and the Ordinance of 24 June 2020 on the Proximity Tracing System for the Coronavirus SARS-CoV-2 (VPTS; SR 818.101.25), the Federal Act on the Statutory Principles for Federal Council Ordinances on Combating the COVID-19 Epidemic (COVID-19 Act; CC 818.102) and the Ordinance of 30 June 2021 on a system for notification of possible infection with the Coronavirus Sars-CoV-2 at events (VBV; CC 818.102.4).

1.3 @@ -229,4 +229,4 @@

9.5 Swiss law shall apply, subject to any divergent mandatory provisions. The exclusive venue for all disputes shall be the competent Swiss court. -

\ No newline at end of file +

diff --git a/DP3TApp/Resources/Disclaimer/FR_App_Datenschutzerklaerung.html b/DP3TApp/Resources/Disclaimer/FR_App_Datenschutzerklaerung.html index f6beb8f7..53b3e63d 100644 --- a/DP3TApp/Resources/Disclaimer/FR_App_Datenschutzerklaerung.html +++ b/DP3TApp/Resources/Disclaimer/FR_App_Datenschutzerklaerung.html @@ -29,7 +29,7 @@ 808.102 - ) et à l’ordonnance du 24 juin 2021 sur un système d’alerte COVID-19 pour les manifestations. + ) et à l’ordonnance du 30 juin 2021 sur un système visant à informer d’une infection possible au coronavirus SARS-CoV-2 lors de manifestations (OSIM ; RS 818.102.4).

On entend par données personnelles toutes les informations qui se rapportent à une personne identifiée ou identifiable. Par traitement, on entend toute opération relative à des données personnelles – quels que soient les moyens et procédés utilisés – notamment la collecte, la conservation, l’exploitation, la modification, la communication, l’archivage ou la destruction de données. @@ -385,4 +385,4 @@

***** -

\ No newline at end of file +

diff --git a/DP3TApp/Resources/Disclaimer/FR_App_Nutzungsbedingungen.html b/DP3TApp/Resources/Disclaimer/FR_App_Nutzungsbedingungen.html index f0541b16..e35aa195 100644 --- a/DP3TApp/Resources/Disclaimer/FR_App_Nutzungsbedingungen.html +++ b/DP3TApp/Resources/Disclaimer/FR_App_Nutzungsbedingungen.html @@ -28,7 +28,7 @@ 818.102 -) et l’ordonnance du 24 juin 2021 sur un système d’alerte COVID-19 pour les manifestations. +) et l’ordonnance du 30 juin 2021 sur un système visant à informer d’une infection possible au coronavirus SARS-CoV-2 lors de manifestations (OSIM ; RS 818.102.4).

1.3 L’application vise à informer les utilisateurs qui pourraient avoir été exposés au virus et à établir des statistiques en rapport avec le coronavirus. @@ -245,4 +245,4 @@

9.5 Le droit suisse s’applique, sous réserve de dispositions impératives divergentes. Le for exclusif pour tous les litiges est le tribunal suisse compétent. -

\ No newline at end of file +

diff --git a/DP3TApp/Resources/Disclaimer/IT_App_Datenschutzerklaerung.html b/DP3TApp/Resources/Disclaimer/IT_App_Datenschutzerklaerung.html index eac51f22..8a248067 100644 --- a/DP3TApp/Resources/Disclaimer/IT_App_Datenschutzerklaerung.html +++ b/DP3TApp/Resources/Disclaimer/IT_App_Datenschutzerklaerung.html @@ -17,7 +17,7 @@ Nella presente informativa sulla protezione dei dati l’Ufficio federale della sanità pubblica (UFSP) spiega in che misura tratterà dati personali nel quadro dell’utilizzo dell’applicazione «app SwissCovid» (di seguito app) in Svizzera. Non si tratta di una descrizione esaustiva; alcuni aspetti specifici possono essere regolamentati da altre informative sulla protezione dei dati, documenti analoghi, condizioni di utilizzo o programmi di applicazione.

- Il trattamento dei dati personali è disciplinato dal diritto sulla protezione dei dati; al trattamento dei dati personali si applica la legislazione federale in materia. La presente informativa è inoltre conforme alla legge del 28 settembre 2012 sulle epidemie (LEp; RS 818.101), all’ordinanza del 24 giugno 2020 sul sistema di tracciamento della prossimità per il coronavirus SARS-CoV-2 (OSTP; RS 818.101.25), alla legge federale del 25 settembre 2020 sulle basi legali delle ordinanze del Consiglio federale volte a far fronte all’epidemia di COVID-19 (legge COVID-19; RS 818.102) nonché all’ordinanza del 24 giugno 2021 su un sistema di allerta COVID-19 per le manifestazioni. + Il trattamento dei dati personali è disciplinato dal diritto sulla protezione dei dati; al trattamento dei dati personali si applica la legislazione federale in materia. La presente informativa è inoltre conforme alla legge del 28 settembre 2012 sulle epidemie (LEp; RS 818.101), all’ordinanza del 24 giugno 2020 sul sistema di tracciamento della prossimità per il coronavirus SARS-CoV-2 (OSTP; RS 818.101.25), alla legge federale del 25 settembre 2020 sulle basi legali delle ordinanze del Consiglio federale volte a far fronte all’epidemia di COVID-19 (legge COVID-19; RS 818.102) nonché all’ordinanza del 30 giugno 2021 su un sistema di segnalazione di un possibile di contagio da coronavirus SARS-CoV-2 durante una manifestazione (OSSM; RS 818.102.4).

Per dati personali s’intendono tutte le informazioni relative a una persona identificata o identificabile. Il trattamento indica qualsiasi operazione relativa a dati personali, indipendentemente dai mezzi e dalle procedure impiegati, segnatamente la raccolta, la conservazione, l’utilizzazione, la modificazione, la comunicazione, l’archiviazione o la distruzione di dati. @@ -266,4 +266,4 @@

***** -

\ No newline at end of file +

diff --git a/DP3TApp/Resources/Disclaimer/IT_App_Nutzungsbedingungen.html b/DP3TApp/Resources/Disclaimer/IT_App_Nutzungsbedingungen.html index 9cd394a2..ea5db3c8 100644 --- a/DP3TApp/Resources/Disclaimer/IT_App_Nutzungsbedingungen.html +++ b/DP3TApp/Resources/Disclaimer/IT_App_Nutzungsbedingungen.html @@ -17,7 +17,7 @@

1.2 - L’app dell’Ufficio federale della sanità pubblica (UFSP) si basa sulla legge del 28 settembre 2012 (LEp; RS 818.101), sull’ordinanza del 24 giugno 2020 sul sistema di tracciamento della prossimità per il coronavirus SARS-CoV-2 (OSTP; RS 818.101.25), sulla legge federale del 25 settembre 2020 sulle basi legali delle ordinanze del Consiglio federale volte a far fronte all’epidemia di COVID-19 (legge COVID-19; RS 818.102) nonché sull’ordinanza del 24 giugno 2021 su un sistema di allerta COVID-19 per le manifestazioni. + L’app dell’Ufficio federale della sanità pubblica (UFSP) si basa sulla legge del 28 settembre 2012 (LEp; RS 818.101), sull’ordinanza del 24 giugno 2020 sul sistema di tracciamento della prossimità per il coronavirus SARS-CoV-2 (OSTP; RS 818.101.25), sulla legge federale del 25 settembre 2020 sulle basi legali delle ordinanze del Consiglio federale volte a far fronte all’epidemia di COVID-19 (legge COVID-19; RS 818.102) nonché sull’ordinanza del 30 giugno 2021 su un sistema di segnalazione di un possibile di contagio da coronavirus SARS-CoV-2 durante una manifestazione (OSSM; RS 818.102.4).

1.3 @@ -229,4 +229,4 @@

9.5 Si applica il diritto svizzero, salvo disposizioni divergenti imperative. Il foro esclusivo per tutte le controversie è il tribunale competente svizzero. -

\ No newline at end of file +

From 9d97f9dca4cbe5ba9736c54297c942a9cccbba3a Mon Sep 17 00:00:00 2001 From: Marco Zimmermann Date: Thu, 2 Sep 2021 13:50:43 +0200 Subject: [PATCH 02/27] implements error popup if the user is already checked in Signed-off-by: Marco Zimmermann --- DP3TApp.xcodeproj/project.pbxproj | 6 ++ DP3TApp/Logic/NSLinkHandler.swift | 17 ++++- ...adyCheckedInErrorPopupViewController.swift | 49 +++++++++++++ .../Scanner/NSCheckInErrorViewModel.swift | 5 -- DP3TApp/SharedUI/Views/NSErrorView.swift | 37 +++++++++- Translations/bs.lproj/Localizable.strings | 63 +++++++++++++++++ Translations/de.lproj/Localizable.strings | 68 +++++++++++++++++++ Translations/en.lproj/Localizable.strings | 63 +++++++++++++++++ Translations/es.lproj/Localizable.strings | 63 +++++++++++++++++ Translations/fr.lproj/Localizable.strings | 63 +++++++++++++++++ Translations/hr.lproj/Localizable.strings | 63 +++++++++++++++++ Translations/it.lproj/Localizable.strings | 63 +++++++++++++++++ Translations/pt.lproj/Localizable.strings | 63 +++++++++++++++++ Translations/rm.lproj/Localizable.strings | 63 +++++++++++++++++ Translations/sq.lproj/Localizable.strings | 63 +++++++++++++++++ .../sr-Latn-RS.lproj/Localizable.strings | 63 +++++++++++++++++ Translations/ti.lproj/Localizable.strings | 63 +++++++++++++++++ Translations/tr.lproj/Localizable.strings | 63 +++++++++++++++++ 18 files changed, 928 insertions(+), 10 deletions(-) create mode 100644 DP3TApp/Screens/CheckIn/Edit/NSAlreadyCheckedInErrorPopupViewController.swift diff --git a/DP3TApp.xcodeproj/project.pbxproj b/DP3TApp.xcodeproj/project.pbxproj index c9181466..e21b6cd5 100644 --- a/DP3TApp.xcodeproj/project.pbxproj +++ b/DP3TApp.xcodeproj/project.pbxproj @@ -288,6 +288,8 @@ 6E7C0D43242E44D80017C4F9 /* NSWebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E7C0D42242E44D80017C4F9 /* NSWebViewController.swift */; }; 6E7C0D45242E4AA90017C4F9 /* NSLoadingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E7C0D44242E4AA90017C4F9 /* NSLoadingView.swift */; }; 6E7C0D47242E58600017C4F9 /* NSAboutViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E7C0D46242E58600017C4F9 /* NSAboutViewController.swift */; }; + 6E84B1A726E0CD770000AC92 /* NSAlreadyCheckedInErrorPopupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E84B1A626E0CD760000AC92 /* NSAlreadyCheckedInErrorPopupViewController.swift */; }; + 6E84B1A826E0CEE80000AC92 /* NSAlreadyCheckedInErrorPopupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E84B1A626E0CD760000AC92 /* NSAlreadyCheckedInErrorPopupViewController.swift */; }; 6E88973C261F01BA00508334 /* NSReportsLeitfadenInfoPopupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E88973B261F01BA00508334 /* NSReportsLeitfadenInfoPopupViewController.swift */; }; 6E889756261F228200508334 /* NSOnboardingBaseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E889755261F228200508334 /* NSOnboardingBaseViewController.swift */; }; 6E88975F261F25A700508334 /* NSOnboardingBaseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E889755261F228200508334 /* NSOnboardingBaseViewController.swift */; }; @@ -845,6 +847,7 @@ 6E7C0D42242E44D80017C4F9 /* NSWebViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSWebViewController.swift; sourceTree = ""; }; 6E7C0D44242E4AA90017C4F9 /* NSLoadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSLoadingView.swift; sourceTree = ""; }; 6E7C0D46242E58600017C4F9 /* NSAboutViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSAboutViewController.swift; sourceTree = ""; }; + 6E84B1A626E0CD760000AC92 /* NSAlreadyCheckedInErrorPopupViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = NSAlreadyCheckedInErrorPopupViewController.swift; path = DP3TApp/Screens/Checkin/Edit/NSAlreadyCheckedInErrorPopupViewController.swift; sourceTree = SOURCE_ROOT; }; 6E88973B261F01BA00508334 /* NSReportsLeitfadenInfoPopupViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSReportsLeitfadenInfoPopupViewController.swift; sourceTree = ""; }; 6E889755261F228200508334 /* NSOnboardingBaseViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSOnboardingBaseViewController.swift; sourceTree = ""; }; 6E889764261F27D400508334 /* NSUpdateBoardingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSUpdateBoardingViewController.swift; sourceTree = ""; }; @@ -1816,6 +1819,7 @@ children = ( DC16175C2638717800B56ADA /* NSTimePickerControl.swift */, DC16175D2638717800B56ADA /* NSCheckInEditViewController.swift */, + 6E84B1A626E0CD760000AC92 /* NSAlreadyCheckedInErrorPopupViewController.swift */, ); path = Edit; sourceTree = ""; @@ -2665,6 +2669,7 @@ F8B44EF12653E8DA009F0ED0 /* NSInformSendViewController.swift in Sources */, 242D21EE245C4BD8005DAEA8 /* NSClickthroughStackView.swift in Sources */, F80E406E2509002200876906 /* StatisticsResponse.swift in Sources */, + 6E84B1A826E0CEE80000AC92 /* NSAlreadyCheckedInErrorPopupViewController.swift in Sources */, DC1617A42638717800B56ADA /* NSCheckInCurrentStateModuleView.swift in Sources */, F86A6A9926383803003CAC1B /* NSVenueView.swift in Sources */, 242D21EF245C4BD8005DAEA8 /* NSSimpleTextButton.swift in Sources */, @@ -2946,6 +2951,7 @@ F8512244250A6F8E009BE733 /* NSChartYAxisLegend.swift in Sources */, AA5ED051267B742E0039A4D6 /* NSCheckInContentView.swift in Sources */, 6E8FC0FB24518BF2002AB1E5 /* UBKeyboardObserver.m in Sources */, + 6E84B1A726E0CD770000AC92 /* NSAlreadyCheckedInErrorPopupViewController.swift in Sources */, DC56B8BB242EACF00077B99C /* NSOnboardingStepViewController.swift in Sources */, 2485F47C2458625F00C3D8C3 /* DatabaseSyncer.swift in Sources */, F8089694250B55080023F639 /* NSStatisticsModuleLegendView.swift in Sources */, diff --git a/DP3TApp/Logic/NSLinkHandler.swift b/DP3TApp/Logic/NSLinkHandler.swift index 8e1f4c33..a02beed6 100644 --- a/DP3TApp/Logic/NSLinkHandler.swift +++ b/DP3TApp/Logic/NSLinkHandler.swift @@ -55,9 +55,20 @@ class NSLinkHandler { appDelegate.tabBarController.currentTab = .homescreen // present checkout controller when already checked in - if CheckInManager.shared.currentCheckIn != nil { - let vc = NSCheckInEditViewController() - vc.presentInNavigationController(from: appDelegate.tabBarController.homescreen, useLine: false) + if let checkIn = CheckInManager.shared.currentCheckIn { + if checkIn.qrCode == url.absoluteString { + // same qr-code: directly present checkout + let vc = NSCheckInEditViewController() + vc.presentInNavigationController(from: appDelegate.tabBarController.homescreen, useLine: false) + } else { + // otherwise show error that you are already checked in + let vc = NSAlreadyCheckedInErrorPopupViewController { + let vc = NSCheckInEditViewController() + vc.presentInNavigationController(from: appDelegate.tabBarController.homescreen, useLine: false) + } + vc.presentInNavigationController(from: appDelegate.tabBarController.homescreen, useLine: false) + } + return true } diff --git a/DP3TApp/Screens/CheckIn/Edit/NSAlreadyCheckedInErrorPopupViewController.swift b/DP3TApp/Screens/CheckIn/Edit/NSAlreadyCheckedInErrorPopupViewController.swift new file mode 100644 index 00000000..a8496cbb --- /dev/null +++ b/DP3TApp/Screens/CheckIn/Edit/NSAlreadyCheckedInErrorPopupViewController.swift @@ -0,0 +1,49 @@ +// +/* + * Copyright (c) 2021 Ubique Innovation AG + * + * 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 + */ + +import Foundation + +class NSAlreadyCheckedInErrorPopupViewController: NSPopupViewController { + // MARK: - Callback + + private let checkoutCallback: () -> Void + + // MARK: - Init + + init(checkoutCallback: @escaping () -> Void) { + self.checkoutCallback = checkoutCallback + super.init(showCloseButton: true, dismissable: true, stackViewInset: UIEdgeInsets(top: NSPadding.medium + NSPadding.small, left: 2 * NSPadding.medium, bottom: NSPadding.medium, right: 2 * NSPadding.medium)) + } + + // MARK: - View + + override func viewDidLoad() { + super.viewDidLoad() + tintColor = .ns_blue + setup() + } + + // MARK: - Setup + + private func setup() { + let errorView = NSErrorView.alreadyCheckedInErrorView(checkOutCallback: { [weak self] in + guard let strongSelf = self else { return } + strongSelf.dismiss(animated: true) { + strongSelf.checkoutCallback() + } + }, cancelCallback: { [weak self] in + guard let strongSelf = self else { return } + strongSelf.dismiss() + }) + + stackView.addArrangedView(errorView) + } +} diff --git a/DP3TApp/Screens/CheckIn/Scanner/NSCheckInErrorViewModel.swift b/DP3TApp/Screens/CheckIn/Scanner/NSCheckInErrorViewModel.swift index 03d17077..3c02022f 100644 --- a/DP3TApp/Screens/CheckIn/Scanner/NSCheckInErrorViewModel.swift +++ b/DP3TApp/Screens/CheckIn/Scanner/NSCheckInErrorViewModel.swift @@ -48,11 +48,6 @@ extension CrowdNotifierError { } extension NSCheckInErrorViewModel { - static let alreadyCheckedIn = NSCheckInErrorViewModel(title: "error_title".ub_localized, - text: "error_already_checked_in".ub_localized, - buttonText: "ok_button".ub_localized, - icon: UIImage(named: "ic-error")) - static let invalidQrCode = NSCheckInErrorViewModel(title: "error_title".ub_localized, text: "qrscanner_error".ub_localized, buttonText: "ok_button".ub_localized, diff --git a/DP3TApp/SharedUI/Views/NSErrorView.swift b/DP3TApp/SharedUI/Views/NSErrorView.swift index 4677b9e5..d1b548ff 100644 --- a/DP3TApp/SharedUI/Views/NSErrorView.swift +++ b/DP3TApp/SharedUI/Views/NSErrorView.swift @@ -27,6 +27,8 @@ class NSErrorView: UIView { } }() + private let secondActionButton = NSUnderlinedButton() + // MARK: - Model struct NSErrorViewModel { @@ -38,6 +40,9 @@ class NSErrorView: UIView { var action: ((NSErrorView?) -> Void)? var customColor: UIColor? = nil var customBackgroundColor: UIColor? = nil + + var secondActionButtonTitle: String? + var secondAction: ((NSErrorView?) -> Void)? } var model: NSErrorViewModel? { @@ -84,7 +89,12 @@ class NSErrorView: UIView { actionButton.touchUpCallback = { [weak self] in self?.model?.action?(self) } + secondActionButton.touchUpCallback = { [weak self] in + self?.model?.secondAction?(self) + } + actionButton.title = model?.buttonTitle + secondActionButton.title = model?.secondActionButtonTitle stackView.setNeedsLayout() stackView.clearSubviews() @@ -97,7 +107,12 @@ class NSErrorView: UIView { stackView.addArrangedView(activityIndicator) activityIndicator.hidesWhenStopped = true activityIndicator.stopAnimating() + + if model?.secondAction != nil { + stackView.addArrangedView(secondActionButton) + } } + if let code = model?.errorCode { stackView.addArrangedView(errorCodeLabel) errorCodeLabel.text = code @@ -115,6 +130,7 @@ class NSErrorView: UIView { if let c = model?.customColor { actionButton.textColor = c + secondActionButton.textColor = c textLabel.textColor = c } } @@ -126,10 +142,11 @@ class NSErrorView: UIView { public var isEnabled: Bool { get { - actionButton.isEnabled + actionButton.isEnabled && secondActionButton.isEnabled } set { actionButton.isEnabled = newValue + secondActionButton.isEnabled = newValue } } @@ -309,6 +326,22 @@ class NSErrorView: UIView { return nil } } + + static func alreadyCheckedInErrorView(checkOutCallback: (() -> Void)? = nil, cancelCallback: (() -> Void)? = nil) -> NSErrorView { + let model = NSErrorViewModel(icon: UIImage(named: "ic-error")!, + title: "error_already_checked_in".ub_localized, + text: "error_already_checked_in_text".ub_localized, + buttonTitle: "checkout_button_title".ub_localized, + action: { _ in + checkOutCallback?() + }, + customBackgroundColor: UIColor.white, + secondActionButtonTitle: "cancel".ub_localized, + secondAction: { _ in + cancelCallback?() + }) + return NSErrorView(model: model) + } } // MARK: - Accessibility @@ -322,7 +355,7 @@ extension NSErrorView { } func updateAccessibility() { - accessibilityElements = model?.action != nil ? [stackView, actionButton] : [stackView] + accessibilityElements = (model?.secondAction != nil) ? [stackView, actionButton, secondActionButton] : ((model?.secondAction != nil) ? [stackView, actionButton] : [stackView]) stackView.accessibilityLabel = model.map { "\($0.title), \($0.text)" } UIAccessibility.post(notification: .screenChanged, argument: nil) } diff --git a/Translations/bs.lproj/Localizable.strings b/Translations/bs.lproj/Localizable.strings index b2fbe779..816b679b 100644 --- a/Translations/bs.lproj/Localizable.strings +++ b/Translations/bs.lproj/Localizable.strings @@ -1737,3 +1737,66 @@ /*Button um Covid Certificate App zu installieren*/ "covid_certificate_install_app" = "Instalirati aplikaciju"; +"web_generator_title" = ""; +"web_generator_title_label" = ""; +"web_generator_generate_button" = ""; + +/*Titel des Buttons, der das PDF herunterlädt*/ +"web_generator_download_pdf_button" = ""; + +/*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ +"accessibility_expandable_box_reduced_state" = "reduced"; + +/*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ +"accessibility_expandable_box_expanded_state" = "expanded"; + +/*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ +"checkin_overlap_popup_title" = ""; + +/*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ +"checkin_overlap_popup_text" = ""; + +/*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ +"checkin_overlap_back_button" = ""; + +/*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ +"accessibility_reminder_option_hours_plural" = "hours"; + +/*This will be read by the screenreader instead of "'" (for the reminder options)*/ +"accessibility_reminder_option_minutes" = "minutes"; + +/*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ +"accessibility_reminder_option_hour" = "hour"; + +/*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ +"checkin_overlap_popup_success_text" = ""; + +/*Infotext beim Generieren eines QR-Codes*/ +"web_generator_message" = ""; + +/*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ +"web_generator_success_title" = ""; + +/*Titel des Buttons, der das PDF ausdruckt*/ +"web_generator_print_pdf_button" = ""; + +/*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ +"web_generator_reset_button" = ""; + +/*Used by VoiceOver to explain what the info button in the navigation bar does*/ +"accessibility_info_button_app" = ""; + +/*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ +"accessibility_info_button_covidcode" = ""; + +/*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ +"accessibility_info_button_numberofcases" = ""; + +/*Is read by the screenreader, when newly created QR-code is shown*/ +"accessibility_preview_qr_code_alternative_text" = ""; + +/*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ +"checkin_generate_web_hint" = ""; + +/*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ +"error_already_checked_in_text" = ""; diff --git a/Translations/de.lproj/Localizable.strings b/Translations/de.lproj/Localizable.strings index 8fe98d9b..c1bb254d 100644 --- a/Translations/de.lproj/Localizable.strings +++ b/Translations/de.lproj/Localizable.strings @@ -1818,3 +1818,71 @@ /*Button um Covid Certificate App zu installieren*/ "covid_certificate_install_app" = "App installieren"; +"web_generator_title" = "QR-Code erstellen"; +"web_generator_title_label" = ""; + +/*Fuzzy*/ +"web_generator_generate_button" = "QR-Code erstellen"; + +/*Titel des Buttons, der das PDF herunterlädt*/ +/*Fuzzy*/ +"web_generator_download_pdf_button" = "PDF herunterladen"; + +/*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ +"accessibility_expandable_box_reduced_state" = "reduziert"; + +/*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ +"accessibility_expandable_box_expanded_state" = "erweitert"; + +/*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ +"checkin_overlap_popup_title" = "Sichern nicht möglich"; + +/*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ +"checkin_overlap_popup_text" = "Ihre gewählten Zeiten für {CHECKIN} überschneiden sich mit anderen Check-ins. Bitte überprüfen Sie nochmals Ihre Angaben."; + +/*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ +"checkin_overlap_back_button" = "Zurück"; + +/*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ +"accessibility_reminder_option_hours_plural" = "Stunden"; + +/*This will be read by the screenreader instead of "'" (for the reminder options)*/ +"accessibility_reminder_option_minutes" = "Minuten"; + +/*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ +"accessibility_reminder_option_hour" = "Stunde"; + +/*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ +"checkin_overlap_popup_success_text" = "Es gibt keine Konflikte mehr für Ihre eingetragene Zeit. Sie können jetzt bei {CHECKIN} auschecken."; + +/*Infotext beim Generieren eines QR-Codes*/ +/*Fuzzy*/ +"web_generator_message" = "Vergeben Sie einen Titel, der den Ort \noder Ihren Anlass näher beschreibt. \nDieser Titel wird beim Check-in angezeigt."; + +/*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ +"web_generator_success_title" = "QR-Code erstellt"; + +/*Titel des Buttons, der das PDF ausdruckt*/ +"web_generator_print_pdf_button" = "PDF drucken"; + +/*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ +"web_generator_reset_button" = "Neuen QR-Code erstellen"; + +/*Used by VoiceOver to explain what the info button in the navigation bar does*/ +"accessibility_info_button_app" = "Mehr Informationen zur App"; + +/*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ +"accessibility_info_button_covidcode" = "Mehr Informationen zu Covidcodes"; + +/*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ +"accessibility_info_button_numberofcases" = "Mehr Informationen zu den Fallzahlen"; + +/*Is read by the screenreader, when newly created QR-code is shown*/ +"accessibility_preview_qr_code_alternative_text" = "Erstellter QR-Code"; + +/*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ +/*Fuzzy*/ +"checkin_generate_web_hint" = "Alternativ können Sie QR-Codes auch auf qr.swisscovid.ch erstellen."; + +/*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ +"error_already_checked_in_text" = "Um sich an einem neuen Ort einzuchecken, müssen Sie sich zuerst auschecken."; diff --git a/Translations/en.lproj/Localizable.strings b/Translations/en.lproj/Localizable.strings index d0fa1314..a6c6bc38 100644 --- a/Translations/en.lproj/Localizable.strings +++ b/Translations/en.lproj/Localizable.strings @@ -1765,3 +1765,66 @@ /*Button um Covid Certificate App zu installieren*/ "covid_certificate_install_app" = "Install app"; +"web_generator_title" = ""; +"web_generator_title_label" = ""; +"web_generator_generate_button" = ""; + +/*Titel des Buttons, der das PDF herunterlädt*/ +"web_generator_download_pdf_button" = ""; + +/*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ +"accessibility_expandable_box_reduced_state" = "reduced"; + +/*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ +"accessibility_expandable_box_expanded_state" = "expanded"; + +/*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ +"checkin_overlap_popup_title" = ""; + +/*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ +"checkin_overlap_popup_text" = ""; + +/*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ +"checkin_overlap_back_button" = ""; + +/*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ +"accessibility_reminder_option_hours_plural" = "hours"; + +/*This will be read by the screenreader instead of "'" (for the reminder options)*/ +"accessibility_reminder_option_minutes" = "minutes"; + +/*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ +"accessibility_reminder_option_hour" = "hour"; + +/*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ +"checkin_overlap_popup_success_text" = ""; + +/*Infotext beim Generieren eines QR-Codes*/ +"web_generator_message" = ""; + +/*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ +"web_generator_success_title" = ""; + +/*Titel des Buttons, der das PDF ausdruckt*/ +"web_generator_print_pdf_button" = ""; + +/*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ +"web_generator_reset_button" = ""; + +/*Used by VoiceOver to explain what the info button in the navigation bar does*/ +"accessibility_info_button_app" = ""; + +/*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ +"accessibility_info_button_covidcode" = ""; + +/*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ +"accessibility_info_button_numberofcases" = ""; + +/*Is read by the screenreader, when newly created QR-code is shown*/ +"accessibility_preview_qr_code_alternative_text" = ""; + +/*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ +"checkin_generate_web_hint" = ""; + +/*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ +"error_already_checked_in_text" = ""; diff --git a/Translations/es.lproj/Localizable.strings b/Translations/es.lproj/Localizable.strings index 960b290c..9c7be918 100644 --- a/Translations/es.lproj/Localizable.strings +++ b/Translations/es.lproj/Localizable.strings @@ -1737,3 +1737,66 @@ /*Button um Covid Certificate App zu installieren*/ "covid_certificate_install_app" = "Instalar la aplicación"; +"web_generator_title" = ""; +"web_generator_title_label" = ""; +"web_generator_generate_button" = ""; + +/*Titel des Buttons, der das PDF herunterlädt*/ +"web_generator_download_pdf_button" = ""; + +/*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ +"accessibility_expandable_box_reduced_state" = "reduced"; + +/*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ +"accessibility_expandable_box_expanded_state" = "expanded"; + +/*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ +"checkin_overlap_popup_title" = ""; + +/*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ +"checkin_overlap_popup_text" = ""; + +/*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ +"checkin_overlap_back_button" = ""; + +/*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ +"accessibility_reminder_option_hours_plural" = "hours"; + +/*This will be read by the screenreader instead of "'" (for the reminder options)*/ +"accessibility_reminder_option_minutes" = "minutes"; + +/*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ +"accessibility_reminder_option_hour" = "hour"; + +/*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ +"checkin_overlap_popup_success_text" = ""; + +/*Infotext beim Generieren eines QR-Codes*/ +"web_generator_message" = ""; + +/*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ +"web_generator_success_title" = ""; + +/*Titel des Buttons, der das PDF ausdruckt*/ +"web_generator_print_pdf_button" = ""; + +/*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ +"web_generator_reset_button" = ""; + +/*Used by VoiceOver to explain what the info button in the navigation bar does*/ +"accessibility_info_button_app" = ""; + +/*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ +"accessibility_info_button_covidcode" = ""; + +/*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ +"accessibility_info_button_numberofcases" = ""; + +/*Is read by the screenreader, when newly created QR-code is shown*/ +"accessibility_preview_qr_code_alternative_text" = ""; + +/*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ +"checkin_generate_web_hint" = ""; + +/*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ +"error_already_checked_in_text" = ""; diff --git a/Translations/fr.lproj/Localizable.strings b/Translations/fr.lproj/Localizable.strings index e69b501e..53bf6123 100644 --- a/Translations/fr.lproj/Localizable.strings +++ b/Translations/fr.lproj/Localizable.strings @@ -1770,3 +1770,66 @@ /*Button um Covid Certificate App zu installieren*/ "covid_certificate_install_app" = "Installer l'application"; +"web_generator_title" = ""; +"web_generator_title_label" = ""; +"web_generator_generate_button" = ""; + +/*Titel des Buttons, der das PDF herunterlädt*/ +"web_generator_download_pdf_button" = ""; + +/*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ +"accessibility_expandable_box_reduced_state" = "réduit"; + +/*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ +"accessibility_expandable_box_expanded_state" = "étendu"; + +/*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ +"checkin_overlap_popup_title" = ""; + +/*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ +"checkin_overlap_popup_text" = ""; + +/*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ +"checkin_overlap_back_button" = ""; + +/*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ +"accessibility_reminder_option_hours_plural" = "hours"; + +/*This will be read by the screenreader instead of "'" (for the reminder options)*/ +"accessibility_reminder_option_minutes" = "minutes"; + +/*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ +"accessibility_reminder_option_hour" = "hour"; + +/*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ +"checkin_overlap_popup_success_text" = ""; + +/*Infotext beim Generieren eines QR-Codes*/ +"web_generator_message" = ""; + +/*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ +"web_generator_success_title" = ""; + +/*Titel des Buttons, der das PDF ausdruckt*/ +"web_generator_print_pdf_button" = ""; + +/*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ +"web_generator_reset_button" = ""; + +/*Used by VoiceOver to explain what the info button in the navigation bar does*/ +"accessibility_info_button_app" = ""; + +/*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ +"accessibility_info_button_covidcode" = ""; + +/*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ +"accessibility_info_button_numberofcases" = ""; + +/*Is read by the screenreader, when newly created QR-code is shown*/ +"accessibility_preview_qr_code_alternative_text" = ""; + +/*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ +"checkin_generate_web_hint" = ""; + +/*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ +"error_already_checked_in_text" = ""; diff --git a/Translations/hr.lproj/Localizable.strings b/Translations/hr.lproj/Localizable.strings index 3fa9c9ea..c4b8b1e0 100644 --- a/Translations/hr.lproj/Localizable.strings +++ b/Translations/hr.lproj/Localizable.strings @@ -1735,3 +1735,66 @@ /*Button um Covid Certificate App zu installieren*/ "covid_certificate_install_app" = "Instalirati aplikaciju"; +"web_generator_title" = ""; +"web_generator_title_label" = ""; +"web_generator_generate_button" = ""; + +/*Titel des Buttons, der das PDF herunterlädt*/ +"web_generator_download_pdf_button" = ""; + +/*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ +"accessibility_expandable_box_reduced_state" = "reduced"; + +/*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ +"accessibility_expandable_box_expanded_state" = "expanded"; + +/*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ +"checkin_overlap_popup_title" = ""; + +/*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ +"checkin_overlap_popup_text" = ""; + +/*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ +"checkin_overlap_back_button" = ""; + +/*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ +"accessibility_reminder_option_hours_plural" = "hours"; + +/*This will be read by the screenreader instead of "'" (for the reminder options)*/ +"accessibility_reminder_option_minutes" = "minutes"; + +/*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ +"accessibility_reminder_option_hour" = "hour"; + +/*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ +"checkin_overlap_popup_success_text" = ""; + +/*Infotext beim Generieren eines QR-Codes*/ +"web_generator_message" = ""; + +/*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ +"web_generator_success_title" = ""; + +/*Titel des Buttons, der das PDF ausdruckt*/ +"web_generator_print_pdf_button" = ""; + +/*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ +"web_generator_reset_button" = ""; + +/*Used by VoiceOver to explain what the info button in the navigation bar does*/ +"accessibility_info_button_app" = ""; + +/*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ +"accessibility_info_button_covidcode" = ""; + +/*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ +"accessibility_info_button_numberofcases" = ""; + +/*Is read by the screenreader, when newly created QR-code is shown*/ +"accessibility_preview_qr_code_alternative_text" = ""; + +/*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ +"checkin_generate_web_hint" = ""; + +/*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ +"error_already_checked_in_text" = ""; diff --git a/Translations/it.lproj/Localizable.strings b/Translations/it.lproj/Localizable.strings index cb6ddd7d..a0949e86 100644 --- a/Translations/it.lproj/Localizable.strings +++ b/Translations/it.lproj/Localizable.strings @@ -1770,3 +1770,66 @@ /*Button um Covid Certificate App zu installieren*/ "covid_certificate_install_app" = "Installa l'app"; +"web_generator_title" = ""; +"web_generator_title_label" = ""; +"web_generator_generate_button" = ""; + +/*Titel des Buttons, der das PDF herunterlädt*/ +"web_generator_download_pdf_button" = ""; + +/*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ +"accessibility_expandable_box_reduced_state" = "compressa"; + +/*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ +"accessibility_expandable_box_expanded_state" = "espansa"; + +/*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ +"checkin_overlap_popup_title" = ""; + +/*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ +"checkin_overlap_popup_text" = ""; + +/*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ +"checkin_overlap_back_button" = ""; + +/*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ +"accessibility_reminder_option_hours_plural" = "hours"; + +/*This will be read by the screenreader instead of "'" (for the reminder options)*/ +"accessibility_reminder_option_minutes" = "minutes"; + +/*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ +"accessibility_reminder_option_hour" = "hour"; + +/*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ +"checkin_overlap_popup_success_text" = ""; + +/*Infotext beim Generieren eines QR-Codes*/ +"web_generator_message" = ""; + +/*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ +"web_generator_success_title" = ""; + +/*Titel des Buttons, der das PDF ausdruckt*/ +"web_generator_print_pdf_button" = ""; + +/*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ +"web_generator_reset_button" = ""; + +/*Used by VoiceOver to explain what the info button in the navigation bar does*/ +"accessibility_info_button_app" = ""; + +/*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ +"accessibility_info_button_covidcode" = ""; + +/*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ +"accessibility_info_button_numberofcases" = ""; + +/*Is read by the screenreader, when newly created QR-code is shown*/ +"accessibility_preview_qr_code_alternative_text" = ""; + +/*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ +"checkin_generate_web_hint" = ""; + +/*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ +"error_already_checked_in_text" = ""; diff --git a/Translations/pt.lproj/Localizable.strings b/Translations/pt.lproj/Localizable.strings index 4a79c501..3523bf64 100644 --- a/Translations/pt.lproj/Localizable.strings +++ b/Translations/pt.lproj/Localizable.strings @@ -1737,3 +1737,66 @@ /*Button um Covid Certificate App zu installieren*/ "covid_certificate_install_app" = "Instalar o aplicativo"; +"web_generator_title" = ""; +"web_generator_title_label" = ""; +"web_generator_generate_button" = ""; + +/*Titel des Buttons, der das PDF herunterlädt*/ +"web_generator_download_pdf_button" = ""; + +/*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ +"accessibility_expandable_box_reduced_state" = "reduced"; + +/*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ +"accessibility_expandable_box_expanded_state" = "expanded"; + +/*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ +"checkin_overlap_popup_title" = ""; + +/*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ +"checkin_overlap_popup_text" = ""; + +/*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ +"checkin_overlap_back_button" = ""; + +/*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ +"accessibility_reminder_option_hours_plural" = "hours"; + +/*This will be read by the screenreader instead of "'" (for the reminder options)*/ +"accessibility_reminder_option_minutes" = "minutes"; + +/*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ +"accessibility_reminder_option_hour" = "hour"; + +/*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ +"checkin_overlap_popup_success_text" = ""; + +/*Infotext beim Generieren eines QR-Codes*/ +"web_generator_message" = ""; + +/*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ +"web_generator_success_title" = ""; + +/*Titel des Buttons, der das PDF ausdruckt*/ +"web_generator_print_pdf_button" = ""; + +/*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ +"web_generator_reset_button" = ""; + +/*Used by VoiceOver to explain what the info button in the navigation bar does*/ +"accessibility_info_button_app" = ""; + +/*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ +"accessibility_info_button_covidcode" = ""; + +/*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ +"accessibility_info_button_numberofcases" = ""; + +/*Is read by the screenreader, when newly created QR-code is shown*/ +"accessibility_preview_qr_code_alternative_text" = ""; + +/*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ +"checkin_generate_web_hint" = ""; + +/*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ +"error_already_checked_in_text" = ""; diff --git a/Translations/rm.lproj/Localizable.strings b/Translations/rm.lproj/Localizable.strings index 354006e5..4f4d7c2f 100644 --- a/Translations/rm.lproj/Localizable.strings +++ b/Translations/rm.lproj/Localizable.strings @@ -1735,3 +1735,66 @@ /*Button um Covid Certificate App zu installieren*/ "covid_certificate_install_app" = "Installar l'app"; +"web_generator_title" = ""; +"web_generator_title_label" = ""; +"web_generator_generate_button" = ""; + +/*Titel des Buttons, der das PDF herunterlädt*/ +"web_generator_download_pdf_button" = ""; + +/*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ +"accessibility_expandable_box_reduced_state" = "reducì"; + +/*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ +"accessibility_expandable_box_expanded_state" = "extendì"; + +/*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ +"checkin_overlap_popup_title" = ""; + +/*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ +"checkin_overlap_popup_text" = ""; + +/*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ +"checkin_overlap_back_button" = ""; + +/*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ +"accessibility_reminder_option_hours_plural" = "hours"; + +/*This will be read by the screenreader instead of "'" (for the reminder options)*/ +"accessibility_reminder_option_minutes" = "minutes"; + +/*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ +"accessibility_reminder_option_hour" = "hour"; + +/*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ +"checkin_overlap_popup_success_text" = ""; + +/*Infotext beim Generieren eines QR-Codes*/ +"web_generator_message" = ""; + +/*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ +"web_generator_success_title" = ""; + +/*Titel des Buttons, der das PDF ausdruckt*/ +"web_generator_print_pdf_button" = ""; + +/*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ +"web_generator_reset_button" = ""; + +/*Used by VoiceOver to explain what the info button in the navigation bar does*/ +"accessibility_info_button_app" = ""; + +/*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ +"accessibility_info_button_covidcode" = ""; + +/*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ +"accessibility_info_button_numberofcases" = ""; + +/*Is read by the screenreader, when newly created QR-code is shown*/ +"accessibility_preview_qr_code_alternative_text" = ""; + +/*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ +"checkin_generate_web_hint" = ""; + +/*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ +"error_already_checked_in_text" = ""; diff --git a/Translations/sq.lproj/Localizable.strings b/Translations/sq.lproj/Localizable.strings index 5990f2d8..f55011c7 100644 --- a/Translations/sq.lproj/Localizable.strings +++ b/Translations/sq.lproj/Localizable.strings @@ -1737,3 +1737,66 @@ /*Button um Covid Certificate App zu installieren*/ "covid_certificate_install_app" = "Instaloni aplikacionin"; +"web_generator_title" = ""; +"web_generator_title_label" = ""; +"web_generator_generate_button" = ""; + +/*Titel des Buttons, der das PDF herunterlädt*/ +"web_generator_download_pdf_button" = ""; + +/*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ +"accessibility_expandable_box_reduced_state" = "reduced"; + +/*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ +"accessibility_expandable_box_expanded_state" = "expanded"; + +/*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ +"checkin_overlap_popup_title" = ""; + +/*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ +"checkin_overlap_popup_text" = ""; + +/*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ +"checkin_overlap_back_button" = ""; + +/*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ +"accessibility_reminder_option_hours_plural" = "hours"; + +/*This will be read by the screenreader instead of "'" (for the reminder options)*/ +"accessibility_reminder_option_minutes" = "minutes"; + +/*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ +"accessibility_reminder_option_hour" = "hour"; + +/*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ +"checkin_overlap_popup_success_text" = ""; + +/*Infotext beim Generieren eines QR-Codes*/ +"web_generator_message" = ""; + +/*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ +"web_generator_success_title" = ""; + +/*Titel des Buttons, der das PDF ausdruckt*/ +"web_generator_print_pdf_button" = ""; + +/*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ +"web_generator_reset_button" = ""; + +/*Used by VoiceOver to explain what the info button in the navigation bar does*/ +"accessibility_info_button_app" = ""; + +/*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ +"accessibility_info_button_covidcode" = ""; + +/*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ +"accessibility_info_button_numberofcases" = ""; + +/*Is read by the screenreader, when newly created QR-code is shown*/ +"accessibility_preview_qr_code_alternative_text" = ""; + +/*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ +"checkin_generate_web_hint" = ""; + +/*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ +"error_already_checked_in_text" = ""; diff --git a/Translations/sr-Latn-RS.lproj/Localizable.strings b/Translations/sr-Latn-RS.lproj/Localizable.strings index 4218877e..be2dfe03 100644 --- a/Translations/sr-Latn-RS.lproj/Localizable.strings +++ b/Translations/sr-Latn-RS.lproj/Localizable.strings @@ -1735,3 +1735,66 @@ /*Button um Covid Certificate App zu installieren*/ "covid_certificate_install_app" = "Instalirati aplikaciju"; +"web_generator_title" = ""; +"web_generator_title_label" = ""; +"web_generator_generate_button" = ""; + +/*Titel des Buttons, der das PDF herunterlädt*/ +"web_generator_download_pdf_button" = ""; + +/*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ +"accessibility_expandable_box_reduced_state" = "reduced"; + +/*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ +"accessibility_expandable_box_expanded_state" = "expanded"; + +/*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ +"checkin_overlap_popup_title" = ""; + +/*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ +"checkin_overlap_popup_text" = ""; + +/*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ +"checkin_overlap_back_button" = ""; + +/*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ +"accessibility_reminder_option_hours_plural" = "hours"; + +/*This will be read by the screenreader instead of "'" (for the reminder options)*/ +"accessibility_reminder_option_minutes" = "minutes"; + +/*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ +"accessibility_reminder_option_hour" = "hour"; + +/*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ +"checkin_overlap_popup_success_text" = ""; + +/*Infotext beim Generieren eines QR-Codes*/ +"web_generator_message" = ""; + +/*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ +"web_generator_success_title" = ""; + +/*Titel des Buttons, der das PDF ausdruckt*/ +"web_generator_print_pdf_button" = ""; + +/*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ +"web_generator_reset_button" = ""; + +/*Used by VoiceOver to explain what the info button in the navigation bar does*/ +"accessibility_info_button_app" = ""; + +/*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ +"accessibility_info_button_covidcode" = ""; + +/*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ +"accessibility_info_button_numberofcases" = ""; + +/*Is read by the screenreader, when newly created QR-code is shown*/ +"accessibility_preview_qr_code_alternative_text" = ""; + +/*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ +"checkin_generate_web_hint" = ""; + +/*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ +"error_already_checked_in_text" = ""; diff --git a/Translations/ti.lproj/Localizable.strings b/Translations/ti.lproj/Localizable.strings index 811d7356..ab823530 100644 --- a/Translations/ti.lproj/Localizable.strings +++ b/Translations/ti.lproj/Localizable.strings @@ -1736,3 +1736,66 @@ /*Button um Covid Certificate App zu installieren*/ "covid_certificate_install_app" = "ኤፕ ምትካል"; +"web_generator_title" = ""; +"web_generator_title_label" = ""; +"web_generator_generate_button" = ""; + +/*Titel des Buttons, der das PDF herunterlädt*/ +"web_generator_download_pdf_button" = ""; + +/*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ +"accessibility_expandable_box_reduced_state" = "reduced"; + +/*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ +"accessibility_expandable_box_expanded_state" = "expanded"; + +/*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ +"checkin_overlap_popup_title" = ""; + +/*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ +"checkin_overlap_popup_text" = ""; + +/*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ +"checkin_overlap_back_button" = ""; + +/*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ +"accessibility_reminder_option_hours_plural" = "hours"; + +/*This will be read by the screenreader instead of "'" (for the reminder options)*/ +"accessibility_reminder_option_minutes" = "minutes"; + +/*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ +"accessibility_reminder_option_hour" = "hour"; + +/*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ +"checkin_overlap_popup_success_text" = ""; + +/*Infotext beim Generieren eines QR-Codes*/ +"web_generator_message" = ""; + +/*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ +"web_generator_success_title" = ""; + +/*Titel des Buttons, der das PDF ausdruckt*/ +"web_generator_print_pdf_button" = ""; + +/*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ +"web_generator_reset_button" = ""; + +/*Used by VoiceOver to explain what the info button in the navigation bar does*/ +"accessibility_info_button_app" = ""; + +/*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ +"accessibility_info_button_covidcode" = ""; + +/*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ +"accessibility_info_button_numberofcases" = ""; + +/*Is read by the screenreader, when newly created QR-code is shown*/ +"accessibility_preview_qr_code_alternative_text" = ""; + +/*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ +"checkin_generate_web_hint" = ""; + +/*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ +"error_already_checked_in_text" = ""; diff --git a/Translations/tr.lproj/Localizable.strings b/Translations/tr.lproj/Localizable.strings index 4d347d30..e2d24d8c 100644 --- a/Translations/tr.lproj/Localizable.strings +++ b/Translations/tr.lproj/Localizable.strings @@ -1736,3 +1736,66 @@ /*Button um Covid Certificate App zu installieren*/ "covid_certificate_install_app" = "Uygulamayı kur"; +"web_generator_title" = ""; +"web_generator_title_label" = ""; +"web_generator_generate_button" = ""; + +/*Titel des Buttons, der das PDF herunterlädt*/ +"web_generator_download_pdf_button" = ""; + +/*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ +"accessibility_expandable_box_reduced_state" = "reduced"; + +/*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ +"accessibility_expandable_box_expanded_state" = "expanded"; + +/*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ +"checkin_overlap_popup_title" = ""; + +/*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ +"checkin_overlap_popup_text" = ""; + +/*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ +"checkin_overlap_back_button" = ""; + +/*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ +"accessibility_reminder_option_hours_plural" = "hours"; + +/*This will be read by the screenreader instead of "'" (for the reminder options)*/ +"accessibility_reminder_option_minutes" = "minutes"; + +/*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ +"accessibility_reminder_option_hour" = "hour"; + +/*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ +"checkin_overlap_popup_success_text" = ""; + +/*Infotext beim Generieren eines QR-Codes*/ +"web_generator_message" = ""; + +/*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ +"web_generator_success_title" = ""; + +/*Titel des Buttons, der das PDF ausdruckt*/ +"web_generator_print_pdf_button" = ""; + +/*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ +"web_generator_reset_button" = ""; + +/*Used by VoiceOver to explain what the info button in the navigation bar does*/ +"accessibility_info_button_app" = ""; + +/*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ +"accessibility_info_button_covidcode" = ""; + +/*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ +"accessibility_info_button_numberofcases" = ""; + +/*Is read by the screenreader, when newly created QR-code is shown*/ +"accessibility_preview_qr_code_alternative_text" = ""; + +/*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ +"checkin_generate_web_hint" = ""; + +/*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ +"error_already_checked_in_text" = ""; From e2015e2f77ca34fad6a22d353c1caaf81a8564db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20R=C3=B6sch?= <30999902+simonroesch@users.noreply.github.com> Date: Thu, 2 Sep 2021 15:27:45 +0200 Subject: [PATCH 03/27] Update README.md --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 80da064c..98917070 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,11 @@ -SwissCovid is the official contact tracing app of Switzerland. The app can be installed from the [App Store](https://apps.apple.com/ch/app/swisscovid/id1509275381). The SwissCovid 2.0 app uses two types of contact tracing to prevent the spread of COVID-19. +SwissCovid is the official contact tracing app of Switzerland. The app can be installed from the [App Store](https://apps.apple.com/ch/app/swisscovid/id1509275381). The app design, UX and implementation was done by [Ubique](https://www.ubique.ch/?app=github). + +## Contact tracing + +The SwissCovid 2.0 app uses two types of contact tracing to prevent the spread of COVID-19. With proximity tracing close contacts are detected using the bluetooth technology. For this the [DP3T iOS SDK](https://github.com/DP-3T/dp3t-sdk-ios) is used that builds on top of the Google & Apple Exposure Notifications. This feature is called SwissCovid encounters. From 497bf54463e7b0f941aa0dfa8876b616ddcf0f45 Mon Sep 17 00:00:00 2001 From: Marco Zimmermann Date: Fri, 3 Sep 2021 08:51:54 +0200 Subject: [PATCH 04/27] fixes dark mode and presentation Signed-off-by: Marco Zimmermann --- DP3TApp/Logic/NSLinkHandler.swift | 4 +++- DP3TApp/SharedUI/Views/NSErrorView.swift | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/DP3TApp/Logic/NSLinkHandler.swift b/DP3TApp/Logic/NSLinkHandler.swift index a02beed6..c448c08b 100644 --- a/DP3TApp/Logic/NSLinkHandler.swift +++ b/DP3TApp/Logic/NSLinkHandler.swift @@ -66,7 +66,9 @@ class NSLinkHandler { let vc = NSCheckInEditViewController() vc.presentInNavigationController(from: appDelegate.tabBarController.homescreen, useLine: false) } - vc.presentInNavigationController(from: appDelegate.tabBarController.homescreen, useLine: false) + + let hs = appDelegate.tabBarController.homescreen + hs.navigationController?.present(vc, animated: true, completion: nil) } return true diff --git a/DP3TApp/SharedUI/Views/NSErrorView.swift b/DP3TApp/SharedUI/Views/NSErrorView.swift index d1b548ff..db484beb 100644 --- a/DP3TApp/SharedUI/Views/NSErrorView.swift +++ b/DP3TApp/SharedUI/Views/NSErrorView.swift @@ -335,7 +335,7 @@ class NSErrorView: UIView { action: { _ in checkOutCallback?() }, - customBackgroundColor: UIColor.white, + customBackgroundColor: UIColor.clear, secondActionButtonTitle: "cancel".ub_localized, secondAction: { _ in cancelCallback?() From e2898962424b3b2dc883d887600e40832f6e80b8 Mon Sep 17 00:00:00 2001 From: Marco Zimmermann Date: Tue, 7 Sep 2021 08:31:06 +0200 Subject: [PATCH 05/27] adds popup for overlapping checkins Signed-off-by: Marco Zimmermann --- DP3TApp.xcodeproj/project.pbxproj | 13 ++ .../CheckIn/ic-edit.imageset/Contents.json | 23 +++ .../CheckIn/ic-edit.imageset/ic-edit.png | Bin 0 -> 223 bytes .../CheckIn/ic-edit.imageset/ic-edit@2x.png | Bin 0 -> 238 bytes .../CheckIn/ic-edit.imageset/ic-edit@3x.png | Bin 0 -> 298 bytes .../Edit/NSCheckInEditViewController.swift | 44 ++++- .../Edit/NSOverlappingCheckInView.swift | 57 ++++++ ...verlappingCheckinPopupViewController.swift | 166 ++++++++++++++++++ .../SharedUI/Base/NSPopupViewController.swift | 3 +- DP3TApp/SharedUI/Helpers/UIView+NS.swift | 6 + 10 files changed, 302 insertions(+), 10 deletions(-) create mode 100644 DP3TApp/Resources/Assets.xcassets/CheckIn/ic-edit.imageset/Contents.json create mode 100644 DP3TApp/Resources/Assets.xcassets/CheckIn/ic-edit.imageset/ic-edit.png create mode 100644 DP3TApp/Resources/Assets.xcassets/CheckIn/ic-edit.imageset/ic-edit@2x.png create mode 100644 DP3TApp/Resources/Assets.xcassets/CheckIn/ic-edit.imageset/ic-edit@3x.png create mode 100644 DP3TApp/Screens/CheckIn/Edit/NSOverlappingCheckInView.swift create mode 100644 DP3TApp/Screens/CheckIn/Edit/NSOverlappingCheckinPopupViewController.swift diff --git a/DP3TApp.xcodeproj/project.pbxproj b/DP3TApp.xcodeproj/project.pbxproj index e21b6cd5..39f88f09 100644 --- a/DP3TApp.xcodeproj/project.pbxproj +++ b/DP3TApp.xcodeproj/project.pbxproj @@ -272,6 +272,9 @@ 6E5B69DD2660C3A400EB0C56 /* NSTracingOnboardingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8F52DD265CD5D600406430 /* NSTracingOnboardingViewController.swift */; }; 6E5B69E22660D67400EB0C56 /* NSCheckinOnboardingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E5B69E12660D67300EB0C56 /* NSCheckinOnboardingViewController.swift */; }; 6E5B69E32660D67C00EB0C56 /* NSCheckinOnboardingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E5B69E12660D67300EB0C56 /* NSCheckinOnboardingViewController.swift */; }; + 6E5F789D26DD4190006D11B0 /* NSOverlappingCheckinPopupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E5F789C26DD4190006D11B0 /* NSOverlappingCheckinPopupViewController.swift */; }; + 6E5F789E26DD41A7006D11B0 /* NSOverlappingCheckinPopupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E5F789C26DD4190006D11B0 /* NSOverlappingCheckinPopupViewController.swift */; }; + 6E5F78A026DD4B5B006D11B0 /* NSOverlappingCheckInView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E5F789F26DD4B5A006D11B0 /* NSOverlappingCheckInView.swift */; }; 6E6E516F242F4FE0006E532E /* ConfigManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E6E516E242F4FE0006E532E /* ConfigManager.swift */; }; 6E6E5171242F5026006E532E /* ConfigResponseBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E6E5170242F5026006E532E /* ConfigResponseBody.swift */; }; 6E6E5184242F9586006E532E /* NSInformThankYouViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E6E517E242F9586006E532E /* NSInformThankYouViewController.swift */; }; @@ -823,6 +826,8 @@ 6E5B6994265F71C600EB0C56 /* AppClipViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppClipViewController.swift; sourceTree = ""; }; 6E5B69C2265FD12D00EB0C56 /* DP3TAppClip-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DP3TAppClip-Bridging-Header.h"; sourceTree = ""; }; 6E5B69E12660D67300EB0C56 /* NSCheckinOnboardingViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSCheckinOnboardingViewController.swift; sourceTree = ""; }; + 6E5F789C26DD4190006D11B0 /* NSOverlappingCheckinPopupViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = NSOverlappingCheckinPopupViewController.swift; path = DP3TApp/Screens/Checkin/Edit/NSOverlappingCheckinPopupViewController.swift; sourceTree = SOURCE_ROOT; }; + 6E5F789F26DD4B5A006D11B0 /* NSOverlappingCheckInView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = NSOverlappingCheckInView.swift; path = DP3TApp/Screens/Checkin/Edit/NSOverlappingCheckInView.swift; sourceTree = SOURCE_ROOT; }; 6E6E516E242F4FE0006E532E /* ConfigManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfigManager.swift; sourceTree = ""; }; 6E6E5170242F5026006E532E /* ConfigResponseBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfigResponseBody.swift; sourceTree = ""; }; 6E6E517E242F9586006E532E /* NSInformThankYouViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSInformThankYouViewController.swift; sourceTree = ""; }; @@ -1819,7 +1824,12 @@ children = ( DC16175C2638717800B56ADA /* NSTimePickerControl.swift */, DC16175D2638717800B56ADA /* NSCheckInEditViewController.swift */, +<<<<<<< HEAD 6E84B1A626E0CD760000AC92 /* NSAlreadyCheckedInErrorPopupViewController.swift */, +======= + 6E5F789C26DD4190006D11B0 /* NSOverlappingCheckinPopupViewController.swift */, + 6E5F789F26DD4B5A006D11B0 /* NSOverlappingCheckInView.swift */, +>>>>>>> b23ce612 (adds popup for overlapping checkins) ); path = Edit; sourceTree = ""; @@ -2735,6 +2745,7 @@ DC1ACCC22637CCEA0054CBFC /* QRCodeUtils.swift in Sources */, 242D2209245C4BD8005DAEA8 /* String+NS.swift in Sources */, F862124F257A727E0043351E /* NSLinkHandler.swift in Sources */, + 6E5F789E26DD41A7006D11B0 /* NSOverlappingCheckinPopupViewController.swift in Sources */, F8ABA2F02526089E00A8D6B5 /* NSTutorialViewController.swift in Sources */, 242D220A245C4BD8005DAEA8 /* UBUserDefaultValue.swift in Sources */, 246FD176249B568F00FD36F8 /* Environment+AppStore.swift in Sources */, @@ -3003,6 +3014,7 @@ DCA3FFB6245048A50003F5AD /* NSUnderlinedButton.swift in Sources */, 242D227D245D6581005DAEA8 /* Endpoint.swift in Sources */, F87E96B02639967100755AF1 /* NSInfoViewController.swift in Sources */, + 6E5F789D26DD4190006D11B0 /* NSOverlappingCheckinPopupViewController.swift in Sources */, 2462BA152451FD150046906D /* AuthorizationModels.swift in Sources */, AAF73663242F2DC90051E34A /* NSModuleHeaderView.swift in Sources */, 6E0D1227263A92050014CF7C /* NSRoundImageButton.swift in Sources */, @@ -3069,6 +3081,7 @@ F85ED9A32499EF93007EBC49 /* Bundle+BuildInfo.swift in Sources */, DC003DE22642E98A0027F379 /* NSCheckInErrorViewModel.swift in Sources */, DCE1398D26382B5E0093D8F6 /* CreatedEventsManager.swift in Sources */, + 6E5F78A026DD4B5B006D11B0 /* NSOverlappingCheckInView.swift in Sources */, 6E6E5188242F9586006E532E /* NSSendViewController.swift in Sources */, DC3B568E25ECCDCD0075B5CE /* NSTravelInfoBoxView.swift in Sources */, DCB44315242DFF8000F19AA5 /* NSHomescreenViewController.swift in Sources */, diff --git a/DP3TApp/Resources/Assets.xcassets/CheckIn/ic-edit.imageset/Contents.json b/DP3TApp/Resources/Assets.xcassets/CheckIn/ic-edit.imageset/Contents.json new file mode 100644 index 00000000..7bd27bda --- /dev/null +++ b/DP3TApp/Resources/Assets.xcassets/CheckIn/ic-edit.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "ic-edit.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "ic-edit@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "ic-edit@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/DP3TApp/Resources/Assets.xcassets/CheckIn/ic-edit.imageset/ic-edit.png b/DP3TApp/Resources/Assets.xcassets/CheckIn/ic-edit.imageset/ic-edit.png new file mode 100644 index 0000000000000000000000000000000000000000..50608d2a7af14ced6a4c2ecaf0000c742cd56538 GIT binary patch literal 223 zcmeAS@N?(olHy`uVBq!ia0vp^5URmDW zxn7=`K0euAUO;Z9zdwkZn+qnL=E?xI@RS7k1v7B$sF1rSFz1ZcOLo4R{%1h(Xipc% z5Q)pl2@1Rh)(SUzth5DXz8No9JD?hrbdKeKg;VajbglZuNJ}eKRxk@TGBK=CS7&0LlXe1V4TGnv KpUXO@geCwKLP321 literal 0 HcmV?d00001 diff --git a/DP3TApp/Resources/Assets.xcassets/CheckIn/ic-edit.imageset/ic-edit@2x.png b/DP3TApp/Resources/Assets.xcassets/CheckIn/ic-edit.imageset/ic-edit@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..fe724613575b9db7fdc437d4e6dc4591281a20c5 GIT binary patch literal 238 zcmeAS@N?(olHy`uVBq!ia0vp^20(1Y!VDx|JaOF*q~rp8LR{Sod;$UryuGr#ys~_J zD*U{%y*;x)$UDo+GxMyravD%2XGxG>FoVK_T5i`RhaGQa-na%7Ec0}646!)<_WW+% z1_J@+0A;a`8w#qjy3qzq*%u6*1?JzL7Ne1DUg8mxZF`fw=J%}B2af6N?0avXX)H8) z)-dT>^V+-!`5^N*t#eW?JyDtD8Lp-|L4J-w00*m|M!}&*SH_?p2e}zo7chu4Far&*B0y85}Sb4q9e0Q&S#<^TWy literal 0 HcmV?d00001 diff --git a/DP3TApp/Resources/Assets.xcassets/CheckIn/ic-edit.imageset/ic-edit@3x.png b/DP3TApp/Resources/Assets.xcassets/CheckIn/ic-edit.imageset/ic-edit@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..d2c58cf76adea377f68d5e0b4b8ba0eca9e7b5fa GIT binary patch literal 298 zcmV+_0oDGAP)6z>XsT006p4L_t(Y z$L-ZI4gxU@1i-){xkaI%g&)xHgL?p?q2&u{*za?>BY`H~tq@3Yy&A=iWQWk}S85nf zJakNvX4ZS81BC!Y4uMh`V$=*VYPdn5&d{lJX}{=RscpNpN1@u%)LNn1Z<=OQsOZjU zpf+`tN;K2 literal 0 HcmV?d00001 diff --git a/DP3TApp/Screens/CheckIn/Edit/NSCheckInEditViewController.swift b/DP3TApp/Screens/CheckIn/Edit/NSCheckInEditViewController.swift index a5e68544..4b31d81a 100644 --- a/DP3TApp/Screens/CheckIn/Edit/NSCheckInEditViewController.swift +++ b/DP3TApp/Screens/CheckIn/Edit/NSCheckInEditViewController.swift @@ -29,6 +29,7 @@ class NSCheckInEditViewController: NSViewController { private var checkIn: CheckIn? public var userWillCheckOutCallback: (() -> Void)? + public var userUpdatedCheckIn: (() -> Void)? private let checkoutButton = NSButton(title: "checkout_button_title".ub_localized, style: .normal(.ns_blue)) @@ -135,19 +136,26 @@ class NSCheckInEditViewController: NSViewController { } static func selectedDatesAreOverlapping(startDate: Date, endDate: Date, excludeCheckIn: CheckIn?) -> Bool { + return overlappingCheckIns(startDate: startDate, endDate: endDate, excludeCheckIn: excludeCheckIn).count != 0 + } + + static func overlappingCheckIns(startDate: Date, endDate: Date, excludeCheckIn: CheckIn?) -> [CheckIn] { var diary = CheckInManager.shared.getDiary() diary = diary.filter { $0 != excludeCheckIn } let selectedTimeRange = startDate ... endDate + var overlappingCheckins: [CheckIn] = [] + for savedCheckIn in diary { if let checkOutTime = savedCheckIn.checkOutTime { // diary entries should always have checkOutTime let savedTimeRange = savedCheckIn.checkInTime ... checkOutTime if savedTimeRange.overlaps(selectedTimeRange) { - return true + overlappingCheckins.append(savedCheckIn) } } } - return false + + return overlappingCheckins } private func selectedTimeRangeExceedsMaximum() -> Bool { @@ -173,10 +181,22 @@ class NSCheckInEditViewController: NSViewController { } private func showOverlappingDatesAlert() { - let alert = UIAlertController(title: "checkout_overlapping_alert_title".ub_localized, message: "checkout_overlapping_alert_description".ub_localized, preferredStyle: .alert) - alert.addAction(UIAlertAction(title: "android_button_ok".ub_localized, style: .default)) + if !isCurrentCheckIn { + let alert = UIAlertController(title: "checkout_overlapping_alert_title".ub_localized, message: "checkout_overlapping_alert_description".ub_localized, preferredStyle: .alert) + alert.addAction(UIAlertAction(title: "android_button_ok".ub_localized, style: .default)) + present(alert, animated: true, completion: nil) + } else { + if let ci = checkIn { + let alert = NSOverlappingCheckinPopupViewController(checkIn: ci, startDate: startDate, endDate: endDate) - present(alert, animated: true, completion: nil) + alert.checkOutCallback = { [weak self] in + guard let strongSelf = self else { return } + strongSelf.saveButtonTouched() + } + + present(alert, animated: true, completion: nil) + } + } } private func showTimeRangeErrorAlert() { @@ -222,13 +242,13 @@ class NSCheckInEditViewController: NSViewController { return } - guard !selectedDatesAreOverlapping() else { - showOverlappingDatesAlert() + guard !selectedTimeRangeExceedsMaximum() else { + showTimeRangeErrorAlert() return } - guard !selectedTimeRangeExceedsMaximum() else { - showTimeRangeErrorAlert() + guard !selectedDatesAreOverlapping() else { + showOverlappingDatesAlert() return } @@ -242,6 +262,8 @@ class NSCheckInEditViewController: NSViewController { } else { updateCheckIn() + + userUpdatedCheckIn?() dismiss(animated: true, completion: nil) } } @@ -342,6 +364,8 @@ class NSCheckInEditViewController: NSViewController { guard let strongSelf = self else { return } CheckInManager.shared.hideFromDiary(identifier: checkIn.identifier) + + strongSelf.userUpdatedCheckIn?() strongSelf.dismiss(animated: true, completion: nil) } @@ -350,6 +374,8 @@ class NSCheckInEditViewController: NSViewController { CheckInManager.shared.hideFromDiary(identifier: checkIn.identifier) CrowdNotifier.removeCheckin(with: checkIn.identifier) + + strongSelf.userUpdatedCheckIn?() strongSelf.dismiss(animated: true, completion: nil) } diff --git a/DP3TApp/Screens/CheckIn/Edit/NSOverlappingCheckInView.swift b/DP3TApp/Screens/CheckIn/Edit/NSOverlappingCheckInView.swift new file mode 100644 index 00000000..31e0dcb7 --- /dev/null +++ b/DP3TApp/Screens/CheckIn/Edit/NSOverlappingCheckInView.swift @@ -0,0 +1,57 @@ +// +/* + * Copyright (c) 2021 Ubique Innovation AG + * + * 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 + */ + +import Foundation + +class NSOverlappingCheckInView: UBButton { + private let checkIn: CheckIn + + private let diaryContentView = NSDiaryEntryContentView() + + init(checkIn: CheckIn) { + self.checkIn = checkIn + super.init() + setup() + } + + required init?(coder _: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: - Setup + + private func setup() { + backgroundColor = UIColor.white + highlightedBackgroundColor = UIColor.black.withAlphaComponent(0.15) + + addSubview(diaryContentView) + diaryContentView.backgroundColor = UIColor.clear + diaryContentView.isUserInteractionEnabled = false + diaryContentView.checkIn = checkIn + + diaryContentView.snp.makeConstraints { make in + make.top.left.bottom.equalToSuperview() + } + + let imageView = UIImageView(image: UIImage(named: "ic-edit")) + addSubview(imageView) + + imageView.ub_setContentPriorityRequired() + + imageView.snp.makeConstraints { make in + make.top.right.equalToSuperview().inset(NSPadding.medium) + } + + layer.cornerRadius = 3.0 + highlightCornerRadius = 3.0 + ub_addShadow(radius: 5.0, opacity: 0.17, xOffset: 0.0, yOffset: 0.0) + } +} diff --git a/DP3TApp/Screens/CheckIn/Edit/NSOverlappingCheckinPopupViewController.swift b/DP3TApp/Screens/CheckIn/Edit/NSOverlappingCheckinPopupViewController.swift new file mode 100644 index 00000000..5c7aa3cb --- /dev/null +++ b/DP3TApp/Screens/CheckIn/Edit/NSOverlappingCheckinPopupViewController.swift @@ -0,0 +1,166 @@ +// +/* + * Copyright (c) 2021 Ubique Innovation AG + * + * 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 + */ + +import Foundation + +class NSOverlappingCheckinPopupViewController: NSPopupViewController { + private let backButton = NSButton(title: "checkin_overlap_back_button".ub_localized, style: .normal(.ns_blue)) + private let checkoutButton = NSButton(title: "checkout_button_title".ub_localized, style: .normal(.ns_blue)) + + private let checkIn: CheckIn + private let startDate: Date + private let endDate: Date + + private var overlappingCheckIns: [CheckIn] = [] + + public var checkOutCallback: (() -> Void)? + + // MARK: - Init + + init(checkIn: CheckIn, startDate: Date, endDate: Date) { + self.checkIn = checkIn + self.startDate = startDate + self.endDate = endDate + super.init(stackViewInset: UIEdgeInsets(top: NSPadding.medium, left: 2.0 * NSPadding.medium, bottom: 40, right: 2.0 * NSPadding.medium)) + } + + // MARK: - View + + override func viewDidLoad() { + super.viewDidLoad() + + tintColor = .ns_blue + resetup() + } + + // MARK: - (Re)Setup + + private func resetup() { + stackView.arrangedSubviews.forEach { view in + if view != self.closeButtonWrapper { + view.removeFromSuperview() + } + } + + overlappingCheckIns = NSCheckInEditViewController.overlappingCheckIns(startDate: startDate, endDate: endDate, excludeCheckIn: checkIn) + + if overlappingCheckIns.count == 0 { + setupSuccess() + } else { + setupCollisions() + } + } + + private func setupSuccess() { + closeButtonWrapper.ub_setHidden(false) + + let v = UIView() + let check = UIImageView(image: UIImage(named: "ic-check-circle")) + v.addSubview(check) + check.snp.makeConstraints { make in + make.top.bottom.centerX.equalToSuperview() + } + + stackView.addArrangedView(v) + stackView.addSpacerView(NSPadding.large) + + let textLabel = NSLabel(.textLight, textAlignment: .left) + textLabel.attributedText = "checkin_overlap_popup_success_text".ub_localized.replacingOccurrences(of: "{CHECKIN}", with: checkIn.venue.description).formattingOccurrenceBold(checkIn.venue.description) + stackView.addArrangedView(textLabel) + + stackView.addSpacerView(2.0 * NSPadding.large) + + let venueTitleLabel = NSLabel(.textBold, textColor: .ns_blue, textAlignment: .center) + let venueTimeLabel = NSLabel(.textLight, textColor: .ns_blue, textAlignment: .center) + + venueTitleLabel.text = checkIn.venue.description + venueTimeLabel.text = DateFormatter.ub_fromTimeToTime(from: startDate, to: endDate) + + stackView.addArrangedView(venueTitleLabel) + stackView.addSpacerView(NSPadding.small) + stackView.addArrangedView(venueTimeLabel) + + stackView.addSpacerView(NSPadding.large) + + let coView = UIView() + coView.addSubview(checkoutButton) + checkoutButton.snp.makeConstraints { make in + make.top.bottom.centerX.equalToSuperview() + make.width.equalTo(150.0) + } + + stackView.addArrangedView(coView) + stackView.addSpacerView(NSPadding.small) + + checkoutButton.touchUpCallback = { [weak self] in + guard let strongSelf = self else { return } + strongSelf.dismiss() + strongSelf.checkOutCallback?() + } + } + + private func setupCollisions() { + closeButtonWrapper.ub_setHidden(true) + + stackView.addSpacerView(NSPadding.large) + + let tileLabel = NSLabel(.title, textAlignment: .left) + tileLabel.text = "checkin_overlap_popup_title".ub_localized + stackView.addArrangedView(tileLabel) + + stackView.addSpacerView(2.0 * NSPadding.medium) + + let textLabel = NSLabel(.textLight, textAlignment: .left) + textLabel.attributedText = "checkin_overlap_popup_text".ub_localized.replacingOccurrences(of: "{CHECKIN}", with: checkIn.venue.description).formattingOccurrenceBold(checkIn.venue.description) + stackView.addArrangedView(textLabel) + + stackView.addSpacerView(NSPadding.large) + + for c in overlappingCheckIns { + let ev = NSOverlappingCheckInView(checkIn: c) + ev.touchUpCallback = { [weak self] in + guard let strongSelf = self else { return } + strongSelf.presentEditViewController(for: c) + } + + stackView.addArrangedView(ev) + + stackView.addSpacerView(NSPadding.small + NSPadding.medium) + } + + stackView.addSpacerView(NSPadding.large) + + let v = UIView() + v.addSubview(backButton) + backButton.snp.makeConstraints { make in + make.top.bottom.centerX.equalToSuperview() + make.width.equalTo(150.0) + } + + stackView.addArrangedView(v) + stackView.addSpacerView(NSPadding.small) + + backButton.touchUpCallback = { [weak self] in + guard let strongSelf = self else { return } + strongSelf.dismiss() + } + } + + private func presentEditViewController(for checkIn: CheckIn) { + let vc = NSCheckInEditViewController(checkIn: checkIn) + vc.userUpdatedCheckIn = { [weak self] in + guard let strongSelf = self else { return } + strongSelf.resetup() + } + + vc.presentInNavigationController(from: self, useLine: false) + } +} diff --git a/DP3TApp/SharedUI/Base/NSPopupViewController.swift b/DP3TApp/SharedUI/Base/NSPopupViewController.swift index 8ee87121..8e458200 100644 --- a/DP3TApp/SharedUI/Base/NSPopupViewController.swift +++ b/DP3TApp/SharedUI/Base/NSPopupViewController.swift @@ -44,6 +44,8 @@ class NSPopupViewController: NSViewController { return button }() + let closeButtonWrapper = UIView() + var tintColor: UIColor = .white { didSet { if showCloseButton { @@ -141,7 +143,6 @@ class NSPopupViewController: NSViewController { stackView.distribution = .fill if showCloseButton { - let closeButtonWrapper = UIView() closeButtonWrapper.addSubview(closeButton) closeButton.snp.makeConstraints { make in make.top.bottom.trailing.equalToSuperview() diff --git a/DP3TApp/SharedUI/Helpers/UIView+NS.swift b/DP3TApp/SharedUI/Helpers/UIView+NS.swift index 6759b4a8..f1429fd3 100644 --- a/DP3TApp/SharedUI/Helpers/UIView+NS.swift +++ b/DP3TApp/SharedUI/Helpers/UIView+NS.swift @@ -29,4 +29,10 @@ public extension UIView { setContentCompressionResistancePriority(.required, for: .horizontal) setContentCompressionResistancePriority(.required, for: .vertical) } + + func ub_setHidden(_ hidden: Bool) { + if isHidden != hidden { + isHidden = hidden + } + } } From dec14e12e38e8d0e9ff98a3aa3d383f409052975 Mon Sep 17 00:00:00 2001 From: Marco Zimmermann Date: Thu, 2 Sep 2021 10:55:14 +0200 Subject: [PATCH 06/27] removes minute rounding to allow for back-to-back checkins Signed-off-by: Marco Zimmermann --- .../CheckIn/CheckInManager/CheckInManager.swift | 12 ++---------- .../CheckIn/Edit/NSCheckInEditViewController.swift | 8 -------- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/DP3TApp/Logic/CheckIn/CheckInManager/CheckInManager.swift b/DP3TApp/Logic/CheckIn/CheckInManager/CheckInManager.swift index 16f5f928..fe21aa4f 100644 --- a/DP3TApp/Logic/CheckIn/CheckInManager/CheckInManager.swift +++ b/DP3TApp/Logic/CheckIn/CheckInManager/CheckInManager.swift @@ -154,16 +154,8 @@ class CheckInManager { static func normalizeDates(start: Date, end: Date) -> (start: Date, end: Date) { // If for some reason, checkout is before checkin, just swap the two dates - var startTime = start > end ? end : start - var endTime = start > end ? start : end - - startTime = startTime.roundedToMinute(rule: .down) - endTime = endTime.roundedToMinute(rule: .up) - - if startTime == endTime { - endTime = endTime.addingTimeInterval(.minute) - } - + let startTime = start > end ? end : start + let endTime = start > end ? start : end return (start: startTime, end: endTime) } diff --git a/DP3TApp/Screens/CheckIn/Edit/NSCheckInEditViewController.swift b/DP3TApp/Screens/CheckIn/Edit/NSCheckInEditViewController.swift index 4b31d81a..ad1b1e43 100644 --- a/DP3TApp/Screens/CheckIn/Edit/NSCheckInEditViewController.swift +++ b/DP3TApp/Screens/CheckIn/Edit/NSCheckInEditViewController.swift @@ -272,19 +272,11 @@ class NSCheckInEditViewController: NSViewController { fromTimePickerControl.inputControl.timeChangedCallback = { [weak self] date in guard let strongSelf = self else { return } strongSelf.startDate = date - if strongSelf.startDate == strongSelf.endDate { - strongSelf.startDate = strongSelf.startDate.addingTimeInterval(-1 * .minute) - strongSelf.fromTimePickerControl.inputControl.setDate(currentStart: strongSelf.startDate, currentEnd: strongSelf.endDate) - } } toTimePickerControl.inputControl.timeChangedCallback = { [weak self] date in guard let strongSelf = self else { return } strongSelf.endDate = date - if strongSelf.startDate == strongSelf.endDate { - strongSelf.endDate = strongSelf.endDate.addingTimeInterval(.minute) - strongSelf.toTimePickerControl.inputControl.setDate(currentStart: strongSelf.startDate, currentEnd: strongSelf.endDate) - } } } From 8ac38b03729a24c8f9c0bf1bbf9a8e782d7fae84 Mon Sep 17 00:00:00 2001 From: Marco Zimmermann Date: Fri, 3 Sep 2021 08:58:27 +0200 Subject: [PATCH 07/27] fixes dark mode Signed-off-by: Marco Zimmermann --- DP3TApp/Screens/CheckIn/Edit/NSOverlappingCheckInView.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DP3TApp/Screens/CheckIn/Edit/NSOverlappingCheckInView.swift b/DP3TApp/Screens/CheckIn/Edit/NSOverlappingCheckInView.swift index 31e0dcb7..9c6e87da 100644 --- a/DP3TApp/Screens/CheckIn/Edit/NSOverlappingCheckInView.swift +++ b/DP3TApp/Screens/CheckIn/Edit/NSOverlappingCheckInView.swift @@ -29,7 +29,7 @@ class NSOverlappingCheckInView: UBButton { // MARK: - Setup private func setup() { - backgroundColor = UIColor.white + backgroundColor = UIColor.ns_background highlightedBackgroundColor = UIColor.black.withAlphaComponent(0.15) addSubview(diaryContentView) @@ -41,7 +41,7 @@ class NSOverlappingCheckInView: UBButton { make.top.left.bottom.equalToSuperview() } - let imageView = UIImageView(image: UIImage(named: "ic-edit")) + let imageView = NSImageView(image: UIImage(named: "ic-edit"), dynamicColor: UIColor.ns_text) addSubview(imageView) imageView.ub_setContentPriorityRequired() From 895cfb535cb76aa8d42021bd07286d965b7d98de Mon Sep 17 00:00:00 2001 From: Marco Zimmermann Date: Fri, 3 Sep 2021 09:25:44 +0200 Subject: [PATCH 08/27] fixes problem with dismissal of checkout after fixing overlapping checkins Signed-off-by: Marco Zimmermann --- .../Edit/NSCheckInEditViewController.swift | 26 ++++++++++++------- ...verlappingCheckinPopupViewController.swift | 5 ++-- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/DP3TApp/Screens/CheckIn/Edit/NSCheckInEditViewController.swift b/DP3TApp/Screens/CheckIn/Edit/NSCheckInEditViewController.swift index ad1b1e43..55c2b6b3 100644 --- a/DP3TApp/Screens/CheckIn/Edit/NSCheckInEditViewController.swift +++ b/DP3TApp/Screens/CheckIn/Edit/NSCheckInEditViewController.swift @@ -191,7 +191,7 @@ class NSCheckInEditViewController: NSViewController { alert.checkOutCallback = { [weak self] in guard let strongSelf = self else { return } - strongSelf.saveButtonTouched() + strongSelf.saveButtonTouched(delayDismiss: 0.15) } present(alert, animated: true, completion: nil) @@ -220,7 +220,7 @@ class NSCheckInEditViewController: NSViewController { fileprivate func setupCheckout() { navigationItem.leftBarButtonItem = UIBarButtonItem(title: "cancel".ub_localized, style: .done, target: self, action: #selector(cancelButtonTouched)) if !isCurrentCheckIn { - navigationItem.rightBarButtonItem = UIBarButtonItem(title: "checkout_save_button_title".ub_localized, style: .done, target: self, action: #selector(saveButtonTouched)) + navigationItem.rightBarButtonItem = UIBarButtonItem(title: "checkout_save_button_title".ub_localized, style: .done, target: self, action: #selector(save)) } let attributes = [ @@ -236,7 +236,11 @@ class NSCheckInEditViewController: NSViewController { dismiss(animated: true, completion: nil) } - @objc private func saveButtonTouched() { + @objc private func save() { + saveButtonTouched() + } + + private func saveButtonTouched(delayDismiss: CGFloat? = nil) { guard startDate < endDate else { showEndDateBeforeStartDateAlert() return @@ -252,18 +256,22 @@ class NSCheckInEditViewController: NSViewController { return } + // update checkin or checkout if isCurrentCheckIn { updateCheckIn() - userWillCheckOutCallback?() CheckInManager.shared.checkOut() - - dismiss(animated: true, completion: nil) - } else { updateCheckIn() - userUpdatedCheckIn?() + } + + // dismiss after saving/checkout + if let d = delayDismiss { + DispatchQueue.main.asyncAfter(deadline: .now() + TimeInterval(d)) { + self.dismiss(animated: true, completion: nil) + } + } else { dismiss(animated: true, completion: nil) } } @@ -322,7 +330,7 @@ class NSCheckInEditViewController: NSViewController { checkoutButton.touchUpCallback = { [weak self] in guard let strongSelf = self else { return } - strongSelf.saveButtonTouched() + strongSelf.save() } stackScrollView.addArrangedView(view) diff --git a/DP3TApp/Screens/CheckIn/Edit/NSOverlappingCheckinPopupViewController.swift b/DP3TApp/Screens/CheckIn/Edit/NSOverlappingCheckinPopupViewController.swift index 5c7aa3cb..821983ae 100644 --- a/DP3TApp/Screens/CheckIn/Edit/NSOverlappingCheckinPopupViewController.swift +++ b/DP3TApp/Screens/CheckIn/Edit/NSOverlappingCheckinPopupViewController.swift @@ -102,8 +102,9 @@ class NSOverlappingCheckinPopupViewController: NSPopupViewController { checkoutButton.touchUpCallback = { [weak self] in guard let strongSelf = self else { return } - strongSelf.dismiss() - strongSelf.checkOutCallback?() + strongSelf.dismiss(animated: true) { + strongSelf.checkOutCallback?() + } } } From 9ea6fc2254db56f3c3c92f56d26412f73506e840 Mon Sep 17 00:00:00 2001 From: Marco Zimmermann Date: Fri, 3 Sep 2021 09:35:29 +0200 Subject: [PATCH 09/27] fixes calibration build Signed-off-by: Marco Zimmermann --- DP3TApp.xcodeproj/project.pbxproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DP3TApp.xcodeproj/project.pbxproj b/DP3TApp.xcodeproj/project.pbxproj index 39f88f09..41f15e8c 100644 --- a/DP3TApp.xcodeproj/project.pbxproj +++ b/DP3TApp.xcodeproj/project.pbxproj @@ -327,6 +327,7 @@ 6EC172CF26411C0F002E27DB /* NSUpdateBoardingCheckInViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EC172CD26411BEF002E27DB /* NSUpdateBoardingCheckInViewController.swift */; }; 6EC47BD42451C3C2000D7686 /* NSReportsDetailExposedEncountersTitleHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EC47BD32451C3C2000D7686 /* NSReportsDetailExposedEncountersTitleHeader.swift */; }; 6EDE754B2667B97E00A2656F /* NSCheckInErrorViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC003DE12642E98A0027F379 /* NSCheckInErrorViewModel.swift */; }; + 6EDF70E726E207A900BB51B1 /* NSOverlappingCheckInView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E5F789F26DD4B5A006D11B0 /* NSOverlappingCheckInView.swift */; }; 6EE81DEB245163C400FC7218 /* PhoneCallHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EE81DEA245163C400FC7218 /* PhoneCallHelper.swift */; }; 6EED5DAC24518DB400AD42D9 /* NSInformGetWellViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EED5DAB24518DB400AD42D9 /* NSInformGetWellViewController.swift */; }; 6EF28CFE26370538001C1565 /* NSQRScannerOverlay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EF28CFC26370538001C1565 /* NSQRScannerOverlay.swift */; }; @@ -2805,6 +2806,7 @@ F80E40742509039400876906 /* NSStatisticsChartView.swift in Sources */, 2411CA9B245F105C002FB5A9 /* Endpoint.swift in Sources */, DCE1398E26382B5E0093D8F6 /* CreatedEventsManager.swift in Sources */, + 6EDF70E726E207A900BB51B1 /* NSOverlappingCheckInView.swift in Sources */, F84BC8AB2664FBBF00678456 /* NSPushRegistrationManager.swift in Sources */, F830799424929090005D3C65 /* LoggingStorage.swift in Sources */, 242D2222245C4BD8005DAEA8 /* NSInformTracingEndViewController.swift in Sources */, From a3f3f08b8748955545c5aae630de6ac26941a885 Mon Sep 17 00:00:00 2001 From: Marco Zimmermann Date: Tue, 7 Sep 2021 08:37:41 +0200 Subject: [PATCH 10/27] updates translations Signed-off-by: Marco Zimmermann --- DP3TApp.xcodeproj/project.pbxproj | 3 --- Translations/bs.lproj/Localizable.strings | 11 +---------- Translations/de.lproj/Localizable.strings | 14 +------------- Translations/en.lproj/Localizable.strings | 11 +---------- Translations/es.lproj/Localizable.strings | 11 +---------- Translations/fr.lproj/Localizable.strings | 11 +---------- Translations/hr.lproj/Localizable.strings | 11 +---------- Translations/it.lproj/Localizable.strings | 11 +---------- Translations/pt.lproj/Localizable.strings | 11 +---------- Translations/rm.lproj/Localizable.strings | 11 +---------- Translations/sq.lproj/Localizable.strings | 11 +---------- Translations/sr-Latn-RS.lproj/Localizable.strings | 11 +---------- Translations/ti.lproj/Localizable.strings | 11 +---------- Translations/tr.lproj/Localizable.strings | 11 +---------- 14 files changed, 13 insertions(+), 136 deletions(-) diff --git a/DP3TApp.xcodeproj/project.pbxproj b/DP3TApp.xcodeproj/project.pbxproj index 41f15e8c..2bc3cd02 100644 --- a/DP3TApp.xcodeproj/project.pbxproj +++ b/DP3TApp.xcodeproj/project.pbxproj @@ -1825,12 +1825,9 @@ children = ( DC16175C2638717800B56ADA /* NSTimePickerControl.swift */, DC16175D2638717800B56ADA /* NSCheckInEditViewController.swift */, -<<<<<<< HEAD 6E84B1A626E0CD760000AC92 /* NSAlreadyCheckedInErrorPopupViewController.swift */, -======= 6E5F789C26DD4190006D11B0 /* NSOverlappingCheckinPopupViewController.swift */, 6E5F789F26DD4B5A006D11B0 /* NSOverlappingCheckInView.swift */, ->>>>>>> b23ce612 (adds popup for overlapping checkins) ); path = Edit; sourceTree = ""; diff --git a/Translations/bs.lproj/Localizable.strings b/Translations/bs.lproj/Localizable.strings index 816b679b..a2e89b84 100644 --- a/Translations/bs.lproj/Localizable.strings +++ b/Translations/bs.lproj/Localizable.strings @@ -1466,7 +1466,7 @@ "error_title" = "Greška"; "qr_scanner_error_code_not_yet_valid" = "QR kod je još nevažeći"; "qr_scanner_error_code_not_valid_anymore" = "QR kod je nevažeći "; -"error_already_checked_in" = "Upravo ste prijavljeni."; +"error_already_checked_in" = ""; "error_update_text" = "Ovaj QR kod nije kompatibilan sa instaliranom verzijom aplikacije. Ažurirajte aplikaciju, da biste nastavili korišćenje."; "error_update_title" = "Potrebno ažuriranje"; "error_action_update" = "Sada ažurirati"; @@ -1737,9 +1737,6 @@ /*Button um Covid Certificate App zu installieren*/ "covid_certificate_install_app" = "Instalirati aplikaciju"; -"web_generator_title" = ""; -"web_generator_title_label" = ""; -"web_generator_generate_button" = ""; /*Titel des Buttons, der das PDF herunterlädt*/ "web_generator_download_pdf_button" = ""; @@ -1771,15 +1768,9 @@ /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ "checkin_overlap_popup_success_text" = ""; -/*Infotext beim Generieren eines QR-Codes*/ -"web_generator_message" = ""; - /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ "web_generator_success_title" = ""; -/*Titel des Buttons, der das PDF ausdruckt*/ -"web_generator_print_pdf_button" = ""; - /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ "web_generator_reset_button" = ""; diff --git a/Translations/de.lproj/Localizable.strings b/Translations/de.lproj/Localizable.strings index c1bb254d..bba469a5 100644 --- a/Translations/de.lproj/Localizable.strings +++ b/Translations/de.lproj/Localizable.strings @@ -1529,7 +1529,7 @@ "error_title" = "Fehler"; "qr_scanner_error_code_not_yet_valid" = "QR-Code noch nicht gültig"; "qr_scanner_error_code_not_valid_anymore" = "QR-Code nicht mehr gültig"; -"error_already_checked_in" = "Sie sind bereits eingecheckt."; +"error_already_checked_in" = "Sie sind bereits an einem anderen Ort eingecheckt."; "error_update_text" = "Dieser QR-Code ist nicht mit der installierten App-Version kompatibel. Bitte aktualisieren Sie die App, um fortzufahren."; "error_update_title" = "Update erforderlich"; "error_action_update" = "Jetzt aktualisieren"; @@ -1818,11 +1818,6 @@ /*Button um Covid Certificate App zu installieren*/ "covid_certificate_install_app" = "App installieren"; -"web_generator_title" = "QR-Code erstellen"; -"web_generator_title_label" = ""; - -/*Fuzzy*/ -"web_generator_generate_button" = "QR-Code erstellen"; /*Titel des Buttons, der das PDF herunterlädt*/ /*Fuzzy*/ @@ -1855,16 +1850,9 @@ /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ "checkin_overlap_popup_success_text" = "Es gibt keine Konflikte mehr für Ihre eingetragene Zeit. Sie können jetzt bei {CHECKIN} auschecken."; -/*Infotext beim Generieren eines QR-Codes*/ -/*Fuzzy*/ -"web_generator_message" = "Vergeben Sie einen Titel, der den Ort \noder Ihren Anlass näher beschreibt. \nDieser Titel wird beim Check-in angezeigt."; - /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ "web_generator_success_title" = "QR-Code erstellt"; -/*Titel des Buttons, der das PDF ausdruckt*/ -"web_generator_print_pdf_button" = "PDF drucken"; - /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ "web_generator_reset_button" = "Neuen QR-Code erstellen"; diff --git a/Translations/en.lproj/Localizable.strings b/Translations/en.lproj/Localizable.strings index a6c6bc38..2c4535ee 100644 --- a/Translations/en.lproj/Localizable.strings +++ b/Translations/en.lproj/Localizable.strings @@ -1494,7 +1494,7 @@ "error_title" = "Error"; "qr_scanner_error_code_not_yet_valid" = "QR code not yet valid"; "qr_scanner_error_code_not_valid_anymore" = "QR code no longer valid"; -"error_already_checked_in" = "You are already checked in."; +"error_already_checked_in" = ""; "error_update_text" = "This QR code is not compatible with the installed version of the app. Please update the app to continue."; "error_update_title" = "Update required"; "error_action_update" = "Update now"; @@ -1765,9 +1765,6 @@ /*Button um Covid Certificate App zu installieren*/ "covid_certificate_install_app" = "Install app"; -"web_generator_title" = ""; -"web_generator_title_label" = ""; -"web_generator_generate_button" = ""; /*Titel des Buttons, der das PDF herunterlädt*/ "web_generator_download_pdf_button" = ""; @@ -1799,15 +1796,9 @@ /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ "checkin_overlap_popup_success_text" = ""; -/*Infotext beim Generieren eines QR-Codes*/ -"web_generator_message" = ""; - /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ "web_generator_success_title" = ""; -/*Titel des Buttons, der das PDF ausdruckt*/ -"web_generator_print_pdf_button" = ""; - /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ "web_generator_reset_button" = ""; diff --git a/Translations/es.lproj/Localizable.strings b/Translations/es.lproj/Localizable.strings index 9c7be918..c4c618d6 100644 --- a/Translations/es.lproj/Localizable.strings +++ b/Translations/es.lproj/Localizable.strings @@ -1466,7 +1466,7 @@ "error_title" = "Error"; "qr_scanner_error_code_not_yet_valid" = "Código QR aún no válido"; "qr_scanner_error_code_not_valid_anymore" = "Código QR ya no es válido"; -"error_already_checked_in" = "Ya ha registrado su entrada."; +"error_already_checked_in" = ""; "error_update_text" = "Este código QR no es compatible con la versión instalada de la app. Actualice la aplicación para continuar."; "error_update_title" = "Se requiere actualización"; "error_action_update" = "Actualizar ahora"; @@ -1737,9 +1737,6 @@ /*Button um Covid Certificate App zu installieren*/ "covid_certificate_install_app" = "Instalar la aplicación"; -"web_generator_title" = ""; -"web_generator_title_label" = ""; -"web_generator_generate_button" = ""; /*Titel des Buttons, der das PDF herunterlädt*/ "web_generator_download_pdf_button" = ""; @@ -1771,15 +1768,9 @@ /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ "checkin_overlap_popup_success_text" = ""; -/*Infotext beim Generieren eines QR-Codes*/ -"web_generator_message" = ""; - /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ "web_generator_success_title" = ""; -/*Titel des Buttons, der das PDF ausdruckt*/ -"web_generator_print_pdf_button" = ""; - /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ "web_generator_reset_button" = ""; diff --git a/Translations/fr.lproj/Localizable.strings b/Translations/fr.lproj/Localizable.strings index 53bf6123..9eda5220 100644 --- a/Translations/fr.lproj/Localizable.strings +++ b/Translations/fr.lproj/Localizable.strings @@ -1499,7 +1499,7 @@ "error_title" = "Erreur"; "qr_scanner_error_code_not_yet_valid" = "Le code QR n’est pas encore valable."; "qr_scanner_error_code_not_valid_anymore" = "Le code QR n’est plus valable."; -"error_already_checked_in" = "Votre check-in a déjà été établie."; +"error_already_checked_in" = ""; "error_update_text" = "Ce code QR n'est pas compatible avec la version installée de l’application. Veuillez mettre à jour l’application."; "error_update_title" = "Mise à jour requise"; "error_action_update" = "Mettre à jour "; @@ -1770,9 +1770,6 @@ /*Button um Covid Certificate App zu installieren*/ "covid_certificate_install_app" = "Installer l'application"; -"web_generator_title" = ""; -"web_generator_title_label" = ""; -"web_generator_generate_button" = ""; /*Titel des Buttons, der das PDF herunterlädt*/ "web_generator_download_pdf_button" = ""; @@ -1804,15 +1801,9 @@ /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ "checkin_overlap_popup_success_text" = ""; -/*Infotext beim Generieren eines QR-Codes*/ -"web_generator_message" = ""; - /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ "web_generator_success_title" = ""; -/*Titel des Buttons, der das PDF ausdruckt*/ -"web_generator_print_pdf_button" = ""; - /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ "web_generator_reset_button" = ""; diff --git a/Translations/hr.lproj/Localizable.strings b/Translations/hr.lproj/Localizable.strings index c4b8b1e0..a3ffcd73 100644 --- a/Translations/hr.lproj/Localizable.strings +++ b/Translations/hr.lproj/Localizable.strings @@ -1464,7 +1464,7 @@ "error_title" = "Greška"; "qr_scanner_error_code_not_yet_valid" = "QR kod je još nevažeći"; "qr_scanner_error_code_not_valid_anymore" = "QR kod je nevažeći "; -"error_already_checked_in" = "Upravo ste prijavljeni."; +"error_already_checked_in" = ""; "error_update_text" = "Ovaj QR kod nije kompatibilan sa instaliranom verzijom aplikacije. Ažurirajte aplikaciju, da biste nastavili korišćenje."; "error_update_title" = "Potrebno ažuriranje"; "error_action_update" = "Sada ažurirati"; @@ -1735,9 +1735,6 @@ /*Button um Covid Certificate App zu installieren*/ "covid_certificate_install_app" = "Instalirati aplikaciju"; -"web_generator_title" = ""; -"web_generator_title_label" = ""; -"web_generator_generate_button" = ""; /*Titel des Buttons, der das PDF herunterlädt*/ "web_generator_download_pdf_button" = ""; @@ -1769,15 +1766,9 @@ /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ "checkin_overlap_popup_success_text" = ""; -/*Infotext beim Generieren eines QR-Codes*/ -"web_generator_message" = ""; - /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ "web_generator_success_title" = ""; -/*Titel des Buttons, der das PDF ausdruckt*/ -"web_generator_print_pdf_button" = ""; - /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ "web_generator_reset_button" = ""; diff --git a/Translations/it.lproj/Localizable.strings b/Translations/it.lproj/Localizable.strings index a0949e86..6e23d903 100644 --- a/Translations/it.lproj/Localizable.strings +++ b/Translations/it.lproj/Localizable.strings @@ -1499,7 +1499,7 @@ "error_title" = "Errore"; "qr_scanner_error_code_not_yet_valid" = "Codice QR non ancora valido"; "qr_scanner_error_code_not_valid_anymore" = "Codice QR non più valido"; -"error_already_checked_in" = "Hai già fatto il check-in."; +"error_already_checked_in" = ""; "error_update_text" = "Questo codice QR non è compatibile con la versione dell'app installata. Aggiorna l'app per continuare."; "error_update_title" = "Aggiornamento necessario"; "error_action_update" = "Aggiorna ora"; @@ -1770,9 +1770,6 @@ /*Button um Covid Certificate App zu installieren*/ "covid_certificate_install_app" = "Installa l'app"; -"web_generator_title" = ""; -"web_generator_title_label" = ""; -"web_generator_generate_button" = ""; /*Titel des Buttons, der das PDF herunterlädt*/ "web_generator_download_pdf_button" = ""; @@ -1804,15 +1801,9 @@ /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ "checkin_overlap_popup_success_text" = ""; -/*Infotext beim Generieren eines QR-Codes*/ -"web_generator_message" = ""; - /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ "web_generator_success_title" = ""; -/*Titel des Buttons, der das PDF ausdruckt*/ -"web_generator_print_pdf_button" = ""; - /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ "web_generator_reset_button" = ""; diff --git a/Translations/pt.lproj/Localizable.strings b/Translations/pt.lproj/Localizable.strings index 3523bf64..bbb8e0c6 100644 --- a/Translations/pt.lproj/Localizable.strings +++ b/Translations/pt.lproj/Localizable.strings @@ -1466,7 +1466,7 @@ "error_title" = "Erro"; "qr_scanner_error_code_not_yet_valid" = "O código QR ainda não é válido!"; "qr_scanner_error_code_not_valid_anymore" = "O código QR não é mais válido!"; -"error_already_checked_in" = "Você já fez check-in."; +"error_already_checked_in" = ""; "error_update_text" = "Este código QR não é compatível com a versão do aplicativo instalada. Por favor, atualize o aplicativo para continuar."; "error_update_title" = "É necessário atualizar."; "error_action_update" = "Atualizar agora"; @@ -1737,9 +1737,6 @@ /*Button um Covid Certificate App zu installieren*/ "covid_certificate_install_app" = "Instalar o aplicativo"; -"web_generator_title" = ""; -"web_generator_title_label" = ""; -"web_generator_generate_button" = ""; /*Titel des Buttons, der das PDF herunterlädt*/ "web_generator_download_pdf_button" = ""; @@ -1771,15 +1768,9 @@ /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ "checkin_overlap_popup_success_text" = ""; -/*Infotext beim Generieren eines QR-Codes*/ -"web_generator_message" = ""; - /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ "web_generator_success_title" = ""; -/*Titel des Buttons, der das PDF ausdruckt*/ -"web_generator_print_pdf_button" = ""; - /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ "web_generator_reset_button" = ""; diff --git a/Translations/rm.lproj/Localizable.strings b/Translations/rm.lproj/Localizable.strings index 4f4d7c2f..f261640b 100644 --- a/Translations/rm.lproj/Localizable.strings +++ b/Translations/rm.lproj/Localizable.strings @@ -1464,7 +1464,7 @@ "error_title" = "Sbagl"; "qr_scanner_error_code_not_yet_valid" = "Il code QR n'è anc betg valaivel"; "qr_scanner_error_code_not_valid_anymore" = "Il code QR n'è betg pli valaivel"; -"error_already_checked_in" = "Vus essas gia As registrada/registrà."; +"error_already_checked_in" = ""; "error_update_text" = "Quest code QR n'è betg cumpatibel cun la versiun da l'app installada. Per plaschair actualisar l'app per cuntinuar."; "error_update_title" = "In update è necessari"; "error_action_update" = "Actualisar ussa"; @@ -1735,9 +1735,6 @@ /*Button um Covid Certificate App zu installieren*/ "covid_certificate_install_app" = "Installar l'app"; -"web_generator_title" = ""; -"web_generator_title_label" = ""; -"web_generator_generate_button" = ""; /*Titel des Buttons, der das PDF herunterlädt*/ "web_generator_download_pdf_button" = ""; @@ -1769,15 +1766,9 @@ /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ "checkin_overlap_popup_success_text" = ""; -/*Infotext beim Generieren eines QR-Codes*/ -"web_generator_message" = ""; - /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ "web_generator_success_title" = ""; -/*Titel des Buttons, der das PDF ausdruckt*/ -"web_generator_print_pdf_button" = ""; - /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ "web_generator_reset_button" = ""; diff --git a/Translations/sq.lproj/Localizable.strings b/Translations/sq.lproj/Localizable.strings index f55011c7..72f0169e 100644 --- a/Translations/sq.lproj/Localizable.strings +++ b/Translations/sq.lproj/Localizable.strings @@ -1466,7 +1466,7 @@ "error_title" = "Gabim"; "qr_scanner_error_code_not_yet_valid" = "Kodi QR nuk është ende i vlefshëm"; "qr_scanner_error_code_not_valid_anymore" = "Kodi QR nuk është më i vlefshëm"; -"error_already_checked_in" = "Ju jeni kontrolluar tashmë."; +"error_already_checked_in" = ""; "error_update_text" = "Ky kod QR nuk është i pajtueshëm me versionin e aplikacionit të instaluar. Përditësoni aplikacionin për të vazhduar më tej."; "error_update_title" = "Përditësimi i nevojshëm"; "error_action_update" = "Përditësoni tani"; @@ -1737,9 +1737,6 @@ /*Button um Covid Certificate App zu installieren*/ "covid_certificate_install_app" = "Instaloni aplikacionin"; -"web_generator_title" = ""; -"web_generator_title_label" = ""; -"web_generator_generate_button" = ""; /*Titel des Buttons, der das PDF herunterlädt*/ "web_generator_download_pdf_button" = ""; @@ -1771,15 +1768,9 @@ /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ "checkin_overlap_popup_success_text" = ""; -/*Infotext beim Generieren eines QR-Codes*/ -"web_generator_message" = ""; - /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ "web_generator_success_title" = ""; -/*Titel des Buttons, der das PDF ausdruckt*/ -"web_generator_print_pdf_button" = ""; - /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ "web_generator_reset_button" = ""; diff --git a/Translations/sr-Latn-RS.lproj/Localizable.strings b/Translations/sr-Latn-RS.lproj/Localizable.strings index be2dfe03..683e09e9 100644 --- a/Translations/sr-Latn-RS.lproj/Localizable.strings +++ b/Translations/sr-Latn-RS.lproj/Localizable.strings @@ -1464,7 +1464,7 @@ "error_title" = "Greška"; "qr_scanner_error_code_not_yet_valid" = "QR kod je još nevažeći"; "qr_scanner_error_code_not_valid_anymore" = "QR kod je nevažeći "; -"error_already_checked_in" = "Upravo ste prijavljeni."; +"error_already_checked_in" = ""; "error_update_text" = "Ovaj QR kod nije kompatibilan sa instaliranom verzijom aplikacije. Ažurirajte aplikaciju, da biste nastavili korišćenje."; "error_update_title" = "Potrebno ažuriranje"; "error_action_update" = "Sada ažurirati"; @@ -1735,9 +1735,6 @@ /*Button um Covid Certificate App zu installieren*/ "covid_certificate_install_app" = "Instalirati aplikaciju"; -"web_generator_title" = ""; -"web_generator_title_label" = ""; -"web_generator_generate_button" = ""; /*Titel des Buttons, der das PDF herunterlädt*/ "web_generator_download_pdf_button" = ""; @@ -1769,15 +1766,9 @@ /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ "checkin_overlap_popup_success_text" = ""; -/*Infotext beim Generieren eines QR-Codes*/ -"web_generator_message" = ""; - /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ "web_generator_success_title" = ""; -/*Titel des Buttons, der das PDF ausdruckt*/ -"web_generator_print_pdf_button" = ""; - /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ "web_generator_reset_button" = ""; diff --git a/Translations/ti.lproj/Localizable.strings b/Translations/ti.lproj/Localizable.strings index ab823530..6c4be22b 100644 --- a/Translations/ti.lproj/Localizable.strings +++ b/Translations/ti.lproj/Localizable.strings @@ -1465,7 +1465,7 @@ "error_title" = "ጉድለት"; "qr_scanner_error_code_not_yet_valid" = "QR-ኮድ ገና ብቑዕ ኣይኮነን"; "qr_scanner_error_code_not_valid_anymore" = "ብቕዓት QR-Code ሓሊፉ"; -"error_already_checked_in" = "ድሮ ኣቲኹም ዲኹም፧"; +"error_already_checked_in" = ""; "error_update_text" = "እዚ ኮድ QR ምስቲ ዝተተከለ ቨርዝዮን ኤፕ ኣይሰርሕን እዩ። ነቲ ኤፕ ኣሕድስዎ ብኽብረትኩም መታን ክትቕጸሉ።"; "error_update_title" = "ምምሕዳስ የድሊ"; "error_action_update" = "ሕጂ ምምሕዳስ"; @@ -1736,9 +1736,6 @@ /*Button um Covid Certificate App zu installieren*/ "covid_certificate_install_app" = "ኤፕ ምትካል"; -"web_generator_title" = ""; -"web_generator_title_label" = ""; -"web_generator_generate_button" = ""; /*Titel des Buttons, der das PDF herunterlädt*/ "web_generator_download_pdf_button" = ""; @@ -1770,15 +1767,9 @@ /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ "checkin_overlap_popup_success_text" = ""; -/*Infotext beim Generieren eines QR-Codes*/ -"web_generator_message" = ""; - /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ "web_generator_success_title" = ""; -/*Titel des Buttons, der das PDF ausdruckt*/ -"web_generator_print_pdf_button" = ""; - /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ "web_generator_reset_button" = ""; diff --git a/Translations/tr.lproj/Localizable.strings b/Translations/tr.lproj/Localizable.strings index e2d24d8c..1c44148e 100644 --- a/Translations/tr.lproj/Localizable.strings +++ b/Translations/tr.lproj/Localizable.strings @@ -1465,7 +1465,7 @@ "error_title" = "Hata"; "qr_scanner_error_code_not_yet_valid" = "Kare kod henüz geçerli değil"; "qr_scanner_error_code_not_valid_anymore" = "Kare kod artık geçerli değil"; -"error_already_checked_in" = "Zaten check-in yaptınız."; +"error_already_checked_in" = ""; "error_update_text" = "Bu kare kod artık kurulu olan uygulama sürümü ile uyumlu değil. Lütfen işleme devam edebilmek için uygulamayı güncelleyin."; "error_update_title" = "Güncelleme gerekiyor"; "error_action_update" = "Şimdi güncelleyin"; @@ -1736,9 +1736,6 @@ /*Button um Covid Certificate App zu installieren*/ "covid_certificate_install_app" = "Uygulamayı kur"; -"web_generator_title" = ""; -"web_generator_title_label" = ""; -"web_generator_generate_button" = ""; /*Titel des Buttons, der das PDF herunterlädt*/ "web_generator_download_pdf_button" = ""; @@ -1770,15 +1767,9 @@ /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ "checkin_overlap_popup_success_text" = ""; -/*Infotext beim Generieren eines QR-Codes*/ -"web_generator_message" = ""; - /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ "web_generator_success_title" = ""; -/*Titel des Buttons, der das PDF ausdruckt*/ -"web_generator_print_pdf_button" = ""; - /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ "web_generator_reset_button" = ""; From c525dfd62d02a0981f5fd4fa7109ffc14c3ffcc6 Mon Sep 17 00:00:00 2001 From: Marco Zimmermann Date: Thu, 2 Sep 2021 14:33:33 +0200 Subject: [PATCH 11/27] adds label with possibility for web qr-code generation Signed-off-by: Marco Zimmermann --- .../NSCreatedEventsViewController.swift | 27 ++++++++++++++++--- .../NSQRCodeGenerationViewController.swift | 1 + 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/DP3TApp/Screens/CheckIn/Events/NSCreatedEventsViewController.swift b/DP3TApp/Screens/CheckIn/Events/NSCreatedEventsViewController.swift index 7d9ba439..21e1ca25 100644 --- a/DP3TApp/Screens/CheckIn/Events/NSCreatedEventsViewController.swift +++ b/DP3TApp/Screens/CheckIn/Events/NSCreatedEventsViewController.swift @@ -21,6 +21,8 @@ class NSCreatedEventsViewController: NSViewController { return NSInfoBoxView(viewModel: model) }() + private let additionalInfoLabel = NSLinkifiedTextView(labelType: .textLight, textColor: .ns_defaultTextColor, linkLabelType: .textBold) + override init() { super.init() NotificationCenter.default.addObserver(self, selector: #selector(updateTitle), name: .createdEventAdded, object: nil) @@ -99,17 +101,27 @@ class NSCreatedEventsViewController: NSViewController { eventsModule.contentView.addSpacerView(NSPadding.medium + NSPadding.small) eventsModule.contentView.addArrangedView(eventsInfoBox) + eventsModule.contentView.addSpacerView(NSPadding.medium + NSPadding.small) eventsInfoBox.snp.makeConstraints { make in make.left.right.equalToSuperview().inset(-(NSPadding.medium + NSPadding.small)) } - eventsModule.contentView.addSpacerView(NSPadding.large) + + eventsModule.contentView.addSpacerView(NSPadding.medium) eventsModule.contentView.addArrangedView(generateButton) generateButton.snp.makeConstraints { make in make.left.right.equalToSuperview().inset(-(NSPadding.medium + NSPadding.small)) } - eventsModule.contentView.addSpacerView(10) + + eventsModule.contentView.addSpacerView(NSPadding.medium) + + // add additional label with hint to qr-code generation in web + eventsModule.contentView.addArrangedView(additionalInfoLabel) + + additionalInfoLabel.snp.remakeConstraints { make in + make.left.right.equalToSuperview().inset(-NSPadding.small) + } stackScrollView.addSpacerView(NSPadding.large) @@ -138,7 +150,14 @@ class NSCreatedEventsViewController: NSViewController { infoBoxModule.ub_addShadow(radius: 4, opacity: 0.1, xOffset: 0, yOffset: -1) eventsInfoBox.snp.makeConstraints { make in - make.edges.equalToSuperview().inset(NSPadding.medium) + make.top.left.right.equalToSuperview().inset(NSPadding.medium) + } + + infoBoxModule.addSubview(additionalInfoLabel) + additionalInfoLabel.snp.remakeConstraints { make in + make.top.equalTo(eventsInfoBox.snp.bottom).offset(2.0 * NSPadding.medium) + make.bottom.equalToSuperview().inset(2.0 * NSPadding.medium) + make.left.right.equalToSuperview().inset(NSPadding.medium) } stackScrollView.addArrangedView(infoBoxModule) @@ -157,6 +176,8 @@ class NSCreatedEventsViewController: NSViewController { let faqButton = NSButton.faqButton(color: .ns_blue) stackScrollView.addArrangedView(faqButton) stackScrollView.addSpacerView(NSPadding.large) + + additionalInfoLabel.text = "checkin_generate_web_hint".ub_localized } deinit { diff --git a/DP3TApp/Screens/CheckIn/Events/NSQRCodeGenerationViewController.swift b/DP3TApp/Screens/CheckIn/Events/NSQRCodeGenerationViewController.swift index 8a3867be..466c691c 100644 --- a/DP3TApp/Screens/CheckIn/Events/NSQRCodeGenerationViewController.swift +++ b/DP3TApp/Screens/CheckIn/Events/NSQRCodeGenerationViewController.swift @@ -75,6 +75,7 @@ class NSQRCodeGenerationViewController: NSViewController { stackScrollView.addSpacerView(NSPadding.large) stackScrollView.addArrangedView(fillerView) stackScrollView.addArrangedView(createButton) + stackScrollView.addSpacerView(NSPadding.large) createButton.isEnabled = false From 209b846bce4963a6a66bf190ec2f6c726282fb07 Mon Sep 17 00:00:00 2001 From: Marco Zimmermann Date: Fri, 3 Sep 2021 08:18:54 +0200 Subject: [PATCH 12/27] only show label, not a clickable link Signed-off-by: Marco Zimmermann --- .../Screens/CheckIn/Events/NSCreatedEventsViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DP3TApp/Screens/CheckIn/Events/NSCreatedEventsViewController.swift b/DP3TApp/Screens/CheckIn/Events/NSCreatedEventsViewController.swift index 21e1ca25..490c8eb0 100644 --- a/DP3TApp/Screens/CheckIn/Events/NSCreatedEventsViewController.swift +++ b/DP3TApp/Screens/CheckIn/Events/NSCreatedEventsViewController.swift @@ -21,7 +21,7 @@ class NSCreatedEventsViewController: NSViewController { return NSInfoBoxView(viewModel: model) }() - private let additionalInfoLabel = NSLinkifiedTextView(labelType: .textLight, textColor: .ns_defaultTextColor, linkLabelType: .textBold) + private let additionalInfoLabel = NSLabel(.textLight, textAlignment: .center) override init() { super.init() From dc553755ec72cc04fcf0ff57419c6f6b0d824ef0 Mon Sep 17 00:00:00 2001 From: Marco Zimmermann Date: Tue, 7 Sep 2021 11:45:33 +0200 Subject: [PATCH 13/27] fixes overlapping check-in view for accessibility Signed-off-by: Marco Zimmermann --- DP3TApp/Screens/CheckIn/Edit/NSOverlappingCheckInView.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DP3TApp/Screens/CheckIn/Edit/NSOverlappingCheckInView.swift b/DP3TApp/Screens/CheckIn/Edit/NSOverlappingCheckInView.swift index 9c6e87da..1db84bd4 100644 --- a/DP3TApp/Screens/CheckIn/Edit/NSOverlappingCheckInView.swift +++ b/DP3TApp/Screens/CheckIn/Edit/NSOverlappingCheckInView.swift @@ -53,5 +53,7 @@ class NSOverlappingCheckInView: UBButton { layer.cornerRadius = 3.0 highlightCornerRadius = 3.0 ub_addShadow(radius: 5.0, opacity: 0.17, xOffset: 0.0, yOffset: 0.0) + + self.accessibilityElements = [self.diaryContentView] } } From 387a1ee4685ca4cbd48f8d9460771cff38cf46bb Mon Sep 17 00:00:00 2001 From: Marco Zimmermann Date: Tue, 7 Sep 2021 08:49:02 +0200 Subject: [PATCH 14/27] first improvements --- DP3TApp.xcodeproj/xcshareddata/xcschemes/Debug.xcscheme | 2 +- .../Modules/NSCheckInCurrentStateModuleView.swift | 1 + .../CheckIn/Modules/NSCheckInDetailCheckedOutView.swift | 5 +++-- .../Onboarding/NSExpandableDisclaimerViewBody.swift | 1 + .../Onboarding/NSExpandableDisclaimerViewHeader.swift | 1 + .../NSOnboardingDisclaimerViewController.swift | 3 +++ .../NSOnboardingPermissionsViewController.swift | 9 +-------- .../Onboarding/NSOnboardingStepViewController.swift | 1 + 8 files changed, 12 insertions(+), 11 deletions(-) diff --git a/DP3TApp.xcodeproj/xcshareddata/xcschemes/Debug.xcscheme b/DP3TApp.xcodeproj/xcshareddata/xcschemes/Debug.xcscheme index 07ddc7bf..9a94d99c 100644 --- a/DP3TApp.xcodeproj/xcshareddata/xcschemes/Debug.xcscheme +++ b/DP3TApp.xcodeproj/xcshareddata/xcschemes/Debug.xcscheme @@ -64,7 +64,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "de" + language = "en" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/DP3TApp/Screens/CheckIn/Modules/NSCheckInCurrentStateModuleView.swift b/DP3TApp/Screens/CheckIn/Modules/NSCheckInCurrentStateModuleView.swift index 3570da6a..515724ce 100644 --- a/DP3TApp/Screens/CheckIn/Modules/NSCheckInCurrentStateModuleView.swift +++ b/DP3TApp/Screens/CheckIn/Modules/NSCheckInCurrentStateModuleView.swift @@ -49,6 +49,7 @@ class NSCheckInCurrentStateModuleView: NSModuleBaseView { checkedInView.isHidden = true checkedOutView.isHidden = false checkInEndedView.isHidden = true + headerTitle = checkedOutView.titleLabel.text?.replacingOccurrences(of: "\n", with: "") case let .checkIn(checkIn): checkedInView.isHidden = false checkedOutView.isHidden = true diff --git a/DP3TApp/Screens/CheckIn/Modules/NSCheckInDetailCheckedOutView.swift b/DP3TApp/Screens/CheckIn/Modules/NSCheckInDetailCheckedOutView.swift index 3aa1bb6f..a1e27c10 100644 --- a/DP3TApp/Screens/CheckIn/Modules/NSCheckInDetailCheckedOutView.swift +++ b/DP3TApp/Screens/CheckIn/Modules/NSCheckInDetailCheckedOutView.swift @@ -14,7 +14,7 @@ import UIKit class NSCheckInDetailCheckedOutView: UIView { private let imageView = UIImageView(image: UIImage(named: "illu-checked-in")) private let superTitleLabel = NSLabel(.textBold, textColor: .ns_blue) - private let titleLabel = NSLabel(.title) + let titleLabel = NSLabel(.title) private let textLabel = NSLabel(.textLight) let scanQrCodeButton = NSButton(title: "scan_qr_code_button_title".ub_localized, style: .normal(.ns_blue)) @@ -38,6 +38,7 @@ class NSCheckInDetailCheckedOutView: UIView { } superTitleLabel.text = "module_checkins_title".ub_localized + superTitleLabel.isAccessibilityElement = false addSubview(superTitleLabel) superTitleLabel.snp.makeConstraints { make in make.top.equalTo(imageView.snp.bottom).offset(20) @@ -45,7 +46,7 @@ class NSCheckInDetailCheckedOutView: UIView { } titleLabel.text = "checkin_detail_checked_out_title".ub_localized - titleLabel.accessibilityTraits = .header + titleLabel.isAccessibilityElement = false addSubview(titleLabel) titleLabel.snp.makeConstraints { make in make.top.equalTo(superTitleLabel.snp.bottom).offset(NSPadding.small) diff --git a/DP3TApp/Screens/Onboarding/NSExpandableDisclaimerViewBody.swift b/DP3TApp/Screens/Onboarding/NSExpandableDisclaimerViewBody.swift index c848ac82..1aa7ff8f 100644 --- a/DP3TApp/Screens/Onboarding/NSExpandableDisclaimerViewBody.swift +++ b/DP3TApp/Screens/Onboarding/NSExpandableDisclaimerViewBody.swift @@ -48,6 +48,7 @@ class NSExpandableDisclaimerViewBody: UIView { privacyButton.title = "onboarding_disclaimer_to_online_version_button".ub_localized privacyButton.accessibilityHint = "accessibility_faq_button_hint".ub_localized + privacyButton.accessibilityTraits = [.link] addSubview(textLabel) addSubview(privacyButton) diff --git a/DP3TApp/Screens/Onboarding/NSExpandableDisclaimerViewHeader.swift b/DP3TApp/Screens/Onboarding/NSExpandableDisclaimerViewHeader.swift index c311f547..dcd5f5c6 100644 --- a/DP3TApp/Screens/Onboarding/NSExpandableDisclaimerViewHeader.swift +++ b/DP3TApp/Screens/Onboarding/NSExpandableDisclaimerViewHeader.swift @@ -58,6 +58,7 @@ class NSExpandableDisclaimerViewHeader: UBButton { } accessibilityLabel = headerLabel.text + accessibilityValue = "accessibility_expandable_box_reduced_state".ub_localized accessibilityTraits = [.button, .header] } diff --git a/DP3TApp/Screens/Onboarding/NSOnboardingDisclaimerViewController.swift b/DP3TApp/Screens/Onboarding/NSOnboardingDisclaimerViewController.swift index fa5d5861..59d0c10e 100644 --- a/DP3TApp/Screens/Onboarding/NSOnboardingDisclaimerViewController.swift +++ b/DP3TApp/Screens/Onboarding/NSOnboardingDisclaimerViewController.swift @@ -113,6 +113,7 @@ class NSOnboardingDisclaimerViewController: NSOnboardingContentViewController { privacyBody.superview?.isHidden = true privacyHeader.didExpand = { [weak self] expanded in guard let self = self else { return } + self.privacyHeader.accessibilityValue = expanded ? "accessibility_expandable_box_expanded_state".ub_localized : "accessibility_expandable_box_reduced_state".ub_localized self.privacyBody.superview?.isHidden = !expanded UIAccessibility.post(notification: .screenChanged, argument: expanded ? self.privacyBody : self.privacyHeader) } @@ -136,6 +137,7 @@ class NSOnboardingDisclaimerViewController: NSOnboardingContentViewController { conditionOfUseBody.superview?.isHidden = true conditionOfUseHeader.didExpand = { [weak self] expanded in guard let self = self else { return } + self.conditionOfUseHeader.accessibilityValue = expanded ? "accessibility_expandable_box_expanded_state".ub_localized : "accessibility_expandable_box_reduced_state".ub_localized self.conditionOfUseBody.superview?.isHidden = !expanded UIAccessibility.post(notification: .screenChanged, argument: expanded ? self.conditionOfUseBody : self.conditionOfUseHeader) } @@ -187,6 +189,7 @@ class NSOnboardingDisclaimerViewController: NSOnboardingContentViewController { info.text = infoText titleLabel.accessibilityTraits = [.header] + headingLabel.accessibilityTraits = [.header] warningTitle.text = "onboarding_disclaimer_warning_title".ub_localized warningBody.text = "onboarding_disclaimer_warning_body".ub_localized } diff --git a/DP3TApp/Screens/Onboarding/NSOnboardingPermissionsViewController.swift b/DP3TApp/Screens/Onboarding/NSOnboardingPermissionsViewController.swift index 5ca94218..e1fe80b4 100644 --- a/DP3TApp/Screens/Onboarding/NSOnboardingPermissionsViewController.swift +++ b/DP3TApp/Screens/Onboarding/NSOnboardingPermissionsViewController.swift @@ -30,7 +30,6 @@ class NSOnboardingPermissionsViewController: NSOnboardingContentViewController { private let type: NSOnboardingPermissionType private let showSkip: Bool - private var elements: [Any] = [] init(type: NSOnboardingPermissionType, showSkip: Bool = true) { self.type = type self.showSkip = showSkip @@ -40,12 +39,8 @@ class NSOnboardingPermissionsViewController: NSOnboardingContentViewController { override func viewDidLoad() { super.viewDidLoad() - elements = [titleLabel, textLabel, goodToKnowContainer].compactMap { $0 } setupViews() fillViews() - - elements.append(permissionButton) - accessibilityElements = elements.compactMap { $0 } } deinit { @@ -80,6 +75,7 @@ class NSOnboardingPermissionsViewController: NSOnboardingContentViewController { } titleLabel.accessibilityTraits = [.header] + goodToKnowLabel.accessibilityTraits = [.header] } private func fillViews() { @@ -98,8 +94,6 @@ class NSOnboardingPermissionsViewController: NSOnboardingContentViewController { let info1 = NSOnboardingInfoView(icon: UIImage(named: "ic-encrypted")!, text: "onboarding_gaen_info_text_1".ub_localized, title: "onboarding_gaen_info_title_1".ub_localized, dynamicIconTintColor: .ns_blue) let info2 = NSOnboardingInfoView(icon: UIImage(named: "ic-battery")!, text: "onboarding_gaen_info_text_2".ub_localized, title: "onboarding_gaen_info_title_2".ub_localized, dynamicIconTintColor: .ns_blue) - elements.append(info1) - elements.append(info2) goodToKnowContainer.addSubview(info1) goodToKnowContainer.addSubview(info2) @@ -122,7 +116,6 @@ class NSOnboardingPermissionsViewController: NSOnboardingContentViewController { permissionButton.title = "onboarding_push_button".ub_localized let info = NSOnboardingInfoView(icon: UIImage(named: "ic-report")!, text: "onboarding_push_gtk_text1".ub_localized, title: "onboarding_push_gtk_title1".ub_localized, dynamicIconTintColor: .ns_blue) - elements.append(info) goodToKnowContainer.addSubview(info) info.snp.makeConstraints { make in make.top.equalTo(goodToKnowLabel.snp.bottom).offset(2 * NSPadding.medium) diff --git a/DP3TApp/Screens/Onboarding/NSOnboardingStepViewController.swift b/DP3TApp/Screens/Onboarding/NSOnboardingStepViewController.swift index a9c760ef..f3b49097 100644 --- a/DP3TApp/Screens/Onboarding/NSOnboardingStepViewController.swift +++ b/DP3TApp/Screens/Onboarding/NSOnboardingStepViewController.swift @@ -68,6 +68,7 @@ class NSOnboardingStepViewController: NSOnboardingContentViewController { addArrangedView(bottomSpacer) headingLabel.accessibilityTraits = [.header] + titleLabel.accessibilityTraits = [.header] } private func fillViews() { From 9580a6f4c52c002de071ae8388586dc78d8fe0f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20Ju=CC=88ni?= Date: Mon, 30 Aug 2021 18:03:04 +0200 Subject: [PATCH 15/27] fix order of items after generating qr code --- .../Events/NSCreatedEventDetailViewController.swift | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/DP3TApp/Screens/CheckIn/Events/NSCreatedEventDetailViewController.swift b/DP3TApp/Screens/CheckIn/Events/NSCreatedEventDetailViewController.swift index cddf190f..4b9e94ae 100644 --- a/DP3TApp/Screens/CheckIn/Events/NSCreatedEventDetailViewController.swift +++ b/DP3TApp/Screens/CheckIn/Events/NSCreatedEventDetailViewController.swift @@ -81,7 +81,13 @@ class NSCreatedEventDetailViewController: NSViewController { self.update(state) } - accessibilityElements = [dismissButton, venueView, checkInButton, shareButton, showPDFButton, deleteButton] + accessibilityElements = [venueView, checkInButton, shareButton, showPDFButton, deleteButton, dismissButton] + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + + UIAccessibility.post(notification: .layoutChanged, argument: venueView) } private func update(_ state: UIStateModel) { From 33f637e2571445f8c574b82021e88cbfb8b8f4fe Mon Sep 17 00:00:00 2001 From: Marco Zimmermann Date: Tue, 7 Sep 2021 08:49:14 +0200 Subject: [PATCH 16/27] accessibility improvements according to list --- .../ReminderManager/ReminderManager.swift | 29 +++++++++++++++++++ DP3TApp/Logic/Helpers/DateFormatter.swift | 4 +-- .../CheckIn/Diary/NSDiaryEmptyView.swift | 1 + ...RemoveFromDiaryWarningViewController.swift | 27 ++++++++++------- .../Edit/NSCheckInEditViewController.swift | 13 +++++++++ .../NSCheckInCurrentStateModuleView.swift | 5 +++- .../CheckIn/NSCheckInContentView.swift | 1 + .../NSCheckInHomescreenModuleView.swift | 1 + .../NSCheckInOverviewViewController.swift | 6 ++++ .../CovidCode/NSCovidCodeModuleView.swift | 2 ++ .../Encounters/NSEncountersModuleView.swift | 4 +++ .../NSHomescreenViewController.swift | 2 +- .../Reports/NSReportsModuleView.swift | 4 +++ .../Screens/Info/NSInfoViewController.swift | 2 +- .../Navigation/NSTabBarController.swift | 2 +- ...etailExposedEncountersViewController.swift | 17 +++++++++-- .../NSCovidCodesStatisticsModuleView.swift | 2 +- .../NSCovidStatisticsModuleView.swift | 2 +- .../NSStatisticsViewController.swift | 2 +- .../Travel/NSTravelDetailModuleView.swift | 1 + ...reTestInformationPopupViewController.swift | 2 ++ DP3TApp/SharedUI/Controls/NSButton.swift | 2 +- .../Views/CheckIn/NSReminderControl.swift | 6 ++++ DP3TApp/SharedUI/Views/NSInfoBoxView.swift | 8 +++-- 24 files changed, 118 insertions(+), 27 deletions(-) diff --git a/DP3TApp/Logic/CheckIn/ReminderManager/ReminderManager.swift b/DP3TApp/Logic/CheckIn/ReminderManager/ReminderManager.swift index c3adb4c7..5e761f46 100644 --- a/DP3TApp/Logic/CheckIn/ReminderManager/ReminderManager.swift +++ b/DP3TApp/Logic/CheckIn/ReminderManager/ReminderManager.swift @@ -45,6 +45,35 @@ enum ReminderOption: Equatable { } } + var accessibilityTitle: String { + switch self { + case .thirtyMinutes: + return title.replacingOccurrences(of: "'", with: "accessibility_reminder_option_minutes".ub_localized) + case .oneHour: + return title.replacingOccurrences(of: "h", with: "accessibility_reminder_option_hour".ub_localized) + case .twoHours, .fourHours: + return title.replacingOccurrences(of: "h", with: "accessibility_reminder_option_hours_plural".ub_localized) + case let .custom(ms): + if ms == -1 { + return "checkin_reminder_option_open_settings".ub_localized + } else if timeInterval < .hour { + return title.replacingOccurrences(of: "'", with: "accessibility_reminder_option_minutes".ub_localized) + } else if timeInterval.milliseconds % .hour == 0, Int((timeInterval / 3600).rounded()) == 1 { + return title.replacingOccurrences(of: "h", with: "accessibility_reminder_option_hour".ub_localized) + } else if timeInterval.milliseconds % .hour == 0 { + return title.replacingOccurrences(of: "h", with: "accessibility_reminder_option_hours_plural".ub_localized) + } else { + if (Int((timeInterval / 60).rounded()) / 60) == 1 { + return title.replacingOccurrences(of: "h", with: "accessibility_reminder_option_hour".ub_localized).replacingOccurrences(of: "'", with: "accessibility_reminder_option_minutes".ub_localized) + } else { + return title.replacingOccurrences(of: "h", with: "accessibility_reminder_option_hours_plural".ub_localized).replacingOccurrences(of: "'", with: "accessibility_reminder_option_minutes".ub_localized) + } + } + default: + return title + } + } + var timeInterval: TimeInterval { switch self { case .off: diff --git a/DP3TApp/Logic/Helpers/DateFormatter.swift b/DP3TApp/Logic/Helpers/DateFormatter.swift index 23c9b0ad..4e55e7ff 100644 --- a/DP3TApp/Logic/Helpers/DateFormatter.swift +++ b/DP3TApp/Logic/Helpers/DateFormatter.swift @@ -109,8 +109,8 @@ extension DateFormatter { static func ub_accessibilityFromTimeToTime(from: Date, to: Date) -> String { return "checkout_from_to_date".ub_localized - .replacingOccurrences(of: "{DATE1}", with: DateComponentsFormatter.localizedString(from: Calendar.current.dateComponents([.hour, .minute], from: from), unitsStyle: .full) ?? "") - .replacingOccurrences(of: "{DATE2}", with: DateComponentsFormatter.localizedString(from: Calendar.current.dateComponents([.hour, .minute], from: to), unitsStyle: .full) ?? "") + .replacingOccurrences(of: "{DATE1}", with: DateComponentsFormatter.localizedString(from: Calendar.current.dateComponents([.hour, .minute], from: from), unitsStyle: .positional) ?? "") + .replacingOccurrences(of: "{DATE2}", with: DateComponentsFormatter.localizedString(from: Calendar.current.dateComponents([.hour, .minute], from: to), unitsStyle: .positional) ?? "") } } diff --git a/DP3TApp/Screens/CheckIn/Diary/NSDiaryEmptyView.swift b/DP3TApp/Screens/CheckIn/Diary/NSDiaryEmptyView.swift index bdc11f22..a0b964be 100644 --- a/DP3TApp/Screens/CheckIn/Diary/NSDiaryEmptyView.swift +++ b/DP3TApp/Screens/CheckIn/Diary/NSDiaryEmptyView.swift @@ -49,6 +49,7 @@ class NSDiaryEmptyView: UIView { titleView.addSubview(titleLabel) titleLabel.text = "empty_diary_title".ub_localized + titleLabel.accessibilityTraits = [.header] titleLabel.snp.makeConstraints { make in make.edges.equalToSuperview().inset(UIEdgeInsets(top: NSPadding.medium, left: NSPadding.medium, bottom: 0, right: NSPadding.medium)) diff --git a/DP3TApp/Screens/CheckIn/Diary/NSRemoveFromDiaryWarningViewController.swift b/DP3TApp/Screens/CheckIn/Diary/NSRemoveFromDiaryWarningViewController.swift index 82ac0db5..c58550b9 100644 --- a/DP3TApp/Screens/CheckIn/Diary/NSRemoveFromDiaryWarningViewController.swift +++ b/DP3TApp/Screens/CheckIn/Diary/NSRemoveFromDiaryWarningViewController.swift @@ -17,6 +17,12 @@ class NSRemoveFromDiaryWarningViewController: NSPopupViewController { private let hideButton = NSButton(title: "remove_diary_warning_hide_button".ub_localized, style: .normal(.ns_blue)) + private let modalTitle = NSLabel(.title) + private let hideTitle = NSLabel(.textBold, textColor: .ns_blue) + private let hideText = NSLabel(.textLight) + private let removeTitle = NSLabel(.textBold) + private let removeLabel = NSLabel(.textLight) + private let venue: VenueInfo private let insets = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20) @@ -56,21 +62,24 @@ class NSRemoveFromDiaryWarningViewController: NSPopupViewController { setupContent() } + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + view.accessibilityElements = [modalTitle, hideTitle, hideText, hideButton, removeTitle, removeLabel, removeButton, closeButton] + UIAccessibility.post(notification: .screenChanged, argument: self) + } + private func setupContent() { - let title = NSLabel(.title) - title.accessibilityTraits = .header - title.text = "remove_diary_warning_title".ub_localized - UIAccessibility.post(notification: .layoutChanged, argument: title) - stackView.addArrangedView(title, insets: insets) + modalTitle.accessibilityTraits = .header + modalTitle.text = "remove_diary_warning_title".ub_localized + stackView.addArrangedView(modalTitle, insets: insets) stackView.addSpacerView(4 * NSPadding.medium) - let hideTitle = NSLabel(.textBold, textColor: .ns_blue) hideTitle.accessibilityTraits = .header hideTitle.text = "remove_diary_warning_hide_title".ub_localized stackView.addArrangedView(hideTitle, insets: insets) stackView.addSpacerView(NSPadding.medium) - let hideText = NSLabel(.textLight) hideText.text = "remove_diary_warning_hide_text".ub_localized stackView.addArrangedView(hideText, insets: insets) stackView.addSpacerView(3 * NSPadding.medium) @@ -79,13 +88,11 @@ class NSRemoveFromDiaryWarningViewController: NSPopupViewController { stackView.addArrangedView(hideButton, insets: insets) stackView.addSpacerView(4 * NSPadding.medium) - let removeTitle = NSLabel(.textBold) removeTitle.accessibilityTraits = .header removeTitle.text = "remove_diary_remove_now_title".ub_localized stackView.addArrangedView(removeTitle, insets: insets) stackView.addSpacerView(NSPadding.medium + NSPadding.small) - let removeLabel = NSLabel(.textLight) removeLabel.text = "remove_diary_remove_now_text".ub_localized stackView.addArrangedView(removeLabel, insets: insets) @@ -94,7 +101,5 @@ class NSRemoveFromDiaryWarningViewController: NSPopupViewController { removeButton.title = "remove_diary_remove_now_button".ub_localized stackView.addArrangedView(removeButton, insets: insets) stackView.addSpacerView(NSPadding.large) - - accessibilityElements = [title, hideTitle, hideText, removeTitle, removeLabel, hideButton, removeButton, closeButton] } } diff --git a/DP3TApp/Screens/CheckIn/Edit/NSCheckInEditViewController.swift b/DP3TApp/Screens/CheckIn/Edit/NSCheckInEditViewController.swift index 55c2b6b3..e55abf04 100644 --- a/DP3TApp/Screens/CheckIn/Edit/NSCheckInEditViewController.swift +++ b/DP3TApp/Screens/CheckIn/Edit/NSCheckInEditViewController.swift @@ -68,6 +68,17 @@ class NSCheckInEditViewController: NSViewController { update() } + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + + if isCurrentCheckIn { + accessibilityElements = [navigationController?.navigationBar as Any, venueView, startDateLabel, fromTimePickerControl, toTimePickerControl, checkoutButton, navigationController?.navigationBar as Any] + } else { + accessibilityElements = [navigationController?.navigationBar as Any, venueView, startDateLabel, fromTimePickerControl, toTimePickerControl, removeFromDiaryButton, navigationController?.navigationBar as Any] + } + UIAccessibility.post(notification: .screenChanged, argument: self) + } + // MARK: - Update private func update(_ state: UIStateModel) { @@ -379,6 +390,8 @@ class NSCheckInEditViewController: NSViewController { strongSelf.dismiss(animated: true, completion: nil) } + controller.view.accessibilityViewIsModal = true + present(controller, animated: true, completion: nil) } diff --git a/DP3TApp/Screens/CheckIn/Modules/NSCheckInCurrentStateModuleView.swift b/DP3TApp/Screens/CheckIn/Modules/NSCheckInCurrentStateModuleView.swift index 515724ce..83218420 100644 --- a/DP3TApp/Screens/CheckIn/Modules/NSCheckInCurrentStateModuleView.swift +++ b/DP3TApp/Screens/CheckIn/Modules/NSCheckInCurrentStateModuleView.swift @@ -49,12 +49,15 @@ class NSCheckInCurrentStateModuleView: NSModuleBaseView { checkedInView.isHidden = true checkedOutView.isHidden = false checkInEndedView.isHidden = true - headerTitle = checkedOutView.titleLabel.text?.replacingOccurrences(of: "\n", with: "") + headerTitle = ("checkin_detail_checked_out_title".ub_localized).replacingOccurrences(of: "\n", with: "") + stackView.accessibilityTraits = [.header] case let .checkIn(checkIn): checkedInView.isHidden = false checkedOutView.isHidden = true checkInEndedView.isHidden = true checkedInView.update(with: checkIn) + headerTitle = "checkin_checked_in".ub_localized + stackView.accessibilityTraits = [] case .checkInEnded: checkedInView.isHidden = true checkedOutView.isHidden = true diff --git a/DP3TApp/Screens/CheckIn/NSCheckInContentView.swift b/DP3TApp/Screens/CheckIn/NSCheckInContentView.swift index 5c7656a5..7a510337 100644 --- a/DP3TApp/Screens/CheckIn/NSCheckInContentView.swift +++ b/DP3TApp/Screens/CheckIn/NSCheckInContentView.swift @@ -75,6 +75,7 @@ class NSCheckInContentView: UIView { imageView.ub_setContentPriorityRequired() stackView.addArrangedView(imageView) stackView.addSpacerView(2.0 * NSPadding.medium) + checkedInLabel.isAccessibilityElement = false } if style != .diary { diff --git a/DP3TApp/Screens/CheckIn/NSCheckInHomescreenModuleView.swift b/DP3TApp/Screens/CheckIn/NSCheckInHomescreenModuleView.swift index 4800767a..33c808e1 100644 --- a/DP3TApp/Screens/CheckIn/NSCheckInHomescreenModuleView.swift +++ b/DP3TApp/Screens/CheckIn/NSCheckInHomescreenModuleView.swift @@ -21,6 +21,7 @@ class NSCheckInHomescreenModuleView: NSModuleBaseView { image: UIImage(named: "ic-stopp"), titleColor: .ns_purple, subtextColor: .ns_text) + viewModel.isClickable = true viewModel.illustration = UIImage(named: "illu-checkin-ended")! viewModel.backgroundColor = .ns_purpleBackground viewModel.dynamicIconTintColor = .ns_purple diff --git a/DP3TApp/Screens/CheckIn/NSCheckInOverviewViewController.swift b/DP3TApp/Screens/CheckIn/NSCheckInOverviewViewController.swift index 853162c0..d611bdca 100644 --- a/DP3TApp/Screens/CheckIn/NSCheckInOverviewViewController.swift +++ b/DP3TApp/Screens/CheckIn/NSCheckInOverviewViewController.swift @@ -32,6 +32,12 @@ class NSCheckInOverviewViewController: NSViewController { setupCallbacks() } + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + + UIAccessibility.post(notification: .screenChanged, argument: currentStateView) + } + private func setupView() { view.backgroundColor = .setColorsForTheme(lightColor: .ns_backgroundSecondary, darkColor: .ns_background) diff --git a/DP3TApp/Screens/Homescreen/Homescreen/CovidCode/NSCovidCodeModuleView.swift b/DP3TApp/Screens/Homescreen/Homescreen/CovidCode/NSCovidCodeModuleView.swift index 1c8949e6..c337f6c9 100644 --- a/DP3TApp/Screens/Homescreen/Homescreen/CovidCode/NSCovidCodeModuleView.swift +++ b/DP3TApp/Screens/Homescreen/Homescreen/CovidCode/NSCovidCodeModuleView.swift @@ -40,6 +40,8 @@ class NSCovidCodeModuleView: NSModuleBaseView { guard let strongSelf = self else { return } strongSelf.endIsolationModeCallback?() } + + stackView.accessibilityTraits = [.header] } required init(coder _: NSCoder) { diff --git a/DP3TApp/Screens/Homescreen/Homescreen/Encounters/NSEncountersModuleView.swift b/DP3TApp/Screens/Homescreen/Homescreen/Encounters/NSEncountersModuleView.swift index ae8f913b..8545e0af 100644 --- a/DP3TApp/Screens/Homescreen/Homescreen/Encounters/NSEncountersModuleView.swift +++ b/DP3TApp/Screens/Homescreen/Homescreen/Encounters/NSEncountersModuleView.swift @@ -41,6 +41,7 @@ class NSEncountersModuleView: NSModuleBaseView { image: UIImage(named: "ic-check"), titleColor: .ns_blue, subtextColor: .ns_text) + viewModel.isClickable = true viewModel.illustration = UIImage(named: "illu-tracking-active")! viewModel.backgroundColor = .ns_blueBackground viewModel.dynamicIconTintColor = .ns_blue @@ -77,6 +78,7 @@ class NSEncountersModuleView: NSModuleBaseView { } imageView.setContentHuggingPriority(UILayoutPriority(rawValue: 260), for: .horizontal) imageView.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 760), for: .horizontal) + titleLabel.accessibilityTraits = [.button] return view }() @@ -125,5 +127,7 @@ class NSEncountersModuleView: NSModuleBaseView { isEnabled = uiState != .tracingEnded stackView.layoutIfNeeded() + stackView.accessibilityTraits = uiState == .tracingEnded ? [.header] : [.header, .button] + UIAccessibility.post(notification: .screenChanged, argument: self) } } diff --git a/DP3TApp/Screens/Homescreen/Homescreen/NSHomescreenViewController.swift b/DP3TApp/Screens/Homescreen/Homescreen/NSHomescreenViewController.swift index 9bcb00d6..e4afb77f 100644 --- a/DP3TApp/Screens/Homescreen/Homescreen/NSHomescreenViewController.swift +++ b/DP3TApp/Screens/Homescreen/Homescreen/NSHomescreenViewController.swift @@ -146,7 +146,7 @@ class NSHomescreenViewController: NSTitleViewScrollViewController { let image = UIImage(named: "ic-info-outline") navigationItem.rightBarButtonItem = UIBarButtonItem(image: image, landscapeImagePhone: image, style: .plain, target: self, action: #selector(infoButtonPressed)) navigationItem.rightBarButtonItem?.tintColor = .ns_blue - navigationItem.rightBarButtonItem?.accessibilityLabel = "accessibility_info_button".ub_localized + navigationItem.rightBarButtonItem?.accessibilityLabel = "accessibility_info_button_app".ub_localized // other views stackScrollView.addArrangedView(infoBoxView) diff --git a/DP3TApp/Screens/Homescreen/Homescreen/Reports/NSReportsModuleView.swift b/DP3TApp/Screens/Homescreen/Homescreen/Reports/NSReportsModuleView.swift index 304d1373..98624eab 100644 --- a/DP3TApp/Screens/Homescreen/Homescreen/Reports/NSReportsModuleView.swift +++ b/DP3TApp/Screens/Homescreen/Homescreen/Reports/NSReportsModuleView.swift @@ -24,6 +24,7 @@ class NSReportsModuleView: NSModuleBaseView { image: UIImage(named: "ic-check-round"), titleColor: .ns_blue, subtextColor: .ns_text) + viewModel.isClickable = true viewModel.illustration = UIImage(named: "illu-no-message")! viewModel.backgroundColor = .ns_blueBackground viewModel.dynamicIconTintColor = .ns_blue @@ -36,6 +37,7 @@ class NSReportsModuleView: NSModuleBaseView { image: UIImage(named: "ic-warning"), titleColor: .white, subtextColor: .white) + viewModel.isClickable = true viewModel.hasBubble = true viewModel.backgroundColor = .ns_blue viewModel.dynamicIconTintColor = .white @@ -48,6 +50,7 @@ class NSReportsModuleView: NSModuleBaseView { image: UIImage(named: "ic-info"), titleColor: .white, subtextColor: .white) + viewModel.isClickable = true viewModel.hasBubble = true viewModel.backgroundColor = .ns_purple viewModel.dynamicIconTintColor = .white @@ -140,6 +143,7 @@ class NSReportsModuleView: NSModuleBaseView { make.top.trailing.bottom.equalToSuperview().inset(NSPadding.small) } views.append(container) + dateLabel.accessibilityTraits = [.button] case .infected: views.append(infectedView) diff --git a/DP3TApp/Screens/Info/NSInfoViewController.swift b/DP3TApp/Screens/Info/NSInfoViewController.swift index 51ed7851..6488f940 100644 --- a/DP3TApp/Screens/Info/NSInfoViewController.swift +++ b/DP3TApp/Screens/Info/NSInfoViewController.swift @@ -106,7 +106,7 @@ class NSInfoViewController: NSViewController { let image = UIImage(named: "ic-info-outline") navigationItem.rightBarButtonItem = UIBarButtonItem(image: image, landscapeImagePhone: image, style: .plain, target: self, action: #selector(infoButtonPressed)) navigationItem.rightBarButtonItem?.tintColor = .ns_blue - navigationItem.rightBarButtonItem?.accessibilityLabel = "accessibility_info_button".ub_localized + navigationItem.rightBarButtonItem?.accessibilityLabel = "accessibility_info_button_app".ub_localized stackScrollView.addSpacerView(NSPadding.large) diff --git a/DP3TApp/Screens/Navigation/NSTabBarController.swift b/DP3TApp/Screens/Navigation/NSTabBarController.swift index 8d732a5e..ad0cd8f8 100644 --- a/DP3TApp/Screens/Navigation/NSTabBarController.swift +++ b/DP3TApp/Screens/Navigation/NSTabBarController.swift @@ -51,7 +51,7 @@ class NSTabBarController: UITabBarController { let image = UIImage(named: "ic-info-outline") navigationItem.rightBarButtonItem = UIBarButtonItem(image: image, landscapeImagePhone: image, style: .plain, target: self, action: #selector(infoButtonPressed)) navigationItem.rightBarButtonItem?.tintColor = .ns_blue - navigationItem.rightBarButtonItem?.accessibilityLabel = "accessibility_info_button".ub_localized + navigationItem.rightBarButtonItem?.accessibilityLabel = "accessibility_info_button_app".ub_localized let swissFlagImage = UIImage(named: "ic_navbar_schweiz_wappen")?.withRenderingMode(.alwaysOriginal) navigationItem.leftBarButtonItem = UIBarButtonItem(customView: UIImageView(image: swissFlagImage)) diff --git a/DP3TApp/Screens/Reports/Exposed/NSReportsDetailExposedEncountersViewController.swift b/DP3TApp/Screens/Reports/Exposed/NSReportsDetailExposedEncountersViewController.swift index 50263bd3..0de4d57b 100644 --- a/DP3TApp/Screens/Reports/Exposed/NSReportsDetailExposedEncountersViewController.swift +++ b/DP3TApp/Screens/Reports/Exposed/NSReportsDetailExposedEncountersViewController.swift @@ -110,7 +110,9 @@ class NSReportsDetailExposedEncountersViewController: NSTitleViewScrollViewContr stackScrollView.addSpacerView(3 * NSPadding.large) - stackScrollView.addArrangedView(NSButton.faqButton(color: .ns_blue)) + let faqButton = NSButton.faqButton(color: .ns_blue) + faqButton.accessibilityTraits = [.link] + stackScrollView.addArrangedView(faqButton) stackScrollView.addSpacerView(NSPadding.large) } @@ -123,7 +125,9 @@ class NSReportsDetailExposedEncountersViewController: NSTitleViewScrollViewContr } notYetOpenedView?.isHidden = didOpenLeitfaden + notYetOpenedView?.accessibilityViewIsModal = didOpenLeitfaden alreadyOpenedView?.isHidden = !didOpenLeitfaden + alreadyOpenedView?.accessibilityViewIsModal = didOpenLeitfaden let quarantinePeriod: TimeInterval = 60 * 60 * 24 * 10 if let latestExposure: Date = reports.map(\.timestamp).sorted(by: >).first { @@ -147,16 +151,19 @@ class NSReportsDetailExposedEncountersViewController: NSTitleViewScrollViewContr whiteBoxView.contentView.addSpacerView(NSPadding.medium) let leitfadenButton = NSExternalLinkButton(style: .outlined(color: .ns_blue), size: .normal, linkType: .url, buttonTintColor: .white) - let text = "meldungen_detail_open_leitfaden_button".ub_localized + let text = "meldungen_detail_open_leitfaden_again_button".ub_localized leitfadenButton.title = text leitfadenButton.backgroundColor = .ns_blue + leitfadenButton.accessibilityTraits = [.link] leitfadenButton.touchUpCallback = { [weak self] in guard let strongSelf = self else { return } strongSelf.openLeitfaden() } - whiteBoxView.contentView.addArrangedSubview(addInfoButton(to: leitfadenButton, buttonText: text)) + let sView = addInfoButton(to: leitfadenButton, buttonText: text) + sView.isAccessibilityElement = false + whiteBoxView.contentView.addArrangedSubview(sView) whiteBoxView.contentView.addSpacerView(40.0) addTextContentSection(to: whiteBoxView) addTestInfo(to: whiteBoxView) @@ -266,6 +273,8 @@ class NSReportsDetailExposedEncountersViewController: NSTitleViewScrollViewContr UIApplication.shared.open(url) } + popupButton.accessibilityTraits = [.link] + moduleView.contentView.addArrangedView(popupButton) moduleView.contentView.addSpacerView(NSPadding.large) } @@ -290,6 +299,7 @@ class NSReportsDetailExposedEncountersViewController: NSTitleViewScrollViewContr titleLabel.text = title view.addArrangedView(titleLabel) view.addSpacerView(2 * NSPadding.small) + titleLabel.accessibilityTraits = [.header] let textLabel = NSLabel(.textLight) textLabel.text = text @@ -323,6 +333,7 @@ class NSReportsDetailExposedEncountersViewController: NSTitleViewScrollViewContr let popup = NSReportsLeitfadenInfoPopupViewController(buttonText: buttonText) strongSelf.present(popup, animated: true, completion: nil) } + stackView.accessibilityElements = [button, infoButton] return stackView } diff --git a/DP3TApp/Screens/Statistics/NSCovidCodesStatisticsModuleView.swift b/DP3TApp/Screens/Statistics/NSCovidCodesStatisticsModuleView.swift index 970b1504..cc6116d7 100644 --- a/DP3TApp/Screens/Statistics/NSCovidCodesStatisticsModuleView.swift +++ b/DP3TApp/Screens/Statistics/NSCovidCodesStatisticsModuleView.swift @@ -55,7 +55,7 @@ class NSCovidCodesStatisticsModuleView: UIView { infoButton.setImage(UIImage(named: "ic-info-outline")?.withRenderingMode(.alwaysTemplate), for: .normal) infoButton.tintColor = .ns_blue infoButton.highlightCornerRadius = 20 - infoButton.accessibilityLabel = "accessibility_info_button".ub_localized + infoButton.accessibilityLabel = "accessibility_info_button_covidcode".ub_localized addSubview(infoButton) infoButton.snp.makeConstraints { make in make.top.trailing.equalToSuperview() diff --git a/DP3TApp/Screens/Statistics/NSCovidStatisticsModuleView.swift b/DP3TApp/Screens/Statistics/NSCovidStatisticsModuleView.swift index 96eb8b6b..b20316b1 100644 --- a/DP3TApp/Screens/Statistics/NSCovidStatisticsModuleView.swift +++ b/DP3TApp/Screens/Statistics/NSCovidStatisticsModuleView.swift @@ -111,7 +111,7 @@ class NSCovidStatisticsModuleView: UIView { infoButton.setImage(UIImage(named: "ic-info-outline")?.withRenderingMode(.alwaysTemplate), for: .normal) infoButton.tintColor = .ns_purple infoButton.highlightCornerRadius = 20 - infoButton.accessibilityLabel = "accessibility_info_button".ub_localized + infoButton.accessibilityLabel = "accessibility_info_button_numberofcases".ub_localized addSubview(infoButton) infoButton.snp.makeConstraints { make in make.top.trailing.equalToSuperview() diff --git a/DP3TApp/Screens/Statistics/NSStatisticsViewController.swift b/DP3TApp/Screens/Statistics/NSStatisticsViewController.swift index 5e736997..5372f678 100644 --- a/DP3TApp/Screens/Statistics/NSStatisticsViewController.swift +++ b/DP3TApp/Screens/Statistics/NSStatisticsViewController.swift @@ -113,7 +113,7 @@ class NSStatisticsViewController: NSTitleViewScrollViewController { let image = UIImage(named: "ic-info-outline") navigationItem.rightBarButtonItem = UIBarButtonItem(image: image, landscapeImagePhone: image, style: .plain, target: self, action: #selector(infoButtonPressed)) navigationItem.rightBarButtonItem?.tintColor = .ns_blue - navigationItem.rightBarButtonItem?.accessibilityLabel = "accessibility_info_button".ub_localized + navigationItem.rightBarButtonItem?.accessibilityLabel = "accessibility_info_button_app".ub_localized stackScrollView.addArrangedView(appUsageStatisticsModule) diff --git a/DP3TApp/Screens/Travel/NSTravelDetailModuleView.swift b/DP3TApp/Screens/Travel/NSTravelDetailModuleView.swift index edebeadc..5eab7f72 100644 --- a/DP3TApp/Screens/Travel/NSTravelDetailModuleView.swift +++ b/DP3TApp/Screens/Travel/NSTravelDetailModuleView.swift @@ -48,6 +48,7 @@ class NSTravelDetailModuleView: UIView { } titleLabel.text = "travel_title".ub_localized + titleLabel.accessibilityTraits = [.header] stackView.addArrangedView(titleLabel, insets: UIEdgeInsets(top: NSPadding.small, left: NSPadding.small, bottom: 0, right: 0)) stackView.addSpacerView(NSPadding.large) diff --git a/DP3TApp/Screens/WhatToDo/NSMoreTestInformationPopupViewController.swift b/DP3TApp/Screens/WhatToDo/NSMoreTestInformationPopupViewController.swift index b4712a32..637abf04 100644 --- a/DP3TApp/Screens/WhatToDo/NSMoreTestInformationPopupViewController.swift +++ b/DP3TApp/Screens/WhatToDo/NSMoreTestInformationPopupViewController.swift @@ -33,6 +33,7 @@ class NSMoreTestInformationPopupViewController: NSPopupViewController { let titleText = "test_location_popup_title".ub_localized let titleLabel = NSLabel(.title) titleLabel.text = titleText + titleLabel.accessibilityTraits = [.header] stackView.addArrangedSubview(titleLabel) stackView.addSpacerView(NSPadding.large) @@ -49,6 +50,7 @@ class NSMoreTestInformationPopupViewController: NSPopupViewController { externalLinkButton.touchUpCallback = { [weak self] in self?.openUrl(location.url) } + externalLinkButton.accessibilityTraits = [.link] stackView.addArrangedSubview(externalLinkButton) if index != (locations.count - 1) { stackView.addSpacerView(NSPadding.medium) diff --git a/DP3TApp/SharedUI/Controls/NSButton.swift b/DP3TApp/SharedUI/Controls/NSButton.swift index 8264003a..f6636a71 100644 --- a/DP3TApp/SharedUI/Controls/NSButton.swift +++ b/DP3TApp/SharedUI/Controls/NSButton.swift @@ -184,7 +184,7 @@ extension NSButton { } faqButton.accessibilityHint = "accessibility_faq_button_hint".ub_localized - faqButton.accessibilityTraits = [.button, .header] + faqButton.accessibilityTraits = [.link, .header] return view } } diff --git a/DP3TApp/SharedUI/Views/CheckIn/NSReminderControl.swift b/DP3TApp/SharedUI/Views/CheckIn/NSReminderControl.swift index fc647003..cef65f53 100644 --- a/DP3TApp/SharedUI/Views/CheckIn/NSReminderControl.swift +++ b/DP3TApp/SharedUI/Views/CheckIn/NSReminderControl.swift @@ -40,6 +40,11 @@ class NSReminderControl: UIView { } }) + // is the only way to set the accessibilityLabels of the segmentedControls + for i in 0 ..< self.options.count { + (segmentedControl.accessibilityElement(at: i) as? UIView)?.accessibilityLabel = self.options[i].accessibilityTitle + } + super.init(frame: .zero) setup() } @@ -76,6 +81,7 @@ class NSReminderControl: UIView { self.options[s] = .custom(milliseconds: newInterval.milliseconds) self.segmentedControl.setTitle(self.options[s].title, forSegmentAt: self.segmentedControl.selectedSegmentIndex) + (self.segmentedControl.accessibilityElement(at: self.segmentedControl.selectedSegmentIndex) as? UIView)?.accessibilityLabel = self.options[self.segmentedControl.selectedSegmentIndex].accessibilityTitle self.changeCallback?(self.options[s]) } } diff --git a/DP3TApp/SharedUI/Views/NSInfoBoxView.swift b/DP3TApp/SharedUI/Views/NSInfoBoxView.swift index d97d8a09..fb0a0cf5 100644 --- a/DP3TApp/SharedUI/Views/NSInfoBoxView.swift +++ b/DP3TApp/SharedUI/Views/NSInfoBoxView.swift @@ -42,7 +42,7 @@ class NSInfoBoxView: UIView { illustrationImageView.image = viewModel.illustration setup(viewModel: viewModel) - setupAccessibility(title: viewModel.title, subTitle: viewModel.subText, boldSubText: viewModel.boldSubText, additionalText: viewModel.additionalText, additionalURL: viewModel.additionalURL, externalLinkType: viewModel.externalLinkType) + setupAccessibility(title: viewModel.title, subTitle: viewModel.subText, boldSubText: viewModel.boldSubText, additionalText: viewModel.additionalText, additionalURL: viewModel.additionalURL, externalLinkType: viewModel.externalLinkType, isClickable: viewModel.isClickable) } public var popupCallback: (() -> Void)? @@ -66,6 +66,7 @@ class NSInfoBoxView: UIView { var externalLinkStyle: NSExternalLinkButton.Style = .normal(color: .white) var externalLinkType: NSExternalLinkButton.LinkType = .url var hearingImpairedButtonCallback: (() -> Void)? = nil + var isClickable: Bool = false } init(viewModel: ViewModel) { @@ -85,7 +86,7 @@ class NSInfoBoxView: UIView { illustrationImageView.image = viewModel.illustration setup(viewModel: viewModel) - setupAccessibility(title: viewModel.title, subTitle: viewModel.subText, boldSubText: viewModel.boldSubText, additionalText: viewModel.additionalText, additionalURL: viewModel.additionalURL, externalLinkType: viewModel.externalLinkType) + setupAccessibility(title: viewModel.title, subTitle: viewModel.subText, boldSubText: viewModel.boldSubText, additionalText: viewModel.additionalText, additionalURL: viewModel.additionalURL, externalLinkType: viewModel.externalLinkType, isClickable: viewModel.isClickable) } required init?(coder _: NSCoder) { @@ -265,7 +266,7 @@ class NSInfoBoxView: UIView { // MARK: - Accessibility extension NSInfoBoxView { - private func setupAccessibility(title: String, subTitle: String, boldSubText: String?, additionalText: String?, additionalURL: String?, externalLinkType: NSExternalLinkButton.LinkType) { + private func setupAccessibility(title: String, subTitle: String, boldSubText: String?, additionalText: String?, additionalURL: String?, externalLinkType: NSExternalLinkButton.LinkType, isClickable: Bool) { if let additionalURL = additionalURL { isAccessibilityElement = false @@ -277,6 +278,7 @@ extension NSInfoBoxView { } isAccessibilityElement = true + accessibilityTraits = isClickable ? [.button] : [] accessibilityLabel = "\(title), \(subTitle), \(boldSubText ?? ""), \(additionalText ?? "")" } } From eeaae8dad1c72a010da25d41b78297744c3227a3 Mon Sep 17 00:00:00 2001 From: Marco Zimmermann Date: Tue, 7 Sep 2021 08:49:21 +0200 Subject: [PATCH 17/27] multiple changes to improve accessibility --- .../NSCreatedEventDetailViewController.swift | 11 +++++++---- .../Events/NSCreatedEventsViewController.swift | 2 +- .../Scanner/NSCheckInViewController.swift | 1 + .../Onboarding/NSOnboardingInfoView.swift | 2 +- ...DetailExposedEncountersViewController.swift | 8 ++------ DP3TApp/SharedUI/Views/NSInfoBoxView.swift | 18 ++++++++++++------ 6 files changed, 24 insertions(+), 18 deletions(-) diff --git a/DP3TApp/Screens/CheckIn/Events/NSCreatedEventDetailViewController.swift b/DP3TApp/Screens/CheckIn/Events/NSCreatedEventDetailViewController.swift index 4b9e94ae..b39c2c52 100644 --- a/DP3TApp/Screens/CheckIn/Events/NSCreatedEventDetailViewController.swift +++ b/DP3TApp/Screens/CheckIn/Events/NSCreatedEventDetailViewController.swift @@ -14,6 +14,7 @@ import UIKit class NSCreatedEventDetailViewController: NSViewController { private let stackScrollView = NSStackScrollView(axis: .vertical, spacing: 0) + private let qrContainer = UIView() private let qrCodeImageView = UIImageView() private let venueView = NSVenueView(large: true) @@ -81,7 +82,7 @@ class NSCreatedEventDetailViewController: NSViewController { self.update(state) } - accessibilityElements = [venueView, checkInButton, shareButton, showPDFButton, deleteButton, dismissButton] + accessibilityElements = [venueView, qrContainer, checkInButton, shareButton, showPDFButton, deleteButton, dismissButton] } override func viewDidAppear(_ animated: Bool) { @@ -117,16 +118,18 @@ class NSCreatedEventDetailViewController: NSViewController { stackScrollView.addArrangedView(venueView) stackScrollView.addSpacerView(NSPadding.large) - let container = UIView() - stackScrollView.addArrangedView(container) + stackScrollView.addArrangedView(qrContainer) qrCodeImageView.layer.magnificationFilter = .nearest - container.addSubview(qrCodeImageView) + qrContainer.addSubview(qrCodeImageView) qrCodeImageView.snp.makeConstraints { make in make.top.bottom.centerX.equalToSuperview() make.size.equalTo(self.view.snp.width).offset(-3 * NSPadding.large) } + qrContainer.isAccessibilityElement = true + qrContainer.accessibilityLabel = "accessibility_preview_qr_code_alternative_text".ub_localized + stackScrollView.addSpacerView(NSPadding.large + NSPadding.small) let contentView = UIView() diff --git a/DP3TApp/Screens/CheckIn/Events/NSCreatedEventsViewController.swift b/DP3TApp/Screens/CheckIn/Events/NSCreatedEventsViewController.swift index 490c8eb0..60266b61 100644 --- a/DP3TApp/Screens/CheckIn/Events/NSCreatedEventsViewController.swift +++ b/DP3TApp/Screens/CheckIn/Events/NSCreatedEventsViewController.swift @@ -17,7 +17,7 @@ class NSCreatedEventsViewController: NSViewController { private let generateButton = NSButton(title: "checkins_create_qr_code".ub_localized, style: .normal(.ns_blue)) private let eventsInfoBox: NSInfoBoxView = { - let model = NSInfoBoxView.ViewModel(title: "events_info_box_title".ub_localized, subText: "events_info_box_text".ub_localized, image: UIImage(named: "ic-info"), titleColor: .ns_blue, subtextColor: .ns_blue, backgroundColor: .ns_blueBackground, dynamicIconTintColor: .ns_blue, titleLabelType: .textBold) + let model = NSInfoBoxView.ViewModel(title: "events_info_box_title".ub_localized, subText: "events_info_box_text".ub_localized, image: UIImage(named: "ic-info"), titleColor: .ns_blue, subtextColor: .ns_blue, backgroundColor: .ns_blueBackground, dynamicIconTintColor: .ns_blue, titleLabelType: .textBold, separateAccessibility: true) return NSInfoBoxView(viewModel: model) }() diff --git a/DP3TApp/Screens/CheckIn/Scanner/NSCheckInViewController.swift b/DP3TApp/Screens/CheckIn/Scanner/NSCheckInViewController.swift index a1438345..6822882d 100644 --- a/DP3TApp/Screens/CheckIn/Scanner/NSCheckInViewController.swift +++ b/DP3TApp/Screens/CheckIn/Scanner/NSCheckInViewController.swift @@ -157,6 +157,7 @@ extension NSCheckInViewController: NSQRScannerViewDelegate { errorContainer.alpha = 1.0 qrErrorLabel.alpha = 1.0 lampButton.alpha = 0.0 + errorContainer.accessibilityViewIsModal = true } func qrScanningSucceededWithCode(_ str: String?) { diff --git a/DP3TApp/Screens/Onboarding/NSOnboardingInfoView.swift b/DP3TApp/Screens/Onboarding/NSOnboardingInfoView.swift index b093b78b..bfb69830 100644 --- a/DP3TApp/Screens/Onboarding/NSOnboardingInfoView.swift +++ b/DP3TApp/Screens/Onboarding/NSOnboardingInfoView.swift @@ -32,7 +32,7 @@ class NSOnboardingInfoView: UIView { imgView.ub_setContentPriorityRequired() label.text = text - label.accessibilityLabel = text.ub_localized.replacingOccurrences(of: "BAG", with: "B. A. G.") + label.accessibilityLabel = text.ub_localized.replacingOccurrences(of: "BAG", with: "B. A. G.").replacingOccurrences(of: "(BLE)", with: "(B. L. E.)") addSubview(imgView) addSubview(label) diff --git a/DP3TApp/Screens/Reports/Exposed/NSReportsDetailExposedEncountersViewController.swift b/DP3TApp/Screens/Reports/Exposed/NSReportsDetailExposedEncountersViewController.swift index 0de4d57b..2a6b2b4f 100644 --- a/DP3TApp/Screens/Reports/Exposed/NSReportsDetailExposedEncountersViewController.swift +++ b/DP3TApp/Screens/Reports/Exposed/NSReportsDetailExposedEncountersViewController.swift @@ -111,7 +111,6 @@ class NSReportsDetailExposedEncountersViewController: NSTitleViewScrollViewContr stackScrollView.addSpacerView(3 * NSPadding.large) let faqButton = NSButton.faqButton(color: .ns_blue) - faqButton.accessibilityTraits = [.link] stackScrollView.addArrangedView(faqButton) stackScrollView.addSpacerView(NSPadding.large) @@ -125,9 +124,7 @@ class NSReportsDetailExposedEncountersViewController: NSTitleViewScrollViewContr } notYetOpenedView?.isHidden = didOpenLeitfaden - notYetOpenedView?.accessibilityViewIsModal = didOpenLeitfaden alreadyOpenedView?.isHidden = !didOpenLeitfaden - alreadyOpenedView?.accessibilityViewIsModal = didOpenLeitfaden let quarantinePeriod: TimeInterval = 60 * 60 * 24 * 10 if let latestExposure: Date = reports.map(\.timestamp).sorted(by: >).first { @@ -161,9 +158,7 @@ class NSReportsDetailExposedEncountersViewController: NSTitleViewScrollViewContr strongSelf.openLeitfaden() } - let sView = addInfoButton(to: leitfadenButton, buttonText: text) - sView.isAccessibilityElement = false - whiteBoxView.contentView.addArrangedSubview(sView) + whiteBoxView.contentView.addArrangedSubview(addInfoButton(to: leitfadenButton, buttonText: text)) whiteBoxView.contentView.addSpacerView(40.0) addTextContentSection(to: whiteBoxView) addTestInfo(to: whiteBoxView) @@ -333,6 +328,7 @@ class NSReportsDetailExposedEncountersViewController: NSTitleViewScrollViewContr let popup = NSReportsLeitfadenInfoPopupViewController(buttonText: buttonText) strongSelf.present(popup, animated: true, completion: nil) } + stackView.shouldGroupAccessibilityChildren = false stackView.accessibilityElements = [button, infoButton] return stackView diff --git a/DP3TApp/SharedUI/Views/NSInfoBoxView.swift b/DP3TApp/SharedUI/Views/NSInfoBoxView.swift index fb0a0cf5..454dedaf 100644 --- a/DP3TApp/SharedUI/Views/NSInfoBoxView.swift +++ b/DP3TApp/SharedUI/Views/NSInfoBoxView.swift @@ -42,7 +42,7 @@ class NSInfoBoxView: UIView { illustrationImageView.image = viewModel.illustration setup(viewModel: viewModel) - setupAccessibility(title: viewModel.title, subTitle: viewModel.subText, boldSubText: viewModel.boldSubText, additionalText: viewModel.additionalText, additionalURL: viewModel.additionalURL, externalLinkType: viewModel.externalLinkType, isClickable: viewModel.isClickable) + setupAccessibility(title: viewModel.title, subTitle: viewModel.subText, boldSubText: viewModel.boldSubText, additionalText: viewModel.additionalText, additionalURL: viewModel.additionalURL, externalLinkType: viewModel.externalLinkType, isClickable: viewModel.isClickable, separateAccessibility: viewModel.separateAccessibility) } public var popupCallback: (() -> Void)? @@ -67,6 +67,7 @@ class NSInfoBoxView: UIView { var externalLinkType: NSExternalLinkButton.LinkType = .url var hearingImpairedButtonCallback: (() -> Void)? = nil var isClickable: Bool = false + var separateAccessibility: Bool = false } init(viewModel: ViewModel) { @@ -86,7 +87,7 @@ class NSInfoBoxView: UIView { illustrationImageView.image = viewModel.illustration setup(viewModel: viewModel) - setupAccessibility(title: viewModel.title, subTitle: viewModel.subText, boldSubText: viewModel.boldSubText, additionalText: viewModel.additionalText, additionalURL: viewModel.additionalURL, externalLinkType: viewModel.externalLinkType, isClickable: viewModel.isClickable) + setupAccessibility(title: viewModel.title, subTitle: viewModel.subText, boldSubText: viewModel.boldSubText, additionalText: viewModel.additionalText, additionalURL: viewModel.additionalURL, externalLinkType: viewModel.externalLinkType, isClickable: viewModel.isClickable, separateAccessibility: viewModel.separateAccessibility) } required init?(coder _: NSCoder) { @@ -266,7 +267,7 @@ class NSInfoBoxView: UIView { // MARK: - Accessibility extension NSInfoBoxView { - private func setupAccessibility(title: String, subTitle: String, boldSubText: String?, additionalText: String?, additionalURL: String?, externalLinkType: NSExternalLinkButton.LinkType, isClickable: Bool) { + private func setupAccessibility(title: String, subTitle: String, boldSubText: String?, additionalText: String?, additionalURL: String?, externalLinkType: NSExternalLinkButton.LinkType, isClickable: Bool, separateAccessibility: Bool) { if let additionalURL = additionalURL { isAccessibilityElement = false @@ -277,8 +278,13 @@ extension NSInfoBoxView { return } - isAccessibilityElement = true - accessibilityTraits = isClickable ? [.button] : [] - accessibilityLabel = "\(title), \(subTitle), \(boldSubText ?? ""), \(additionalText ?? "")" + if !separateAccessibility { + isAccessibilityElement = true + accessibilityTraits = isClickable ? [.button] : [] + accessibilityLabel = "\(title), \(subTitle), \(boldSubText ?? ""), \(additionalText ?? "")" + } else { + isAccessibilityElement = false + titleLabel.accessibilityTraits = [.header] + } } } From b7ae7b031a45df90553bf4b74395ef0ae47d9d7f Mon Sep 17 00:00:00 2001 From: Marco Zimmermann Date: Tue, 7 Sep 2021 08:52:18 +0200 Subject: [PATCH 18/27] resets default debugging language to german Signed-off-by: Marco Zimmermann --- DP3TApp.xcodeproj/xcshareddata/xcschemes/Debug.xcscheme | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DP3TApp.xcodeproj/xcshareddata/xcschemes/Debug.xcscheme b/DP3TApp.xcodeproj/xcshareddata/xcschemes/Debug.xcscheme index 9a94d99c..07ddc7bf 100644 --- a/DP3TApp.xcodeproj/xcshareddata/xcschemes/Debug.xcscheme +++ b/DP3TApp.xcodeproj/xcshareddata/xcschemes/Debug.xcscheme @@ -64,7 +64,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "en" + language = "de" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" From 7b3bc591c41a0d9bd5fdad3ff1d754fc5b00f6e7 Mon Sep 17 00:00:00 2001 From: Marco Zimmermann Date: Wed, 8 Sep 2021 08:43:16 +0200 Subject: [PATCH 19/27] updates accessibility of overlapping checkin view Signed-off-by: Marco Zimmermann --- DP3TApp/Screens/CheckIn/Edit/NSOverlappingCheckInView.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/DP3TApp/Screens/CheckIn/Edit/NSOverlappingCheckInView.swift b/DP3TApp/Screens/CheckIn/Edit/NSOverlappingCheckInView.swift index 1db84bd4..8d437e35 100644 --- a/DP3TApp/Screens/CheckIn/Edit/NSOverlappingCheckInView.swift +++ b/DP3TApp/Screens/CheckIn/Edit/NSOverlappingCheckInView.swift @@ -54,6 +54,7 @@ class NSOverlappingCheckInView: UBButton { highlightCornerRadius = 3.0 ub_addShadow(radius: 5.0, opacity: 0.17, xOffset: 0.0, yOffset: 0.0) - self.accessibilityElements = [self.diaryContentView] + isAccessibilityElement = true + accessibilityLabel = diaryContentView.accessibilityLabel } } From ede75c522297ef29021b7cb3d98c63272e1ba0a2 Mon Sep 17 00:00:00 2001 From: Marco Zimmermann Date: Thu, 9 Sep 2021 09:48:16 +0200 Subject: [PATCH 20/27] updates translations Signed-off-by: Marco Zimmermann --- Translations/bs.lproj/Localizable.strings | 36 +++++++++--------- Translations/en.lproj/Localizable.strings | 36 +++++++++--------- Translations/es.lproj/Localizable.strings | 36 +++++++++--------- Translations/fr.lproj/Localizable.strings | 32 ++++++++-------- Translations/hr.lproj/Localizable.strings | 36 +++++++++--------- Translations/it.lproj/Localizable.strings | 38 +++++++++---------- Translations/pt.lproj/Localizable.strings | 36 +++++++++--------- Translations/rm.lproj/Localizable.strings | 34 ++++++++--------- Translations/sq.lproj/Localizable.strings | 36 +++++++++--------- .../sr-Latn-RS.lproj/Localizable.strings | 36 +++++++++--------- Translations/ti.lproj/Localizable.strings | 36 +++++++++--------- Translations/tr.lproj/Localizable.strings | 36 +++++++++--------- 12 files changed, 214 insertions(+), 214 deletions(-) diff --git a/Translations/bs.lproj/Localizable.strings b/Translations/bs.lproj/Localizable.strings index a2e89b84..b5702668 100644 --- a/Translations/bs.lproj/Localizable.strings +++ b/Translations/bs.lproj/Localizable.strings @@ -1466,7 +1466,7 @@ "error_title" = "Greška"; "qr_scanner_error_code_not_yet_valid" = "QR kod je još nevažeći"; "qr_scanner_error_code_not_valid_anymore" = "QR kod je nevažeći "; -"error_already_checked_in" = ""; +"error_already_checked_in" = "You are already checked in at another location."; "error_update_text" = "Ovaj QR kod nije kompatibilan sa instaliranom verzijom aplikacije. Ažurirajte aplikaciju, da biste nastavili korišćenje."; "error_update_title" = "Potrebno ažuriranje"; "error_action_update" = "Sada ažurirati"; @@ -1739,55 +1739,55 @@ "covid_certificate_install_app" = "Instalirati aplikaciju"; /*Titel des Buttons, der das PDF herunterlädt*/ -"web_generator_download_pdf_button" = ""; +"web_generator_download_pdf_button" = "Download PDF"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ -"accessibility_expandable_box_reduced_state" = "reduced"; +"accessibility_expandable_box_reduced_state" = "collapsed"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ "accessibility_expandable_box_expanded_state" = "expanded"; /*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ -"checkin_overlap_popup_title" = ""; +"checkin_overlap_popup_title" = "Cannot save"; /*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ -"checkin_overlap_popup_text" = ""; +"checkin_overlap_popup_text" = "The times you selected for {CHECKIN} overlap with other check-ins. Please check your entries again."; /*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ -"checkin_overlap_back_button" = ""; +"checkin_overlap_back_button" = "Back"; /*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ -"accessibility_reminder_option_hours_plural" = "hours"; +"accessibility_reminder_option_hours_plural" = "Hours"; /*This will be read by the screenreader instead of "'" (for the reminder options)*/ -"accessibility_reminder_option_minutes" = "minutes"; +"accessibility_reminder_option_minutes" = "Minutes"; /*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ -"accessibility_reminder_option_hour" = "hour"; +"accessibility_reminder_option_hour" = "Hour"; /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ -"checkin_overlap_popup_success_text" = ""; +"checkin_overlap_popup_success_text" = "There are no longer any conflicts for the time you entered. You can now check out of {CHECKIN}."; /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ -"web_generator_success_title" = ""; +"web_generator_success_title" = "QR code generated"; /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ -"web_generator_reset_button" = ""; +"web_generator_reset_button" = "Generate new QR code"; /*Used by VoiceOver to explain what the info button in the navigation bar does*/ -"accessibility_info_button_app" = ""; +"accessibility_info_button_app" = "More information on the app"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ -"accessibility_info_button_covidcode" = ""; +"accessibility_info_button_covidcode" = "More information on Covidcodes"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ -"accessibility_info_button_numberofcases" = ""; +"accessibility_info_button_numberofcases" = "More information on case numbers"; /*Is read by the screenreader, when newly created QR-code is shown*/ -"accessibility_preview_qr_code_alternative_text" = ""; +"accessibility_preview_qr_code_alternative_text" = "Generated QR code"; /*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ -"checkin_generate_web_hint" = ""; +"checkin_generate_web_hint" = "Alternatively, you can also generate QR codes at qr.swisscovid.ch."; /*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ -"error_already_checked_in_text" = ""; +"error_already_checked_in_text" = "To check in to a new location, you first need to check out."; diff --git a/Translations/en.lproj/Localizable.strings b/Translations/en.lproj/Localizable.strings index 2c4535ee..0a1c19f6 100644 --- a/Translations/en.lproj/Localizable.strings +++ b/Translations/en.lproj/Localizable.strings @@ -1494,7 +1494,7 @@ "error_title" = "Error"; "qr_scanner_error_code_not_yet_valid" = "QR code not yet valid"; "qr_scanner_error_code_not_valid_anymore" = "QR code no longer valid"; -"error_already_checked_in" = ""; +"error_already_checked_in" = "You are already checked in at another location."; "error_update_text" = "This QR code is not compatible with the installed version of the app. Please update the app to continue."; "error_update_title" = "Update required"; "error_action_update" = "Update now"; @@ -1767,55 +1767,55 @@ "covid_certificate_install_app" = "Install app"; /*Titel des Buttons, der das PDF herunterlädt*/ -"web_generator_download_pdf_button" = ""; +"web_generator_download_pdf_button" = "Download PDF"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ -"accessibility_expandable_box_reduced_state" = "reduced"; +"accessibility_expandable_box_reduced_state" = "collapsed"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ "accessibility_expandable_box_expanded_state" = "expanded"; /*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ -"checkin_overlap_popup_title" = ""; +"checkin_overlap_popup_title" = "Cannot save"; /*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ -"checkin_overlap_popup_text" = ""; +"checkin_overlap_popup_text" = "The times you selected for {CHECKIN} overlap with other check-ins. Please check your entries again."; /*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ -"checkin_overlap_back_button" = ""; +"checkin_overlap_back_button" = "Back"; /*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ -"accessibility_reminder_option_hours_plural" = "hours"; +"accessibility_reminder_option_hours_plural" = "Hours"; /*This will be read by the screenreader instead of "'" (for the reminder options)*/ -"accessibility_reminder_option_minutes" = "minutes"; +"accessibility_reminder_option_minutes" = "Minutes"; /*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ -"accessibility_reminder_option_hour" = "hour"; +"accessibility_reminder_option_hour" = "Hour"; /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ -"checkin_overlap_popup_success_text" = ""; +"checkin_overlap_popup_success_text" = "There are no longer any conflicts for the time you entered. You can now check out of {CHECKIN}."; /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ -"web_generator_success_title" = ""; +"web_generator_success_title" = "QR code generated"; /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ -"web_generator_reset_button" = ""; +"web_generator_reset_button" = "Generate new QR code"; /*Used by VoiceOver to explain what the info button in the navigation bar does*/ -"accessibility_info_button_app" = ""; +"accessibility_info_button_app" = "More information on the app"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ -"accessibility_info_button_covidcode" = ""; +"accessibility_info_button_covidcode" = "More information on Covidcodes"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ -"accessibility_info_button_numberofcases" = ""; +"accessibility_info_button_numberofcases" = "More information on case numbers"; /*Is read by the screenreader, when newly created QR-code is shown*/ -"accessibility_preview_qr_code_alternative_text" = ""; +"accessibility_preview_qr_code_alternative_text" = "Generated QR code"; /*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ -"checkin_generate_web_hint" = ""; +"checkin_generate_web_hint" = "Alternatively, you can also generate QR codes at qr.swisscovid.ch."; /*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ -"error_already_checked_in_text" = ""; +"error_already_checked_in_text" = "To check in to a new location, you first need to check out."; diff --git a/Translations/es.lproj/Localizable.strings b/Translations/es.lproj/Localizable.strings index c4c618d6..054a0905 100644 --- a/Translations/es.lproj/Localizable.strings +++ b/Translations/es.lproj/Localizable.strings @@ -1466,7 +1466,7 @@ "error_title" = "Error"; "qr_scanner_error_code_not_yet_valid" = "Código QR aún no válido"; "qr_scanner_error_code_not_valid_anymore" = "Código QR ya no es válido"; -"error_already_checked_in" = ""; +"error_already_checked_in" = "You are already checked in at another location."; "error_update_text" = "Este código QR no es compatible con la versión instalada de la app. Actualice la aplicación para continuar."; "error_update_title" = "Se requiere actualización"; "error_action_update" = "Actualizar ahora"; @@ -1739,55 +1739,55 @@ "covid_certificate_install_app" = "Instalar la aplicación"; /*Titel des Buttons, der das PDF herunterlädt*/ -"web_generator_download_pdf_button" = ""; +"web_generator_download_pdf_button" = "Download PDF"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ -"accessibility_expandable_box_reduced_state" = "reduced"; +"accessibility_expandable_box_reduced_state" = "collapsed"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ "accessibility_expandable_box_expanded_state" = "expanded"; /*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ -"checkin_overlap_popup_title" = ""; +"checkin_overlap_popup_title" = "Cannot save"; /*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ -"checkin_overlap_popup_text" = ""; +"checkin_overlap_popup_text" = "The times you selected for {CHECKIN} overlap with other check-ins. Please check your entries again."; /*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ -"checkin_overlap_back_button" = ""; +"checkin_overlap_back_button" = "Back"; /*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ -"accessibility_reminder_option_hours_plural" = "hours"; +"accessibility_reminder_option_hours_plural" = "Hours"; /*This will be read by the screenreader instead of "'" (for the reminder options)*/ -"accessibility_reminder_option_minutes" = "minutes"; +"accessibility_reminder_option_minutes" = "Minutes"; /*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ -"accessibility_reminder_option_hour" = "hour"; +"accessibility_reminder_option_hour" = "Hour"; /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ -"checkin_overlap_popup_success_text" = ""; +"checkin_overlap_popup_success_text" = "There are no longer any conflicts for the time you entered. You can now check out of {CHECKIN}."; /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ -"web_generator_success_title" = ""; +"web_generator_success_title" = "QR code generated"; /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ -"web_generator_reset_button" = ""; +"web_generator_reset_button" = "Generate new QR code"; /*Used by VoiceOver to explain what the info button in the navigation bar does*/ -"accessibility_info_button_app" = ""; +"accessibility_info_button_app" = "More information on the app"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ -"accessibility_info_button_covidcode" = ""; +"accessibility_info_button_covidcode" = "More information on Covidcodes"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ -"accessibility_info_button_numberofcases" = ""; +"accessibility_info_button_numberofcases" = "More information on case numbers"; /*Is read by the screenreader, when newly created QR-code is shown*/ -"accessibility_preview_qr_code_alternative_text" = ""; +"accessibility_preview_qr_code_alternative_text" = "Generated QR code"; /*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ -"checkin_generate_web_hint" = ""; +"checkin_generate_web_hint" = "Alternatively, you can also generate QR codes at qr.swisscovid.ch."; /*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ -"error_already_checked_in_text" = ""; +"error_already_checked_in_text" = "To check in to a new location, you first need to check out."; diff --git a/Translations/fr.lproj/Localizable.strings b/Translations/fr.lproj/Localizable.strings index 9eda5220..f7590af8 100644 --- a/Translations/fr.lproj/Localizable.strings +++ b/Translations/fr.lproj/Localizable.strings @@ -1499,7 +1499,7 @@ "error_title" = "Erreur"; "qr_scanner_error_code_not_yet_valid" = "Le code QR n’est pas encore valable."; "qr_scanner_error_code_not_valid_anymore" = "Le code QR n’est plus valable."; -"error_already_checked_in" = ""; +"error_already_checked_in" = "Vous êtes déjà enregistré à un autre endroit."; "error_update_text" = "Ce code QR n'est pas compatible avec la version installée de l’application. Veuillez mettre à jour l’application."; "error_update_title" = "Mise à jour requise"; "error_action_update" = "Mettre à jour "; @@ -1772,7 +1772,7 @@ "covid_certificate_install_app" = "Installer l'application"; /*Titel des Buttons, der das PDF herunterlädt*/ -"web_generator_download_pdf_button" = ""; +"web_generator_download_pdf_button" = "Télécharger le PDF"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ "accessibility_expandable_box_reduced_state" = "réduit"; @@ -1781,46 +1781,46 @@ "accessibility_expandable_box_expanded_state" = "étendu"; /*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ -"checkin_overlap_popup_title" = ""; +"checkin_overlap_popup_title" = "Sauvegarde impossible"; /*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ -"checkin_overlap_popup_text" = ""; +"checkin_overlap_popup_text" = "Les heures que vous avez saisies pour {CHECKIN} sont en conflit avec d'autres enregistrements. Veuillez vérifier à nouveau vos données."; /*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ -"checkin_overlap_back_button" = ""; +"checkin_overlap_back_button" = "Retour"; /*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ -"accessibility_reminder_option_hours_plural" = "hours"; +"accessibility_reminder_option_hours_plural" = "heures"; /*This will be read by the screenreader instead of "'" (for the reminder options)*/ "accessibility_reminder_option_minutes" = "minutes"; /*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ -"accessibility_reminder_option_hour" = "hour"; +"accessibility_reminder_option_hour" = "heure"; /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ -"checkin_overlap_popup_success_text" = ""; +"checkin_overlap_popup_success_text" = "Il n'y a plus de conflits pour les heures que vous avez saisies. Vous pouvez maintenant enregistrer votre départ pour {CHECKIN}."; /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ -"web_generator_success_title" = ""; +"web_generator_success_title" = "Code QR créé"; /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ -"web_generator_reset_button" = ""; +"web_generator_reset_button" = "Créer un nouveau code QR"; /*Used by VoiceOver to explain what the info button in the navigation bar does*/ -"accessibility_info_button_app" = ""; +"accessibility_info_button_app" = "Plus d'informations sur l'application"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ -"accessibility_info_button_covidcode" = ""; +"accessibility_info_button_covidcode" = "Plus d'informations sur les codes COVID"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ -"accessibility_info_button_numberofcases" = ""; +"accessibility_info_button_numberofcases" = "Plus d'informations sur le nombre de cas"; /*Is read by the screenreader, when newly created QR-code is shown*/ -"accessibility_preview_qr_code_alternative_text" = ""; +"accessibility_preview_qr_code_alternative_text" = "Code QR créé"; /*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ -"checkin_generate_web_hint" = ""; +"checkin_generate_web_hint" = "Vous pouvez également créer des codes QR sur qr.swisscovid.ch."; /*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ -"error_already_checked_in_text" = ""; +"error_already_checked_in_text" = "Pour vous connecter à un nouvel endroit, vous devez d'abord enregistrer votre départ."; diff --git a/Translations/hr.lproj/Localizable.strings b/Translations/hr.lproj/Localizable.strings index a3ffcd73..ac3273d0 100644 --- a/Translations/hr.lproj/Localizable.strings +++ b/Translations/hr.lproj/Localizable.strings @@ -1464,7 +1464,7 @@ "error_title" = "Greška"; "qr_scanner_error_code_not_yet_valid" = "QR kod je još nevažeći"; "qr_scanner_error_code_not_valid_anymore" = "QR kod je nevažeći "; -"error_already_checked_in" = ""; +"error_already_checked_in" = "You are already checked in at another location."; "error_update_text" = "Ovaj QR kod nije kompatibilan sa instaliranom verzijom aplikacije. Ažurirajte aplikaciju, da biste nastavili korišćenje."; "error_update_title" = "Potrebno ažuriranje"; "error_action_update" = "Sada ažurirati"; @@ -1737,55 +1737,55 @@ "covid_certificate_install_app" = "Instalirati aplikaciju"; /*Titel des Buttons, der das PDF herunterlädt*/ -"web_generator_download_pdf_button" = ""; +"web_generator_download_pdf_button" = "Download PDF"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ -"accessibility_expandable_box_reduced_state" = "reduced"; +"accessibility_expandable_box_reduced_state" = "collapsed"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ "accessibility_expandable_box_expanded_state" = "expanded"; /*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ -"checkin_overlap_popup_title" = ""; +"checkin_overlap_popup_title" = "Cannot save"; /*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ -"checkin_overlap_popup_text" = ""; +"checkin_overlap_popup_text" = "The times you selected for {CHECKIN} overlap with other check-ins. Please check your entries again."; /*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ -"checkin_overlap_back_button" = ""; +"checkin_overlap_back_button" = "Back"; /*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ -"accessibility_reminder_option_hours_plural" = "hours"; +"accessibility_reminder_option_hours_plural" = "Hours"; /*This will be read by the screenreader instead of "'" (for the reminder options)*/ -"accessibility_reminder_option_minutes" = "minutes"; +"accessibility_reminder_option_minutes" = "Minutes"; /*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ -"accessibility_reminder_option_hour" = "hour"; +"accessibility_reminder_option_hour" = "Hour"; /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ -"checkin_overlap_popup_success_text" = ""; +"checkin_overlap_popup_success_text" = "There are no longer any conflicts for the time you entered. You can now check out of {CHECKIN}."; /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ -"web_generator_success_title" = ""; +"web_generator_success_title" = "QR code generated"; /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ -"web_generator_reset_button" = ""; +"web_generator_reset_button" = "Generate new QR code"; /*Used by VoiceOver to explain what the info button in the navigation bar does*/ -"accessibility_info_button_app" = ""; +"accessibility_info_button_app" = "More information on the app"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ -"accessibility_info_button_covidcode" = ""; +"accessibility_info_button_covidcode" = "More information on Covidcodes"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ -"accessibility_info_button_numberofcases" = ""; +"accessibility_info_button_numberofcases" = "More information on case numbers"; /*Is read by the screenreader, when newly created QR-code is shown*/ -"accessibility_preview_qr_code_alternative_text" = ""; +"accessibility_preview_qr_code_alternative_text" = "Generated QR code"; /*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ -"checkin_generate_web_hint" = ""; +"checkin_generate_web_hint" = "Alternatively, you can also generate QR codes at qr.swisscovid.ch."; /*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ -"error_already_checked_in_text" = ""; +"error_already_checked_in_text" = "To check in to a new location, you first need to check out."; diff --git a/Translations/it.lproj/Localizable.strings b/Translations/it.lproj/Localizable.strings index 6e23d903..1016d3da 100644 --- a/Translations/it.lproj/Localizable.strings +++ b/Translations/it.lproj/Localizable.strings @@ -1499,7 +1499,7 @@ "error_title" = "Errore"; "qr_scanner_error_code_not_yet_valid" = "Codice QR non ancora valido"; "qr_scanner_error_code_not_valid_anymore" = "Codice QR non più valido"; -"error_already_checked_in" = ""; +"error_already_checked_in" = "Hai già fatto il check-in altrove."; "error_update_text" = "Questo codice QR non è compatibile con la versione dell'app installata. Aggiorna l'app per continuare."; "error_update_title" = "Aggiornamento necessario"; "error_action_update" = "Aggiorna ora"; @@ -1772,55 +1772,55 @@ "covid_certificate_install_app" = "Installa l'app"; /*Titel des Buttons, der das PDF herunterlädt*/ -"web_generator_download_pdf_button" = ""; +"web_generator_download_pdf_button" = "Scarica PDF"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ -"accessibility_expandable_box_reduced_state" = "compressa"; +"accessibility_expandable_box_reduced_state" = "versione compressa"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ -"accessibility_expandable_box_expanded_state" = "espansa"; +"accessibility_expandable_box_expanded_state" = "versione espansa"; /*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ -"checkin_overlap_popup_title" = ""; +"checkin_overlap_popup_title" = "Impossibile salvare"; /*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ -"checkin_overlap_popup_text" = ""; +"checkin_overlap_popup_text" = "Gli orari da te selezionati per {CHECKIN} si sovrappongono ad altri check-in. Ricontrolla i dati immessi."; /*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ -"checkin_overlap_back_button" = ""; +"checkin_overlap_back_button" = "Indietro"; /*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ -"accessibility_reminder_option_hours_plural" = "hours"; +"accessibility_reminder_option_hours_plural" = "Ore"; /*This will be read by the screenreader instead of "'" (for the reminder options)*/ -"accessibility_reminder_option_minutes" = "minutes"; +"accessibility_reminder_option_minutes" = "Minuti"; /*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ -"accessibility_reminder_option_hour" = "hour"; +"accessibility_reminder_option_hour" = "Ora"; /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ -"checkin_overlap_popup_success_text" = ""; +"checkin_overlap_popup_success_text" = "Non ci sono più conflitti tra gli orari che hai immesso. Ora puoi fare il check-out da {CHECKIN}."; /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ -"web_generator_success_title" = ""; +"web_generator_success_title" = "Codice QR creato"; /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ -"web_generator_reset_button" = ""; +"web_generator_reset_button" = "Crea nuovo codice QR"; /*Used by VoiceOver to explain what the info button in the navigation bar does*/ -"accessibility_info_button_app" = ""; +"accessibility_info_button_app" = "Più informazioni sull'app"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ -"accessibility_info_button_covidcode" = ""; +"accessibility_info_button_covidcode" = "Più informazioni sui codici Covid"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ -"accessibility_info_button_numberofcases" = ""; +"accessibility_info_button_numberofcases" = "Più informazioni sul numero di casi"; /*Is read by the screenreader, when newly created QR-code is shown*/ -"accessibility_preview_qr_code_alternative_text" = ""; +"accessibility_preview_qr_code_alternative_text" = "Codice QR creato"; /*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ -"checkin_generate_web_hint" = ""; +"checkin_generate_web_hint" = "In alternativa, puoi creare i codici QR anche su qr.swisscovid.ch"; /*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ -"error_already_checked_in_text" = ""; +"error_already_checked_in_text" = "Per fare il check-in altrove, devi prima fare il check-out."; diff --git a/Translations/pt.lproj/Localizable.strings b/Translations/pt.lproj/Localizable.strings index bbb8e0c6..9fb88f0c 100644 --- a/Translations/pt.lproj/Localizable.strings +++ b/Translations/pt.lproj/Localizable.strings @@ -1466,7 +1466,7 @@ "error_title" = "Erro"; "qr_scanner_error_code_not_yet_valid" = "O código QR ainda não é válido!"; "qr_scanner_error_code_not_valid_anymore" = "O código QR não é mais válido!"; -"error_already_checked_in" = ""; +"error_already_checked_in" = "You are already checked in at another location."; "error_update_text" = "Este código QR não é compatível com a versão do aplicativo instalada. Por favor, atualize o aplicativo para continuar."; "error_update_title" = "É necessário atualizar."; "error_action_update" = "Atualizar agora"; @@ -1739,55 +1739,55 @@ "covid_certificate_install_app" = "Instalar o aplicativo"; /*Titel des Buttons, der das PDF herunterlädt*/ -"web_generator_download_pdf_button" = ""; +"web_generator_download_pdf_button" = "Download PDF"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ -"accessibility_expandable_box_reduced_state" = "reduced"; +"accessibility_expandable_box_reduced_state" = "collapsed"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ "accessibility_expandable_box_expanded_state" = "expanded"; /*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ -"checkin_overlap_popup_title" = ""; +"checkin_overlap_popup_title" = "Cannot save"; /*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ -"checkin_overlap_popup_text" = ""; +"checkin_overlap_popup_text" = "The times you selected for {CHECKIN} overlap with other check-ins. Please check your entries again."; /*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ -"checkin_overlap_back_button" = ""; +"checkin_overlap_back_button" = "Back"; /*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ -"accessibility_reminder_option_hours_plural" = "hours"; +"accessibility_reminder_option_hours_plural" = "Hours"; /*This will be read by the screenreader instead of "'" (for the reminder options)*/ -"accessibility_reminder_option_minutes" = "minutes"; +"accessibility_reminder_option_minutes" = "Minutes"; /*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ -"accessibility_reminder_option_hour" = "hour"; +"accessibility_reminder_option_hour" = "Hour"; /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ -"checkin_overlap_popup_success_text" = ""; +"checkin_overlap_popup_success_text" = "There are no longer any conflicts for the time you entered. You can now check out of {CHECKIN}."; /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ -"web_generator_success_title" = ""; +"web_generator_success_title" = "QR code generated"; /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ -"web_generator_reset_button" = ""; +"web_generator_reset_button" = "Generate new QR code"; /*Used by VoiceOver to explain what the info button in the navigation bar does*/ -"accessibility_info_button_app" = ""; +"accessibility_info_button_app" = "More information on the app"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ -"accessibility_info_button_covidcode" = ""; +"accessibility_info_button_covidcode" = "More information on Covidcodes"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ -"accessibility_info_button_numberofcases" = ""; +"accessibility_info_button_numberofcases" = "More information on case numbers"; /*Is read by the screenreader, when newly created QR-code is shown*/ -"accessibility_preview_qr_code_alternative_text" = ""; +"accessibility_preview_qr_code_alternative_text" = "Generated QR code"; /*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ -"checkin_generate_web_hint" = ""; +"checkin_generate_web_hint" = "Alternatively, you can also generate QR codes at qr.swisscovid.ch."; /*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ -"error_already_checked_in_text" = ""; +"error_already_checked_in_text" = "To check in to a new location, you first need to check out."; diff --git a/Translations/rm.lproj/Localizable.strings b/Translations/rm.lproj/Localizable.strings index f261640b..6956c2c3 100644 --- a/Translations/rm.lproj/Localizable.strings +++ b/Translations/rm.lproj/Localizable.strings @@ -1464,7 +1464,7 @@ "error_title" = "Sbagl"; "qr_scanner_error_code_not_yet_valid" = "Il code QR n'è anc betg valaivel"; "qr_scanner_error_code_not_valid_anymore" = "Il code QR n'è betg pli valaivel"; -"error_already_checked_in" = ""; +"error_already_checked_in" = "Vus essas gia registrà/registrada en in auter lieu."; "error_update_text" = "Quest code QR n'è betg cumpatibel cun la versiun da l'app installada. Per plaschair actualisar l'app per cuntinuar."; "error_update_title" = "In update è necessari"; "error_action_update" = "Actualisar ussa"; @@ -1737,7 +1737,7 @@ "covid_certificate_install_app" = "Installar l'app"; /*Titel des Buttons, der das PDF herunterlädt*/ -"web_generator_download_pdf_button" = ""; +"web_generator_download_pdf_button" = "Chargiar giu il PDF"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ "accessibility_expandable_box_reduced_state" = "reducì"; @@ -1746,46 +1746,46 @@ "accessibility_expandable_box_expanded_state" = "extendì"; /*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ -"checkin_overlap_popup_title" = ""; +"checkin_overlap_popup_title" = "Betg pussaivel da segirar"; /*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ -"checkin_overlap_popup_text" = ""; +"checkin_overlap_popup_text" = "Vossas uras tschernidas per {CHECKIN} sa cruschan cun auters check-ins. Controllai per plaschair anc ina giada Vossas indicaziuns."; /*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ -"checkin_overlap_back_button" = ""; +"checkin_overlap_back_button" = "Enavos"; /*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ -"accessibility_reminder_option_hours_plural" = "hours"; +"accessibility_reminder_option_hours_plural" = "uras"; /*This will be read by the screenreader instead of "'" (for the reminder options)*/ -"accessibility_reminder_option_minutes" = "minutes"; +"accessibility_reminder_option_minutes" = "minutas"; /*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ -"accessibility_reminder_option_hour" = "hour"; +"accessibility_reminder_option_hour" = "ura"; /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ -"checkin_overlap_popup_success_text" = ""; +"checkin_overlap_popup_success_text" = "I n'èn avant maun nagins conflicts pli per Vossas uras endatadas. Vus pudais ussa sortir da {CHECKIN}."; /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ -"web_generator_success_title" = ""; +"web_generator_success_title" = "Il code QR è generà"; /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ -"web_generator_reset_button" = ""; +"web_generator_reset_button" = "Generar in nov code QR"; /*Used by VoiceOver to explain what the info button in the navigation bar does*/ -"accessibility_info_button_app" = ""; +"accessibility_info_button_app" = "Dapli infurmaziuns davart l'app"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ -"accessibility_info_button_covidcode" = ""; +"accessibility_info_button_covidcode" = "Dapli infurmaziuns davart ils codes covid"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ -"accessibility_info_button_numberofcases" = ""; +"accessibility_info_button_numberofcases" = "Dapli infurmaziuns davart ils dumbers da cas"; /*Is read by the screenreader, when newly created QR-code is shown*/ -"accessibility_preview_qr_code_alternative_text" = ""; +"accessibility_preview_qr_code_alternative_text" = "Code QR generà"; /*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ -"checkin_generate_web_hint" = ""; +"checkin_generate_web_hint" = "Sco alternativa pudais Vus generar ils codes QR er sin qr.swisscovid.ch."; /*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ -"error_already_checked_in_text" = ""; +"error_already_checked_in_text" = "Per As registrar en in nov lieu stuais Vus l'emprim sortir dal vegl lieu."; diff --git a/Translations/sq.lproj/Localizable.strings b/Translations/sq.lproj/Localizable.strings index 72f0169e..6c5937d8 100644 --- a/Translations/sq.lproj/Localizable.strings +++ b/Translations/sq.lproj/Localizable.strings @@ -1466,7 +1466,7 @@ "error_title" = "Gabim"; "qr_scanner_error_code_not_yet_valid" = "Kodi QR nuk është ende i vlefshëm"; "qr_scanner_error_code_not_valid_anymore" = "Kodi QR nuk është më i vlefshëm"; -"error_already_checked_in" = ""; +"error_already_checked_in" = "You are already checked in at another location."; "error_update_text" = "Ky kod QR nuk është i pajtueshëm me versionin e aplikacionit të instaluar. Përditësoni aplikacionin për të vazhduar më tej."; "error_update_title" = "Përditësimi i nevojshëm"; "error_action_update" = "Përditësoni tani"; @@ -1739,55 +1739,55 @@ "covid_certificate_install_app" = "Instaloni aplikacionin"; /*Titel des Buttons, der das PDF herunterlädt*/ -"web_generator_download_pdf_button" = ""; +"web_generator_download_pdf_button" = "Download PDF"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ -"accessibility_expandable_box_reduced_state" = "reduced"; +"accessibility_expandable_box_reduced_state" = "collapsed"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ "accessibility_expandable_box_expanded_state" = "expanded"; /*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ -"checkin_overlap_popup_title" = ""; +"checkin_overlap_popup_title" = "Cannot save"; /*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ -"checkin_overlap_popup_text" = ""; +"checkin_overlap_popup_text" = "The times you selected for {CHECKIN} overlap with other check-ins. Please check your entries again."; /*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ -"checkin_overlap_back_button" = ""; +"checkin_overlap_back_button" = "Back"; /*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ -"accessibility_reminder_option_hours_plural" = "hours"; +"accessibility_reminder_option_hours_plural" = "Hours"; /*This will be read by the screenreader instead of "'" (for the reminder options)*/ -"accessibility_reminder_option_minutes" = "minutes"; +"accessibility_reminder_option_minutes" = "Minutes"; /*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ -"accessibility_reminder_option_hour" = "hour"; +"accessibility_reminder_option_hour" = "Hour"; /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ -"checkin_overlap_popup_success_text" = ""; +"checkin_overlap_popup_success_text" = "There are no longer any conflicts for the time you entered. You can now check out of {CHECKIN}."; /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ -"web_generator_success_title" = ""; +"web_generator_success_title" = "QR code generated"; /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ -"web_generator_reset_button" = ""; +"web_generator_reset_button" = "Generate new QR code"; /*Used by VoiceOver to explain what the info button in the navigation bar does*/ -"accessibility_info_button_app" = ""; +"accessibility_info_button_app" = "More information on the app"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ -"accessibility_info_button_covidcode" = ""; +"accessibility_info_button_covidcode" = "More information on Covidcodes"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ -"accessibility_info_button_numberofcases" = ""; +"accessibility_info_button_numberofcases" = "More information on case numbers"; /*Is read by the screenreader, when newly created QR-code is shown*/ -"accessibility_preview_qr_code_alternative_text" = ""; +"accessibility_preview_qr_code_alternative_text" = "Generated QR code"; /*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ -"checkin_generate_web_hint" = ""; +"checkin_generate_web_hint" = "Alternatively, you can also generate QR codes at qr.swisscovid.ch."; /*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ -"error_already_checked_in_text" = ""; +"error_already_checked_in_text" = "To check in to a new location, you first need to check out."; diff --git a/Translations/sr-Latn-RS.lproj/Localizable.strings b/Translations/sr-Latn-RS.lproj/Localizable.strings index 683e09e9..d38741f9 100644 --- a/Translations/sr-Latn-RS.lproj/Localizable.strings +++ b/Translations/sr-Latn-RS.lproj/Localizable.strings @@ -1464,7 +1464,7 @@ "error_title" = "Greška"; "qr_scanner_error_code_not_yet_valid" = "QR kod je još nevažeći"; "qr_scanner_error_code_not_valid_anymore" = "QR kod je nevažeći "; -"error_already_checked_in" = ""; +"error_already_checked_in" = "You are already checked in at another location."; "error_update_text" = "Ovaj QR kod nije kompatibilan sa instaliranom verzijom aplikacije. Ažurirajte aplikaciju, da biste nastavili korišćenje."; "error_update_title" = "Potrebno ažuriranje"; "error_action_update" = "Sada ažurirati"; @@ -1737,55 +1737,55 @@ "covid_certificate_install_app" = "Instalirati aplikaciju"; /*Titel des Buttons, der das PDF herunterlädt*/ -"web_generator_download_pdf_button" = ""; +"web_generator_download_pdf_button" = "Download PDF"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ -"accessibility_expandable_box_reduced_state" = "reduced"; +"accessibility_expandable_box_reduced_state" = "collapsed"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ "accessibility_expandable_box_expanded_state" = "expanded"; /*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ -"checkin_overlap_popup_title" = ""; +"checkin_overlap_popup_title" = "Cannot save"; /*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ -"checkin_overlap_popup_text" = ""; +"checkin_overlap_popup_text" = "The times you selected for {CHECKIN} overlap with other check-ins. Please check your entries again."; /*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ -"checkin_overlap_back_button" = ""; +"checkin_overlap_back_button" = "Back"; /*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ -"accessibility_reminder_option_hours_plural" = "hours"; +"accessibility_reminder_option_hours_plural" = "Hours"; /*This will be read by the screenreader instead of "'" (for the reminder options)*/ -"accessibility_reminder_option_minutes" = "minutes"; +"accessibility_reminder_option_minutes" = "Minutes"; /*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ -"accessibility_reminder_option_hour" = "hour"; +"accessibility_reminder_option_hour" = "Hour"; /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ -"checkin_overlap_popup_success_text" = ""; +"checkin_overlap_popup_success_text" = "There are no longer any conflicts for the time you entered. You can now check out of {CHECKIN}."; /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ -"web_generator_success_title" = ""; +"web_generator_success_title" = "QR code generated"; /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ -"web_generator_reset_button" = ""; +"web_generator_reset_button" = "Generate new QR code"; /*Used by VoiceOver to explain what the info button in the navigation bar does*/ -"accessibility_info_button_app" = ""; +"accessibility_info_button_app" = "More information on the app"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ -"accessibility_info_button_covidcode" = ""; +"accessibility_info_button_covidcode" = "More information on Covidcodes"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ -"accessibility_info_button_numberofcases" = ""; +"accessibility_info_button_numberofcases" = "More information on case numbers"; /*Is read by the screenreader, when newly created QR-code is shown*/ -"accessibility_preview_qr_code_alternative_text" = ""; +"accessibility_preview_qr_code_alternative_text" = "Generated QR code"; /*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ -"checkin_generate_web_hint" = ""; +"checkin_generate_web_hint" = "Alternatively, you can also generate QR codes at qr.swisscovid.ch."; /*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ -"error_already_checked_in_text" = ""; +"error_already_checked_in_text" = "To check in to a new location, you first need to check out."; diff --git a/Translations/ti.lproj/Localizable.strings b/Translations/ti.lproj/Localizable.strings index 6c4be22b..164f1c4d 100644 --- a/Translations/ti.lproj/Localizable.strings +++ b/Translations/ti.lproj/Localizable.strings @@ -1465,7 +1465,7 @@ "error_title" = "ጉድለት"; "qr_scanner_error_code_not_yet_valid" = "QR-ኮድ ገና ብቑዕ ኣይኮነን"; "qr_scanner_error_code_not_valid_anymore" = "ብቕዓት QR-Code ሓሊፉ"; -"error_already_checked_in" = ""; +"error_already_checked_in" = "You are already checked in at another location."; "error_update_text" = "እዚ ኮድ QR ምስቲ ዝተተከለ ቨርዝዮን ኤፕ ኣይሰርሕን እዩ። ነቲ ኤፕ ኣሕድስዎ ብኽብረትኩም መታን ክትቕጸሉ።"; "error_update_title" = "ምምሕዳስ የድሊ"; "error_action_update" = "ሕጂ ምምሕዳስ"; @@ -1738,55 +1738,55 @@ "covid_certificate_install_app" = "ኤፕ ምትካል"; /*Titel des Buttons, der das PDF herunterlädt*/ -"web_generator_download_pdf_button" = ""; +"web_generator_download_pdf_button" = "Download PDF"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ -"accessibility_expandable_box_reduced_state" = "reduced"; +"accessibility_expandable_box_reduced_state" = "collapsed"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ "accessibility_expandable_box_expanded_state" = "expanded"; /*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ -"checkin_overlap_popup_title" = ""; +"checkin_overlap_popup_title" = "Cannot save"; /*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ -"checkin_overlap_popup_text" = ""; +"checkin_overlap_popup_text" = "The times you selected for {CHECKIN} overlap with other check-ins. Please check your entries again."; /*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ -"checkin_overlap_back_button" = ""; +"checkin_overlap_back_button" = "Back"; /*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ -"accessibility_reminder_option_hours_plural" = "hours"; +"accessibility_reminder_option_hours_plural" = "Hours"; /*This will be read by the screenreader instead of "'" (for the reminder options)*/ -"accessibility_reminder_option_minutes" = "minutes"; +"accessibility_reminder_option_minutes" = "Minutes"; /*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ -"accessibility_reminder_option_hour" = "hour"; +"accessibility_reminder_option_hour" = "Hour"; /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ -"checkin_overlap_popup_success_text" = ""; +"checkin_overlap_popup_success_text" = "There are no longer any conflicts for the time you entered. You can now check out of {CHECKIN}."; /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ -"web_generator_success_title" = ""; +"web_generator_success_title" = "QR code generated"; /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ -"web_generator_reset_button" = ""; +"web_generator_reset_button" = "Generate new QR code"; /*Used by VoiceOver to explain what the info button in the navigation bar does*/ -"accessibility_info_button_app" = ""; +"accessibility_info_button_app" = "More information on the app"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ -"accessibility_info_button_covidcode" = ""; +"accessibility_info_button_covidcode" = "More information on Covidcodes"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ -"accessibility_info_button_numberofcases" = ""; +"accessibility_info_button_numberofcases" = "More information on case numbers"; /*Is read by the screenreader, when newly created QR-code is shown*/ -"accessibility_preview_qr_code_alternative_text" = ""; +"accessibility_preview_qr_code_alternative_text" = "Generated QR code"; /*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ -"checkin_generate_web_hint" = ""; +"checkin_generate_web_hint" = "Alternatively, you can also generate QR codes at qr.swisscovid.ch."; /*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ -"error_already_checked_in_text" = ""; +"error_already_checked_in_text" = "To check in to a new location, you first need to check out."; diff --git a/Translations/tr.lproj/Localizable.strings b/Translations/tr.lproj/Localizable.strings index 1c44148e..9186d71e 100644 --- a/Translations/tr.lproj/Localizable.strings +++ b/Translations/tr.lproj/Localizable.strings @@ -1465,7 +1465,7 @@ "error_title" = "Hata"; "qr_scanner_error_code_not_yet_valid" = "Kare kod henüz geçerli değil"; "qr_scanner_error_code_not_valid_anymore" = "Kare kod artık geçerli değil"; -"error_already_checked_in" = ""; +"error_already_checked_in" = "You are already checked in at another location."; "error_update_text" = "Bu kare kod artık kurulu olan uygulama sürümü ile uyumlu değil. Lütfen işleme devam edebilmek için uygulamayı güncelleyin."; "error_update_title" = "Güncelleme gerekiyor"; "error_action_update" = "Şimdi güncelleyin"; @@ -1738,55 +1738,55 @@ "covid_certificate_install_app" = "Uygulamayı kur"; /*Titel des Buttons, der das PDF herunterlädt*/ -"web_generator_download_pdf_button" = ""; +"web_generator_download_pdf_button" = "Download PDF"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ -"accessibility_expandable_box_reduced_state" = "reduced"; +"accessibility_expandable_box_reduced_state" = "collapsed"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ "accessibility_expandable_box_expanded_state" = "expanded"; /*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ -"checkin_overlap_popup_title" = ""; +"checkin_overlap_popup_title" = "Cannot save"; /*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ -"checkin_overlap_popup_text" = ""; +"checkin_overlap_popup_text" = "The times you selected for {CHECKIN} overlap with other check-ins. Please check your entries again."; /*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ -"checkin_overlap_back_button" = ""; +"checkin_overlap_back_button" = "Back"; /*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ -"accessibility_reminder_option_hours_plural" = "hours"; +"accessibility_reminder_option_hours_plural" = "Hours"; /*This will be read by the screenreader instead of "'" (for the reminder options)*/ -"accessibility_reminder_option_minutes" = "minutes"; +"accessibility_reminder_option_minutes" = "Minutes"; /*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ -"accessibility_reminder_option_hour" = "hour"; +"accessibility_reminder_option_hour" = "Hour"; /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ -"checkin_overlap_popup_success_text" = ""; +"checkin_overlap_popup_success_text" = "There are no longer any conflicts for the time you entered. You can now check out of {CHECKIN}."; /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ -"web_generator_success_title" = ""; +"web_generator_success_title" = "QR code generated"; /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ -"web_generator_reset_button" = ""; +"web_generator_reset_button" = "Generate new QR code"; /*Used by VoiceOver to explain what the info button in the navigation bar does*/ -"accessibility_info_button_app" = ""; +"accessibility_info_button_app" = "More information on the app"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ -"accessibility_info_button_covidcode" = ""; +"accessibility_info_button_covidcode" = "More information on Covidcodes"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ -"accessibility_info_button_numberofcases" = ""; +"accessibility_info_button_numberofcases" = "More information on case numbers"; /*Is read by the screenreader, when newly created QR-code is shown*/ -"accessibility_preview_qr_code_alternative_text" = ""; +"accessibility_preview_qr_code_alternative_text" = "Generated QR code"; /*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ -"checkin_generate_web_hint" = ""; +"checkin_generate_web_hint" = "Alternatively, you can also generate QR codes at qr.swisscovid.ch."; /*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ -"error_already_checked_in_text" = ""; +"error_already_checked_in_text" = "To check in to a new location, you first need to check out."; From 64c6a502e1b6cf1493746e7a126fefe74e624eaf Mon Sep 17 00:00:00 2001 From: Marco Zimmermann Date: Thu, 9 Sep 2021 09:48:22 +0200 Subject: [PATCH 21/27] updates terms of use Signed-off-by: Marco Zimmermann --- .../DE_App_Nutzungsbedingungen.html | 10 ++++++--- .../EN_App_Nutzungsbedingungen.html | 11 +++++----- .../FR_App_Nutzungsbedingungen.html | 21 ++++++++++--------- .../IT_App_Nutzungsbedingungen.html | 11 +++++----- 4 files changed, 30 insertions(+), 23 deletions(-) diff --git a/DP3TApp/Resources/Disclaimer/DE_App_Nutzungsbedingungen.html b/DP3TApp/Resources/Disclaimer/DE_App_Nutzungsbedingungen.html index f33e4191..dfab428b 100644 --- a/DP3TApp/Resources/Disclaimer/DE_App_Nutzungsbedingungen.html +++ b/DP3TApp/Resources/Disclaimer/DE_App_Nutzungsbedingungen.html @@ -17,7 +17,7 @@

1.2 - Die App des Bundesamtes für Gesundheit (BAG) stützt sich auf das Epidemiengesetz vom 28. September 2012 (EpG; SR 818.101), die Verordnung vom 24. Juni 2020 über das Proximity-Tracing-System für das Coronavirus SARS-CoV-2 (VPTS; SR 818.101.25), dem Bundesgesetz über die gesetzlichen Grundlagen für Verordnungen des Bundesrates zur Bewältigung der Covid-19-Epidemie vom 25. September 2020 (Covid-19-Gesetz; SR 818.102) sowie der Verordnung vom 30. Juni 2021 über ein System zur Benachrichtigung über eine mögliche Ansteckung mit dem Coronavirus Sars-CoV-2 an Veranstaltungen (VBV; SR 818.102.4). + Die App des Bundesamtes für Gesundheit (BAG) stützt sich auf das Epidemiengesetz vom 28. September 2012 (EpG; SR 818.101), die Verordnung vom 24. Juni 2020 über das Proximity-Tracing-System für das Coronavirus SARS-CoV-2 (VPTS; SR 818.101.25), dem Bundesgesetz über die gesetzlichen Grundlagen für Verordnungen des Bundesrates zur Bewältigung der Covid-19-Epidemie vom 25. September 2020 (Covid-19-Gesetz; SR 818.102) sowie der Verordnung vom 30. Juni 2021 über ein System zur Benachrichtigung über eine mögliche Ansteckung mit dem Coronavirus Sars-CoV-2 an Veranstaltungen (VBV; SR 818.102.4).

1.3 @@ -65,11 +65,15 @@ Die App ruft periodisch eine Liste der privaten Schlüssel der infizierten Benutzerinnen und Benutzer der SwissCovid-App und anderen interoperablen Apps ab und lässt vom Betriebssystem überprüfen, ob mindestens ein lokal gespeicherter Identifizierungscode mit einem privaten Schlüssel der Liste generiert wurde. Ist dies der Fall und bestand zu mindestens einem Mobiltelefon einer infizierten Benutzerin oder einem infizierten Benutzer der SwissCovid-App oder anderen interoperablen Apps eine Annährung von 1,5 Metern oder weniger und erreicht die Summe der Dauer aller solchen Annäherungen innerhalb eines Tages 15 Minuten, so gibt die App die Benachrichtigung aus. Der Abstand wird anhand der Stärke der empfangenen Signale geschätzt.

- Warnsystem für Veranstaltungen: Die Organisatorin oder der Organisator einer Veranstaltung generiert in seiner App einen QR-Code. Besucherinnen und Besucher der Veranstaltung können mit ihrer App den gezeigten QR-Code scannen und sind so an der Veranstaltung eingecheckt. + Warnsystem für Veranstaltungen: Die Organisatorin oder der Organisator einer Veranstaltung generiert in seiner App oder über die Internetseite + + qr.swisscovid.ch + + einen QR-Code. Besucherinnen und Besucher der Veranstaltung können mit ihrer App den gezeigten QR-Code scannen und sind so an der Veranstaltung eingecheckt.

3.4 - Die App speichert auf dem Mobiltelefon die Veranstaltungs-Identifizierungscodes mit dem jeweiligen Datum, die Dauer des Aufenthaltes und die Bezeichnung der Veranstaltung. Sie ruft periodisch vom Veranstaltungs-Backend im Abrufverfahren die Liste der Veranstaltungs-Identifizierungscodes der infizierten teilnehmenden Personen ab. Sie gleicht die Veranstaltungs-Identifizierungscodes mit den von ihr lokal gespeicherten Veranstaltungs-Identifizierungscodes ab. Ergibt der Abgleich eine Übereinstimmung, so gibt die App die Benachrichtigung aus.Ist eine Infektion bei einer Benutzerin oder einem Benutzer nachgewiesen, generieren zugriffsberechtigte Fachpersonen (z.B. behandelnde Ärztinnen und Ärzte oder Apothekerinnen und Apotheker) einen einmaligen und zeitlich begrenzt gültigen Freischaltcode («Covidcode») und geben diesen der infizierten Benutzerin oder dem infizierten Benutzer bekannt. Diese oder dieser kann den Freischaltcode in ihre oder seine App freiwillig eingeben. Die Benachrichtigung bzw. die Eingabe des Freischaltcodes erfolgt nur mit der ausdrücklichen Einwilligung der infizierten Benutzerin oder des infizierten Benutzers. Die infizierte Benutzerin oder der infizierte Benutzer kann ausserdem wählen, ob sie oder er sowohl die engen Kontakte aufgrund des Proximity-Tracing-Systems als auch die Kontakte aufgrund der Teilnahme an einer Veranstaltung warnen will. Darüber hinaus kann sie oder er auch entscheiden, ob er für jede Veranstaltung, an welcher er im relevanten Zeitraum teilgenommen hat, eine Benachrichtigung auslösen will oder nur für einzelne. + Die App speichert auf dem Mobiltelefon die Veranstaltungs-Identifizierungscodes mit dem jeweiligen Datum, die Dauer des Aufenthaltes und die Bezeichnung der Veranstaltung. Sie ruft periodisch vom Veranstaltungs-Backend im Abrufverfahren die Liste der Veranstaltungs-Identifizierungscodes der infizierten teilnehmenden Personen ab. Sie gleicht die Veranstaltungs-Identifizierungscodes mit den von ihr lokal gespeicherten Veranstaltungs-Identifizierungscodes ab. Ergibt der Abgleich eine Übereinstimmung, so gibt die App die Benachrichtigung aus. Ist eine Infektion bei einer Benutzerin oder einem Benutzer nachgewiesen, generieren zugriffsberechtigte Fachpersonen (z.B. behandelnde Ärztinnen und Ärzte oder Apothekerinnen und Apotheker) einen einmaligen und zeitlich begrenzt gültigen Freischaltcode («Covidcode») und geben diesen der infizierten Benutzerin oder dem infizierten Benutzer bekannt. Diese oder dieser kann den Freischaltcode in ihre oder seine App freiwillig eingeben. Die Benachrichtigung bzw. die Eingabe des Freischaltcodes erfolgt nur mit der ausdrücklichen Einwilligung der infizierten Benutzerin oder des infizierten Benutzers. Die infizierte Benutzerin oder der infizierte Benutzer kann ausserdem wählen, ob sie oder er sowohl die engen Kontakte aufgrund des Proximity-Tracing-Systems als auch die Kontakte aufgrund der Teilnahme an einer Veranstaltung warnen will. Darüber hinaus kann sie oder er auch entscheiden, ob er für jede Veranstaltung, an welcher er im relevanten Zeitraum teilgenommen hat, eine Benachrichtigung auslösen will oder nur für einzelne.

Die anderen Benutzerinnen und Benutzer der SwissCovid-App diff --git a/DP3TApp/Resources/Disclaimer/EN_App_Nutzungsbedingungen.html b/DP3TApp/Resources/Disclaimer/EN_App_Nutzungsbedingungen.html index 4c34e971..9f1c5b89 100644 --- a/DP3TApp/Resources/Disclaimer/EN_App_Nutzungsbedingungen.html +++ b/DP3TApp/Resources/Disclaimer/EN_App_Nutzungsbedingungen.html @@ -65,14 +65,15 @@ The app periodically retrieves a list of the private keys of users of the SwissCovid app and other interoperable apps known to be infected and allows the operating system to check whether at least one locally stored identification code was generated by a private key included in the list. If this is the case, and if proximity of 1.5 metres or less to the mobile phone of at least one infected user of the SwissCovid app or another interoperable app was registered, and if the duration of all such proximity events within one day amounts to at least 15 minutes, then the app issues a notification. Proximity is estimated on the basis of the strength of the signals received.

- Warning system for events: The organiser of an event generates a QR code in their app. People attending the event can use their app to scan the displayed QR code and are thus checked in to the event. -

-

- The app saves on the mobile phone the event identification codes with the relevant date, duration of attendance and designation of the event. It periodically retrieves from the event back end the list of event identification codes of the infected participants. It compares these event participation codes with the event participation codes stored locally by the app. If there is a match, the app issues the notification. + Warning system for events: The organiser of an event generates a QR code in their app or on the website + + qr.swisscovid.ch + + . People attending the event can use their app to scan the displayed QR code and are thus checked in to the event.

3.4 - If an infection is confirmed in a user, experts with access rights (e.g. attending physicians or pharmacists) generate a unique activation code (Covid code), valid for a limited period, which they disclose to the infected user. This user can voluntarily enter the activation code in the app. Notification, or entry of the activation code, occurs only with the explicit consent of the infected user. The infected user can also choose whether they want to warn close contacts on the basis of the proximity tracing system and contacts on the basis of participation in an event. In addition, they can decide whether they want to trigger a notification for every event they attended during the relevant period or only for individual events. + The app saves on the mobile phone the event identification codes with the relevant date, duration of attendance and designation of the event. It periodically retrieves from the event back end the list of event identification codes of the infected participants. It compares these event participation codes with the event participation codes stored locally by the app. If there is a match, the app issues the notification. If an infection is confirmed in a user, experts with access rights (e.g. attending physicians or pharmacists) generate a unique activation code (Covid code), valid for a limited period, which they disclose to the infected user. This user can voluntarily enter the activation code in the app. Notification, or entry of the activation code, occurs only with the explicit consent of the infected user. The infected user can also choose whether they want to warn close contacts on the basis of the proximity tracing system and contacts on the basis of participation in an event. In addition, they can decide whether they want to trigger a notification for every event they attended during the relevant period or only for individual events.

Other users of the SwissCovid app or other interoperable apps who came into proximity, as defined in Section 3.3, with the infected user during the infectious period or participated in the same event at the same time are notified by their own apps. diff --git a/DP3TApp/Resources/Disclaimer/FR_App_Nutzungsbedingungen.html b/DP3TApp/Resources/Disclaimer/FR_App_Nutzungsbedingungen.html index e35aa195..f0e57dae 100644 --- a/DP3TApp/Resources/Disclaimer/FR_App_Nutzungsbedingungen.html +++ b/DP3TApp/Resources/Disclaimer/FR_App_Nutzungsbedingungen.html @@ -28,7 +28,7 @@ 818.102 -) et l’ordonnance du 30 juin 2021 sur un système visant à informer d’une infection possible au coronavirus SARS-CoV-2 lors de manifestations (OSIM ; RS 818.102.4). +) et l’ordonnance du 30 juin 2021 sur un système visant à informer d’une infection possible au coronavirus SARS-CoV-2 lors de manifestations (OSIM; RS 818.102.4).

1.3 L’application vise à informer les utilisateurs qui pourraient avoir été exposés au virus et à établir des statistiques en rapport avec le coronavirus. @@ -75,17 +75,18 @@ À intervalles réguliers, l’application extrait la liste des clés privées des utilisateurs infectés de l’application SwissCovid ou d’autres applications interopérables, et le système d’exploitation contrôle si au moins un code d’identification enregistré localement a été généré avec une clé privée. Si tel est le cas et qu’un rapprochement d’un mètre et demi ou moins a été établi avec au moins un téléphone mobile d’au moins un utilisateur infecté de l’application SwissCovid ou d’autres applications interopérables et que la durée totale de ces rapprochements atteint ou dépasse les quinze minutes au cours de la même journée, l’application envoie une information. La distance est évaluée en fonction de l’intensité du signal reçu.

- Système d’alerte pour les manifestations : l’organisateur d’une manifestation génère un code QR dans son application. Les visiteurs de la manifestation peuvent scanner le code QR présenté avec leur application et indiquent ainsi avoir participé à la manifestation. -

-

- L’application enregistre sur le téléphone portable le code d’identification de la manifestation avec sa date, sa durée et sa description. Depuis le - - backend - - manifestations, elle consulte régulièrement les codes d’identification de la manifestation chez les participants infectés. Elle compare ces codes avec ceux qu’elle a stocké localement. Si deux codes sont les mêmes, elle envoie alors une notification. + Système d’alerte pour les manifestations : l’organisateur d’une manifestation génère un code QR dans son application ou sur le site Internet + + qr.swisscovid.ch + + Les visiteurs de la manifestation peuvent scanner le code QR présenté avec leur application et indiquent ainsi avoir participé à la manifestation.

+L’application enregistre sur le téléphone portable le code d’identification de la manifestation avec sa date, sa durée et sa description. Depuis le + + backend + +manifestations, elle consulte régulièrement les codes d’identification de la manifestation chez les participants infectés. Elle compare ces codes avec ceux qu’elle a stocké localement. Si deux codes sont les mêmes, elle envoie alors une notification

- 3.4 Si une infection est attestée chez un utilisateur, les professionnels disposant des droits d’accès (p. ex. les médecins traitants ou les pharmaciens) génèrent un code d’autorisation unique et temporaire (code COVID) et le communiquent à l’utilisateur infecté. Ce dernier peut saisir de manière volontaire le code d’autorisation dans son application. La notification et la saisie du code d’autorisation ne se font qu’avec le consentement explicite de la personne infectée. Cette dernière peut par ailleurs choisir si elle souhaite alerter non seulement les contacts étroits détectés par le système de traçage de proximité mais également ceux détectés en raison de leur présence à une manifestation. Elle peut aussi décider de déclencher une notification pour toutes les manifestations auxquelles elle a participé pendant la période concernée ou seulement pour certaines d’entre elles.

diff --git a/DP3TApp/Resources/Disclaimer/IT_App_Nutzungsbedingungen.html b/DP3TApp/Resources/Disclaimer/IT_App_Nutzungsbedingungen.html index ea5db3c8..25d5d74b 100644 --- a/DP3TApp/Resources/Disclaimer/IT_App_Nutzungsbedingungen.html +++ b/DP3TApp/Resources/Disclaimer/IT_App_Nutzungsbedingungen.html @@ -65,14 +65,15 @@ L’app richiama periodicamente un elenco delle chiavi private degli utenti infetti dell’app SwissCovid e delle altre app interoperabili e controlla con il suo sistema operativo se almeno un codice d’identificazione memorizzato localmente è stato generato con una chiave privata dell’elenco. Se ciò si verifica nonché la prossimità da almeno un telefono cellulare di un utente dell’app SwissCovid o delle altre app interoperabili infetto è pari o inferiore a 1,5 metri e la somma della durata di tutte queste prossimità in un giorno raggiunge i quindici minuti, l’app ne informa l’utente. La distanza è stimata in base alla potenza del segnale ricevuto.

- Sistema di allerta per le manifestazioni: l’organizzatore di una manifestazione genera nella propria app un codice QR che i visitatori della manifestazione possono scansionare per effettuare il check-in alla manifestazione. -

-

- L’app memorizza sul telefono cellulare il codice di identificazione della manifestazione con la rispettiva data, la durata della permanenza e la designazione della manifestazione. Richiama periodicamente dal back end delle manifestazioni l’elenco dei codici di identificazione delle manifestazioni dei partecipanti infetti. Confronta tali codici con i codici di identificazione delle manifestazioni che ha memorizzato localmente. Se da tale confronto emerge una corrispondenza, genera una notifica. + Sistema di allerta per le manifestazioni: l’organizzatore di una manifestazione genera nella propria app o tramite la pagina Internet + + qr.swisscovid.ch + + un codice QR che i visitatori della manifestazione possono scansionare per effettuare il check-in alla manifestazione.

3.4 - In caso di infezione accertata di un utente, il personale specialistico avente diritto di accesso (p. es. medici curanti o farmacisti) genera un codice di attivazione (codice Covid) univoco e la cui validità è limitata nel tempo e lo comunica all’utente infetto, che può immetterlo nell’app su base volontaria. La notifica ovvero l’inserimento del codice di attivazione richiedono il consenso esplicito dell’utente infetto. L’utente infetto può scegliere se allertare sia i contatti stretti in base al sistema di tracciamento della prossimità sia i contatti in base alla partecipazione a una manifestazione. Può inoltre decidere se generare una notifica per tutte le manifestazioni alle quali ha partecipato nel periodo rilevante o solo per alcune. + L’app memorizza sul telefono cellulare il codice di identificazione della manifestazione con la rispettiva data, la durata della permanenza e la designazione della manifestazione. Richiama periodicamente dal back end delle manifestazioni l’elenco dei codici di identificazione delle manifestazioni dei partecipanti infetti. Confronta tali codici con i codici di identificazione delle manifestazioni che ha memorizzato localmente. Se da tale confronto emerge una corrispondenza, genera una notifica. In caso di infezione accertata di un utente, il personale specialistico avente diritto di accesso (p. es. medici curanti o farmacisti) genera un codice di attivazione (codice Covid) univoco e la cui validità è limitata nel tempo e lo comunica all’utente infetto, che può immetterlo nell’app su base volontaria. La notifica ovvero l’inserimento del codice di attivazione richiedono il consenso esplicito dell’utente infetto. L’utente infetto può scegliere se allertare sia i contatti stretti in base al sistema di tracciamento della prossimità sia i contatti in base alla partecipazione a una manifestazione. Può inoltre decidere se generare una notifica per tutte le manifestazioni alle quali ha partecipato nel periodo rilevante o solo per alcune.

Gli altri utenti dell’app SwissCovid o delle altre app interoperabili che sono stati in prossimità secondo il numero 3.3 con l’utente infetto durante il periodo di infettività o che hanno partecipato nello stesso momento alla medesima manifestazione vengono informati dalla loro app. From 154087646d0855fcc0c5b2eed3c5137740a7f791 Mon Sep 17 00:00:00 2001 From: Marco Zimmermann Date: Thu, 9 Sep 2021 13:53:18 +0200 Subject: [PATCH 22/27] improves header announcements Signed-off-by: Marco Zimmermann --- .../CheckIn/Modules/NSCheckInCurrentStateModuleView.swift | 2 +- .../Screens/Statistics/NSCovidCodesStatisticsModuleView.swift | 1 + .../Screens/Statistics/NSStatisticInfoPopupViewController.swift | 1 + DP3TApp/SharedUI/Views/NSErrorView.swift | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/DP3TApp/Screens/CheckIn/Modules/NSCheckInCurrentStateModuleView.swift b/DP3TApp/Screens/CheckIn/Modules/NSCheckInCurrentStateModuleView.swift index 83218420..71e55452 100644 --- a/DP3TApp/Screens/CheckIn/Modules/NSCheckInCurrentStateModuleView.swift +++ b/DP3TApp/Screens/CheckIn/Modules/NSCheckInCurrentStateModuleView.swift @@ -49,7 +49,7 @@ class NSCheckInCurrentStateModuleView: NSModuleBaseView { checkedInView.isHidden = true checkedOutView.isHidden = false checkInEndedView.isHidden = true - headerTitle = ("checkin_detail_checked_out_title".ub_localized).replacingOccurrences(of: "\n", with: "") + headerTitle = "checkin_detail_checked_out_title".ub_localized.replacingOccurrences(of: "\n", with: "") stackView.accessibilityTraits = [.header] case let .checkIn(checkIn): checkedInView.isHidden = false diff --git a/DP3TApp/Screens/Statistics/NSCovidCodesStatisticsModuleView.swift b/DP3TApp/Screens/Statistics/NSCovidCodesStatisticsModuleView.swift index cc6116d7..03d9f89f 100644 --- a/DP3TApp/Screens/Statistics/NSCovidCodesStatisticsModuleView.swift +++ b/DP3TApp/Screens/Statistics/NSCovidCodesStatisticsModuleView.swift @@ -67,6 +67,7 @@ class NSCovidCodesStatisticsModuleView: UIView { private func addContent() { title.text = "stats_covidcodes_title".ub_localized + title.accessibilityTraits = [.header] stackView.addArrangedView(title) stackView.addSpacerView(NSPadding.medium) diff --git a/DP3TApp/Screens/Statistics/NSStatisticInfoPopupViewController.swift b/DP3TApp/Screens/Statistics/NSStatisticInfoPopupViewController.swift index b9b7e595..0003ed17 100644 --- a/DP3TApp/Screens/Statistics/NSStatisticInfoPopupViewController.swift +++ b/DP3TApp/Screens/Statistics/NSStatisticInfoPopupViewController.swift @@ -30,6 +30,7 @@ class NSStatisticInfoPopupViewController: NSPopupViewController { let subtitle = NSLabel(.title) subtitle.text = type.subtitle + subtitle.accessibilityTraits = [.header] let insets = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20) diff --git a/DP3TApp/SharedUI/Views/NSErrorView.swift b/DP3TApp/SharedUI/Views/NSErrorView.swift index db484beb..f6aa70aa 100644 --- a/DP3TApp/SharedUI/Views/NSErrorView.swift +++ b/DP3TApp/SharedUI/Views/NSErrorView.swift @@ -85,6 +85,7 @@ class NSErrorView: UIView { imageView.image = model?.icon titleLabel.text = model?.title titleLabel.accessibilityLabel = "\("loading_view_error_title".ub_localized): \(titleLabel.text ?? "")" + titleLabel.accessibilityTraits = [.header] textLabel.text = model?.text actionButton.touchUpCallback = { [weak self] in self?.model?.action?(self) From 250970491ae23adb028833f1482b0eaf07cbe589 Mon Sep 17 00:00:00 2001 From: Marco Zimmermann Date: Thu, 9 Sep 2021 17:06:48 +0200 Subject: [PATCH 23/27] updates missing translations Signed-off-by: Marco Zimmermann --- Translations/bs.lproj/Localizable.strings | 38 +++++++++---------- Translations/es.lproj/Localizable.strings | 38 +++++++++---------- Translations/hr.lproj/Localizable.strings | 38 +++++++++---------- Translations/pt.lproj/Localizable.strings | 38 +++++++++---------- Translations/sq.lproj/Localizable.strings | 38 +++++++++---------- .../sr-Latn-RS.lproj/Localizable.strings | 38 +++++++++---------- Translations/ti.lproj/Localizable.strings | 38 +++++++++---------- Translations/tr.lproj/Localizable.strings | 38 +++++++++---------- 8 files changed, 152 insertions(+), 152 deletions(-) diff --git a/Translations/bs.lproj/Localizable.strings b/Translations/bs.lproj/Localizable.strings index b5702668..3347bbe8 100644 --- a/Translations/bs.lproj/Localizable.strings +++ b/Translations/bs.lproj/Localizable.strings @@ -1466,7 +1466,7 @@ "error_title" = "Greška"; "qr_scanner_error_code_not_yet_valid" = "QR kod je još nevažeći"; "qr_scanner_error_code_not_valid_anymore" = "QR kod je nevažeći "; -"error_already_checked_in" = "You are already checked in at another location."; +"error_already_checked_in" = "Već se prijavljeni na drugom mestu."; "error_update_text" = "Ovaj QR kod nije kompatibilan sa instaliranom verzijom aplikacije. Ažurirajte aplikaciju, da biste nastavili korišćenje."; "error_update_title" = "Potrebno ažuriranje"; "error_action_update" = "Sada ažurirati"; @@ -1739,55 +1739,55 @@ "covid_certificate_install_app" = "Instalirati aplikaciju"; /*Titel des Buttons, der das PDF herunterlädt*/ -"web_generator_download_pdf_button" = "Download PDF"; +"web_generator_download_pdf_button" = "Skini PDF"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ -"accessibility_expandable_box_reduced_state" = "collapsed"; +"accessibility_expandable_box_reduced_state" = "redukovano"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ -"accessibility_expandable_box_expanded_state" = "expanded"; +"accessibility_expandable_box_expanded_state" = "prošireno"; /*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ -"checkin_overlap_popup_title" = "Cannot save"; +"checkin_overlap_popup_title" = "Nije moguće osigurati"; /*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ -"checkin_overlap_popup_text" = "The times you selected for {CHECKIN} overlap with other check-ins. Please check your entries again."; +"checkin_overlap_popup_text" = "Odabrano vreme za {CHECKIN} se poklapa sa drugim vremenom prijave. Molimo proverite još jednom vaše unose."; /*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ -"checkin_overlap_back_button" = "Back"; +"checkin_overlap_back_button" = "Nazad"; /*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ -"accessibility_reminder_option_hours_plural" = "Hours"; +"accessibility_reminder_option_hours_plural" = "Sati"; /*This will be read by the screenreader instead of "'" (for the reminder options)*/ -"accessibility_reminder_option_minutes" = "Minutes"; +"accessibility_reminder_option_minutes" = "Minuta"; /*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ -"accessibility_reminder_option_hour" = "Hour"; +"accessibility_reminder_option_hour" = "Sat"; /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ -"checkin_overlap_popup_success_text" = "There are no longer any conflicts for the time you entered. You can now check out of {CHECKIN}."; +"checkin_overlap_popup_success_text" = "Više ne postoje protivrečnosti kod unetog vremena. Sada se možete odjaviti sa {CHECKIN}."; /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ -"web_generator_success_title" = "QR code generated"; +"web_generator_success_title" = "QR kod je izrađen"; /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ -"web_generator_reset_button" = "Generate new QR code"; +"web_generator_reset_button" = "Izradi novi QR kod"; /*Used by VoiceOver to explain what the info button in the navigation bar does*/ -"accessibility_info_button_app" = "More information on the app"; +"accessibility_info_button_app" = "Više informacija o aplikaciji"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ -"accessibility_info_button_covidcode" = "More information on Covidcodes"; +"accessibility_info_button_covidcode" = "Više informacija o Covid kodu"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ -"accessibility_info_button_numberofcases" = "More information on case numbers"; +"accessibility_info_button_numberofcases" = "Više informacija o broju slučajeva"; /*Is read by the screenreader, when newly created QR-code is shown*/ -"accessibility_preview_qr_code_alternative_text" = "Generated QR code"; +"accessibility_preview_qr_code_alternative_text" = "Izrađeni QR kod"; /*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ -"checkin_generate_web_hint" = "Alternatively, you can also generate QR codes at qr.swisscovid.ch."; +"checkin_generate_web_hint" = "Alternativno, možete izraditi QR kod na qr.swisscovid.ch."; /*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ -"error_already_checked_in_text" = "To check in to a new location, you first need to check out."; +"error_already_checked_in_text" = "Kako biste se prijavili na nekom drugom mestu, najpre se morate odjaviti odavde."; diff --git a/Translations/es.lproj/Localizable.strings b/Translations/es.lproj/Localizable.strings index 054a0905..a28a4fe0 100644 --- a/Translations/es.lproj/Localizable.strings +++ b/Translations/es.lproj/Localizable.strings @@ -1466,7 +1466,7 @@ "error_title" = "Error"; "qr_scanner_error_code_not_yet_valid" = "Código QR aún no válido"; "qr_scanner_error_code_not_valid_anymore" = "Código QR ya no es válido"; -"error_already_checked_in" = "You are already checked in at another location."; +"error_already_checked_in" = "Está usted registrado mediante Check-in en otro lugar."; "error_update_text" = "Este código QR no es compatible con la versión instalada de la app. Actualice la aplicación para continuar."; "error_update_title" = "Se requiere actualización"; "error_action_update" = "Actualizar ahora"; @@ -1739,55 +1739,55 @@ "covid_certificate_install_app" = "Instalar la aplicación"; /*Titel des Buttons, der das PDF herunterlädt*/ -"web_generator_download_pdf_button" = "Download PDF"; +"web_generator_download_pdf_button" = "Descargar PDF"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ -"accessibility_expandable_box_reduced_state" = "collapsed"; +"accessibility_expandable_box_reduced_state" = "visión reducida"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ -"accessibility_expandable_box_expanded_state" = "expanded"; +"accessibility_expandable_box_expanded_state" = "visión ampliada"; /*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ -"checkin_overlap_popup_title" = "Cannot save"; +"checkin_overlap_popup_title" = "No es posible guardar"; /*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ -"checkin_overlap_popup_text" = "The times you selected for {CHECKIN} overlap with other check-ins. Please check your entries again."; +"checkin_overlap_popup_text" = "La hora seleccionada para {CHECKIN} coincide con otros Check-ins. Por favor, controle nuevamente las indicaciones."; /*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ -"checkin_overlap_back_button" = "Back"; +"checkin_overlap_back_button" = "Volver"; /*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ -"accessibility_reminder_option_hours_plural" = "Hours"; +"accessibility_reminder_option_hours_plural" = "horas"; /*This will be read by the screenreader instead of "'" (for the reminder options)*/ -"accessibility_reminder_option_minutes" = "Minutes"; +"accessibility_reminder_option_minutes" = "minutos"; /*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ -"accessibility_reminder_option_hour" = "Hour"; +"accessibility_reminder_option_hour" = "hora"; /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ -"checkin_overlap_popup_success_text" = "There are no longer any conflicts for the time you entered. You can now check out of {CHECKIN}."; +"checkin_overlap_popup_success_text" = "No hay conflicto para la hora indicada. Puede usted salir de {CHECKIN}."; /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ -"web_generator_success_title" = "QR code generated"; +"web_generator_success_title" = "Código QR ha sido generado"; /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ -"web_generator_reset_button" = "Generate new QR code"; +"web_generator_reset_button" = "Generar un nuevo código QR"; /*Used by VoiceOver to explain what the info button in the navigation bar does*/ -"accessibility_info_button_app" = "More information on the app"; +"accessibility_info_button_app" = "Más información sobre la app"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ -"accessibility_info_button_covidcode" = "More information on Covidcodes"; +"accessibility_info_button_covidcode" = "Más información sobre el código Covid"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ -"accessibility_info_button_numberofcases" = "More information on case numbers"; +"accessibility_info_button_numberofcases" = "Más información sobre el número de casos"; /*Is read by the screenreader, when newly created QR-code is shown*/ -"accessibility_preview_qr_code_alternative_text" = "Generated QR code"; +"accessibility_preview_qr_code_alternative_text" = "Código QR generado"; /*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ -"checkin_generate_web_hint" = "Alternatively, you can also generate QR codes at qr.swisscovid.ch."; +"checkin_generate_web_hint" = "También puede usted generar códigos QR en qr.swisscovid.ch."; /*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ -"error_already_checked_in_text" = "To check in to a new location, you first need to check out."; +"error_already_checked_in_text" = "Para poder registrarse en una nueva localidad, tiene que primero darse de baja mediante Check-out. "; diff --git a/Translations/hr.lproj/Localizable.strings b/Translations/hr.lproj/Localizable.strings index ac3273d0..e87fe704 100644 --- a/Translations/hr.lproj/Localizable.strings +++ b/Translations/hr.lproj/Localizable.strings @@ -1464,7 +1464,7 @@ "error_title" = "Greška"; "qr_scanner_error_code_not_yet_valid" = "QR kod je još nevažeći"; "qr_scanner_error_code_not_valid_anymore" = "QR kod je nevažeći "; -"error_already_checked_in" = "You are already checked in at another location."; +"error_already_checked_in" = "Već se prijavljeni na drugom mestu."; "error_update_text" = "Ovaj QR kod nije kompatibilan sa instaliranom verzijom aplikacije. Ažurirajte aplikaciju, da biste nastavili korišćenje."; "error_update_title" = "Potrebno ažuriranje"; "error_action_update" = "Sada ažurirati"; @@ -1737,55 +1737,55 @@ "covid_certificate_install_app" = "Instalirati aplikaciju"; /*Titel des Buttons, der das PDF herunterlädt*/ -"web_generator_download_pdf_button" = "Download PDF"; +"web_generator_download_pdf_button" = "Skini PDF"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ -"accessibility_expandable_box_reduced_state" = "collapsed"; +"accessibility_expandable_box_reduced_state" = "redukovano"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ -"accessibility_expandable_box_expanded_state" = "expanded"; +"accessibility_expandable_box_expanded_state" = "prošireno"; /*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ -"checkin_overlap_popup_title" = "Cannot save"; +"checkin_overlap_popup_title" = "Nije moguće osigurati"; /*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ -"checkin_overlap_popup_text" = "The times you selected for {CHECKIN} overlap with other check-ins. Please check your entries again."; +"checkin_overlap_popup_text" = "Odabrano vreme za {CHECKIN} se poklapa sa drugim vremenom prijave. Molimo proverite još jednom vaše unose."; /*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ -"checkin_overlap_back_button" = "Back"; +"checkin_overlap_back_button" = "Nazad"; /*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ -"accessibility_reminder_option_hours_plural" = "Hours"; +"accessibility_reminder_option_hours_plural" = "Sati"; /*This will be read by the screenreader instead of "'" (for the reminder options)*/ -"accessibility_reminder_option_minutes" = "Minutes"; +"accessibility_reminder_option_minutes" = "Minuta"; /*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ -"accessibility_reminder_option_hour" = "Hour"; +"accessibility_reminder_option_hour" = "Sat"; /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ -"checkin_overlap_popup_success_text" = "There are no longer any conflicts for the time you entered. You can now check out of {CHECKIN}."; +"checkin_overlap_popup_success_text" = "Više ne postoje protivrečnosti kod unetog vremena. Sada se možete odjaviti sa {CHECKIN}."; /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ -"web_generator_success_title" = "QR code generated"; +"web_generator_success_title" = "QR kod je izrađen"; /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ -"web_generator_reset_button" = "Generate new QR code"; +"web_generator_reset_button" = "Izradi novi QR kod"; /*Used by VoiceOver to explain what the info button in the navigation bar does*/ -"accessibility_info_button_app" = "More information on the app"; +"accessibility_info_button_app" = "Više informacija o aplikaciji"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ -"accessibility_info_button_covidcode" = "More information on Covidcodes"; +"accessibility_info_button_covidcode" = "Više informacija o Covid kodu"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ -"accessibility_info_button_numberofcases" = "More information on case numbers"; +"accessibility_info_button_numberofcases" = "Više informacija o broju slučajeva"; /*Is read by the screenreader, when newly created QR-code is shown*/ -"accessibility_preview_qr_code_alternative_text" = "Generated QR code"; +"accessibility_preview_qr_code_alternative_text" = "Izrađeni QR kod"; /*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ -"checkin_generate_web_hint" = "Alternatively, you can also generate QR codes at qr.swisscovid.ch."; +"checkin_generate_web_hint" = "Alternativno, možete izraditi QR kod na qr.swisscovid.ch."; /*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ -"error_already_checked_in_text" = "To check in to a new location, you first need to check out."; +"error_already_checked_in_text" = "Kako biste se prijavili na nekom drugom mestu, najpre se morate odjaviti odavde."; diff --git a/Translations/pt.lproj/Localizable.strings b/Translations/pt.lproj/Localizable.strings index 9fb88f0c..efce7e0f 100644 --- a/Translations/pt.lproj/Localizable.strings +++ b/Translations/pt.lproj/Localizable.strings @@ -1466,7 +1466,7 @@ "error_title" = "Erro"; "qr_scanner_error_code_not_yet_valid" = "O código QR ainda não é válido!"; "qr_scanner_error_code_not_valid_anymore" = "O código QR não é mais válido!"; -"error_already_checked_in" = "You are already checked in at another location."; +"error_already_checked_in" = "Já fez check-in noutro lugar."; "error_update_text" = "Este código QR não é compatível com a versão do aplicativo instalada. Por favor, atualize o aplicativo para continuar."; "error_update_title" = "É necessário atualizar."; "error_action_update" = "Atualizar agora"; @@ -1739,55 +1739,55 @@ "covid_certificate_install_app" = "Instalar o aplicativo"; /*Titel des Buttons, der das PDF herunterlädt*/ -"web_generator_download_pdf_button" = "Download PDF"; +"web_generator_download_pdf_button" = "Baixar o PDF"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ -"accessibility_expandable_box_reduced_state" = "collapsed"; +"accessibility_expandable_box_reduced_state" = "reduzido"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ -"accessibility_expandable_box_expanded_state" = "expanded"; +"accessibility_expandable_box_expanded_state" = "ampliado"; /*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ -"checkin_overlap_popup_title" = "Cannot save"; +"checkin_overlap_popup_title" = "Não é possível salvar"; /*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ -"checkin_overlap_popup_text" = "The times you selected for {CHECKIN} overlap with other check-ins. Please check your entries again."; +"checkin_overlap_popup_text" = "Os seus períodos de tempo selecionados para {CHECKIN} sobrepõem-se a outros check-ins. Por favor, verifique as suas informações."; /*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ -"checkin_overlap_back_button" = "Back"; +"checkin_overlap_back_button" = "Voltar"; /*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ -"accessibility_reminder_option_hours_plural" = "Hours"; +"accessibility_reminder_option_hours_plural" = "horas"; /*This will be read by the screenreader instead of "'" (for the reminder options)*/ -"accessibility_reminder_option_minutes" = "Minutes"; +"accessibility_reminder_option_minutes" = "minutos"; /*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ -"accessibility_reminder_option_hour" = "Hour"; +"accessibility_reminder_option_hour" = "hora"; /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ -"checkin_overlap_popup_success_text" = "There are no longer any conflicts for the time you entered. You can now check out of {CHECKIN}."; +"checkin_overlap_popup_success_text" = "Não há mais conflitos para o seu período de tempo introduzido. Agora, você pode fazer check-out em {CHECKIN}."; /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ -"web_generator_success_title" = "QR code generated"; +"web_generator_success_title" = "Criou um código QR"; /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ -"web_generator_reset_button" = "Generate new QR code"; +"web_generator_reset_button" = "Criar um novo código QR"; /*Used by VoiceOver to explain what the info button in the navigation bar does*/ -"accessibility_info_button_app" = "More information on the app"; +"accessibility_info_button_app" = "Mais informações sobre o aplicativo"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ -"accessibility_info_button_covidcode" = "More information on Covidcodes"; +"accessibility_info_button_covidcode" = "Mais informações sobre Covidcodes"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ -"accessibility_info_button_numberofcases" = "More information on case numbers"; +"accessibility_info_button_numberofcases" = "Mais informações sobre os números de incidentes"; /*Is read by the screenreader, when newly created QR-code is shown*/ -"accessibility_preview_qr_code_alternative_text" = "Generated QR code"; +"accessibility_preview_qr_code_alternative_text" = "Código QR criado"; /*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ -"checkin_generate_web_hint" = "Alternatively, you can also generate QR codes at qr.swisscovid.ch."; +"checkin_generate_web_hint" = "Alternativamente também pode criar códigos QR em qr.swisscovid.ch."; /*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ -"error_already_checked_in_text" = "To check in to a new location, you first need to check out."; +"error_already_checked_in_text" = "Para fazer check-in noutro lugar, primeiro é necessário fazer check-out."; diff --git a/Translations/sq.lproj/Localizable.strings b/Translations/sq.lproj/Localizable.strings index 6c5937d8..24aeaa07 100644 --- a/Translations/sq.lproj/Localizable.strings +++ b/Translations/sq.lproj/Localizable.strings @@ -1466,7 +1466,7 @@ "error_title" = "Gabim"; "qr_scanner_error_code_not_yet_valid" = "Kodi QR nuk është ende i vlefshëm"; "qr_scanner_error_code_not_valid_anymore" = "Kodi QR nuk është më i vlefshëm"; -"error_already_checked_in" = "You are already checked in at another location."; +"error_already_checked_in" = "Ju tashmë jeni regjistruar në një vend tjetër."; "error_update_text" = "Ky kod QR nuk është i pajtueshëm me versionin e aplikacionit të instaluar. Përditësoni aplikacionin për të vazhduar më tej."; "error_update_title" = "Përditësimi i nevojshëm"; "error_action_update" = "Përditësoni tani"; @@ -1739,55 +1739,55 @@ "covid_certificate_install_app" = "Instaloni aplikacionin"; /*Titel des Buttons, der das PDF herunterlädt*/ -"web_generator_download_pdf_button" = "Download PDF"; +"web_generator_download_pdf_button" = "Shkarkoni PDF"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ -"accessibility_expandable_box_reduced_state" = "collapsed"; +"accessibility_expandable_box_reduced_state" = "E reduktuar"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ -"accessibility_expandable_box_expanded_state" = "expanded"; +"accessibility_expandable_box_expanded_state" = "E zgjeruar"; /*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ -"checkin_overlap_popup_title" = "Cannot save"; +"checkin_overlap_popup_title" = "Ruajtja nuk është e mundur"; /*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ -"checkin_overlap_popup_text" = "The times you selected for {CHECKIN} overlap with other check-ins. Please check your entries again."; +"checkin_overlap_popup_text" = "Kohët tuaja të zgjedhura për {CHECKIN} përkojnë me Check-in e tjera. Kontrolloni edhe njëherë të dhënat tuaja."; /*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ -"checkin_overlap_back_button" = "Back"; +"checkin_overlap_back_button" = "Kthehu"; /*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ -"accessibility_reminder_option_hours_plural" = "Hours"; +"accessibility_reminder_option_hours_plural" = "Orë"; /*This will be read by the screenreader instead of "'" (for the reminder options)*/ -"accessibility_reminder_option_minutes" = "Minutes"; +"accessibility_reminder_option_minutes" = "Minuta"; /*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ -"accessibility_reminder_option_hour" = "Hour"; +"accessibility_reminder_option_hour" = "Orë"; /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ -"checkin_overlap_popup_success_text" = "There are no longer any conflicts for the time you entered. You can now check out of {CHECKIN}."; +"checkin_overlap_popup_success_text" = "Nuk ka më konflikte për kohën tuaj të regjistruar. Ju mund të kontrolloheni tani te {CHECKIN}."; /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ -"web_generator_success_title" = "QR code generated"; +"web_generator_success_title" = "Kodi i krijuar QR"; /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ -"web_generator_reset_button" = "Generate new QR code"; +"web_generator_reset_button" = "Krijoni kodin e ri QR"; /*Used by VoiceOver to explain what the info button in the navigation bar does*/ -"accessibility_info_button_app" = "More information on the app"; +"accessibility_info_button_app" = "Më shumë informacione për aplikacionin"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ -"accessibility_info_button_covidcode" = "More information on Covidcodes"; +"accessibility_info_button_covidcode" = "Më shumë informacione për kodin e Covid"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ -"accessibility_info_button_numberofcases" = "More information on case numbers"; +"accessibility_info_button_numberofcases" = "Më shumë informacione për numrin e rasteve"; /*Is read by the screenreader, when newly created QR-code is shown*/ -"accessibility_preview_qr_code_alternative_text" = "Generated QR code"; +"accessibility_preview_qr_code_alternative_text" = "Kodi i krijuar QR"; /*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ -"checkin_generate_web_hint" = "Alternatively, you can also generate QR codes at qr.swisscovid.ch."; +"checkin_generate_web_hint" = "Si alternativë mund të krijoni kodin QR edhe në qr.swisscovid.ch."; /*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ -"error_already_checked_in_text" = "To check in to a new location, you first need to check out."; +"error_already_checked_in_text" = "Për t’u regjistruar në një vend të ri, së pari duhet të kontrolloheni."; diff --git a/Translations/sr-Latn-RS.lproj/Localizable.strings b/Translations/sr-Latn-RS.lproj/Localizable.strings index d38741f9..01bfdc12 100644 --- a/Translations/sr-Latn-RS.lproj/Localizable.strings +++ b/Translations/sr-Latn-RS.lproj/Localizable.strings @@ -1464,7 +1464,7 @@ "error_title" = "Greška"; "qr_scanner_error_code_not_yet_valid" = "QR kod je još nevažeći"; "qr_scanner_error_code_not_valid_anymore" = "QR kod je nevažeći "; -"error_already_checked_in" = "You are already checked in at another location."; +"error_already_checked_in" = "Već se prijavljeni na drugom mestu."; "error_update_text" = "Ovaj QR kod nije kompatibilan sa instaliranom verzijom aplikacije. Ažurirajte aplikaciju, da biste nastavili korišćenje."; "error_update_title" = "Potrebno ažuriranje"; "error_action_update" = "Sada ažurirati"; @@ -1737,55 +1737,55 @@ "covid_certificate_install_app" = "Instalirati aplikaciju"; /*Titel des Buttons, der das PDF herunterlädt*/ -"web_generator_download_pdf_button" = "Download PDF"; +"web_generator_download_pdf_button" = "Skini PDF"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ -"accessibility_expandable_box_reduced_state" = "collapsed"; +"accessibility_expandable_box_reduced_state" = "redukovano"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ -"accessibility_expandable_box_expanded_state" = "expanded"; +"accessibility_expandable_box_expanded_state" = "prošireno"; /*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ -"checkin_overlap_popup_title" = "Cannot save"; +"checkin_overlap_popup_title" = "Nije moguće osigurati"; /*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ -"checkin_overlap_popup_text" = "The times you selected for {CHECKIN} overlap with other check-ins. Please check your entries again."; +"checkin_overlap_popup_text" = "Odabrano vreme za {CHECKIN} se poklapa sa drugim vremenom prijave. Molimo proverite još jednom vaše unose."; /*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ -"checkin_overlap_back_button" = "Back"; +"checkin_overlap_back_button" = "Nazad"; /*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ -"accessibility_reminder_option_hours_plural" = "Hours"; +"accessibility_reminder_option_hours_plural" = "Sati"; /*This will be read by the screenreader instead of "'" (for the reminder options)*/ -"accessibility_reminder_option_minutes" = "Minutes"; +"accessibility_reminder_option_minutes" = "Minuta"; /*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ -"accessibility_reminder_option_hour" = "Hour"; +"accessibility_reminder_option_hour" = "Sat"; /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ -"checkin_overlap_popup_success_text" = "There are no longer any conflicts for the time you entered. You can now check out of {CHECKIN}."; +"checkin_overlap_popup_success_text" = "Više ne postoje protivrečnosti kod unetog vremena. Sada se možete odjaviti sa {CHECKIN}."; /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ -"web_generator_success_title" = "QR code generated"; +"web_generator_success_title" = "QR kod je izrađen"; /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ -"web_generator_reset_button" = "Generate new QR code"; +"web_generator_reset_button" = "Izradi novi QR kod"; /*Used by VoiceOver to explain what the info button in the navigation bar does*/ -"accessibility_info_button_app" = "More information on the app"; +"accessibility_info_button_app" = "Više informacija o aplikaciji"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ -"accessibility_info_button_covidcode" = "More information on Covidcodes"; +"accessibility_info_button_covidcode" = "Više informacija o Covid kodu"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ -"accessibility_info_button_numberofcases" = "More information on case numbers"; +"accessibility_info_button_numberofcases" = "Više informacija o broju slučajeva"; /*Is read by the screenreader, when newly created QR-code is shown*/ -"accessibility_preview_qr_code_alternative_text" = "Generated QR code"; +"accessibility_preview_qr_code_alternative_text" = "Izrađeni QR kod"; /*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ -"checkin_generate_web_hint" = "Alternatively, you can also generate QR codes at qr.swisscovid.ch."; +"checkin_generate_web_hint" = "Alternativno, možete izraditi QR kod na qr.swisscovid.ch."; /*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ -"error_already_checked_in_text" = "To check in to a new location, you first need to check out."; +"error_already_checked_in_text" = "Kako biste se prijavili na nekom drugom mestu, najpre se morate odjaviti odavde."; diff --git a/Translations/ti.lproj/Localizable.strings b/Translations/ti.lproj/Localizable.strings index 164f1c4d..80ea5285 100644 --- a/Translations/ti.lproj/Localizable.strings +++ b/Translations/ti.lproj/Localizable.strings @@ -1465,7 +1465,7 @@ "error_title" = "ጉድለት"; "qr_scanner_error_code_not_yet_valid" = "QR-ኮድ ገና ብቑዕ ኣይኮነን"; "qr_scanner_error_code_not_valid_anymore" = "ብቕዓት QR-Code ሓሊፉ"; -"error_already_checked_in" = "You are already checked in at another location."; +"error_already_checked_in" = "ድሮ ኣብ ካልእ ቦታ ኣቲኻ ዘለኻ።"; "error_update_text" = "እዚ ኮድ QR ምስቲ ዝተተከለ ቨርዝዮን ኤፕ ኣይሰርሕን እዩ። ነቲ ኤፕ ኣሕድስዎ ብኽብረትኩም መታን ክትቕጸሉ።"; "error_update_title" = "ምምሕዳስ የድሊ"; "error_action_update" = "ሕጂ ምምሕዳስ"; @@ -1738,55 +1738,55 @@ "covid_certificate_install_app" = "ኤፕ ምትካል"; /*Titel des Buttons, der das PDF herunterlädt*/ -"web_generator_download_pdf_button" = "Download PDF"; +"web_generator_download_pdf_button" = "PDF ኣራግፍ"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ -"accessibility_expandable_box_reduced_state" = "collapsed"; +"accessibility_expandable_box_reduced_state" = "ዝነከየ"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ -"accessibility_expandable_box_expanded_state" = "expanded"; +"accessibility_expandable_box_expanded_state" = "ዝሰፍሐ"; /*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ -"checkin_overlap_popup_title" = "Cannot save"; +"checkin_overlap_popup_title" = "ክድግፍ ኣይክእልን ኢዩ"; /*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ -"checkin_overlap_popup_text" = "The times you selected for {CHECKIN} overlap with other check-ins. Please check your entries again."; +"checkin_overlap_popup_text" = "እቲ ዝመረጽካዮ ግዜታት ን {CHECKIN} ምስ ካልእ ቸክ-ኢን ተመሳቒሉ። ተ ብኽብረትካ ዝርዝር ሓበሬታኻ እንደገና ርአ።"; /*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ -"checkin_overlap_back_button" = "Back"; +"checkin_overlap_back_button" = "ተመለስ"; /*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ -"accessibility_reminder_option_hours_plural" = "Hours"; +"accessibility_reminder_option_hours_plural" = "ሰዓታት"; /*This will be read by the screenreader instead of "'" (for the reminder options)*/ -"accessibility_reminder_option_minutes" = "Minutes"; +"accessibility_reminder_option_minutes" = "ደቓይቕ"; /*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ -"accessibility_reminder_option_hour" = "Hour"; +"accessibility_reminder_option_hour" = "ሰዓት"; /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ -"checkin_overlap_popup_success_text" = "There are no longer any conflicts for the time you entered. You can now check out of {CHECKIN}."; +"checkin_overlap_popup_success_text" = "ኣብቲ እትምዝገብሉ ግዜ ግጭት ኣይኪህሉን እዩ ። ሕጂ ኣብ {CHECKIN} ክትወጽእ ትኽእል ኢኻ።"; /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ -"web_generator_success_title" = "QR code generated"; +"web_generator_success_title" = "ኮድ QR ተፈጢሩ"; /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ -"web_generator_reset_button" = "Generate new QR code"; +"web_generator_reset_button" = "ሓድሽ ኮድ QR ምፍጣር"; /*Used by VoiceOver to explain what the info button in the navigation bar does*/ -"accessibility_info_button_app" = "More information on the app"; +"accessibility_info_button_app" = "ብዛዕባ እቲ ኣፕሊኬሽን ዝያዳ ሓበሬታ"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ -"accessibility_info_button_covidcode" = "More information on Covidcodes"; +"accessibility_info_button_covidcode" = "ብዛዕባ ኮቪድኮድ ዝያዳ ሓበሬታ"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ -"accessibility_info_button_numberofcases" = "More information on case numbers"; +"accessibility_info_button_numberofcases" = "ብዛዕባ ብዝሒ ተለበድቲ ዝያዳ ሓበሬታ"; /*Is read by the screenreader, when newly created QR-code is shown*/ -"accessibility_preview_qr_code_alternative_text" = "Generated QR code"; +"accessibility_preview_qr_code_alternative_text" = "ዝተፈጥረ QR-ኮድ"; /*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ -"checkin_generate_web_hint" = "Alternatively, you can also generate QR codes at qr.swisscovid.ch."; +"checkin_generate_web_hint" = "ብዘይካዚ ኣብ qr.swisscovid.ch ኮድ QR ክትፈጥር ትኽእል ኢኻ።"; /*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ -"error_already_checked_in_text" = "To check in to a new location, you first need to check out."; +"error_already_checked_in_text" = "ናብ ካልእ ቦታ ኽትከይድ እንተ ደሊኻ ፈለማ ክትወጽእ (ቸክ-ኣውት ክትገብር) ኣሎካ።"; diff --git a/Translations/tr.lproj/Localizable.strings b/Translations/tr.lproj/Localizable.strings index 9186d71e..02b8521d 100644 --- a/Translations/tr.lproj/Localizable.strings +++ b/Translations/tr.lproj/Localizable.strings @@ -1465,7 +1465,7 @@ "error_title" = "Hata"; "qr_scanner_error_code_not_yet_valid" = "Kare kod henüz geçerli değil"; "qr_scanner_error_code_not_valid_anymore" = "Kare kod artık geçerli değil"; -"error_already_checked_in" = "You are already checked in at another location."; +"error_already_checked_in" = "Şu anda başka bir yerde Check-in yapmış durumdasınız."; "error_update_text" = "Bu kare kod artık kurulu olan uygulama sürümü ile uyumlu değil. Lütfen işleme devam edebilmek için uygulamayı güncelleyin."; "error_update_title" = "Güncelleme gerekiyor"; "error_action_update" = "Şimdi güncelleyin"; @@ -1738,55 +1738,55 @@ "covid_certificate_install_app" = "Uygulamayı kur"; /*Titel des Buttons, der das PDF herunterlädt*/ -"web_generator_download_pdf_button" = "Download PDF"; +"web_generator_download_pdf_button" = "PDF indir"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is reduced*/ -"accessibility_expandable_box_reduced_state" = "collapsed"; +"accessibility_expandable_box_reduced_state" = "azaltılmış"; /*Shown when the Datenschutzerklärung/Nutzungsbedingungen is expanded*/ -"accessibility_expandable_box_expanded_state" = "expanded"; +"accessibility_expandable_box_expanded_state" = "genişletilmiş"; /*CheckIns: Titel in Popup bei überlappenden Check-Ins*/ -"checkin_overlap_popup_title" = "Cannot save"; +"checkin_overlap_popup_title" = "Kaydedilemiyor"; /*Check-Ins: Text bei Popup bei überlappenden Check-Ins, {CHECKIN} wird z.B. durch "Sitzungszimmer E318" ersetzt*/ -"checkin_overlap_popup_text" = "The times you selected for {CHECKIN} overlap with other check-ins. Please check your entries again."; +"checkin_overlap_popup_text" = "Seçmiş olduğunuz saatler {CHECKIN} başka Ckeck-in'ler ile kesişiyor. Lütfen bilgilerinizi yeniden kontrol edin."; /*Check-Ins: Button bei Popup bei überlappenden Check-Ins*/ -"checkin_overlap_back_button" = "Back"; +"checkin_overlap_back_button" = "Geri"; /*This will be read by the screenreader instead of "h" (for the reminder options), in plural form*/ -"accessibility_reminder_option_hours_plural" = "Hours"; +"accessibility_reminder_option_hours_plural" = "saat"; /*This will be read by the screenreader instead of "'" (for the reminder options)*/ -"accessibility_reminder_option_minutes" = "Minutes"; +"accessibility_reminder_option_minutes" = "dakika"; /*This will be read by the screenreader instead of "h" (for the reminder options), in singular form*/ -"accessibility_reminder_option_hour" = "Hour"; +"accessibility_reminder_option_hour" = "saat"; /*Check-Ins: Text im Popup bei überlappenden Check-Ins, wenn keine Überlappungen mehr da sind. {CHECKIN} wird durch Raum ersetzt.*/ -"checkin_overlap_popup_success_text" = "There are no longer any conflicts for the time you entered. You can now check out of {CHECKIN}."; +"checkin_overlap_popup_success_text" = "Girmiş olduğunuz süreler için artık çatışma yok. Şimdi {CHECKIN}'de çıkış yapabilirsiniz."; /*Wird angezeigt, wenn der QR-Code erfolgreich erstellt wurde*/ -"web_generator_success_title" = "QR code generated"; +"web_generator_success_title" = "Kare kod oluşturuldu"; /*Titel des Buttons, mit dem man einen neuen QR-Code erstellen kann*/ -"web_generator_reset_button" = "Generate new QR code"; +"web_generator_reset_button" = "Yeni kare kod oluştur"; /*Used by VoiceOver to explain what the info button in the navigation bar does*/ -"accessibility_info_button_app" = "More information on the app"; +"accessibility_info_button_app" = "Uygulama hakkında daha fazla bilgi"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at CovidCodes does*/ -"accessibility_info_button_covidcode" = "More information on Covidcodes"; +"accessibility_info_button_covidcode" = "Covid kodları hakkında daha fazla bilgi"; /*Used by VoiceOver to explain what the info button in the Stats-Tab at Number of cases does*/ -"accessibility_info_button_numberofcases" = "More information on case numbers"; +"accessibility_info_button_numberofcases" = "Vaka sayıları hakkında daha fazla bilgi"; /*Is read by the screenreader, when newly created QR-code is shown*/ -"accessibility_preview_qr_code_alternative_text" = "Generated QR code"; +"accessibility_preview_qr_code_alternative_text" = "Oluşturulan kare kod"; /*Check-In: Hinweis, dass QR-Codes auch im Web erstellt werden können*/ -"checkin_generate_web_hint" = "Alternatively, you can also generate QR codes at qr.swisscovid.ch."; +"checkin_generate_web_hint" = "Alternatif olarak kare kodları qr.swisscovid.ch sayfasında da oluşturabilirsiniz."; /*Check-In: Hinweis dass man sich beim vorherigen Ort zuerst auschecken muss.*/ -"error_already_checked_in_text" = "To check in to a new location, you first need to check out."; +"error_already_checked_in_text" = "Yeni bir yere Check-in yapmak için öncelikle Check-out yapmanız gerekir."; From f5c8e56df532aef2f4c9aab9a147010c75eeba9c Mon Sep 17 00:00:00 2001 From: Marco Zimmermann Date: Thu, 9 Sep 2021 17:10:56 +0200 Subject: [PATCH 24/27] removes clickable link in terms of use Signed-off-by: Marco Zimmermann --- DP3TApp/Resources/Disclaimer/DE_App_Nutzungsbedingungen.html | 2 -- DP3TApp/Resources/Disclaimer/EN_App_Nutzungsbedingungen.html | 2 -- DP3TApp/Resources/Disclaimer/FR_App_Nutzungsbedingungen.html | 2 -- DP3TApp/Resources/Disclaimer/IT_App_Nutzungsbedingungen.html | 2 -- 4 files changed, 8 deletions(-) diff --git a/DP3TApp/Resources/Disclaimer/DE_App_Nutzungsbedingungen.html b/DP3TApp/Resources/Disclaimer/DE_App_Nutzungsbedingungen.html index dfab428b..c2d501a2 100644 --- a/DP3TApp/Resources/Disclaimer/DE_App_Nutzungsbedingungen.html +++ b/DP3TApp/Resources/Disclaimer/DE_App_Nutzungsbedingungen.html @@ -66,9 +66,7 @@

Warnsystem für Veranstaltungen: Die Organisatorin oder der Organisator einer Veranstaltung generiert in seiner App oder über die Internetseite - qr.swisscovid.ch - einen QR-Code. Besucherinnen und Besucher der Veranstaltung können mit ihrer App den gezeigten QR-Code scannen und sind so an der Veranstaltung eingecheckt.

diff --git a/DP3TApp/Resources/Disclaimer/EN_App_Nutzungsbedingungen.html b/DP3TApp/Resources/Disclaimer/EN_App_Nutzungsbedingungen.html index 9f1c5b89..f788b23a 100644 --- a/DP3TApp/Resources/Disclaimer/EN_App_Nutzungsbedingungen.html +++ b/DP3TApp/Resources/Disclaimer/EN_App_Nutzungsbedingungen.html @@ -66,9 +66,7 @@

Warning system for events: The organiser of an event generates a QR code in their app or on the website - qr.swisscovid.ch - . People attending the event can use their app to scan the displayed QR code and are thus checked in to the event.

diff --git a/DP3TApp/Resources/Disclaimer/FR_App_Nutzungsbedingungen.html b/DP3TApp/Resources/Disclaimer/FR_App_Nutzungsbedingungen.html index f0e57dae..3b52f473 100644 --- a/DP3TApp/Resources/Disclaimer/FR_App_Nutzungsbedingungen.html +++ b/DP3TApp/Resources/Disclaimer/FR_App_Nutzungsbedingungen.html @@ -76,9 +76,7 @@

Système d’alerte pour les manifestations : l’organisateur d’une manifestation génère un code QR dans son application ou sur le site Internet - qr.swisscovid.ch - Les visiteurs de la manifestation peuvent scanner le code QR présenté avec leur application et indiquent ainsi avoir participé à la manifestation.

L’application enregistre sur le téléphone portable le code d’identification de la manifestation avec sa date, sa durée et sa description. Depuis le diff --git a/DP3TApp/Resources/Disclaimer/IT_App_Nutzungsbedingungen.html b/DP3TApp/Resources/Disclaimer/IT_App_Nutzungsbedingungen.html index 25d5d74b..4e27745e 100644 --- a/DP3TApp/Resources/Disclaimer/IT_App_Nutzungsbedingungen.html +++ b/DP3TApp/Resources/Disclaimer/IT_App_Nutzungsbedingungen.html @@ -66,9 +66,7 @@

Sistema di allerta per le manifestazioni: l’organizzatore di una manifestazione genera nella propria app o tramite la pagina Internet - qr.swisscovid.ch - un codice QR che i visitatori della manifestazione possono scansionare per effettuare il check-in alla manifestazione.

From 2897202d84871a14d75eb68ba57a4b00f7c61c29 Mon Sep 17 00:00:00 2001 From: Marco Zimmermann Date: Fri, 10 Sep 2021 09:48:26 +0200 Subject: [PATCH 25/27] adds problematic events check on app start Signed-off-by: Marco Zimmermann --- DP3TApp/Logic/AppDelegate.swift | 2 ++ .../CheckIn/ProblematicEventsManager.swift | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/DP3TApp/Logic/AppDelegate.swift b/DP3TApp/Logic/AppDelegate.swift index 9fa7b9a4..044c42b1 100644 --- a/DP3TApp/Logic/AppDelegate.swift +++ b/DP3TApp/Logic/AppDelegate.swift @@ -101,6 +101,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate { DatabaseSyncer.shared.syncDatabaseIfNeeded() } + ProblematicEventsManager.shared.syncIfNeeded() + window?.makeKey() if TracingManager.shared.isSupported { window?.rootViewController = navigationController diff --git a/DP3TApp/Logic/CheckIn/ProblematicEventsManager.swift b/DP3TApp/Logic/CheckIn/ProblematicEventsManager.swift index 89d2e15c..7258acf3 100644 --- a/DP3TApp/Logic/CheckIn/ProblematicEventsManager.swift +++ b/DP3TApp/Logic/CheckIn/ProblematicEventsManager.swift @@ -33,6 +33,9 @@ class ProblematicEventsManager { @UBOptionalUserDefault(key: "ch.admin.bag.dp3t.exposure.lastKeyBundleTag") private var lastKeyBundleTag: Int? + @UBOptionalUserDefault(key: "ch.admin.bag.dp3t.exposure.lastSync") + private var lastSync: Date? + @UBUserDefault(key: "ch.admin.bag.dp3t.exposure.notifiedIds", defaultValue: []) private(set) var notifiedIds: [String] @@ -55,6 +58,18 @@ class ProblematicEventsManager { exposureEvents = CrowdNotifier.getExposureEvents() } + public func syncIfNeeded() { + var syncNeeded = true + if let date = lastSync, + Date(timeIntervalSinceNow: -2 * 60 * 60) < date { + syncNeeded = false + } + + if syncNeeded { + sync { _, _ in } + } + } + public func sync(isInBackground: Bool = false, completion: @escaping (_ newData: Bool, _ needsNotification: Bool) -> Void) { logger.trace() // Before every sync, check if user has been checked in for more than the maximum time and if so, automatically check out and set the checkout time to the maximum allowed duration @@ -91,6 +106,9 @@ class ProblematicEventsManager { UIStateManager.shared.checkInError = nil strongSelf.lastSyncFailed = error != nil + if error == nil { + strongSelf.lastSync = Date() + } if let error = error { UIStateManager.shared.checkInError = CheckInError.networkError(error: .unexpected(error: error)) From 93cb8e10c61f700eecf2b628df3c6d647b988ea6 Mon Sep 17 00:00:00 2001 From: Marco Zimmermann Date: Fri, 3 Sep 2021 09:29:06 +0200 Subject: [PATCH 26/27] updates version Signed-off-by: Marco Zimmermann --- DP3TApp/Supporting Files/Info.plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DP3TApp/Supporting Files/Info.plist b/DP3TApp/Supporting Files/Info.plist index 38302ce1..a3880ce9 100644 --- a/DP3TApp/Supporting Files/Info.plist +++ b/DP3TApp/Supporting Files/Info.plist @@ -24,7 +24,7 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 2.0.0 + 2.1.0 CFBundleVersion $(CURRENT_PROJECT_VERSION) ENAPIVersion From ca23d9d45a6982d564317a2c3bdf058104ec259f Mon Sep 17 00:00:00 2001 From: Marco Zimmermann Date: Mon, 6 Sep 2021 07:46:02 +0200 Subject: [PATCH 27/27] updates version of app clip Signed-off-by: Marco Zimmermann --- DP3TAppClip/Info.plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DP3TAppClip/Info.plist b/DP3TAppClip/Info.plist index cc4b122b..6ffe791d 100644 --- a/DP3TAppClip/Info.plist +++ b/DP3TAppClip/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 2.0.0 + 2.1.0 CFBundleVersion $(CURRENT_PROJECT_VERSION) LSRequiresIPhoneOS