Ind.ie is now Small Technology Foundation.
Commit ce435db7 authored by Aral Balkan's avatar Aral Balkan

Working on the initial setup screen. Added a formatter for the Ind.ie name.

parent 2b9f20e2
......@@ -25,6 +25,7 @@
A75AABCA1A5ECFB000B105BA /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A75AABC91A5ECFB000B105BA /* AppDelegate.swift */; };
A75AABCC1A5ECFB000B105BA /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A75AABCB1A5ECFB000B105BA /* ViewController.swift */; };
A75AABDD1A5ECFB000B105BA /* HeartbeatTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A75AABDC1A5ECFB000B105BA /* HeartbeatTests.swift */; };
A760C9901A75A51100E84890 /* IndieNameFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A760C98F1A75A51100E84890 /* IndieNameFormatter.swift */; };
A7CC1FFA1A6C8FEB00B49AA9 /* MASShortcut.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7CC1FF91A6C8FEB00B49AA9 /* MASShortcut.framework */; };
A7CC20071A6C992F00B49AA9 /* SwiftyJSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7CC20061A6C992F00B49AA9 /* SwiftyJSON.swift */; };
A7CD7F121A6FBB2400BE31D6 /* node.js in Resources */ = {isa = PBXBuildFile; fileRef = A7CD7F111A6FBB2400BE31D6 /* node.js */; };
......@@ -86,6 +87,7 @@
A75AABD61A5ECFB000B105BA /* HeartbeatTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HeartbeatTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
A75AABDB1A5ECFB000B105BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
A75AABDC1A5ECFB000B105BA /* HeartbeatTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeartbeatTests.swift; sourceTree = "<group>"; };
A760C98F1A75A51100E84890 /* IndieNameFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IndieNameFormatter.swift; sourceTree = "<group>"; };
A7CC1FF91A6C8FEB00B49AA9 /* MASShortcut.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MASShortcut.framework; path = "../../../../../Library/Developer/Xcode/DerivedData/Heartbeat-bwptofoniwaoqzcgkxzhjtbmtjak/Build/Products/Debug/MASShortcut.framework"; sourceTree = "<group>"; };
A7CC1FFB1A6C8FF700B49AA9 /* SwiftyJSON.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftyJSON.framework; path = ../../sandbox/SwiftyJSON/build/Debug/SwiftyJSON.framework; sourceTree = "<group>"; };
A7CC1FFD1A6C901400B49AA9 /* SwiftyJSON.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftyJSON.framework; path = ../../sandbox/SwiftyJSON/build/Debug/SwiftyJSON.framework; sourceTree = "<group>"; };
......@@ -160,6 +162,7 @@
children = (
A70634B91A63114200A75BC0 /* StepOneViewController.swift */,
A70634BA1A63114200A75BC0 /* StepTwoViewController.swift */,
A760C98F1A75A51100E84890 /* IndieNameFormatter.swift */,
);
name = Steps;
sourceTree = "<group>";
......@@ -228,6 +231,7 @@
A75AABC61A5ECFB000B105BA /* Heartbeat */ = {
isa = PBXGroup;
children = (
A760C9911A75C41200E84890 /* Playgrounds */,
A7E49FD21A65846900FC06E3 /* Bridging-Header.h */,
A74CC6621A66A24D0083B288 /* Heartbeat.entitlements */,
A74C9EF21A66893B0083B288 /* External processes */,
......@@ -239,7 +243,6 @@
A75AABC91A5ECFB000B105BA /* AppDelegate.swift */,
A75AABCB1A5ECFB000B105BA /* ViewController.swift */,
A75AABC71A5ECFB000B105BA /* Supporting Files */,
A704E31D1A6C583A00E40913 /* Node.playground */,
);
path = Heartbeat;
sourceTree = "<group>";
......@@ -270,6 +273,14 @@
name = "Supporting Files";
sourceTree = "<group>";
};
A760C9911A75C41200E84890 /* Playgrounds */ = {
isa = PBXGroup;
children = (
A704E31D1A6C583A00E40913 /* Node.playground */,
);
name = Playgrounds;
sourceTree = "<group>";
};
A7E7D7AA1A616AA9003501C1 /* Classes */ = {
isa = PBXGroup;
children = (
......@@ -514,6 +525,7 @@
A7E7D7D61A616B90003501C1 /* NSNotificationCenterExtensions.swift in Sources */,
A7E7D7B51A616B0B003501C1 /* IndieSplitView.swift in Sources */,
A70634BC1A63114200A75BC0 /* StepTwoViewController.swift in Sources */,
A760C9901A75A51100E84890 /* IndieNameFormatter.swift in Sources */,
A7E7D7B61A616B0B003501C1 /* IndieSplitViewController.swift in Sources */,
A7E7D7B41A616B0B003501C1 /* IndieWindow.swift in Sources */,
A70634B61A6310E900A75BC0 /* SetupViewController.swift in Sources */,
......
......@@ -18,12 +18,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, NodeDelegate {
println(">>>>>>> APPLICATION DID FINISH LAUNCHING <<<<<<<<<")
startTime = CFAbsoluteTimeGetCurrent()
}
func applicationDidBecomeActive(notification: NSNotification) {
println(">>>>>>> APPLICATION DID BECOME ACTIVE <<<<<<<<<")
//
// Start NodeSocket.
//
......@@ -34,6 +28,12 @@ class AppDelegate: NSObject, NSApplicationDelegate, NodeDelegate {
self.node = Node.sharedInstance
self.node.delegate = self
self.node.start()
}
func applicationDidBecomeActive(notification: NSNotification) {
println(">>>>>>> APPLICATION DID BECOME ACTIVE <<<<<<<<<")
}
func applicationWillTerminate(aNotification: NSNotification) {
......
This diff is collapsed.
......@@ -26,3 +26,26 @@ func delay(delay:Double, closure:()->())
),
dispatch_get_main_queue(), closure)
}
//
// Coverted to Swift from Cameron Lowell Palmer’s Obj-C category
// (http://stackoverflow.com/a/23606211/253485)
//
extension String {
func stringByStrippingCharactersInSet(set:NSCharacterSet) -> String
{
return (self.componentsSeparatedByCharactersInSet(set) as NSArray).componentsJoinedByString("")
}
func stringByCollapsingWhitespace() -> String
{
var components:NSArray = self.componentsSeparatedByCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
let predicate = NSPredicate(format: "self <> ''", argumentArray: nil)
components = components.filteredArrayUsingPredicate(predicate)
return components.componentsJoinedByString(" ")
}
}
//
// IndieNameFormatter.swift
// Heartbeat
//
// Created by Aral Balkan on 25/01/2015.
// Copyright (c) 2015 Ind.ie. All rights reserved.
//
import Cocoa
class IndieNameFormatter: NSFormatter {
//
// MARK: - Control entry
//
//////////////////////////////////////////////////////////////////////
//
// Check for and disallow entry of invalid characters.
// (We only accept alphanumeric characters in Ind.ie names.)
//
//////////////////////////////////////////////////////////////////////
// override func isPartialStringValid(partialStringPtr: AutoreleasingUnsafeMutablePointer<NSString?>, proposedSelectedRange proposedSelRangePtr: NSRangePointer, originalString origString: String, originalSelectedRange origSelRange: NSRange, errorDescription error: AutoreleasingUnsafeMutablePointer<NSString?>) -> Bool {
override func isPartialStringValid(partialString: String, newEditingString newString: AutoreleasingUnsafeMutablePointer<NSString?>, errorDescription error: AutoreleasingUnsafeMutablePointer<NSString?>) -> Bool {
// // Check for length
// var acceptableString = partialString
// Create set of acceptable characters, starting with alpha-numeric ones.
var acceptableCharactersSet:NSMutableCharacterSet = NSCharacterSet.alphanumericCharacterSet().mutableCopy() as NSMutableCharacterSet
// Add whitespace characters (whitespace is not allowed in Ind.ie names
// but we will automatically convert them into dashes when presenting the
// string back to the user. This is a delightful little user experience
// detail where instead of scolding them, we teach them the rules).
acceptableCharactersSet.formUnionWithCharacterSet(NSCharacterSet.whitespaceCharacterSet())
// Add the hyphen character
acceptableCharactersSet.formUnionWithCharacterSet(NSCharacterSet(charactersInString: "-"))
// Make a set of unacceptable characters by inverting the acceptable ones.
var unacceptableCharactersSet:NSMutableCharacterSet = acceptableCharactersSet.mutableCopy() as NSMutableCharacterSet
unacceptableCharactersSet.invert()
var acceptableString:String = (partialString.componentsSeparatedByCharactersInSet(unacceptableCharactersSet) as NSArray).componentsJoinedByString("")
if acceptableString == partialString {
println("Partial string is a valid Ind.ie name")
// // 1. Convert it to lowercase.
// var acceptableString = acceptableString.lowercaseString
//
// // 2. Replace whitespace with hyphens.
// acceptableString = acceptableString.stringByReplacingOccurrencesOfString(" ", withString: "-", options: NSStringCompareOptions.allZeros, range: nil)
//
// //
// // 3. Remove redundant hyphens.
// //
// var error:NSError?
// let regex = NSRegularExpression(pattern: "(-+)", options: NSRegularExpressionOptions.DotMatchesLineSeparators, error: &error)
//
// if let regex = regex {
// acceptableString = regex.stringByReplacingMatchesInString(acceptableString, options: NSMatchingOptions.allZeros, range: NSMakeRange(0, countElements(acceptableString)), withTemplate: "-")
// } else {
// fatalError("Regular expression in IndieNameFormatter.isPartialStringValid…() failed.")
// }
//
// println ("String length: \(countElements(acceptableString))")
//
// if countElements(acceptableString) > 10 {
// println("String >\(acceptableString)< above character limit.")
// let maximumAllowableLengthIndex:String.Index = advance(acceptableString.startIndex, 10)
// acceptableString = acceptableString.substringToIndex(maximumAllowableLengthIndex)
// println("Truncated it to >\(acceptableString)<")
// }
//
println("isPartialStringValid: indieName = \(acceptableString)")
// let newStringToReturn:String = acceptableString.copy() as String
// newString.memory = newStringToReturn
return true
} else {
println("Partial string is not a valid Ind.ie name")
return false
}
}
//
// MARK: - Massage display
//
//////////////////////////////////////////////////////////////////////
//
// Massage what has been entered to make it conform to a valid
// Ind.ie name. Currently:
//
// 1. Convert it into lowercase (as they are also used as subdomains
// and we don’t want to deal with case-sensitivity-based phishing/
// impersonations, etc.)
//
// 2. Replace whitespace with hyphens.
//
// 3. Remove redundant hyphens. (We only allow a single hyphen
// between characters in Ind.ie names.)
//
//////////////////////////////////////////////////////////////////////
override func stringForObjectValue(obj: AnyObject?) -> String? {
switch (obj) {
case nil:
println("stringForObjectValue: obj is nil, returning nil")
return nil
case let indieName as String:
// return indieName
// 1. Convert it to lowercase.
var massagedIndieName = indieName.lowercaseString
// 2. Replace whitespace with hyphens.
massagedIndieName = massagedIndieName.stringByReplacingOccurrencesOfString(" ", withString: "-", options: NSStringCompareOptions.allZeros, range: nil)
//
// 3. Remove redundant hyphens.
//
var error:NSError?
let regex = NSRegularExpression(pattern: "(-+)", options: NSRegularExpressionOptions.DotMatchesLineSeparators, error: &error)
if let regex = regex {
massagedIndieName = regex.stringByReplacingMatchesInString(massagedIndieName, options: NSMatchingOptions.allZeros, range: NSMakeRange(0, countElements(massagedIndieName)), withTemplate: "-")
} else {
fatalError("Regular expression in IndieNameFormatter.stringForObjectValue() failed.")
}
println ("String length: \(countElements(massagedIndieName))")
if countElements(massagedIndieName) > 10 {
println("String >\(massagedIndieName)< above character limit.")
let maximumAllowableLengthIndex:String.Index = advance(massagedIndieName.startIndex, 10)
massagedIndieName = massagedIndieName.substringToIndex(maximumAllowableLengthIndex)
println("Truncated it to >\(massagedIndieName)<")
}
println("stringForObjectValue: indieName = \(massagedIndieName)")
return massagedIndieName
default:
println("stringForObjectValue: obj is not string, returning nil")
return nil
}
}
// MARK: - Unimportant but necessary.
//
// A standard override that we have to implement but which we’re not really using.
//
override func getObjectValue(obj: AutoreleasingUnsafeMutablePointer<AnyObject?>, forString string: String, errorDescription error: AutoreleasingUnsafeMutablePointer<NSString?>) -> Bool {
println("getObjectValue: \(string)")
// Thanks to: http://stackoverflow.com/a/27868984/253485
let stringToReturn:String = string.copy() as String
obj.memory = stringToReturn
return true
}
}
......@@ -31,26 +31,32 @@ class StepOneViewController: SetupStepViewController
func textDidChange(notification:NSNotification) {
let textField = (notification.object as NSTextField)
println("New text: \(textField.stringValue)")
// Resize text field test
//
// With help from:
// http://stackoverflow.com/questions/14643180/nstextfield-width-and-autolayout
//
// println("Text did change: \(notification)")
let textField = (notification.object as NSTextField)
textField.sizeToFit()
var newTextFieldWidth = NSWidth(textField.frame)
// println("> \(newTextFieldWidth)")
if newTextFieldWidth < 100 {
newTextFieldWidth = 100
}
// if newTextFieldWidth > 200 {
// newTextFieldWidth = 200
//// println("Text did change: \(notification)")
// let textField = (notification.object as NSTextField)
// textField.sizeToFit()
// var newTextFieldWidth = NSWidth(textField.frame)
//
//// println("> \(newTextFieldWidth)")
//
// if newTextFieldWidth < 100 {
// newTextFieldWidth = 100
// }
//
nameTextFieldWidthConstraint.constant = newTextFieldWidth
//// if newTextFieldWidth > 200 {
//// newTextFieldWidth = 200
//// }
////
// nameTextFieldWidthConstraint.constant = newTextFieldWidth
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment