diff --git a/NicoDownloader/Base.lproj/Main.storyboard b/NicoDownloader/Base.lproj/Main.storyboard index 5db5673..b0487f2 100644 --- a/NicoDownloader/Base.lproj/Main.storyboard +++ b/NicoDownloader/Base.lproj/Main.storyboard @@ -1,8 +1,9 @@ - + + @@ -442,11 +443,11 @@ - + - + @@ -454,7 +455,7 @@ - + @@ -462,7 +463,7 @@ - + @@ -473,7 +474,7 @@ - + @@ -487,23 +488,23 @@ - + - + - + @@ -511,7 +512,7 @@ - + @@ -525,7 +526,7 @@ - + @@ -533,7 +534,7 @@ - + @@ -563,7 +564,7 @@ - + @@ -575,7 +576,7 @@ - + @@ -591,6 +592,7 @@ + @@ -598,7 +600,7 @@ - + @@ -606,7 +608,7 @@ - + @@ -616,56 +618,130 @@ - + + + + + + + + + + + + - + - - - + + + - + - + + + + + + + - + + - + + + + + + @@ -679,7 +755,7 @@ - + @@ -789,8 +865,8 @@ - - + + @@ -920,5 +996,18 @@ + + + + + + + + + + + + + diff --git a/NicoDownloader/Extensions/ProgressViewController+Download.swift b/NicoDownloader/Extensions/ProgressViewController+Download.swift index ab3e864..63844f1 100644 --- a/NicoDownloader/Extensions/ProgressViewController+Download.swift +++ b/NicoDownloader/Extensions/ProgressViewController+Download.swift @@ -104,7 +104,7 @@ extension ProgressViewController { func download() { self.updateStatusMessage(message: "Downloading items...") downloadWorkItem = DispatchWorkItem { - let semaphore = DispatchSemaphore(value: 1) + let semaphore = DispatchSemaphore(value: self.options.concurrentDownloadCount - 1) for (idx, item) in self.items.enumerated() { Thread.sleep(forTimeInterval: 3) self.items[idx].status = .fetching @@ -115,7 +115,7 @@ extension ProgressViewController { self.items[idx].videoUrl = url return self.prefetchVideoPage(videoId: item.videoId) }.then { title -> Promise in - self.items[idx].name = title + self.items[idx].name = self.items[idx].name ?? title self.items[idx].status = .downloading return self.downloadVideo(item: self.items[idx], url: self.items[idx].videoUrl!, progressCallback: { self.items[idx].progress = $0 diff --git a/NicoDownloader/Extensions/ProgressViewController+Tableview.swift b/NicoDownloader/Extensions/ProgressViewController+Tableview.swift index fb4e99c..a8e1b6b 100644 --- a/NicoDownloader/Extensions/ProgressViewController+Tableview.swift +++ b/NicoDownloader/Extensions/ProgressViewController+Tableview.swift @@ -32,7 +32,7 @@ extension ProgressViewController: NSTableViewDelegate { } case tableView.tableColumns[1]: if let cell = tableView.make(withIdentifier: CellIdentifiers.TitleCell, owner: nil) as? NSTableCellView { - cell.textField?.stringValue = item.name + cell.textField?.stringValue = item.name ?? "Unknown" return cell } case tableView.tableColumns[2]: diff --git a/NicoDownloader/Info.plist b/NicoDownloader/Info.plist index f0887a8..c2084ac 100644 --- a/NicoDownloader/Info.plist +++ b/NicoDownloader/Info.plist @@ -2,11 +2,6 @@ - NSAppTransportSecurity - - NSAllowsArbitraryLoads - - CFBundleDevelopmentRegion en CFBundleExecutable @@ -22,11 +17,16 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.0 + 1.0.1 CFBundleVersion - 1 + 2 LSMinimumSystemVersion $(MACOSX_DEPLOYMENT_TARGET) + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + NSHumanReadableCopyright Copyright © 2017년 Jeong. All rights reserved. NSMainStoryboardFile diff --git a/NicoDownloader/Metadata.swift b/NicoDownloader/Metadata.swift index 455da49..643c91c 100644 --- a/NicoDownloader/Metadata.swift +++ b/NicoDownloader/Metadata.swift @@ -15,10 +15,12 @@ struct Account { struct Options { let videoInfo: VideoInfo + let concurrentDownloadCount: Int var saveDirectory: URL = FileManager.default.urls(for: .downloadsDirectory, in: .userDomainMask)[0] - init(videoInfo: VideoInfo) { + init(videoInfo: VideoInfo, concurrentDownloadCount: Int) { self.videoInfo = videoInfo + self.concurrentDownloadCount = concurrentDownloadCount } } diff --git a/NicoDownloader/Models/Item.swift b/NicoDownloader/Models/Item.swift index 53ac773..32eb2ff 100644 --- a/NicoDownloader/Models/Item.swift +++ b/NicoDownloader/Models/Item.swift @@ -33,7 +33,7 @@ enum Status { struct Item { let videoId: String - var name: String + var name: String! var pubdate: Date? var status: Status = .sleeping var videoUrl: String? @@ -42,7 +42,6 @@ struct Item { init(videoId: String) { self.videoId = videoId - self.name = "Unknown" } init(videoId: String, name: String, pubdate: Date) { diff --git a/NicoDownloader/ViewControllers/ViewController.swift b/NicoDownloader/ViewControllers/ViewController.swift index fdc4881..f91e3b9 100644 --- a/NicoDownloader/ViewControllers/ViewController.swift +++ b/NicoDownloader/ViewControllers/ViewController.swift @@ -21,6 +21,10 @@ class ViewController: NSViewController { @IBOutlet weak var rememberAccountCheckbox: NSButton! @IBOutlet weak var modeTabView: NSTabView! @IBOutlet weak var videoIdsTextField: NSTextField! + @IBOutlet weak var advancedOptionsBox: NSBox! + @IBOutlet weak var advancedOptionsDisclosure: NSButton! + @IBOutlet weak var advancedOptionHeightConstraint: NSLayoutConstraint! + @IBOutlet weak var concurrentDownloadCountButton: NSPopUpButton! var sessionManager: SessionManager! var saveDirectory: URL? @@ -38,6 +42,8 @@ class ViewController: NSViewController { if let saveDirectory = UserDefaults.standard.url(forKey: "saveDirectory") { setSaveDirectory(url: saveDirectory) } + + toggleAdvancedOptions(animate: false) } override func viewDidAppear() { @@ -51,8 +57,10 @@ class ViewController: NSViewController { } override func prepare(for segue: NSStoryboardSegue, sender: Any?) { - guard let segID = segue.identifier, segID == "showDownloadController", let dest = segue.destinationController as? ProgressViewController else { - return + guard let segID = segue.identifier, segID == "showDownloadController", + let dest = segue.destinationController as? ProgressViewController, + let options = createOptions() else { + return } let account = Account(email: emailField.stringValue, password: passwordField.stringValue) @@ -63,7 +71,7 @@ class ViewController: NSViewController { } dest.account = account - dest.options = createOptions() + dest.options = options } @IBAction func chooseDirectoryButtonDidTap(_ sender: Any) { @@ -73,7 +81,7 @@ class ViewController: NSViewController { } } - private func createOptions() -> Options { + private func createOptions() -> Options? { let videoInfo: VideoInfo switch modeTabView.selectedTabViewItem?.label { case .some("Video"): @@ -86,8 +94,12 @@ class ViewController: NSViewController { } videoInfo = mylist } + guard let concurrentDownloadCountString = concurrentDownloadCountButton.selectedItem?.title, + let concurrentDownloadCount = Int(concurrentDownloadCountString) else { + return nil + } - var options = Options(videoInfo: videoInfo) + var options = Options(videoInfo: videoInfo, concurrentDownloadCount: concurrentDownloadCount) if let saveDirectory = saveDirectory { options.saveDirectory = saveDirectory @@ -100,5 +112,20 @@ class ViewController: NSViewController { saveDirectory = url selectedDirectoryTextField.stringValue = url.path } + + @IBAction func advancedOptionsDidClick(_ sender: Any) { + toggleAdvancedOptions() + } + + private func toggleAdvancedOptions(animate: Bool = true) { + let show = advancedOptionHeightConstraint.constant == 0 + let constraint = animate ? advancedOptionHeightConstraint.animator() : advancedOptionHeightConstraint + let box = animate ? advancedOptionsBox.animator() : advancedOptionsBox + let disclosure = animate ? advancedOptionsDisclosure.animator() : advancedOptionsDisclosure + + constraint!.constant = show ? 34 : 0 + box!.isHidden = !show + disclosure!.state = show ? NSOnState : NSOffState + } }