Skip to content

Commit

Permalink
Home notifications & refactor (#267)
Browse files Browse the repository at this point in the history
* Rewrite home to use table view, add notifications

* Animate notification dot
  • Loading branch information
ivnsch authored Jun 11, 2020
1 parent 56db958 commit cffde50
Show file tree
Hide file tree
Showing 15 changed files with 420 additions and 151 deletions.
12 changes: 12 additions & 0 deletions CoEpi.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@
8498115D243630E500EBD1DA /* ScannedCensHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8498115C243630E500EBD1DA /* ScannedCensHandler.swift */; };
849B3F7D247F00F7003CCE4B /* SymptomView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 849B3F7C247F00F7003CCE4B /* SymptomView.xib */; };
849C6A46249253790047BC10 /* AutoEquatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849C6A45249253790047BC10 /* AutoEquatable.swift */; };
849C6A5224925B5C0047BC10 /* Equatable.generated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849C6A5124925B5C0047BC10 /* Equatable.generated.swift */; };
849C6A55249260A00047BC10 /* HomeItemCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849C6A53249260A00047BC10 /* HomeItemCell.swift */; };
849C6A5A24927C340047BC10 /* HomeItemView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 849C6A5924927C340047BC10 /* HomeItemView.xib */; };
849CEFA3242FEE23003F9284 /* UIColor+Hex.swift in Sources */ = {isa = PBXBuildFile; fileRef = D41B0D16242F5A2A00A50447 /* UIColor+Hex.swift */; };
849D1AFC2439D7B300804511 /* RxSwiftExt in Frameworks */ = {isa = PBXBuildFile; productRef = 849D1AFB2439D7B300804511 /* RxSwiftExt */; };
849D1AFF2439D90C00804511 /* Completable+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849D1AFE2439D90C00804511 /* Completable+Convenience.swift */; };
Expand Down Expand Up @@ -329,6 +332,9 @@
8498115C243630E500EBD1DA /* ScannedCensHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScannedCensHandler.swift; sourceTree = "<group>"; };
849B3F7C247F00F7003CCE4B /* SymptomView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SymptomView.xib; sourceTree = "<group>"; };
849C6A45249253790047BC10 /* AutoEquatable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoEquatable.swift; sourceTree = "<group>"; };
849C6A5124925B5C0047BC10 /* Equatable.generated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Equatable.generated.swift; sourceTree = "<group>"; };
849C6A53249260A00047BC10 /* HomeItemCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeItemCell.swift; sourceTree = "<group>"; };
849C6A5924927C340047BC10 /* HomeItemView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HomeItemView.xib; sourceTree = "<group>"; };
849D1AFE2439D90C00804511 /* Completable+Convenience.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Completable+Convenience.swift"; sourceTree = "<group>"; };
849D1B072439EAD200804511 /* UINotifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UINotifier.swift; sourceTree = "<group>"; };
849D1B092439F31D00804511 /* DaoError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DaoError.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -481,6 +487,7 @@
054A34FA244E68F700282E17 /* generated */ = {
isa = PBXGroup;
children = (
849C6A5124925B5C0047BC10 /* Equatable.generated.swift */,
054A34FB244E691500282E17 /* strings.swift */,
);
path = generated;
Expand Down Expand Up @@ -1040,6 +1047,8 @@
84FA00FE2427ED5E00318104 /* HomeViewController.swift */,
84FA00FF2427ED5E00318104 /* HomeViewController.xib */,
8486BDDF242BC8B600A63DD5 /* HomeViewModel.swift */,
849C6A53249260A00047BC10 /* HomeItemCell.swift */,
849C6A5924927C340047BC10 /* HomeItemView.xib */,
);
path = home;
sourceTree = "<group>";
Expand Down Expand Up @@ -1266,6 +1275,7 @@
849D7B3A248E8E8600C9DDBD /* LogsViewController.xib in Resources */,
622AC2F4245FD34300A6EB90 /* FeverTempViewController.xib in Resources */,
84DE6A24243F99A200CCF4A6 /* AlertsViewController.xib in Resources */,
849C6A5A24927C340047BC10 /* HomeItemView.xib in Resources */,
30EF957A24379E01007D61C7 /* CoEpiLaunchScreen.storyboard in Resources */,
848434572438C046006A5839 /* ErrorView.xib in Resources */,
622AC2CC245FC5E000A6EB90 /* CoughTypeViewController.xib in Resources */,
Expand Down Expand Up @@ -1419,6 +1429,7 @@
849DFE702427D3750008ED65 /* CoEpi.xcdatamodeld in Sources */,
30EF94FB242CFC9F007D61C7 /* AlertsViewController.swift in Sources */,
8486BDD9242BBCE700A63DD5 /* DebugBleViewController.swift in Sources */,
849C6A55249260A00047BC10 /* HomeItemCell.swift in Sources */,
622AC2D4245FC65A00A6EB90 /* CoughDaysViewController.swift in Sources */,
84D069672455E6E40004E8B6 /* DateFormatters.swift in Sources */,
849C6A46249253790047BC10 /* AutoEquatable.swift in Sources */,
Expand All @@ -1438,6 +1449,7 @@
84FA00F22427E13000318104 /* Dependencies.swift in Sources */,
841D39A0244E3EE200A9CD64 /* StartPermissions.swift in Sources */,
84B48A9F24530AAB001908E8 /* RootNav.swift in Sources */,
849C6A5224925B5C0047BC10 /* Equatable.generated.swift in Sources */,
848434642438C71F006A5839 /* UIViewController+Rx.swift in Sources */,
849327B42452D92C009589E6 /* FetchAlertsBackgroundRegisterer.swift in Sources */,
8420169A244CA1AC000EE281 /* ActivityIndicatorView.swift in Sources */,
Expand Down
5 changes: 4 additions & 1 deletion CoEpi/Dependencies.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ class Dependencies {
}

