Skip to content

Commit

Permalink
Merge pull request #496 from SwissCovid/release/2.1.0
Browse files Browse the repository at this point in the history
Release 2.1.0
  • Loading branch information
stmitt authored Sep 13, 2021
2 parents a686a9c + ca23d9d commit 6bc8df6
Show file tree
Hide file tree
Showing 76 changed files with 1,383 additions and 144 deletions.
18 changes: 18 additions & 0 deletions DP3TApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -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 */; };
Expand All @@ -288,6 +291,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 */; };
Expand Down Expand Up @@ -322,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 */; };
Expand Down Expand Up @@ -821,6 +827,8 @@
6E5B6994265F71C600EB0C56 /* AppClipViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppClipViewController.swift; sourceTree = "<group>"; };
6E5B69C2265FD12D00EB0C56 /* DP3TAppClip-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DP3TAppClip-Bridging-Header.h"; sourceTree = "<group>"; };
6E5B69E12660D67300EB0C56 /* NSCheckinOnboardingViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSCheckinOnboardingViewController.swift; sourceTree = "<group>"; };
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 = "<group>"; };
6E6E5170242F5026006E532E /* ConfigResponseBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfigResponseBody.swift; sourceTree = "<group>"; };
6E6E517E242F9586006E532E /* NSInformThankYouViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSInformThankYouViewController.swift; sourceTree = "<group>"; };
Expand All @@ -845,6 +853,7 @@
6E7C0D42242E44D80017C4F9 /* NSWebViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSWebViewController.swift; sourceTree = "<group>"; };
6E7C0D44242E4AA90017C4F9 /* NSLoadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSLoadingView.swift; sourceTree = "<group>"; };
6E7C0D46242E58600017C4F9 /* NSAboutViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSAboutViewController.swift; sourceTree = "<group>"; };
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 = "<group>"; };
6E889755261F228200508334 /* NSOnboardingBaseViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSOnboardingBaseViewController.swift; sourceTree = "<group>"; };
6E889764261F27D400508334 /* NSUpdateBoardingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSUpdateBoardingViewController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1816,6 +1825,9 @@
children = (
DC16175C2638717800B56ADA /* NSTimePickerControl.swift */,
DC16175D2638717800B56ADA /* NSCheckInEditViewController.swift */,
6E84B1A626E0CD760000AC92 /* NSAlreadyCheckedInErrorPopupViewController.swift */,
6E5F789C26DD4190006D11B0 /* NSOverlappingCheckinPopupViewController.swift */,
6E5F789F26DD4B5A006D11B0 /* NSOverlappingCheckInView.swift */,
);
path = Edit;
sourceTree = "<group>";
Expand Down Expand Up @@ -2665,6 +2677,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 */,
Expand Down Expand Up @@ -2730,6 +2743,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 */,
Expand Down Expand Up @@ -2789,6 +2803,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 */,
Expand Down Expand Up @@ -2946,6 +2961,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 */,
Expand Down Expand Up @@ -2997,6 +3013,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 */,
Expand Down Expand Up @@ -3063,6 +3080,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 */,
Expand Down
2 changes: 2 additions & 0 deletions DP3TApp/Logic/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
DatabaseSyncer.shared.syncDatabaseIfNeeded()
}

ProblematicEventsManager.shared.syncIfNeeded()

window?.makeKey()
if TracingManager.shared.isSupported {
window?.rootViewController = navigationController
Expand Down
12 changes: 2 additions & 10 deletions DP3TApp/Logic/CheckIn/CheckInManager/CheckInManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
18 changes: 18 additions & 0 deletions DP3TApp/Logic/CheckIn/ProblematicEventsManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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]

Expand All @@ -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
Expand Down Expand Up @@ -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))
Expand Down
29 changes: 29 additions & 0 deletions DP3TApp/Logic/CheckIn/ReminderManager/ReminderManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
4 changes: 2 additions & 2 deletions DP3TApp/Logic/Helpers/DateFormatter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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) ?? "")
}
}

Expand Down
19 changes: 16 additions & 3 deletions DP3TApp/Logic/NSLinkHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,22 @@ 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)
}

let hs = appDelegate.tabBarController.homescreen
hs.navigationController?.present(vc, animated: true, completion: nil)
}

return true
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 6bc8df6

Please sign in to comment.