Show search results in timeline. Show selected item in detail view.

This commit is contained in:
Brent Simmons
2019-02-24 22:39:57 -08:00
parent 0a45dda375
commit 315af1ef7f
5 changed files with 110 additions and 53 deletions

View File

@@ -133,7 +133,6 @@
840F7C8321BDA4B40057E851 /* Feed+Scriptability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5F4EDB620074D6500B9E363 /* Feed+Scriptability.swift */; };
840F7C8421BDA4B40057E851 /* AuthorAvatarDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84E850851FCB60CE0072EA88 /* AuthorAvatarDownloader.swift */; };
840F7C8521BDA4B40057E851 /* SingleLineTextFieldSizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84E185B2203B74E500F69BFA /* SingleLineTextFieldSizer.swift */; };
840F7C8621BDA4B40057E851 /* MainWindowController+Toolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849EE71E20391DF20082A1EA /* MainWindowController+Toolbar.swift */; };
840F7C8721BDA4B40057E851 /* TimelineTableCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849A97741ED9EC04007D329B /* TimelineTableCellView.swift */; };
840F7C8821BDA4B40057E851 /* TimelineCellAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849A97701ED9EC04007D329B /* TimelineCellAppearance.swift */; };
840F7C8921BDA4B40057E851 /* InitialFeedDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849A97A01ED9F180007D329B /* InitialFeedDownloader.swift */; };
@@ -266,7 +265,6 @@
849C64681ED37A5D003D8FC0 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 849C64671ED37A5D003D8FC0 /* Assets.xcassets */; };
849C646B1ED37A5D003D8FC0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 849C64691ED37A5D003D8FC0 /* Main.storyboard */; };
849EE70F203919360082A1EA /* AppImages.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849EE70E203919360082A1EA /* AppImages.swift */; };
849EE71F20391DF20082A1EA /* MainWindowController+Toolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849EE71E20391DF20082A1EA /* MainWindowController+Toolbar.swift */; };
849EE72120391F560082A1EA /* SharingServicePickerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849EE72020391F560082A1EA /* SharingServicePickerDelegate.swift */; };
84A14FF320048CA70046AD9A /* SendToMicroBlogCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84A14FF220048CA70046AD9A /* SendToMicroBlogCommand.swift */; };
84A1500320048D660046AD9A /* SendToCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84A1500220048D660046AD9A /* SendToCommand.swift */; };
@@ -862,7 +860,6 @@
849C646C1ED37A5D003D8FC0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = ../Info.plist; sourceTree = "<group>"; };
849C64711ED37A5D003D8FC0 /* NetNewsWireTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NetNewsWireTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
849EE70E203919360082A1EA /* AppImages.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppImages.swift; path = NetNewsWire/AppImages.swift; sourceTree = "<group>"; };
849EE71E20391DF20082A1EA /* MainWindowController+Toolbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainWindowController+Toolbar.swift"; sourceTree = "<group>"; };
849EE72020391F560082A1EA /* SharingServicePickerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharingServicePickerDelegate.swift; sourceTree = "<group>"; };
84A14FF220048CA70046AD9A /* SendToMicroBlogCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendToMicroBlogCommand.swift; sourceTree = "<group>"; };
84A1500220048D660046AD9A /* SendToCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendToCommand.swift; sourceTree = "<group>"; };
@@ -1123,7 +1120,6 @@
849A97B01ED9FA69007D329B /* MainWindow.storyboard */,
842E45E21ED8C681000A8B52 /* KeyboardDelegateProtocol.swift */,
849A975D1ED9EB72007D329B /* MainWindowController.swift */,
849EE71E20391DF20082A1EA /* MainWindowController+Toolbar.swift */,
519B8D322143397200FA689C /* SharingServiceDelegate.swift */,
849EE72020391F560082A1EA /* SharingServicePickerDelegate.swift */,
844B5B6B1FEA224B00C7C76A /* Keyboard */,
@@ -2470,7 +2466,6 @@
840F7C8321BDA4B40057E851 /* Feed+Scriptability.swift in Sources */,
840F7C8421BDA4B40057E851 /* AuthorAvatarDownloader.swift in Sources */,
840F7C8521BDA4B40057E851 /* SingleLineTextFieldSizer.swift in Sources */,
840F7C8621BDA4B40057E851 /* MainWindowController+Toolbar.swift in Sources */,
840F7C8721BDA4B40057E851 /* TimelineTableCellView.swift in Sources */,
840F7C8821BDA4B40057E851 /* TimelineCellAppearance.swift in Sources */,
840F7C8921BDA4B40057E851 /* InitialFeedDownloader.swift in Sources */,
@@ -2598,7 +2593,6 @@
D5F4EDB720074D6500B9E363 /* Feed+Scriptability.swift in Sources */,
84E850861FCB60CE0072EA88 /* AuthorAvatarDownloader.swift in Sources */,
84E185B3203B74E500F69BFA /* SingleLineTextFieldSizer.swift in Sources */,
849EE71F20391DF20082A1EA /* MainWindowController+Toolbar.swift in Sources */,
849A977A1ED9EC04007D329B /* TimelineTableCellView.swift in Sources */,
849A97761ED9EC04007D329B /* TimelineCellAppearance.swift in Sources */,
849A97A21ED9F180007D329B /* InitialFeedDownloader.swift in Sources */,

