mirror of
https://github.com/Ranchero-Software/NetNewsWire
synced 2025-08-12 06:26:36 +00:00
Add basic ExtensionPoint support.
This commit is contained in:
20
Shared/ExtensionPoints/ExtensionPoint.swift
Normal file
20
Shared/ExtensionPoints/ExtensionPoint.swift
Normal file
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// ExtensionPoint.swift
|
||||
// NetNewsWire
|
||||
//
|
||||
// Created by Maurice Parker on 4/7/20.
|
||||
// Copyright © 2020 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import RSCore
|
||||
|
||||
protocol ExtensionPoint {
|
||||
|
||||
/// The title of the command.
|
||||
var title: String { get }
|
||||
|
||||
/// The template image for the command.
|
||||
var templateImage: RSImage { get }
|
||||
|
||||
}
|
||||
49
Shared/ExtensionPoints/ExtensionPointManager.swift
Normal file
49
Shared/ExtensionPoints/ExtensionPointManager.swift
Normal file
@@ -0,0 +1,49 @@
|
||||
//
|
||||
// ExtensionPointManager.swift
|
||||
// NetNewsWire
|
||||
//
|
||||
// Created by Maurice Parker on 4/7/20.
|
||||
// Copyright © 2020 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import FeedProvider
|
||||
import RSCore
|
||||
|
||||
struct ExtensionPointManager {
|
||||
|
||||
static let shared = ExtensionPointManager()
|
||||
|
||||
let marsEdit = SendToMarsEditCommand()
|
||||
let microblog = SendToMicroBlogCommand()
|
||||
let twitter = TwitterFeedProvider()
|
||||
|
||||
let availableExtensionPoints: [ExtensionPoint]
|
||||
let activeSendToCommands: [SendToCommand]
|
||||
let activeFeedProviders: [FeedProvider]
|
||||
|
||||
init() {
|
||||
#if os(macOS)
|
||||
#if DEBUG
|
||||
availableExtensionPoints = [marsEdit, microblog, twitter]
|
||||
activeSendToCommands = [marsEdit, microblog]
|
||||
activeFeedProviders = [twitter]
|
||||
#else
|
||||
availableExtensionPoints = [marsEdit, microblog, twitter]
|
||||
activeSendToCommands = [marsEdit, microblog]
|
||||
activeFeedProviders = [twitter]
|
||||
#endif
|
||||
#else
|
||||
#if DEBUG
|
||||
availableExtensionPoints = [twitter]
|
||||
activeSendToCommands = []()
|
||||
activeFeedProviders = [twitter]
|
||||
#else
|
||||
availableExtensionPoints = [twitter]
|
||||
activeSendToCommands = []()
|
||||
activeFeedProviders = [twitter]
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
14
Shared/ExtensionPoints/ExtensionPointType.swift
Normal file
14
Shared/ExtensionPoints/ExtensionPointType.swift
Normal file
@@ -0,0 +1,14 @@
|
||||
//
|
||||
// ExtensionPointType.swift
|
||||
// NetNewsWire
|
||||
//
|
||||
// Created by Maurice Parker on 4/7/20.
|
||||
// Copyright © 2020 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum ExtensionPoint: Int, Codable {
|
||||
case sentToCommand = 1
|
||||
case feedProvider = 2
|
||||
}
|
||||
84
Shared/ExtensionPoints/SendToMarsEditCommand.swift
Normal file
84
Shared/ExtensionPoints/SendToMarsEditCommand.swift
Normal file
@@ -0,0 +1,84 @@
|
||||
//
|
||||
// SendToMarsEditCommand.swift
|
||||
// NetNewsWire
|
||||
//
|
||||
// Created by Brent Simmons on 1/8/18.
|
||||
// Copyright © 2018 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import AppKit
|
||||
import RSCore
|
||||
import Articles
|
||||
|
||||
final class SendToMarsEditCommand: ExtensionPoint, SendToCommand {
|
||||
|
||||
let title = NSLocalizedString("MarsEdit", comment: "MarsEdit")
|
||||
let templateImage = AppAssets.extensionPointMarsEdit
|
||||
|
||||
var image: NSImage? {
|
||||
return appToUse()?.icon ?? nil
|
||||
}
|
||||
|
||||
|
||||
private let marsEditApps = [UserApp(bundleID: "com.red-sweater.marsedit4"), UserApp(bundleID: "com.red-sweater.marsedit")]
|
||||
|
||||
func canSendObject(_ object: Any?, selectedText: String?) -> Bool {
|
||||
|
||||
if let _ = appToUse() {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func sendObject(_ object: Any?, selectedText: String?) {
|
||||
|
||||
guard canSendObject(object, selectedText: selectedText) else {
|
||||
return
|
||||
}
|
||||
guard let article = (object as? ArticlePasteboardWriter)?.article else {
|
||||
return
|
||||
}
|
||||
guard let app = appToUse(), app.launchIfNeeded(), app.bringToFront() else {
|
||||
return
|
||||
}
|
||||
|
||||
send(article, to: app)
|
||||
}
|
||||
}
|
||||
|
||||
private extension SendToMarsEditCommand {
|
||||
|
||||
func send(_ article: Article, to app: UserApp) {
|
||||
|
||||
// App has already been launched.
|
||||
|
||||
guard let targetDescriptor = app.targetDescriptor() else {
|
||||
return
|
||||
}
|
||||
|
||||
let body = article.contentHTML ?? article.contentText ?? article.summary
|
||||
let authorName = article.authors?.first?.name
|
||||
|
||||
let sender = SendToBlogEditorApp(targetDescriptor: targetDescriptor, title: article.title, body: body, summary: article.summary, link: article.externalURL, permalink: article.url, subject: nil, creator: authorName, commentsURL: nil, guid: article.uniqueID, sourceName: article.webFeed?.nameForDisplay, sourceHomeURL: article.webFeed?.homePageURL, sourceFeedURL: article.webFeed?.url)
|
||||
let _ = sender.send()
|
||||
}
|
||||
|
||||
func appToUse() -> UserApp? {
|
||||
|
||||
marsEditApps.forEach{ $0.updateStatus() }
|
||||
|
||||
for app in marsEditApps {
|
||||
if app.isRunning {
|
||||
return app
|
||||
}
|
||||
}
|
||||
|
||||
for app in marsEditApps {
|
||||
if app.existsOnDisk {
|
||||
return app
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
97
Shared/ExtensionPoints/SendToMicroBlogCommand.swift
Normal file
97
Shared/ExtensionPoints/SendToMicroBlogCommand.swift
Normal file
@@ -0,0 +1,97 @@
|
||||
//
|
||||
// SendToMicroBlogCommand.swift
|
||||
// NetNewsWire
|
||||
//
|
||||
// Created by Brent Simmons on 1/8/18.
|
||||
// Copyright © 2018 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import AppKit
|
||||
import Articles
|
||||
import RSCore
|
||||
|
||||
// Not undoable.
|
||||
|
||||
final class SendToMicroBlogCommand: ExtensionPoint, SendToCommand {
|
||||
|
||||
let title = NSLocalizedString("Micro.blog", comment: "Micro.blog")
|
||||
let templateImage = AppAssets.extensionPointMicroblog
|
||||
|
||||
var image: NSImage? {
|
||||
return microBlogApp.icon
|
||||
}
|
||||
|
||||
private let microBlogApp = UserApp(bundleID: "blog.micro.mac")
|
||||
|
||||
func canSendObject(_ object: Any?, selectedText: String?) -> Bool {
|
||||
|
||||
microBlogApp.updateStatus()
|
||||
guard microBlogApp.existsOnDisk, let article = (object as? ArticlePasteboardWriter)?.article, let _ = article.preferredLink else {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func sendObject(_ object: Any?, selectedText: String?) {
|
||||
|
||||
guard canSendObject(object, selectedText: selectedText) else {
|
||||
return
|
||||
}
|
||||
guard let article = (object as? ArticlePasteboardWriter)?.article else {
|
||||
return
|
||||
}
|
||||
guard microBlogApp.launchIfNeeded(), microBlogApp.bringToFront() else {
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: get text from contentHTML or contentText if no title and no selectedText.
|
||||
// TODO: consider selectedText.
|
||||
|
||||
let s = article.attributionString + article.linkString
|
||||
|
||||
let urlQueryDictionary = ["text": s]
|
||||
guard let urlQueryString = urlQueryDictionary.urlQueryString else {
|
||||
return
|
||||
}
|
||||
guard let url = URL(string: "microblog://post?" + urlQueryString) else {
|
||||
return
|
||||
}
|
||||
|
||||
let _ = try? NSWorkspace.shared.open(url, options: [], configuration: [:])
|
||||
}
|
||||
}
|
||||
|
||||
private extension Article {
|
||||
|
||||
var attributionString: String {
|
||||
|
||||
// Feed name, or feed name + author name (if author is specified per-article).
|
||||
// Includes trailing space.
|
||||
|
||||
if let feedName = webFeed?.nameForDisplay, let authorName = authors?.first?.name {
|
||||
return feedName + ", " + authorName + ": "
|
||||
}
|
||||
if let feedName = webFeed?.nameForDisplay {
|
||||
return feedName + ": "
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var linkString: String {
|
||||
|
||||
// Title + link or just title (if no link) or just link if no title
|
||||
|
||||
if let title = title, let link = preferredLink {
|
||||
return "[" + title + "](" + link + ")"
|
||||
}
|
||||
if let preferredLink = preferredLink {
|
||||
return preferredLink
|
||||
}
|
||||
if let title = title {
|
||||
return title
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
}
|
||||
23
Shared/ExtensionPoints/TwitterFeedProvider+Extensions.swift
Normal file
23
Shared/ExtensionPoints/TwitterFeedProvider+Extensions.swift
Normal file
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// TwitterFeedProvider+Extensions.swift
|
||||
// NetNewsWire
|
||||
//
|
||||
// Created by Maurice Parker on 4/7/20.
|
||||
// Copyright © 2020 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import FeedProvider
|
||||
import RSCore
|
||||
|
||||
extension TwitterFeedProvider: ExtensionPoint {
|
||||
|
||||
var title: String {
|
||||
return NSLocalizedString("Twitter", comment: "Twitter")
|
||||
}
|
||||
|
||||
var templateImage: RSImage {
|
||||
return AppAssets.extensionPointTwitter
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user