Browse Source

Email signup additions!

pull/92/head
Abhishek 5 years ago
parent
commit
bc68842164
  1. 97
      Clocker/Onboarding/FinalOnboardingViewController.swift
  2. 27
      Clocker/Onboarding/Onboarding.storyboard
  3. 2
      Clocker/Onboarding/OnboardingParentViewController.swift

97
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
}
}

27
Clocker/Onboarding/Onboarding.storyboard

@ -647,25 +647,52 @@ DQ
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="6WD-GP-iz1">
<rect key="frame" x="122" y="122" width="288" height="22"/>
<constraints>
<constraint firstAttribute="height" constant="22" id="OvB-hh-3zl"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="border" placeholderString="Email ID" drawsBackground="YES" id="sOr-bC-0RP">
<font key="font" size="12" name="Avenir-Book"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="vVa-Wi-DxT">
<rect key="frame" x="120" y="78" width="292" height="20"/>
<textFieldCell key="cell" selectable="YES" title="Email Explanation Text" id="aOm-4b-2yt">
<font key="font" size="12" name="Avenir-Book"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstItem="nbC-4o-Xjf" firstAttribute="leading" secondItem="fEE-QM-0Pi" secondAttribute="leading" id="0e8-gV-Vtv"/>
<constraint firstItem="rQQ-Iw-KIs" firstAttribute="top" secondItem="Hbh-9r-F30" secondAttribute="top" id="5HI-nS-H0q"/>
<constraint firstAttribute="trailing" secondItem="kMo-BE-OAn" secondAttribute="trailing" constant="20" id="Blg-oa-r4s"/>
<constraint firstItem="6WD-GP-iz1" firstAttribute="top" secondItem="kMo-BE-OAn" secondAttribute="bottom" constant="28" id="JBL-3r-4rQ"/>
<constraint firstItem="fEE-QM-0Pi" firstAttribute="leading" secondItem="rQQ-Iw-KIs" secondAttribute="leading" constant="2" id="ONk-e6-XAu"/>
<constraint firstItem="vVa-Wi-DxT" firstAttribute="trailing" secondItem="6WD-GP-iz1" secondAttribute="trailing" id="OSn-gm-o2b"/>
<constraint firstAttribute="trailing" secondItem="nbC-4o-Xjf" secondAttribute="trailing" constant="20" id="TOW-1R-mJC"/>
<constraint firstItem="Hbh-9r-F30" firstAttribute="top" secondItem="DF5-si-VO7" secondAttribute="top" constant="20" id="Ttw-wI-zuQ"/>
<constraint firstAttribute="trailing" secondItem="6WD-GP-iz1" secondAttribute="trailing" constant="26" id="VBH-zO-odL"/>
<constraint firstItem="6WD-GP-iz1" firstAttribute="leading" secondItem="kMo-BE-OAn" secondAttribute="leading" id="WAj-0z-FfB"/>
<constraint firstItem="kMo-BE-OAn" firstAttribute="top" secondItem="nbC-4o-Xjf" secondAttribute="bottom" constant="40" id="ZFQ-Wg-6MB"/>
<constraint firstItem="rQQ-Iw-KIs" firstAttribute="leading" secondItem="Hbh-9r-F30" secondAttribute="trailing" constant="20" id="ZQY-pi-fPT"/>
<constraint firstItem="fEE-QM-0Pi" firstAttribute="top" secondItem="rQQ-Iw-KIs" secondAttribute="bottom" constant="-5" id="eCn-Co-mzu"/>
<constraint firstItem="nbC-4o-Xjf" firstAttribute="top" secondItem="fEE-QM-0Pi" secondAttribute="bottom" constant="42" id="j7b-Af-bcv"/>
<constraint firstItem="Hbh-9r-F30" firstAttribute="leading" secondItem="DF5-si-VO7" secondAttribute="leading" constant="20" id="jof-jK-gX8"/>
<constraint firstItem="vVa-Wi-DxT" firstAttribute="leading" secondItem="6WD-GP-iz1" secondAttribute="leading" id="mns-Ph-FKK"/>
<constraint firstItem="vVa-Wi-DxT" firstAttribute="top" secondItem="6WD-GP-iz1" secondAttribute="bottom" constant="24" id="qe3-dK-63b"/>
<constraint firstItem="kMo-BE-OAn" firstAttribute="leading" secondItem="fEE-QM-0Pi" secondAttribute="leading" id="z80-9e-u9d"/>
</constraints>
</view>
<connections>
<outlet property="accesoryLabel" destination="kMo-BE-OAn" id="zmK-wY-Ptp"/>
<outlet property="accessoryImageView" destination="nbC-4o-Xjf" id="bzc-jC-v0k"/>
<outlet property="emailExplanationLabel" destination="vVa-Wi-DxT" id="oD8-p1-DJo"/>
<outlet property="emailTextField" destination="6WD-GP-iz1" id="tbr-Ld-eMc"/>
<outlet property="subtitleLabel" destination="fEE-QM-0Pi" id="BkA-rd-TKV"/>
<outlet property="titleLabel" destination="rQQ-Iw-KIs" id="Bka-gU-05I"/>
</connections>

2
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!

Loading…
Cancel
Save