More catalyst toolbar stuff
This commit is contained in:
parent
1d2e666c00
commit
36fda4d51f
|
@ -13,6 +13,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|||
var window: UIWindow?
|
||||
|
||||
private(set) var fervorController: FervorController!
|
||||
private(set) var toggleReadBarButtonItem: UIBarButtonItem?
|
||||
|
||||
private let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "SceneDelegate")
|
||||
|
||||
|
@ -144,23 +145,31 @@ extension SceneDelegate: HomeViewControllerDelegate {
|
|||
#if targetEnvironment(macCatalyst)
|
||||
extension NSToolbarItem.Identifier {
|
||||
static let toggleItemRead = NSToolbarItem.Identifier("ToggleItemRead")
|
||||
static let shareItem = NSToolbarItem.Identifier("ShareItem")
|
||||
}
|
||||
|
||||
extension SceneDelegate: NSToolbarDelegate {
|
||||
func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier, willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? {
|
||||
let item = NSToolbarItem(itemIdentifier: .toggleItemRead)
|
||||
item.target = nil
|
||||
item.action = #selector(AppSplitViewController.toggleItemRead)
|
||||
item.image = UIImage(systemName: "checkmark.circle")
|
||||
return item
|
||||
if itemIdentifier == .toggleItemRead {
|
||||
// need an item bar button item to make the size of the image match the share button
|
||||
let item = NSToolbarItem(itemIdentifier: .toggleItemRead, barButtonItem: UIBarButtonItem(image: nil, style: .plain, target: nil, action: nil))
|
||||
item.image = UIImage(systemName: "checkmark.circle")
|
||||
item.target = nil
|
||||
item.action = #selector(ReadViewController.toggleItemRead(_:))
|
||||
return item
|
||||
} else if itemIdentifier == .shareItem {
|
||||
return NSSharingServicePickerToolbarItem(itemIdentifier: .shareItem)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
|
||||
return [.toggleItemRead]
|
||||
return [.shareItem, .toggleItemRead]
|
||||
}
|
||||
|
||||
func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
|
||||
return [.toggleItemRead]
|
||||
return [.shareItem, .toggleItemRead]
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -51,55 +51,12 @@ class AppSplitViewController: UISplitViewController {
|
|||
let nav = AppNavigationController(rootViewController: home)
|
||||
setViewController(nav, for: .compact)
|
||||
}
|
||||
|
||||
#if targetEnvironment(macCatalyst)
|
||||
@objc func toggleItemRead(_ item: NSToolbarItem) {
|
||||
guard let nav = viewController(for: .secondary) as? UINavigationController,
|
||||
let read = nav.topViewController as? ReadViewController else {
|
||||
return
|
||||
}
|
||||
Task {
|
||||
await fervorController.markItem(read.item, read: !read.item.read)
|
||||
updateImage(toolbarItem: item)
|
||||
}
|
||||
}
|
||||
|
||||
private func updateImage(toolbarItem: NSToolbarItem) {
|
||||
if let nav = viewController(for: .secondary) as? UINavigationController,
|
||||
let read = nav.topViewController as? ReadViewController {
|
||||
toolbarItem.image = UIImage(systemName: read.item.read ? "checkmark.circle.fill" : "checkmark.circle")
|
||||
} else {
|
||||
toolbarItem.image = UIImage(systemName: "checkmark.circle")
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
extension AppSplitViewController: ItemsViewControllerDelegate {
|
||||
func showReadItem(_ item: Item) {
|
||||
secondaryNav.setViewControllers([ReadViewController(item: item, fervorController: fervorController)], animated: false)
|
||||
|
||||
#if targetEnvironment(macCatalyst)
|
||||
if let titlebar = view.window?.windowScene?.titlebar,
|
||||
let toggleRead = titlebar.toolbar?.items.first(where: { $0.itemIdentifier == .toggleItemRead }) {
|
||||
updateImage(toolbarItem: toggleRead)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if targetEnvironment(macCatalyst)
|
||||
extension AppSplitViewController {
|
||||
override func responds(to aSelector: Selector!) -> Bool {
|
||||
if aSelector == #selector(toggleItemRead) {
|
||||
guard let nav = viewController(for: .secondary) as? UINavigationController else {
|
||||
return false
|
||||
}
|
||||
return nav.topViewController is ReadViewController
|
||||
} else {
|
||||
return super.responds(to: aSelector)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -87,18 +87,21 @@ class ItemCollectionViewCell: UICollectionViewListCell {
|
|||
}
|
||||
|
||||
func setRead(_ read: Bool, animated: Bool) {
|
||||
guard self.item.read != read else { return }
|
||||
Task {
|
||||
await self.delegate?.fervorController.markItem(self.item, read: read)
|
||||
|
||||
if animated {
|
||||
// i don't know why .transition works but .animate doesn't
|
||||
UIView.transition(with: self, duration: 0.2, options: .transitionCrossDissolve) {
|
||||
self.updateColors()
|
||||
}
|
||||
} else {
|
||||
updateColors()
|
||||
guard item.read != read else { return }
|
||||
|
||||
item.read = read
|
||||
|
||||
if animated {
|
||||
// i don't know why .transition works but .animate doesn't
|
||||
UIView.transition(with: self, duration: 0.2, options: .transitionCrossDissolve) {
|
||||
self.updateColors()
|
||||
}
|
||||
} else {
|
||||
updateColors()
|
||||
}
|
||||
|
||||
Task {
|
||||
await delegate?.fervorController.markItem(item, read: read)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -127,16 +127,21 @@ extension ItemsViewController: UICollectionViewDelegate {
|
|||
return UIContextMenuConfiguration(identifier: nil, previewProvider: {
|
||||
ReadViewController(item: item, fervorController: self.fervorController)
|
||||
}, actionProvider: { _ in
|
||||
var children: [UIAction] = []
|
||||
var children: [UIMenuElement] = []
|
||||
if let url = item.url {
|
||||
children.append(UIAction(title: "Open in Safari", image: UIImage(systemName: "safari"), handler: { [weak self] _ in
|
||||
let vc = SFSafariViewController(url: url)
|
||||
vc.preferredControlTintColor = .appTintColor
|
||||
self?.present(vc, animated: true)
|
||||
}))
|
||||
#if targetEnvironment(macCatalyst)
|
||||
self.activityItemsConfiguration = UIActivityItemsConfiguration(objects: [url as NSURL])
|
||||
children.append(UICommand(title: "Share…", action: Selector(("unused")), propertyList: UICommandTagShare))
|
||||
#else
|
||||
children.append(UIAction(title: "Share", image: UIImage(systemName: "square.and.arrow.up"), handler: { [weak self] _ in
|
||||
self?.present(UIActivityViewController(activityItems: [url], applicationActivities: nil), animated: true)
|
||||
}))
|
||||
#endif
|
||||
}
|
||||
if item.read {
|
||||
children.append(UIAction(title: "Mark as Unread", image: UIImage(systemName: "checkmark.circle"), handler: { [unowned self] _ in
|
||||
|
|
|
@ -22,6 +22,10 @@ class ReadViewController: UIViewController {
|
|||
let fervorController: FervorController
|
||||
let item: Item
|
||||
|
||||
#if targetEnvironment(macCatalyst)
|
||||
private var itemReadObservation: NSKeyValueObservation?
|
||||
#endif
|
||||
|
||||
override var prefersStatusBarHidden: Bool {
|
||||
navigationController?.isNavigationBarHidden ?? false
|
||||
}
|
||||
|
@ -68,6 +72,15 @@ class ReadViewController: UIViewController {
|
|||
webView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
|
||||
])
|
||||
|
||||
if let url = item.url {
|
||||
activityItemsConfiguration = UIActivityItemsConfiguration(objects: [url as NSURL])
|
||||
}
|
||||
|
||||
#if targetEnvironment(macCatalyst)
|
||||
itemReadObservation = item.observe(\.read) { [unowned self] _, _ in
|
||||
self.updateToggleReadToolbarImage()
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private static let css = try! String(contentsOf: Bundle.main.url(forResource: "read", withExtension: "css")!)
|
||||
|
@ -125,6 +138,24 @@ class ReadViewController: UIViewController {
|
|||
vc.preferredControlTintColor = .appTintColor
|
||||
return vc
|
||||
}
|
||||
|
||||
#if targetEnvironment(macCatalyst)
|
||||
@objc func toggleItemRead(_ item: NSToolbarItem) {
|
||||
Task {
|
||||
await fervorController.markItem(self.item, read: !self.item.read)
|
||||
updateToggleReadToolbarImage()
|
||||
}
|
||||
}
|
||||
|
||||
private func updateToggleReadToolbarImage() {
|
||||
guard let titlebar = view.window?.windowScene?.titlebar,
|
||||
let item = titlebar.toolbar?.items.first(where: { $0.itemIdentifier == .toggleItemRead }) else {
|
||||
return
|
||||
}
|
||||
|
||||
item.image = UIImage(systemName: self.item.read ? "checkmark.circle.fill" : "checkmark.circle")
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
@ -181,18 +212,21 @@ extension ReadViewController: StretchyMenuInteractionDelegate {
|
|||
guard let url = item.url else {
|
||||
return []
|
||||
}
|
||||
return [
|
||||
var items = [
|
||||
StretchyMenuItem(title: "Open in Safari", subtitle: nil, action: { [unowned self] in
|
||||
self.present(createSafariVC(url: url), animated: true)
|
||||
}),
|
||||
StretchyMenuItem(title: "Share", subtitle: nil, action: { [unowned self] in
|
||||
self.present(UIActivityViewController(activityItems: [url], applicationActivities: nil), animated: true)
|
||||
}),
|
||||
StretchyMenuItem(title: item.read ? "Mark as Unread" : "Mark as Read", subtitle: nil, action: { [unowned self] in
|
||||
Task {
|
||||
await self.fervorController.markItem(item, read: !item.read)
|
||||
}
|
||||
}),
|
||||
]
|
||||
#if !targetEnvironment(macCatalyst)
|
||||
items.insert(StretchyMenuItem(title: "Share", subtitle: nil, action: { [unowned self] in
|
||||
self.present(UIActivityViewController(activityItems: [url], applicationActivities: nil), animated: true)
|
||||
}), at: 1)
|
||||
#endif
|
||||
return items
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue