diff --git a/Clocker/Onboarding/FinalOnboardingViewController.swift b/Clocker/Onboarding/FinalOnboardingViewController.swift
index f74304a..f985511 100644
--- a/Clocker/Onboarding/FinalOnboardingViewController.swift
+++ b/Clocker/Onboarding/FinalOnboardingViewController.swift
@@ -1,12 +1,40 @@
// Copyright © 2015 Abhishek Banthia
import Cocoa
+import Firebase
+
+struct EmailSignupConstants {
+ static let CLEmailSignupEmailProperty = "email"
+ static let CLOperatingSystemVersion = "OS"
+ static let CLClockerVersion = "Clocker version"
+ static let CLAppFeedbackDateProperty = "date"
+}
class FinalOnboardingViewController: NSViewController {
@IBOutlet var titleLabel: NSTextField!
@IBOutlet var subtitleLabel: NSTextField!
@IBOutlet var accesoryLabel: NSTextField!
@IBOutlet var accessoryImageView: NSImageView!
+ @IBOutlet var emailTextField: NSTextField!
+ @IBOutlet var emailExplanationLabel: NSTextField!
+
+ private let emailValidator = EmailTextFieldValidator()
+
+ private var serialNumber: String? {
+ let platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"))
+
+ guard platformExpert > 0 else {
+ return nil
+ }
+
+ guard let serialNumber = (IORegistryEntryCreateCFProperty(platformExpert, kIOPlatformSerialNumberKey as CFString, kCFAllocatorDefault, 0).takeUnretainedValue() as? String) else {
+ return nil
+ }
+
+ IOObjectRelease(platformExpert)
+
+ return serialNumber
+ }
override func viewDidLoad() {
super.viewDidLoad()
@@ -14,5 +42,74 @@ class FinalOnboardingViewController: NSViewController {
subtitleLabel.stringValue = "Thank you for the details."
accesoryLabel.stringValue = "You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences."
accessoryImageView.image = Themer.shared().menubarOnboardingImage()
+ emailExplanationLabel.stringValue = "If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!"
+ }
+
+ override func viewWillAppear() {
+ super.viewWillAppear()
+ emailTextField.becomeFirstResponder()
+ }
+
+ private func todaysDate() -> String {
+ let dateFormatter = DateFormatter()
+ dateFormatter.dateStyle = .medium
+ dateFormatter.timeStyle = .short
+ dateFormatter.timeZone = TimeZone(identifier: AppFeedbackConstants.CLCaliforniaTimezoneIdentifier)
+ return dateFormatter.string(from: Date())
+ }
+
+ private func extraData() -> [String: String] {
+ guard let validEmail = emailValidator.validate(field: emailTextField) else {
+ print("Not sending up email because it was invalid")
+ return [:]
+ }
+
+ guard let shortVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String,
+ let appVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as? String else {
+ return [:]
+ }
+ let operatingSystem = ProcessInfo.processInfo.operatingSystemVersion
+ let osVersion = "\(operatingSystem.majorVersion).\(operatingSystem.minorVersion).\(operatingSystem.patchVersion)"
+ let versionInfo = "Clocker \(shortVersion) (\(appVersion))"
+
+ return [
+ EmailSignupConstants.CLEmailSignupEmailProperty: validEmail,
+ EmailSignupConstants.CLOperatingSystemVersion: osVersion,
+ EmailSignupConstants.CLClockerVersion: versionInfo,
+ EmailSignupConstants.CLAppFeedbackDateProperty: todaysDate(),
+ ]
+ }
+
+ func sendUpEmailIfValid() {
+ let annotations = extraData()
+ guard let identifier = serialNumber else {
+ assertionFailure("Serial Identifier was unexpectedly nil")
+ return
+ }
+
+ let myRootReference = Firebase(url: "https://fiery-heat-5237.firebaseio.com/EmailSignup")
+ let feedbackReference = myRootReference?.child(byAppendingPath: identifier)
+ feedbackReference?.setValue(annotations)
+ }
+}
+
+class EmailTextFieldValidator {
+ func validate(field: NSTextField) -> String? {
+ let trimmedText = field.stringValue.trimmingCharacters(in: .whitespacesAndNewlines)
+
+ guard let dataDetector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) else {
+ return nil
+ }
+
+ let range = NSMakeRange(0, NSString(string: trimmedText).length)
+ let allMatches = dataDetector.matches(in: trimmedText,
+ options: [],
+ range: range)
+
+ if allMatches.count == 1,
+ allMatches.first?.url?.absoluteString.contains("mailto:") == true {
+ return trimmedText
+ }
+ return nil
}
}
diff --git a/Clocker/Onboarding/Onboarding.storyboard b/Clocker/Onboarding/Onboarding.storyboard
index ecb9e3f..ed9fdcd 100644
--- a/Clocker/Onboarding/Onboarding.storyboard
+++ b/Clocker/Onboarding/Onboarding.storyboard
@@ -647,25 +647,52 @@ DQ
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Clocker/Onboarding/OnboardingParentViewController.swift b/Clocker/Onboarding/OnboardingParentViewController.swift
index 7eabc80..8f5edd9 100644
--- a/Clocker/Onboarding/OnboardingParentViewController.swift
+++ b/Clocker/Onboarding/OnboardingParentViewController.swift
@@ -181,6 +181,8 @@ class OnboardingParentViewController: NSViewController {
}
private func performFinalStepsBeforeFinishing() {
+ finalOnboardingVC?.sendUpEmailIfValid()
+
positiveButton.tag = OnboardingType.complete.rawValue
// Install the menubar option!