// C o p y r i g h t © 2 0 1 5 A b h i s h e k B a n t h i a
import Cocoa
import Firebase
struct EmailSignupConstants {
static let CLEmailSignupEmailProperty = " email "
static let CLOperatingSystemVersion = " OS "
static let CLClockerVersion = " Clocker version "
static let CLAppFeedbackDateProperty = " date "
static let CLAppLanguageKey = " language "
}
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 localizationButton : UnderlinedButton !
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 ( )
titleLabel . stringValue = " You're all set! " . localized ( )
subtitleLabel . stringValue = " Thank you for the details. " . localized ( )
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. " . localized ( )
accessoryImageView . image = Themer . shared ( ) . menubarOnboardingImage ( )
emailTextField . isHidden = true
setupLocalizationButton ( )
}
private func setupLocalizationButton ( ) {
let mutableParaghStyle = NSMutableParagraphStyle ( )
mutableParaghStyle . alignment = . center
let underlineRange = NSRange ( location : 42 , length : 14 )
let originalText = NSMutableAttributedString ( string : " Help localize Clocker in your language by clicking here! " )
originalText . addAttribute ( NSAttributedString . Key . underlineStyle ,
value : NSNumber ( value : Int8 ( NSUnderlineStyle . single . rawValue ) ) ,
range : underlineRange )
originalText . addAttribute ( NSAttributedString . Key . foregroundColor ,
value : Themer . shared ( ) . mainTextColor ( ) ,
range : NSRange ( location : 0 , length : localizationButton . attributedTitle . string . count ) )
originalText . addAttribute ( NSAttributedString . Key . font ,
value : ( localizationButton ? . font ) ! ,
range : NSRange ( location : 0 , length : localizationButton . attributedTitle . string . count ) )
originalText . addAttribute ( NSAttributedString . Key . paragraphStyle ,
value : mutableParaghStyle ,
range : NSRange ( location : 0 , length : localizationButton . attributedTitle . string . count ) )
localizationButton . attributedTitle = originalText
}
@IBAction func localizationAction ( _ : Any ) {
guard let localizationURL = URL ( string : AboutUsConstants . CrowdInLocalizationLink ) ,
let languageCode = Locale . preferredLanguages . first else { return }
NSWorkspace . shared . open ( localizationURL )
// L o g t h i s
let custom : [ String : Any ] = [ " Language " : languageCode ]
Logger . log ( object : custom , for : " Opened Localization Link " )
guard let parentVC = parent as ? OnboardingParentViewController else { return }
parentVC . performFinalStepsBeforeFinishing ( )
}
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 nil
}
guard let shortVersion = Bundle . main . object ( forInfoDictionaryKey : " CFBundleShortVersionString " ) as ? String ,
let appVersion = Bundle . main . object ( forInfoDictionaryKey : " CFBundleVersion " ) as ? String else {
return nil
}
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 ( ) ,
EmailSignupConstants . CLAppLanguageKey : Locale . preferredLanguages . first ? ? " en-US " ,
]
}
func sendUpEmailIfValid ( ) {
guard let identifier = serialNumber , let annotations = extraData ( ) else {
// E i t h e r s e r i a l n u m b e r w a s n ' t p r e s e n t o r e m a i l w a s n ' t a d d e d . A b o r t .
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
}
}