2020-10-30 20:43:42 +01:00
|
|
|
//
|
|
|
|
// EnableExtensionPointView.swift
|
|
|
|
// NetNewsWire
|
|
|
|
//
|
|
|
|
// Created by Maurice Parker on 10/30/20.
|
|
|
|
// Copyright © 2020 Ranchero Software. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
import AppKit
|
|
|
|
import SwiftUI
|
|
|
|
import RSCore
|
|
|
|
|
2020-11-06 12:07:28 +01:00
|
|
|
|
2020-10-30 20:43:42 +01:00
|
|
|
struct EnableExtensionPointView: View {
|
|
|
|
|
|
|
|
weak var parent: NSHostingController<EnableExtensionPointView>? // required because presentationMode.dismiss() doesn't work
|
|
|
|
weak var enabler: ExtensionPointPreferencesEnabler?
|
2020-11-06 12:07:28 +01:00
|
|
|
@State private var extensionPointTypeName = String(describing: Self.sendToCommandExtensionPointTypes.first)
|
|
|
|
private var selectedType: ExtensionPoint.Type?
|
2020-10-30 20:43:42 +01:00
|
|
|
|
2020-11-06 12:07:28 +01:00
|
|
|
init(enabler: ExtensionPointPreferencesEnabler?, selectedType: ExtensionPoint.Type? ) {
|
2020-10-30 20:43:42 +01:00
|
|
|
self.enabler = enabler
|
2020-11-06 12:07:28 +01:00
|
|
|
self.selectedType = selectedType
|
2020-10-30 20:43:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
var body: some View {
|
|
|
|
VStack(alignment: .leading, spacing: 8) {
|
2020-11-19 06:48:30 +01:00
|
|
|
Text("Choose an extension to add...")
|
2020-10-30 20:43:42 +01:00
|
|
|
.font(.headline)
|
|
|
|
.padding()
|
|
|
|
|
|
|
|
feedProviderExtensionPoints
|
2020-10-30 21:33:44 +01:00
|
|
|
sendToCommandExtensionPoints
|
|
|
|
|
2020-10-30 20:43:42 +01:00
|
|
|
HStack(spacing: 12) {
|
|
|
|
Spacer()
|
|
|
|
if #available(OSX 11.0, *) {
|
|
|
|
Button(action: {
|
|
|
|
parent?.dismiss(nil)
|
|
|
|
}, label: {
|
|
|
|
Text("Cancel")
|
|
|
|
.frame(width: 80)
|
|
|
|
})
|
|
|
|
.help("Cancel")
|
|
|
|
.keyboardShortcut(.cancelAction)
|
|
|
|
|
|
|
|
} else {
|
|
|
|
Button(action: {
|
|
|
|
parent?.dismiss(nil)
|
|
|
|
}, label: {
|
|
|
|
Text("Cancel")
|
|
|
|
.frame(width: 80)
|
|
|
|
})
|
2020-11-03 06:02:46 +01:00
|
|
|
.accessibility(label: Text("Add Extension"))
|
2020-10-30 20:43:42 +01:00
|
|
|
}
|
|
|
|
if #available(OSX 11.0, *) {
|
|
|
|
Button(action: {
|
|
|
|
enabler?.enable(typeFromName(extensionPointTypeName))
|
|
|
|
parent?.dismiss(nil)
|
|
|
|
}, label: {
|
|
|
|
Text("Continue")
|
|
|
|
.frame(width: 80)
|
|
|
|
})
|
2020-11-03 06:02:46 +01:00
|
|
|
.help("Add Extension")
|
2020-10-30 20:43:42 +01:00
|
|
|
.keyboardShortcut(.defaultAction)
|
2020-11-06 12:07:28 +01:00
|
|
|
.disabled(disableContinue())
|
2020-10-30 20:43:42 +01:00
|
|
|
} else {
|
|
|
|
Button(action: {
|
|
|
|
enabler?.enable(typeFromName(extensionPointTypeName))
|
|
|
|
parent?.dismiss(nil)
|
|
|
|
}, label: {
|
|
|
|
Text("Continue")
|
|
|
|
.frame(width: 80)
|
|
|
|
})
|
2020-11-06 12:07:28 +01:00
|
|
|
.disabled(disableContinue())
|
2020-10-30 20:43:42 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
.padding(.top, 12)
|
|
|
|
.padding(.bottom, 4)
|
|
|
|
}
|
|
|
|
.pickerStyle(RadioGroupPickerStyle())
|
|
|
|
.fixedSize(horizontal: false, vertical: true)
|
|
|
|
.frame(width: 420)
|
|
|
|
.padding()
|
2020-11-06 12:07:28 +01:00
|
|
|
.onAppear {
|
|
|
|
if selectedType != nil {
|
|
|
|
extensionPointTypeName = String(describing: selectedType!)
|
|
|
|
}
|
|
|
|
}
|
2020-10-30 20:43:42 +01:00
|
|
|
}
|
|
|
|
|
2020-10-30 21:33:44 +01:00
|
|
|
var feedProviderExtensionPoints: some View {
|
2020-10-30 20:43:42 +01:00
|
|
|
VStack(alignment: .leading) {
|
2020-10-30 21:33:44 +01:00
|
|
|
let extensionPointTypeNames = Self.feedProviderExtensionPointTypes.map { String(describing: $0) }
|
2020-10-30 20:43:42 +01:00
|
|
|
if extensionPointTypeNames.count > 0 {
|
2020-10-30 21:33:44 +01:00
|
|
|
Text("Feed Provider")
|
2020-10-30 20:43:42 +01:00
|
|
|
.font(.headline)
|
|
|
|
.padding(.horizontal)
|
2020-10-30 21:33:44 +01:00
|
|
|
|
2020-10-30 20:43:42 +01:00
|
|
|
Picker(selection: $extensionPointTypeName, label: Text(""), content: {
|
|
|
|
ForEach(extensionPointTypeNames, id: \.self, content: { extensionPointTypeName in
|
|
|
|
let extensionPointType = typeFromName(extensionPointTypeName)
|
|
|
|
HStack(alignment: .center) {
|
2020-10-30 21:42:45 +01:00
|
|
|
Image(nsImage: extensionPointType.image)
|
2020-10-30 20:43:42 +01:00
|
|
|
.resizable()
|
|
|
|
.aspectRatio(contentMode: .fit)
|
|
|
|
.frame(width: 25, height: 25, alignment: .center)
|
|
|
|
.padding(.leading, 4)
|
|
|
|
|
|
|
|
|
|
|
|
Text(extensionPointType.title)
|
|
|
|
}
|
2020-11-06 12:07:28 +01:00
|
|
|
.tag(extensionPointTypeName)
|
2020-10-30 20:43:42 +01:00
|
|
|
})
|
|
|
|
})
|
|
|
|
.pickerStyle(RadioGroupPickerStyle())
|
|
|
|
.offset(x: 7.5, y: 0)
|
|
|
|
|
2020-11-04 03:35:53 +01:00
|
|
|
Text("An extension that makes websites appear to provide RSS feeds for their content.")
|
2020-10-30 20:43:42 +01:00
|
|
|
.foregroundColor(.gray)
|
|
|
|
.font(.caption)
|
|
|
|
.padding(.horizontal)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2020-10-30 21:33:44 +01:00
|
|
|
|
|
|
|
var sendToCommandExtensionPoints: some View {
|
2020-10-30 20:43:42 +01:00
|
|
|
VStack(alignment: .leading) {
|
2020-10-30 21:33:44 +01:00
|
|
|
let extensionPointTypeNames = Self.sendToCommandExtensionPointTypes.map { String(describing: $0) }
|
2020-10-30 20:43:42 +01:00
|
|
|
if extensionPointTypeNames.count > 0 {
|
2020-10-30 21:33:44 +01:00
|
|
|
Text("Third-Party Integration")
|
2020-10-30 20:43:42 +01:00
|
|
|
.font(.headline)
|
|
|
|
.padding(.horizontal)
|
|
|
|
.padding(.top, 8)
|
|
|
|
|
|
|
|
Picker(selection: $extensionPointTypeName, label: Text(""), content: {
|
|
|
|
ForEach(extensionPointTypeNames, id: \.self, content: { extensionPointTypeName in
|
|
|
|
let extensionPointType = typeFromName(extensionPointTypeName)
|
|
|
|
HStack(alignment: .center) {
|
2020-10-30 21:42:45 +01:00
|
|
|
Image(nsImage: extensionPointType.image)
|
2020-10-30 20:43:42 +01:00
|
|
|
.resizable()
|
|
|
|
.aspectRatio(contentMode: .fit)
|
|
|
|
.frame(width: 25, height: 25, alignment: .center)
|
|
|
|
.padding(.leading, 4)
|
|
|
|
|
|
|
|
|
|
|
|
Text(extensionPointType.title)
|
|
|
|
}
|
2020-11-06 12:07:28 +01:00
|
|
|
.tag(extensionPointTypeName)
|
2020-10-30 20:43:42 +01:00
|
|
|
})
|
|
|
|
})
|
|
|
|
.pickerStyle(RadioGroupPickerStyle())
|
|
|
|
.offset(x: 7.5, y: 0)
|
|
|
|
|
2020-11-04 03:35:53 +01:00
|
|
|
Text("An extension that enables a share menu item that passes article data to a third-party application.")
|
2020-10-30 20:43:42 +01:00
|
|
|
.foregroundColor(.gray)
|
|
|
|
.font(.caption)
|
|
|
|
.padding(.horizontal)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2020-10-30 21:33:44 +01:00
|
|
|
|
|
|
|
static var sendToCommandExtensionPointTypes: [ExtensionPoint.Type] {
|
2020-10-30 20:43:42 +01:00
|
|
|
return ExtensionPointManager.shared.availableExtensionPointTypes.filter({ $0 is SendToCommand.Type })
|
|
|
|
}
|
|
|
|
|
2020-10-30 21:33:44 +01:00
|
|
|
static var feedProviderExtensionPointTypes: [ExtensionPoint.Type] {
|
2020-10-30 20:43:42 +01:00
|
|
|
return ExtensionPointManager.shared.availableExtensionPointTypes.filter({ !($0 is SendToCommand.Type) })
|
|
|
|
}
|
|
|
|
|
|
|
|
func typeFromName(_ name: String) -> ExtensionPoint.Type {
|
|
|
|
for type in ExtensionPointManager.shared.possibleExtensionPointTypes {
|
|
|
|
if name == String(describing: type) {
|
|
|
|
return type
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fatalError()
|
|
|
|
}
|
2020-11-06 12:07:28 +01:00
|
|
|
|
|
|
|
func disableContinue() -> Bool {
|
|
|
|
ExtensionPointManager.shared.availableExtensionPointTypes.count == 0
|
|
|
|
}
|
2020-10-30 20:43:42 +01:00
|
|
|
}
|
2020-11-04 03:35:53 +01:00
|
|
|
|
|
|
|
|
|
|
|
|