private func registerViewModels(container: DependencyContainer) {
container.register { HomeViewModel(startPermissions: try container.resolve(), rootNav: try container.resolve()) }
container.register { HomeViewModel(startPermissions: try container.resolve(),
rootNav: try container.resolve(),
alertRepo: try container.resolve(),
envInfos: try container.resolve()) }
container.register { OnboardingViewModel() }

container.register { ThankYouViewModel(rootNav: try container.resolve()) }
Expand Down
18 changes: 18 additions & 0 deletions CoEpi/common/EnvInfos.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,21 @@ class EnvInfos {
UIDevice.current.systemVersion
}
}
//
//private func getVersionNumber() -> String{
//
// guard let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
// else{
// fatalError("Failed to read bundle version")
// }
// print("Version : \(version)");
// return "\(L10n.Ux.Home.Footer.version): \(version)"
//}
//
//private func getBuildNumber() -> String {
// guard let build = Bundle.main.infoDictionary?["CFBundleVersion"] as? String else {
// fatalError("Failed to read build number")
// }
// print("Build : \(build)")
// return "\(L10n.Ux.Home.Footer.build): \(build)"
//}
2 changes: 1 addition & 1 deletion CoEpi/domain/model/Alert.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
struct Alert {
struct Alert: AutoEquatable {
let id: String
let contactTime: UnixTime
let reportTime: UnixTime
Expand Down
2 changes: 1 addition & 1 deletion CoEpi/domain/model/SymptomInputs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ struct SymptomInputs {
}


enum UserInput<T> {
enum UserInput<T>: AutoEquatable {
case none, some(_ value: T)

func map<U>(f: (T) -> U) -> UserInput<U> {
Expand Down
2 changes: 1 addition & 1 deletion CoEpi/domain/model/UnixTime.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Foundation

struct UnixTime: Codable {
struct UnixTime: Codable, AutoEquatable {
let value: Int64

static func minTimestamp() -> UnixTime {
Expand Down
15 changes: 7 additions & 8 deletions CoEpi/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@
"alerts.subtitle" = "Click each alert to learn more";
"alerts.buttonLabel" = "What are exposure alerts?";
"alerts.moreInfoTitle" = "Exposure Alert";
"alerts.count.none" = "No new exposure alerts";
"alerts.count.one" = "1 new exposure alert";
"alerts.count.some" = "%d new exposure alerts";
"alerts.title" = "Alerts";
"alerts.label.no_symptoms_reported" = "No symptoms reported";
"alerts.label.fever.mild" = "Mild Fever";
Expand Down Expand Up @@ -119,16 +116,18 @@

//homescreen
"UX.home.title" = "CoEpi";
"UX.home.report1" = " Symptom Reporting\n\n";
"UX.home.report2" = " Share how you are feeling";
"UX.home.alerts1" = " Exposure Alerts\n\n";
"UX.home.alerts2" = " Review your potential exposures";
"UX.home.detected" = " new exposures detected\n\n";
"UX.home.report1" = "Symptom Reporting";
"UX.home.report2" = "Share how you are feeling";
"UX.home.alerts1" = "Exposure Alerts";
"UX.home.alerts2" = "Review your potential exposures";
"UX.home.detected" = "new exposures detected";
"UX.home.how" = "How is my data being used?";
"UX.home.share" = "Share";
"UX.home.footer.build" = "Build";
"UX.home.footer.debug" = "Debug";
"UX.home.footer.version" = "Version";
"home.items.alerts.notification.one" = "1 new exposure alert";
"home.items.alerts.notification.some" = "%d new exposure alerts";

// symptom days
"UX.symptomsdays.heading" = "Follow up: Earliest Symptoms";
Expand Down
30 changes: 30 additions & 0 deletions CoEpi/generated/Equatable.generated.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Generated using Sourcery 0.18.0 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT


// MARK: Alert Equatable
extension Alert: Equatable {
static func ==(lhs: Alert, rhs: Alert) -> Bool {
guard lhs.id == rhs.id else { return false }
guard lhs.contactTime == rhs.contactTime else { return false }
guard lhs.reportTime == rhs.reportTime else { return false }
guard lhs.earliestSymptomTime == rhs.earliestSymptomTime else { return false }
guard lhs.feverSeverity == rhs.feverSeverity else { return false }
guard lhs.coughSeverity == rhs.coughSeverity else { return false }
guard lhs.breathlessness == rhs.breathlessness else { return false }
return true
}
}
// MARK: UnixTime Equatable
extension UnixTime: Equatable {
static func ==(lhs: UnixTime, rhs: UnixTime) -> Bool {
guard lhs.value == rhs.value else { return false }
return true
}
}
// MARK: UserInput Equatable
extension UserInput: Equatable {
static func ==(lhs: UserInput, rhs: UserInput) -> Bool {
return true
}
}
25 changes: 19 additions & 6 deletions CoEpi/generated/strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -211,14 +211,12 @@ internal enum L10n {
/// Alerts
internal static let title = L10n.tr("Localizable", "alerts.title")
internal enum Count {
/// No new exposure alerts
/// No new contact alerts
internal static let `none` = L10n.tr("Localizable", "alerts.count.none")
/// 1 new exposure alert
/// Click the alert to learn more
internal static let one = L10n.tr("Localizable", "alerts.count.one")
/// %d new exposure alerts
internal static func some(_ p1: Int) -> String {
return L10n.tr("Localizable", "alerts.count.some", p1)
}
/// Click each alert to learn more
internal static let some = L10n.tr("Localizable", "alerts.count.some")
}
internal enum Details {
/// Exposure Alert
Expand Down Expand Up @@ -260,6 +258,21 @@ internal enum L10n {
}
}

internal enum Home {
internal enum Items {
internal enum Alerts {
internal enum Notification {
/// 1 new exposure alert
internal static let one = L10n.tr("Localizable", "home.items.alerts.notification.one")
/// %d new exposure alerts
internal static func some(_ p1: Int) -> String {
return L10n.tr("Localizable", "home.items.alerts.notification.some", p1)
}
}
}
}
}

internal enum WhatExposure {
/// <body><p><font color='black' face='-apple-system' size='5'><b>Exposure alerts</b> indicate that you have been in close proximity (e.g. within several feet) to someone with symptoms also using a compatible app. <br /><br /><b>How does CoEpi work?</b> <br /><br /> CoEpi generates exposure alerts if your device has flagged another tracing app user who may have been infectious during your contact. <br /><br /> Based on the symptom report in the exposure alert, you can: <br /><br /> <b>• Monitor</b> yourself for symptoms in the days following the potential exposure<br /><br /> <b>• Self-isolate</b> within your household to reduce the risk of transmitting to others <br /><br /> <b>• Talk with a healthcare provider</b> about your exposure</font</p><body>
internal static let htmlBody = L10n.tr("Localizable", "whatExposure.html_body")
Expand Down
87 changes: 87 additions & 0 deletions CoEpi/ui/home/HomeItemCell.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import UIKit

class HomeItemCell: UITableViewCell {

private var homeItemView: HomeItemView?

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupUI()

}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

private func setupUI() {
backgroundColor = .clear
contentView.backgroundColor = .clear

selectionStyle = .none

let view: HomeItemView = HomeItemView.fromNib()
contentView.addSubview(view)
view.pinAllEdgesToParent()
self.homeItemView = view
}

public func setup(viewData: HomeItemViewData) {
homeItemView?.setup(item: viewData)
}
}


class HomeItemView: UIView {
public var onAcknowledged: (() ->())?

@IBOutlet weak var notificationView: UIView!
@IBOutlet weak var notificationLabel: UILabel!
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var descrLabel: UILabel!
@IBOutlet weak var backgroundView: UIView!

override func awakeFromNib() {
super.awakeFromNib()
notificationView.layer.cornerRadius = 20

backgroundView.layer.cornerRadius = 15
backgroundView.layer.shadowColor = UIColor.black.cgColor
backgroundView.layer.shadowOffset = CGSize(width: 4, height: 4)
backgroundView.layer.shadowRadius = 4
backgroundView.layer.shadowOpacity = 0.25
}

func setup(item: HomeItemViewData) {
notificationView.isHidden = item.notification == nil
notificationLabel.isHidden = item.notification == nil
notificationLabel.text = item.notification?.text
titleLabel.text = item.title
descrLabel.text = item.descr

if item.notification != nil {
notificationView.transform = CGAffineTransform(scaleX: 0, y: 0)
notificationLabel.alpha = 0
UIView.animate(withDuration: 0.5, delay: 0.5, usingSpringWithDamping:
0.6, initialSpringVelocity: 0.6, options: .curveEaseOut, animations: {
self.notificationView.transform = CGAffineTransform(scaleX: 1, y: 1)
self.notificationLabel.alpha = 1
}, completion: nil)
}
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
backgroundView.backgroundColor = .coEpiLightGray
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
backgroundView.backgroundColor = .white
}

override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesCancelled(touches, with: event)
backgroundView.backgroundColor = .white
}
}
Loading

0 comments on commit cffde50

Please # to comment.