View File

@@ -52,6 +52,10 @@ final class DetailViewController: NSViewController, WKUIDelegate {
webViewController(for: mode).state = state
}
func showDetail(for mode: TimelineSourceMode) {
currentWebViewController = webViewController(for: mode)
}
func canScrollDown(_ callback: @escaping (Bool) -> Void) {
currentWebViewController.canScrollDown(callback)
}

View File

@@ -1,42 +0,0 @@
//
// MainWindowController+Toolbar.swift
// NetNewsWire
//
// Created by Brent Simmons on 2/17/18.
// Copyright © 2018 Ranchero Software. All rights reserved.
//
import AppKit
extension NSToolbarItem.Identifier {
static let Share = NSToolbarItem.Identifier("share")
static let Search = NSToolbarItem.Identifier("search")
}
extension MainWindowController: NSToolbarDelegate {
func toolbarWillAddItem(_ notification: Notification) {
guard let item = notification.userInfo?["item"] as? NSToolbarItem else {
return
}
if item.itemIdentifier == .Share, let button = item.view as? NSButton {
// The share button should send its action on mouse down, not mouse up.
button.sendAction(on: .leftMouseDown)
}
if item.itemIdentifier == .Search, let searchField = item.view as? NSSearchField {
searchField.delegate = self
}
}
func toolbarDidRemoveItem(_ notification: Notification) {
guard let item = notification.userInfo?["item"] as? NSToolbarItem else {
return
}
if item.itemIdentifier == .Search, let searchField = item.view as? NSSearchField {
searchField.delegate = nil
}
}
}

View File

