Continue removing ExtensionPoint code. Start fixing build errors.

This commit is contained in:
Brent Simmons
2023-06-30 21:55:54 -07:00
parent d309c05cb0
commit 8a9c680cfc
17 changed files with 46 additions and 562 deletions

View File

@@ -173,7 +173,7 @@ final class CloudKitAccountDelegate: AccountDelegate, Logging {
}
func createWebFeed(for account: Account, url urlString: String, name: String?, container: Container, validateFeed: Bool, completion: @escaping (Result<WebFeed, Error>) -> Void) {
guard let url = URL(string: urlString), let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false) else {
guard let url = URL(string: urlString) else {
completion(.failure(LocalAccountDelegateError.invalidParameter))
return
}

View File

@@ -120,7 +120,7 @@ final class LocalAccountDelegate: AccountDelegate, Logging {
}
func createWebFeed(for account: Account, url urlString: String, name: String?, container: Container, validateFeed: Bool, completion: @escaping (Result<WebFeed, Error>) -> Void) {
guard let url = URL(string: urlString), let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false) else {
guard let url = URL(string: urlString) else {
completion(.failure(LocalAccountDelegateError.invalidParameter))
return
}

View File

@@ -39,9 +39,6 @@ private struct ToolbarItemIdentifier {
specs += [PreferencesToolbarItemSpec(identifierRawValue: ToolbarItemIdentifier.Accounts,
name: NSLocalizedString("button.title.accounts", comment: "Account"),
image: AppAssets.preferencesToolbarAccountsImage)]
specs += [PreferencesToolbarItemSpec(identifierRawValue: ToolbarItemIdentifier.Extensions,
name: NSLocalizedString("button.title.extensions", comment: "Extensions"),
image: AppAssets.preferencesToolbarExtensionsImage)]
// Omit the Advanced Preferences for now because the Software Update related functionality is
// forbidden/non-applicable, and we can rely upon Apple to some extent for crash reports. We

View File

@@ -0,0 +1,25 @@
{
"images" : [
{
"filename" : "micro.blog.24.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "micro.blog.48.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "original"
}
}

View File

@@ -764,15 +764,12 @@
DF28B44D294ED52700C4D8CA /* View+DismissOnExternalContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF28B44C294ED52700C4D8CA /* View+DismissOnExternalContext.swift */; };
DF28B44F294ED92F00C4D8CA /* NewsBlurAddAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF28B44E294ED92F00C4D8CA /* NewsBlurAddAccountView.swift */; };
DF28B451294EFC6C00C4D8CA /* View+DismissOnAccountAdd.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF28B450294EFC6C00C4D8CA /* View+DismissOnAccountAdd.swift */; };
DF28B453294FE6C600C4D8CA /* EnableExtensionPointView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF28B452294FE6C600C4D8CA /* EnableExtensionPointView.swift */; };
DF28B455294FE74A00C4D8CA /* ExtensionSectionHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF28B454294FE74A00C4D8CA /* ExtensionSectionHeader.swift */; };
DF28B4572950163F00C4D8CA /* EnableExtensionViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF28B4562950163F00C4D8CA /* EnableExtensionViewModel.swift */; };
DF3630EB2936183D00326FB8 /* OPMLDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF3630EA2936183D00326FB8 /* OPMLDocument.swift */; };
DF3630EC2936183D00326FB8 /* OPMLDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF3630EA2936183D00326FB8 /* OPMLDocument.swift */; };
DF3630ED2936183D00326FB8 /* OPMLDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF3630EA2936183D00326FB8 /* OPMLDocument.swift */; };
DF3630EF293618A900326FB8 /* SettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF3630EE293618A900326FB8 /* SettingsViewModel.swift */; };
DF394F0029357A180081EB6E /* NewArticleNotificationsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF394EFF29357A180081EB6E /* NewArticleNotificationsView.swift */; };
DF47CDB2294803AB00FCD57E /* AddExtensionListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF47CDB1294803AB00FCD57E /* AddExtensionListView.swift */; };
DF5124CA2A22D5FA00BBAB1F /* Html in Frameworks */ = {isa = PBXBuildFile; productRef = DF5124C92A22D5FA00BBAB1F /* Html */; };
DF5124CC2A22D62600BBAB1F /* AboutHTML.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF5124CB2A22D62600BBAB1F /* AboutHTML.swift */; };
DF5124CD2A230FC100BBAB1F /* Inspector.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DF5124D02A230FC100BBAB1F /* Inspector.storyboard */; };
@@ -810,7 +807,6 @@
DF6DE5212965924D002EC085 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = DF6DE51E2965924C002EC085 /* Localizable.strings */; };
DF6DE52529659443002EC085 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = DF6DE52329659443002EC085 /* InfoPlist.strings */; };
DF6DE5282965971A002EC085 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = DF6DE5262965971A002EC085 /* InfoPlist.strings */; };
DF766FED29377FD9006FBBE2 /* ExtensionsManagementView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF766FEC29377FD9006FBBE2 /* ExtensionsManagementView.swift */; };
DF790D6228E990A900455FC7 /* AboutData.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF790D6128E990A900455FC7 /* AboutData.swift */; };
DF84E563295122BA0045C334 /* TimelineCustomizerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF84E562295122BA0045C334 /* TimelineCustomizerView.swift */; };
DF93DB2B296A319000586C0E /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = DF93DB2D296A319000586C0E /* Localizable.stringsdict */; };
@@ -1568,16 +1564,13 @@
DF28B44C294ED52700C4D8CA /* View+DismissOnExternalContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+DismissOnExternalContext.swift"; sourceTree = "<group>"; };
DF28B44E294ED92F00C4D8CA /* NewsBlurAddAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsBlurAddAccountView.swift; sourceTree = "<group>"; };
DF28B450294EFC6C00C4D8CA /* View+DismissOnAccountAdd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+DismissOnAccountAdd.swift"; sourceTree = "<group>"; };
DF28B452294FE6C600C4D8CA /* EnableExtensionPointView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnableExtensionPointView.swift; sourceTree = "<group>"; };
DF28B454294FE74A00C4D8CA /* ExtensionSectionHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionSectionHeader.swift; sourceTree = "<group>"; };
DF28B4562950163F00C4D8CA /* EnableExtensionViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnableExtensionViewModel.swift; sourceTree = "<group>"; };
DF332714295BBBB900BFD911 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Main.strings; sourceTree = "<group>"; };
DF332716295BBBBF00BFD911 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/LaunchScreenPad.strings; sourceTree = "<group>"; };
DF332718295BBBC200BFD911 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/LaunchScreenPhone.strings; sourceTree = "<group>"; };
DF3630EA2936183D00326FB8 /* OPMLDocument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OPMLDocument.swift; sourceTree = "<group>"; };
DF3630EE293618A900326FB8 /* SettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewModel.swift; sourceTree = "<group>"; };
DF394EFF29357A180081EB6E /* NewArticleNotificationsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewArticleNotificationsView.swift; sourceTree = "<group>"; };
DF47CDB1294803AB00FCD57E /* AddExtensionListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddExtensionListView.swift; sourceTree = "<group>"; };
DF5124CB2A22D62600BBAB1F /* AboutHTML.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutHTML.swift; sourceTree = "<group>"; };
DF5124CF2A230FC100BBAB1F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Inspector.storyboard; sourceTree = "<group>"; };
DF5124D22A230FC700BBAB1F /* en-GB */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "en-GB"; path = "en-GB.lproj/Inspector.strings"; sourceTree = "<group>"; };
@@ -1614,7 +1607,6 @@
DF6DE5222965937C002EC085 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
DF6DE52429659443002EC085 /* en-GB */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "en-GB"; path = "en-GB.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
DF6DE5272965971A002EC085 /* en-GB */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "en-GB"; path = "en-GB.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
DF766FEC29377FD9006FBBE2 /* ExtensionsManagementView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionsManagementView.swift; sourceTree = "<group>"; };
DF790D6128E990A900455FC7 /* AboutData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutData.swift; sourceTree = "<group>"; };
DF84E562295122BA0045C334 /* TimelineCustomizerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineCustomizerView.swift; sourceTree = "<group>"; };
DF93DB2C296A319000586C0E /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
@@ -2019,7 +2011,7 @@
children = (
DF766FEB2936344D006FBBE2 /* General */,
DFD406FD291FDBD900C02962 /* Appearance */,
DF59F0752920E42000ACD33D /* Account and Extensions */,
DFB3497B294AA95200BC81AD /* Accounts */,
DF3630E92936038400326FB8 /* New Article Notifications */,
DF766FEA2936337A006FBBE2 /* Help */,
5137C2E926F63AE6009EFEDB /* ArticleThemeImporter.swift */,
@@ -2898,15 +2890,6 @@
path = "New Article Notifications";
sourceTree = "<group>";
};
DF59F0752920E42000ACD33D /* Account and Extensions */ = {
isa = PBXGroup;
children = (
DFB3497B294AA95200BC81AD /* Accounts */,
DFB3497C294AA95A00BC81AD /* Extensions */,
);
path = "Account and Extensions";
sourceTree = "<group>";
};
DF766FEA2936337A006FBBE2 /* Help */ = {
isa = PBXGroup;
children = (
@@ -2935,17 +2918,6 @@
path = Accounts;
sourceTree = "<group>";
};
DFB3497C294AA95A00BC81AD /* Extensions */ = {
isa = PBXGroup;
children = (
DF766FEC29377FD9006FBBE2 /* ExtensionsManagementView.swift */,
DF47CDB1294803AB00FCD57E /* AddExtensionListView.swift */,
DF28B452294FE6C600C4D8CA /* EnableExtensionPointView.swift */,
DF28B4562950163F00C4D8CA /* EnableExtensionViewModel.swift */,
);
path = Extensions;
sourceTree = "<group>";
};
DFB34985294B3B0800BC81AD /* Localizations */ = {
isa = PBXGroup;
children = (
@@ -4126,7 +4098,6 @@
512E08E72268801200BDCFDD /* WebFeedTreeControllerDelegate.swift in Sources */,
51C452A422650A2D00C03939 /* ArticleUtilities.swift in Sources */,
51EF0F79227716380050506E /* ColorHash.swift in Sources */,
DF28B4572950163F00C4D8CA /* EnableExtensionViewModel.swift in Sources */,
DF59F072292085B800ACD33D /* ColorPaletteSelectorView.swift in Sources */,
51F9F3FB23DFB25700A314FD /* Animations.swift in Sources */,
DFB34988294B447F00BC81AD /* InjectedNavigationView.swift in Sources */,
@@ -4159,7 +4130,6 @@
51C452772265091600C03939 /* MultilineUILabelSizer.swift in Sources */,
DFEB034F2A273BFE00C7573A /* UTType.swift in Sources */,
51C452A522650A2D00C03939 /* SmallIconProvider.swift in Sources */,
DF28B453294FE6C600C4D8CA /* EnableExtensionPointView.swift in Sources */,
51AB8AB323B7F4C6008F147D /* WebViewController.swift in Sources */,
DFD406F7291FB1A600C02962 /* SafariView.swift in Sources */,
DF3630ED2936183D00326FB8 /* OPMLDocument.swift in Sources */,
@@ -4241,7 +4211,6 @@
51E595A6228CC36500FCC42B /* ArticleStatusSyncTimer.swift in Sources */,
51F9F3F723DF6DB200A314FD /* ArticleIconSchemeHandler.swift in Sources */,
512AF9C2236ED52C0066F8BE /* ImageHeaderView.swift in Sources */,
DF766FED29377FD9006FBBE2 /* ExtensionsManagementView.swift in Sources */,
51C45290226509C100C03939 /* PseudoFeed.swift in Sources */,
51C452A922650DC600C03939 /* ArticleRenderer.swift in Sources */,
51C45297226509E300C03939 /* DefaultFeedsImporter.swift in Sources */,
@@ -4251,7 +4220,6 @@
51C452AC22650FD200C03939 /* AppNotifications.swift in Sources */,
51EF0F7E2277A57D0050506E /* MasterTimelineAccessibilityCellLayout.swift in Sources */,
512D554423C804DE0023FFFA /* OpenInSafariActivity.swift in Sources */,
DF47CDB2294803AB00FCD57E /* AddExtensionListView.swift in Sources */,
DFB34994294C0E3900BC81AD /* ReaderAPIAddAccountView.swift in Sources */,
51C452762265091600C03939 /* MasterTimelineViewController.swift in Sources */,
5195C1DC2720BD3000888867 /* MasterFeedRowIdentifier.swift in Sources */,

View File

@@ -1,51 +1,6 @@
{
"object": {
"pins": [
{
"package": "BrightFutures",
"repositoryURL": "https://github.com/Thomvis/BrightFutures.git",
"state": {
"branch": null,
"revision": "fa66fa183dce7196d431244d0215748cd14c5758",
"version": "8.2.0"
}
},
{
"package": "Erik",
"repositoryURL": "https://github.com/phimage/Erik.git",
"state": {
"branch": null,
"revision": "109a130e9cdb00789a43a7a625293eeb12d22989",
"version": "5.1.0"
}
},
{
"package": "FileKit",
"repositoryURL": "https://github.com/nvzqz/FileKit.git",
"state": {
"branch": null,
"revision": "826d9161b184509f80d85c28cd612d630646de98",
"version": "6.0.0"
}
},
{
"package": "Kanna",
"repositoryURL": "https://github.com/tid-kijyun/Kanna.git",
"state": {
"branch": null,
"revision": "f9e4922223dd0d3dfbf02ca70812cf5531fc0593",
"version": "5.2.7"
}
},
{
"package": "OAuthSwift",
"repositoryURL": "https://github.com/OAuthSwift/OAuthSwift.git",
"state": {
"branch": null,
"revision": "fde77955e6983fbfaabd491709d52b8a82fda4d0",
"version": "2.1.2"
}
},
{
"package": "PLCrashReporter",
"repositoryURL": "https://github.com/microsoft/plcrashreporter.git",
@@ -127,15 +82,6 @@
"version": "1.11.0"
}
},
{
"package": "Swifter",
"repositoryURL": "https://github.com/httpswift/swifter.git",
"state": {
"branch": null,
"revision": "9483a5d459b45c3ffd059f7b55f9638e268632fd",
"version": "1.5.0"
}
},
{
"package": "Zip",
"repositoryURL": "https://github.com/marmelroy/Zip.git",

View File

@@ -3,21 +3,18 @@ import PackageDescription
let package = Package(
name: "Secrets",
platforms: [.macOS(SupportedPlatform.MacOSVersion.v11), .iOS(SupportedPlatform.IOSVersion.v14)],
platforms: [.macOS(SupportedPlatform.MacOSVersion.v11), .iOS(SupportedPlatform.IOSVersion.v14)],
products: [
.library(
name: "Secrets",
type: .dynamic,
type: .dynamic,
targets: ["Secrets"]),
],
dependencies: [
.package(url: "https://github.com/OAuthSwift/OAuthSwift.git", .exact("2.1.2")),
],
dependencies: [],
targets: [
.target(
name: "Secrets",
dependencies: [
"OAuthSwift",
]),
dependencies: []
)
]
)

View File

@@ -1,17 +0,0 @@
//
// OAuth1SwiftProvider.swift
// Secrets
//
// Created by Maurice Parker on 4/14/20.
// Copyright © 2020 Ranchero Software, LLC. All rights reserved.
//
import Foundation
import OAuthSwift
public protocol OAuth1SwiftProvider {
static var oauth1Swift: OAuth1Swift { get }
static var callbackURL: URL { get }
}

View File

@@ -1,19 +0,0 @@
//
// OAuth2SwiftProvider.swift
// Secrets
//
// Created by Maurice Parker on 5/2/20.
// Copyright © 2020 Ranchero Software, LLC. All rights reserved.
//
import Foundation
import OAuthSwift
public protocol OAuth2SwiftProvider {
static var oauth2Swift: OAuth2Swift { get }
static var callbackURL: URL { get }
static var oauth2Vars: (state: String, scope: String, params: [String: String]) { get }
}

View File

@@ -46,15 +46,15 @@ extension Article {
}
var url: URL? {
return URL.reparingIfRequired(rawLink)
return URL.encodingSpacesIfNeeded(rawLink)
}
var externalURL: URL? {
return URL.reparingIfRequired(rawExternalLink)
return URL.encodingSpacesIfNeeded(rawExternalLink)
}
var imageURL: URL? {
return URL.reparingIfRequired(rawImageLink)
return URL.encodingSpacesIfNeeded(rawImageLink)
}
var link: String? {

View File

@@ -17,24 +17,18 @@ extension URL {
/// Percent encoded `mailto` URL for use with `canOpenUrl`. If the URL doesn't contain the `mailto` scheme, this is `nil`.
var percentEncodedEmailAddress: URL? {
scheme == "mailto" ? self.string.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)?.url : nil
guard scheme == "mailto" else {
return nil
}
guard let urlString = absoluteString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {
return nil
}
return URL(string: urlString)
}
/// URL pointing to current app version release notes.
static var releaseNotes: URL {
var gitHub = "https://github.com/Ranchero-Software/NetNewsWire/releases/tag/"
#if os(macOS)
gitHub += "mac-"
#else
gitHub += "ios-"
#endif
gitHub += "\(Bundle.main.versionNumber)-\(Bundle.main.buildNumber)"
/// Reverse chronological list of release notes.
static var releaseNotes = URL(string: "https://github.com/Ranchero-Software/NetNewsWire/releases/")!
return URL(string: gitHub)!
}
func valueFor(_ parameter: String) -> String? {
guard let components = URLComponents(url: self, resolvingAgainstBaseURL: false),
let queryItems = components.queryItems,
@@ -45,7 +39,7 @@ extension URL {
}
static func reparingIfRequired(_ link: String?) -> URL? {
static func encodingSpacesIfNeeded(_ link: String?) -> URL? {
// If required, we replace any space characters to handle malformed links that are otherwise percent
// encoded but contain spaces. For performance reasons, only try this if initial URL init fails.
guard let link = link, !link.isEmpty else { return nil }

View File

@@ -1,65 +0,0 @@
//
// AddExtensionListView.swift
// NetNewsWire-iOS
//
// Created by Stuart Breckenridge on 13/12/2022.
// Copyright © 2022 Ranchero Software. All rights reserved.
//
import SwiftUI
import Accounts
struct AddExtensionListView: View {
@State private var availableExtensionPointTypes = ExtensionPointManager.shared.availableExtensionPointTypes.sorted(by: { $0.title < $1.title })
@Environment(\.dismiss) var dismiss
@State private var showExtensionPointView: (ExtensionPoint.Type?, Bool) = (nil, false)
var body: some View {
NavigationView {
List {
Section(header: Text("label.text.feed-providers", comment: "Feed Providers"),
footer: Text("label.text.feed-providers-explainer", comment: "Feed Providers allow you to subscribe to some pages as if they were RSS feeds")) {
ForEach(0..<availableExtensionPointTypes.count, id: \.self) { i in
Button {
showExtensionPointView = (availableExtensionPointTypes[i], true)
} label: {
Image(uiImage: availableExtensionPointTypes[i].image)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 25, height: 25)
Text("\(availableExtensionPointTypes[i].title)")
}
}
}
}
.navigationBarTitleDisplayMode(.inline)
.navigationTitle(Text("navigation.title.add-extensions", comment: "Add Extensions"))
.sheet(isPresented: $showExtensionPointView.1, content: {
if showExtensionPointView.0 != nil {
EnableExtensionPointView(extensionPoint: showExtensionPointView.0!)
}
})
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button(role: .cancel) {
dismiss()
} label: {
Text("button.title.cancel", comment: "Cancel")
}
}
}
.onReceive(NotificationCenter.default.publisher(for: .ActiveExtensionPointsDidChange), perform: { _ in
dismiss()
})
}
}
}
struct AddExtensionListView_Previews: PreviewProvider {
static var previews: some View {
AddExtensionListView()
}
}

View File

@@ -1,69 +0,0 @@
//
// EnableExtensionPointView.swift
// NetNewsWire-iOS
//
// Created by Stuart Breckenridge on 19/12/2022.
// Copyright © 2022 Ranchero Software. All rights reserved.
//
import SwiftUI
struct EnableExtensionPointView: View {
@Environment(\.dismiss) var dismiss
@StateObject private var viewModel = EnableExtensionViewModel()
@State private var extensionError: (Error?, Bool) = (nil, false)
var extensionPoint: ExtensionPoint.Type
var body: some View {
Form {
ExtensionSectionHeader(extensionPoint: extensionPoint)
Section(footer: extensionExplainer) {}
Section { enableButton }
}
.alert(Text("alert.title.error", comment: "Error"), isPresented: $extensionError.1, actions: {
}, message: {
Text(verbatim: extensionError.0?.localizedDescription ?? "Unknown Error")
})
.alert(Text("alert.title.error", comment: "Error"), isPresented: $viewModel.showExtensionError.1, actions: {
}, message: {
Text(verbatim: viewModel.showExtensionError.0?.localizedDescription ?? "Unknown Error")
})
.navigationTitle(extensionPoint.title)
.navigationBarTitleDisplayMode(.inline)
.dismissOnExternalContextLaunch()
.onReceive(NotificationCenter.default.publisher(for: .ActiveExtensionPointsDidChange), perform: { _ in
dismiss()
})
.edgesIgnoringSafeArea(.bottom)
}
var extensionExplainer: some View {
Text(extensionPoint.description.string)
.multilineTextAlignment(.center)
}
var enableButton: some View {
Button {
Task {
viewModel.configure(extensionPoint)
do {
try await viewModel.enableExtension()
} catch {
extensionError = (error, true)
}
}
} label: {
HStack {
Spacer()
Text("button.title.enable-extension", comment: "Enable Extension")
Spacer()
}
}
}
}

View File

@@ -1,183 +0,0 @@
//
// EnableExtensionViewModel.swift
// NetNewsWire-iOS
//
// Created by Stuart Breckenridge on 19/12/2022.
// Copyright © 2022 Ranchero Software. All rights reserved.
//
import Foundation
import AuthenticationServices
import Account
import OAuthSwift
import Secrets
import RSCore
public final class EnableExtensionViewModel: NSObject, ObservableObject, OAuthSwiftURLHandlerType, ASWebAuthenticationPresentationContextProviding, Logging {
@Published public var showExtensionError: (Error?, Bool) = (nil, false)
private var extensionPointType: ExtensionPoint.Type?
private var oauth: OAuthSwift?
private var callbackURL: URL? = nil
func configure(_ extensionPointType: ExtensionPoint.Type) {
self.extensionPointType = extensionPointType
}
func enableExtension() async throws {
guard let extensionPointType = extensionPointType else { return }
if let oauth1 = extensionPointType as? OAuth1SwiftProvider.Type {
try await enableOAuth1(oauth1)
} else if let oauth2 = extensionPointType as? OAuth2SwiftProvider.Type {
try await enableOAuth2(oauth2)
} else {
try await activateExtensionPoint(extensionPointType)
}
}
private func activateExtensionPoint(_ point: ExtensionPoint.Type) async throws {
return try await withCheckedThrowingContinuation { continuation in
ExtensionPointManager.shared.activateExtensionPoint(point) { result in
switch result {
case .success(_):
continuation.resume()
return
case .failure(let failure):
continuation.resume(throwing: failure)
return
}
}
}
}
// MARK: Enable OAuth
private func enableOAuth1(_ provider: OAuth1SwiftProvider.Type) async throws {
callbackURL = provider.callbackURL
let oauth1 = provider.oauth1Swift
self.oauth = oauth1
oauth1.authorizeURLHandler = self
return try await withCheckedThrowingContinuation { continuation in
oauth1.authorize(withCallbackURL: callbackURL!) { [weak self] result in
guard let self = self, let extensionPointType = self.extensionPointType else { return }
switch result {
case .success(let tokenSuccess):
ExtensionPointManager.shared.activateExtensionPoint(extensionPointType, tokenSuccess: tokenSuccess) { result in
switch result {
case .success(_):
continuation.resume()
return
case .failure(let failure):
continuation.resume(throwing: failure)
return
}
}
case .failure(let error):
continuation.resume(throwing: error)
return
}
self.oauth?.cancel()
self.oauth = nil
}
continuation.resume()
}
}
private func enableOAuth2(_ provider: OAuth2SwiftProvider.Type) async throws {
callbackURL = provider.callbackURL
let oauth2 = provider.oauth2Swift
self.oauth = oauth2
oauth2.authorizeURLHandler = self
let oauth2Vars = provider.oauth2Vars
return try await withCheckedThrowingContinuation { continuation in
oauth2.authorize(withCallbackURL: callbackURL!, scope: oauth2Vars.scope, state: oauth2Vars.state, parameters: oauth2Vars.params) { [weak self] result in
guard let self = self, let extensionPointType = self.extensionPointType else { return }
switch result {
case .success(let tokenSuccess):
ExtensionPointManager.shared.activateExtensionPoint(extensionPointType, tokenSuccess: tokenSuccess) { [weak self] result in
switch result {
case .success(_):
self?.logger.debug("Enabled extension successfully.")
case .failure(let failure):
continuation.resume(throwing: failure)
return
}
}
case .failure(let oauthSwiftError):
continuation.resume(throwing: oauthSwiftError)
return
}
self.oauth?.cancel()
self.oauth = nil
}
continuation.resume()
}
}
public func handle(_ url: URL) {
let session = ASWebAuthenticationSession(url: url, callbackURLScheme: callbackURL!.scheme, completionHandler: { (url, error) in
if let callbackedURL = url {
OAuth1Swift.handle(url: callbackedURL)
}
guard let error = error else { return }
self.oauth?.cancel()
self.oauth = nil
DispatchQueue.main.async {
//self.dismiss(animated: true, completion: nil)
//self.delegate?.dismiss()
}
if case ASWebAuthenticationSessionError.canceledLogin = error {
self.logger.debug("Login cancelled.")
} else {
self.showExtensionError = (error, true)
}
})
session.presentationContextProvider = self
if !session.start() {
logger.debug("Session failed to start!!!")
}
}
public func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
return rootViewController!.view.window!
}
public var rootViewController: UIViewController? {
var currentKeyWindow: UIWindow? {
UIApplication.shared.connectedScenes
.filter { $0.activationState == .foregroundActive }
.map { $0 as? UIWindowScene }
.compactMap { $0 }
.first?.windows
.filter { $0.isKeyWindow }
.first
}
var rootViewController: UIViewController? {
currentKeyWindow?.rootViewController
}
return rootViewController
}
}

View File

@@ -1,90 +0,0 @@
//
// ExtensionsManagementView.swift
// NetNewsWire-iOS
//
// Created by Stuart Breckenridge on 30/11/2022.
// Copyright © 2022 Ranchero Software. All rights reserved.
//
import SwiftUI
import Account
struct ExtensionsManagementView: View {
@State private var availableExtensionPointTypes = ExtensionPointManager.shared.availableExtensionPointTypes.sorted(by: { $0.title < $1.title })
@State private var showAddExtensionView: Bool = false
@State private var showDeactivateAlert: Bool = false
@State private var extensionToDeactivate: Dictionary<ExtensionPointIdentifer, any ExtensionPoint>.Element? = nil
var body: some View {
List {
activeExtensionsSection
}
.navigationTitle(Text("navigation.title.manage-extensions", comment: " Manage Extensions"))
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button {
showAddExtensionView = true
} label: {
Image(systemName: "plus")
}
}
}
.sheet(isPresented: $showAddExtensionView) {
AddExtensionListView()
}
.alert(Text("alert.title.deactive-extension.\(extensionToDeactivate?.value.extensionPointID.extensionPointType.title ?? "").\(extensionToDeactivate?.value.title ?? "")", comment: "Are you sure you want to deactivate the %@ extension “%@“? Note: the ordering of the variables is extension type, extension name."),
isPresented: $showDeactivateAlert) {
Button(role: .destructive) {
ExtensionPointManager.shared.deactivateExtensionPoint(extensionToDeactivate!.value.extensionPointID)
} label: {
Text("button.title.deactivate-extension", comment: "Deactivate Extension")
}
Button(role: .cancel) {
extensionToDeactivate = nil
} label: {
Text("button.title.cancel", comment: "Button title")
}
} message: {
Text("alert.message.cannot-undo-action", comment: "You can't undo this action.")
}
.onReceive(NotificationCenter.default.publisher(for: .ActiveExtensionPointsDidChange), perform: { _ in
availableExtensionPointTypes = ExtensionPointManager.shared.availableExtensionPointTypes.sorted(by: { $0.title < $1.title })
})
}
private var activeExtensionsSection: some View {
Section(header: Text("label.text.active-extensions", comment: "Active Extensions")) {
ForEach(0..<ExtensionPointManager.shared.activeExtensionPoints.count, id: \.self) { i in
let point = Array(ExtensionPointManager.shared.activeExtensionPoints)[i]
NavigationLink {
ExtensionInspectorView(extensionPoint: point.value)
} label: {
Image(uiImage: point.value.image)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 25, height: 25)
Text(point.value.title)
}.swipeActions(edge: .trailing, allowsFullSwipe: false) {
Button(role: .destructive) {
extensionToDeactivate = point
showDeactivateAlert = true
} label: {
Text("button.title.deactivate-extension", comment: "Deactivate Extension")
Image(systemName: "minus.circle")
}.tint(.red)
}
}
}
}
}
struct ExtensionsManagementView_Previews: PreviewProvider {
static var previews: some View {
ExtensionsManagementView()
}
}