Skip to content

Commit

Permalink
Merge branch 'setlocation'
Browse files Browse the repository at this point in the history
  • Loading branch information
insidegui committed Dec 10, 2016
2 parents 2e30167 + 1aeaf10 commit 967eeba
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 56 deletions.
8 changes: 4 additions & 4 deletions PlayAways.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
9893205A1DFB6085003A20A3 /* PersistenceHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 989320591DFB6085003A20A3 /* PersistenceHelper.swift */; };
DD7A4F181DF9FBB80015054B /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD7A4F171DF9FBB80015054B /* AppDelegate.swift */; };
DD7A4F1C1DF9FBB80015054B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DD7A4F1B1DF9FBB80015054B /* Assets.xcassets */; };
DD7A4F2B1DF9FC280015054B /* AppRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD7A4F2A1DF9FC280015054B /* AppRouter.swift */; };
Expand All @@ -20,7 +21,6 @@
DD7A4F4D1DFA01020015054B /* PlayAlwaysMaker.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD7A4F4C1DFA01020015054B /* PlayAlwaysMaker.swift */; };
DD7A4F4F1DFA01760015054B /* MainWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD7A4F4E1DFA01760015054B /* MainWindowController.swift */; };
DD7A4F511DFA017C0015054B /* PlaygroundViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD7A4F501DFA017C0015054B /* PlaygroundViewController.swift */; };
DD7A4F541DFA02670015054B /* FinderHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD7A4F531DFA02670015054B /* FinderHelper.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -48,6 +48,7 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
989320591DFB6085003A20A3 /* PersistenceHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PersistenceHelper.swift; sourceTree = "<group>"; };
DD7A4F141DF9FBB80015054B /* PlayAways.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PlayAways.app; sourceTree = BUILT_PRODUCTS_DIR; };
DD7A4F171DF9FBB80015054B /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
DD7A4F1B1DF9FBB80015054B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
Expand All @@ -63,7 +64,6 @@
DD7A4F4C1DFA01020015054B /* PlayAlwaysMaker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlayAlwaysMaker.swift; sourceTree = "<group>"; };
DD7A4F4E1DFA01760015054B /* MainWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainWindowController.swift; sourceTree = "<group>"; };
DD7A4F501DFA017C0015054B /* PlaygroundViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlaygroundViewController.swift; sourceTree = "<group>"; };
DD7A4F531DFA02670015054B /* FinderHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FinderHelper.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -174,7 +174,7 @@
DD7A4F521DFA02580015054B /* Helpers */ = {
isa = PBXGroup;
children = (
DD7A4F531DFA02670015054B /* FinderHelper.swift */,
989320591DFB6085003A20A3 /* PersistenceHelper.swift */,
);
name = Helpers;
sourceTree = "<group>";
Expand Down Expand Up @@ -301,8 +301,8 @@
DD7A4F4F1DFA01760015054B /* MainWindowController.swift in Sources */,
DD7A4F511DFA017C0015054B /* PlaygroundViewController.swift in Sources */,
DD7A4F2F1DF9FCED0015054B /* StatusItemController.swift in Sources */,
DD7A4F541DFA02670015054B /* FinderHelper.swift in Sources */,
DD7A4F4D1DFA01020015054B /* PlayAlwaysMaker.swift in Sources */,
9893205A1DFB6085003A20A3 /* PersistenceHelper.swift in Sources */,
DD7A4F2B1DF9FC280015054B /* AppRouter.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
10 changes: 9 additions & 1 deletion PlayAways/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ class AppDelegate: NSObject, NSApplicationDelegate {
private var router: AppRouter!

func applicationDidFinishLaunching(_ aNotification: Notification) {
self.router = AppRouter(statusItemController: StatusItemController(), playgroundMaker: PlayAlwaysMaker())
self.router = AppRouter(
statusItemController: StatusItemController(),
playgroundMaker: PlayAlwaysMaker(),
persistence: PersistenceHelper(storage: UserDefaults.standard)
)
}

@IBAction func createNewPlayground(sender: NSMenuItem) {
Expand All @@ -25,5 +29,9 @@ class AppDelegate: NSObject, NSApplicationDelegate {

router.createPlayground(with: options)
}

@IBAction func setPath(_ sender: NSMenuItem) {
_ = router.storageLocationShowingPanelIfNeeded(force: true)
}
}

78 changes: 53 additions & 25 deletions PlayAways/AppRouter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ final class AppRouter {

private let statusItemController: StatusItemController
private let playgroundMaker: PlaygroundMaker
private let persistence: PersistenceHelper

init(statusItemController: StatusItemController, playgroundMaker: PlaygroundMaker) {
init(statusItemController: StatusItemController, playgroundMaker: PlaygroundMaker, persistence: PersistenceHelper) {
self.statusItemController = statusItemController
self.playgroundMaker = playgroundMaker
self.persistence = persistence
}

func createPlayground(with options: MenuOptions) {
Expand Down Expand Up @@ -52,45 +54,71 @@ final class AppRouter {

guard let url = panel.url else { return }

createPlayground(for: platform, at: url)
createPlayground(for: platform, at: url, usingDefaultName: false)
} else {
createPlayground(for: platform, at: nil)
let url = storageLocationShowingPanelIfNeeded()

createPlayground(for: platform, at: url, usingDefaultName: true)
}

}

private func createPlayground(for platform: PlaygroundPlatform, at location: URL?) {
private func createPlayground(for platform: PlaygroundPlatform, at location: URL?, usingDefaultName defaultName: Bool) {
var playgroundUrl: URL?

if let location = location {
let directory = location.deletingLastPathComponent().path
let name = location.deletingPathExtension().lastPathComponent

do {
playgroundUrl = try playgroundMaker.createPlayground(named: name, at: directory, platform: platform)
} catch {
handle(error)
}
guard let location = location else {
// cancelled
return
}

let directory = defaultName ? location.path : location.deletingLastPathComponent().path

let name: String?

if defaultName {
name = nil
} else {
guard let desktopDir = NSSearchPathForDirectoriesInDomains(.desktopDirectory, .userDomainMask, true).first else {
NSLog("NSSearchPathForDirectoriesInDomains returned nil for desktop dir, this should never happen!")
return
}

let directory = FinderHelper.getFrontmostFinderWindowLocation(fallback: desktopDir)

do {
playgroundUrl = try playgroundMaker.createPlayground(named: nil, at: directory, platform: platform)
} catch {
handle(error)
}
name = location.deletingPathExtension().lastPathComponent
}

do {
playgroundUrl = try playgroundMaker.createPlayground(named: name, at: directory, platform: platform)
} catch {
handle(error)
}

if let url = playgroundUrl {
NSWorkspace.shared().open(url)
}
}

func storageLocationShowingPanelIfNeeded(force: Bool = false) -> URL? {
if let path = persistence.storagePath, !force {
return URL(fileURLWithPath: path)
} else {
let url = runStorageLocationPanel()
persistence.storagePath = url?.path

return url
}
}

private func runStorageLocationPanel() -> URL? {
let panel = NSOpenPanel()

panel.prompt = NSLocalizedString("Select", comment: "Select (open panel button to set storage location)")
panel.canChooseDirectories = true
panel.canCreateDirectories = true
panel.canChooseFiles = false
panel.title = NSLocalizedString("Select a location to create playgrounds into", comment: "Select a location to create playgrounds into")

if panel.runModal() != NSFileHandlingPanelOKButton {
return nil
} else {
return panel.url
}
}

private func handle(_ error: Error) {
NSAlert(error: error).runModal()
}
Expand Down
26 changes: 0 additions & 26 deletions PlayAways/FinderHelper.swift

This file was deleted.

63 changes: 63 additions & 0 deletions PlayAways/PersistenceHelper.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//
// PersistenceHelper.swift
// PlayAways
//
// Created by Leonardo Cardoso on 09/12/2016.
// Copyright © 2016 Guilherme Rambo. All rights reserved.
//

import Foundation

protocol DefaultsStorage {
func synchronize() -> Bool
func set(_ value: Any?, forKey defaultName: String)
func removeObject(forKey defaultName: String)
func object(forKey defaultName: String) -> Any?
}

extension UserDefaults: DefaultsStorage { }
extension NSUbiquitousKeyValueStore: DefaultsStorage { }

final class PersistenceHelper {

fileprivate let storage: DefaultsStorage

init(storage: DefaultsStorage) {
self.storage = storage
}

func save(value: AnyObject, key: String) {
storage.set(value, forKey: key)
}

func read(key: String) -> AnyObject? {
return storage.object(forKey: key) as AnyObject?
}

func remove(key: String) {
storage.removeObject(forKey: key)
}

}

extension PersistenceHelper {

private struct Keys {
static let storagePath = "PlayPath"
}

class var userDefaults: PersistenceHelper {
return PersistenceHelper(storage: UserDefaults.standard)
}

/// The path where the app will store the user's playgrounds by default
var storagePath: String? {
get {
return storage.object(forKey: Keys.storagePath) as? String
}
set {
storage.set(newValue, forKey: Keys.storagePath)
}
}

}
14 changes: 14 additions & 0 deletions PlayAways/StatusItemController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,36 +22,50 @@ final class StatusItemController {
private let menu: NSMenu = {
let m = NSMenu(title: "PlayAlways")

// New iOS Playground
let newEmbeddedItem = NSMenuItem(title: NSLocalizedString("New iOS Playground", comment: "New iOS Playgroud menu item"), action: #selector(AppDelegate.createNewPlayground(sender:)), keyEquivalent: "1")
newEmbeddedItem.tag = MenuOptions.iOS.rawValue
m.addItem(newEmbeddedItem)

// New iOS Playground (with path selection)
let newEmbeddedItemAlternate = NSMenuItem(title: NSLocalizedString("New iOS Playground…", comment: "New iOS Playgroud menu item (alternate, with ellipsis)"), action: #selector(AppDelegate.createNewPlayground(sender:)), keyEquivalent: "1")
newEmbeddedItemAlternate.tag = MenuOptions.iOSWithPanel.rawValue
newEmbeddedItemAlternate.isAlternate = true
newEmbeddedItemAlternate.keyEquivalentModifierMask = [.command, .option]
m.addItem(newEmbeddedItemAlternate)

// New macOS Playground
let newMacItem = NSMenuItem(title: NSLocalizedString("New macOS Playground", comment: "New macOS Playgroud menu item"), action: #selector(AppDelegate.createNewPlayground(sender:)), keyEquivalent: "2")
newMacItem.tag = MenuOptions.macOS.rawValue
m.addItem(newMacItem)

// New macOS Playground (with path selection)
let newMacItemAlternate = NSMenuItem(title: NSLocalizedString("New macOS Playground…", comment: "New macOS Playgroud menu item (alternate, with ellipsis)"), action: #selector(AppDelegate.createNewPlayground(sender:)), keyEquivalent: "2")
newMacItemAlternate.tag = MenuOptions.macOSWithPanel.rawValue
newMacItemAlternate.isAlternate = true
newMacItemAlternate.keyEquivalentModifierMask = [.command, .option]
m.addItem(newMacItemAlternate)

// New tvOS Playground
let newTVItem = NSMenuItem(title: NSLocalizedString("New tvOS Playground", comment: "New tvOS Playgroud menu item"), action: #selector(AppDelegate.createNewPlayground(sender:)), keyEquivalent: "3")
newTVItem.tag = MenuOptions.tvOS.rawValue
m.addItem(newTVItem)

// New tvOS Playground (with path selection)
let newTVItemAlternate = NSMenuItem(title: NSLocalizedString("New tvOS Playground…", comment: "New tvOS Playgroud menu item (alternate, with ellipsis)"), action: #selector(AppDelegate.createNewPlayground(sender:)), keyEquivalent: "3")
newTVItemAlternate.tag = MenuOptions.tvOSWithPanel.rawValue
newTVItemAlternate.isAlternate = true
newTVItemAlternate.keyEquivalentModifierMask = [.command, .option]
m.addItem(newTVItemAlternate)

// Separator
m.addItem(NSMenuItem.separator())

// Set Path
let pathItem = NSMenuItem(title: NSLocalizedString("Set Path…", comment: "Set Path…"), action: #selector(AppDelegate.setPath(_:)), keyEquivalent: "p")
m.addItem(pathItem)

// Quit
let quitItem = NSMenuItem(title: NSLocalizedString("Quit", comment: "Quit"), action: #selector(NSApplication.terminate(_:)), keyEquivalent: "q")
m.addItem(quitItem)

Expand Down

0 comments on commit 967eeba

Please sign in to comment.