@@ -37,6 +37,16 @@ class MainWindowController : NSWindowController, NSUserInterfaceValidations, NSW
private var sidebarViewController: SidebarViewController?
private var timelineContainerViewController: TimelineContainerViewController?
private var detailViewController: DetailViewController?
private var currentSearchField: NSSearchField? = nil
private var searchString: String? = nil
private var lastSentSearchString: String? = nil
private var timelineSourceMode: TimelineSourceMode = .regular {
didSet {
timelineContainerViewController?.showTimeline(for: timelineSourceMode)
detailViewController?.showDetail(for: timelineSourceMode)
}
}
private var searchSmartFeed: SmartFeed? = nil
// MARK: - NSWindowController
@@ -353,7 +363,7 @@ extension MainWindowController: SidebarDelegate {
func sidebarSelectionDidChange(_: SidebarViewController, selectedObjects: [AnyObject]?) {
// TODO: if searching, cancel search
timelineContainerViewController?.setRepresentedObjects(selectedObjects, mode: .regular)
timelineContainerViewController?.showTimeline(.regular)
forceSearchToEnd()
updateWindowTitle()
NotificationCenter.default.post(name: .InspectableObjectsDidChange, object: nil)
}
@@ -380,11 +390,61 @@ extension MainWindowController: TimelineContainerViewControllerDelegate {
extension MainWindowController: NSSearchFieldDelegate {
func searchFieldDidStartSearching(_ sender: NSSearchField) {
// TODO
startSearchingIfNeeded()
}
func searchFieldDidEndSearching(_ sender: NSSearchField) {
// TODO
stopSearchingIfNeeded()
}
@IBAction func runSearch(_ sender: NSSearchField) {
if sender.stringValue == "" {
return
}
startSearchingIfNeeded()
handleSearchFieldTextChange(sender)
}
private func handleSearchFieldTextChange(_ searchField: NSSearchField) {
let s = searchField.stringValue
if s == searchString {
return
}
searchString = s
updateSmartFeed()
}
func updateSmartFeed() {
guard timelineSourceMode == .search, let searchString = searchString else {
return
}
if searchString == lastSentSearchString {
return
}
lastSentSearchString = searchString
let smartFeed = SmartFeed(delegate: SearchFeedDelegate(searchString: searchString))
timelineContainerViewController?.setRepresentedObjects([smartFeed], mode: .search)
searchSmartFeed = smartFeed
}
func forceSearchToEnd() {
timelineSourceMode = .regular
searchString = nil
lastSentSearchString = nil
if let searchField = currentSearchField {
searchField.stringValue = ""
}
}
private func startSearchingIfNeeded() {
timelineSourceMode = .search
}
private func stopSearchingIfNeeded() {
searchString = nil
lastSentSearchString = nil
timelineSourceMode = .regular
timelineContainerViewController?.setRepresentedObjects(nil, mode: .search)
}
}
@@ -409,6 +469,47 @@ extension MainWindowController : ScriptingMainWindowController {
}
}
// MARK: - NSToolbarDelegate
extension NSToolbarItem.Identifier {
static let Share = NSToolbarItem.Identifier("share")
static let Search = NSToolbarItem.Identifier("search")
}
extension MainWindowController: NSToolbarDelegate {
func toolbarWillAddItem(_ notification: Notification) {
guard let item = notification.userInfo?["item"] as? NSToolbarItem else {
return
}
if item.itemIdentifier == .Share, let button = item.view as? NSButton {
// The share button should send its action on mouse down, not mouse up.
button.sendAction(on: .leftMouseDown)
}
if item.itemIdentifier == .Search, let searchField = item.view as? NSSearchField {
searchField.delegate = self
searchField.target = self
searchField.action = #selector(runSearch(_:))
currentSearchField = searchField
}
}
func toolbarDidRemoveItem(_ notification: Notification) {
guard let item = notification.userInfo?["item"] as? NSToolbarItem else {
return
}
if item.itemIdentifier == .Search, let searchField = item.view as? NSSearchField {
searchField.delegate = nil
searchField.target = nil
searchField.action = nil
currentSearchField = nil
}
}
}
// MARK: - Private
private extension MainWindowController {

View File

@@ -39,7 +39,7 @@ final class TimelineContainerViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
setRepresentedObjects(nil, mode: .regular)
showTimeline(.regular)
showTimeline(for: .regular)
}
// MARK: - API
@@ -48,7 +48,7 @@ final class TimelineContainerViewController: NSViewController {
timelineViewController(for: mode).representedObjects = objects
}
func showTimeline(_ mode: TimelineSourceMode) {
func showTimeline(for mode: TimelineSourceMode) {
currentTimelineViewController = timelineViewController(for: mode)
}
}