Add Extension Point maintenance to the iOS app.

This commit is contained in:
Maurice Parker
2020-04-16 08:25:40 -05:00
parent f8a664d035
commit d168658e05
26 changed files with 906 additions and 88 deletions

View File

@@ -132,6 +132,11 @@ private extension TwitterFeedProvider {
// TODO: Update to retrieve the full user
func fetchIconURL(screenName: String, completion: @escaping (Result<String, Error>) -> Void) {
guard screenName != "search" else {
completion(.failure(TwitterFeedProviderError.unknown))
return
}
let url = "\(Self.apiBase)users/show.json"
let parameters = ["screen_name": screenName]

View File

@@ -140,8 +140,6 @@
515A5178243E90200089E588 /* ExtensionPointIdentifer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5176243E90200089E588 /* ExtensionPointIdentifer.swift */; };
515A517B243E90260089E588 /* ExtensionPoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 510C43F6243D035C009F70C3 /* ExtensionPoint.swift */; };
515A517C243E90260089E588 /* ExtensionPointManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A50E5243D07A90089E588 /* ExtensionPointManager.swift */; };
515A517E243E90260089E588 /* SendToMarsEditCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84A1500420048DDF0046AD9A /* SendToMarsEditCommand.swift */; };
515A517F243E90260089E588 /* SendToMicroBlogCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84A14FF220048CA70046AD9A /* SendToMicroBlogCommand.swift */; };
515A5180243E90260089E588 /* TwitterFeedProvider-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5106243D0CCD0089E588 /* TwitterFeedProvider-Extensions.swift */; };
515A5181243E90260089E588 /* ExtensionPointIdentifer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A5176243E90200089E588 /* ExtensionPointIdentifer.swift */; };
515D4FC123257A3200EE1167 /* FolderTreeControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849A97A11ED9F180007D329B /* FolderTreeControllerDelegate.swift */; };
@@ -152,8 +150,8 @@
51627A6923861DED007B3B4B /* MasterFeedViewController+Drop.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51627A6823861DED007B3B4B /* MasterFeedViewController+Drop.swift */; };
51627A6B238629D8007B3B4B /* MasterFeedDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51627A6A238629D8007B3B4B /* MasterFeedDataSource.swift */; };
51627A93238A3836007B3B4B /* CroppingPreviewParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51627A92238A3836007B3B4B /* CroppingPreviewParameters.swift */; };
516A093723609A3600EAE89B /* SettingsAccountTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 516A091D23609A3600EAE89B /* SettingsAccountTableViewCell.xib */; };
516A09392360A2AE00EAE89B /* SettingsAccountTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 516A09382360A2AE00EAE89B /* SettingsAccountTableViewCell.swift */; };
516A093723609A3600EAE89B /* SettingsComboTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 516A091D23609A3600EAE89B /* SettingsComboTableViewCell.xib */; };
516A09392360A2AE00EAE89B /* SettingsComboTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 516A09382360A2AE00EAE89B /* SettingsComboTableViewCell.swift */; };
516A093B2360A4A000EAE89B /* SettingsTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 516A093A2360A4A000EAE89B /* SettingsTableViewCell.xib */; };
516A09402361240900EAE89B /* Account.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 516A093F2361240900EAE89B /* Account.storyboard */; };
516A09422361248000EAE89B /* Inspector.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 516A09412361248000EAE89B /* Inspector.storyboard */; };
@@ -189,6 +187,11 @@
51938DF3231AFC660055A1A0 /* SearchTimelineFeedDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51938DF1231AFC660055A1A0 /* SearchTimelineFeedDelegate.swift */; };
519B8D332143397200FA689C /* SharingServiceDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 519B8D322143397200FA689C /* SharingServiceDelegate.swift */; };
519E743D22C663F900A78E47 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 519E743422C663F900A78E47 /* SceneDelegate.swift */; };
519ED43F24482629007F8E94 /* FeedProvider.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51107672243BCE0500D97C8C /* FeedProvider.framework */; };
519ED44024482629007F8E94 /* FeedProvider.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 51107672243BCE0500D97C8C /* FeedProvider.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
519ED456244828C3007F8E94 /* AddExtensionPointViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 519ED455244828C3007F8E94 /* AddExtensionPointViewController.swift */; };
519ED47A24482AEB007F8E94 /* EnableExtensionPointViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 519ED47924482AEB007F8E94 /* EnableExtensionPointViewController.swift */; };
519ED47C24488C6F007F8E94 /* ExtensionInspectorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 519ED47B24488C6F007F8E94 /* ExtensionInspectorViewController.swift */; };
51A16999235E10D700EB091F /* LocalAccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A1698F235E10D600EB091F /* LocalAccountViewController.swift */; };
51A1699A235E10D700EB091F /* Settings.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 51A16990235E10D600EB091F /* Settings.storyboard */; };
51A1699B235E10D700EB091F /* AccountInspectorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A16991235E10D600EB091F /* AccountInspectorViewController.swift */; };
@@ -1277,6 +1280,7 @@
51C451F92264C83E00C03939 /* Account.framework in Embed Frameworks */,
51C451F12264C83100C03939 /* ArticlesDatabase.framework in Embed Frameworks */,
517A757C24451C1500B553B9 /* OAuthSwift.framework in Embed Frameworks */,
519ED44024482629007F8E94 /* FeedProvider.framework in Embed Frameworks */,
51C451F52264C83900C03939 /* Articles.framework in Embed Frameworks */,
51C451E92264C81000C03939 /* RSDatabase.framework in Embed Frameworks */,
51554C31228B71A10055115A /* SyncDatabase.framework in Embed Frameworks */,
@@ -1463,8 +1467,8 @@
51627A6823861DED007B3B4B /* MasterFeedViewController+Drop.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MasterFeedViewController+Drop.swift"; sourceTree = "<group>"; };
51627A6A238629D8007B3B4B /* MasterFeedDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MasterFeedDataSource.swift; sourceTree = "<group>"; };
51627A92238A3836007B3B4B /* CroppingPreviewParameters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CroppingPreviewParameters.swift; sourceTree = "<group>"; };
516A091D23609A3600EAE89B /* SettingsAccountTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SettingsAccountTableViewCell.xib; sourceTree = "<group>"; };
516A09382360A2AE00EAE89B /* SettingsAccountTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsAccountTableViewCell.swift; sourceTree = "<group>"; };
516A091D23609A3600EAE89B /* SettingsComboTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SettingsComboTableViewCell.xib; sourceTree = "<group>"; };
516A09382360A2AE00EAE89B /* SettingsComboTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsComboTableViewCell.swift; sourceTree = "<group>"; };
516A093A2360A4A000EAE89B /* SettingsTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SettingsTableViewCell.xib; sourceTree = "<group>"; };
516A093F2361240900EAE89B /* Account.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Account.storyboard; sourceTree = "<group>"; };
516A09412361248000EAE89B /* Inspector.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Inspector.storyboard; sourceTree = "<group>"; };
@@ -1490,6 +1494,9 @@
51938DF1231AFC660055A1A0 /* SearchTimelineFeedDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchTimelineFeedDelegate.swift; sourceTree = "<group>"; };
519B8D322143397200FA689C /* SharingServiceDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharingServiceDelegate.swift; sourceTree = "<group>"; };
519E743422C663F900A78E47 /* SceneDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
519ED455244828C3007F8E94 /* AddExtensionPointViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddExtensionPointViewController.swift; sourceTree = "<group>"; };
519ED47924482AEB007F8E94 /* EnableExtensionPointViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnableExtensionPointViewController.swift; sourceTree = "<group>"; };
519ED47B24488C6F007F8E94 /* ExtensionInspectorViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionInspectorViewController.swift; sourceTree = "<group>"; };
51A1698F235E10D600EB091F /* LocalAccountViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocalAccountViewController.swift; sourceTree = "<group>"; };
51A16990235E10D600EB091F /* Settings.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Settings.storyboard; sourceTree = "<group>"; };
51A16991235E10D600EB091F /* AccountInspectorViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountInspectorViewController.swift; sourceTree = "<group>"; };
@@ -1885,6 +1892,7 @@
51C451E82264C81000C03939 /* RSDatabase.framework in Frameworks */,
51E4DB082425F9EB0091EB5B /* CloudKit.framework in Frameworks */,
51C451EC2264C81B00C03939 /* RSCore.framework in Frameworks */,
519ED43F24482629007F8E94 /* FeedProvider.framework in Frameworks */,
51554C30228B71A10055115A /* SyncDatabase.framework in Frameworks */,
51C451E42264C80600C03939 /* RSParser.framework in Frameworks */,
);
@@ -1982,8 +1990,9 @@
children = (
516A09412361248000EAE89B /* Inspector.storyboard */,
51A16991235E10D600EB091F /* AccountInspectorViewController.swift */,
5141E7382373C18B0013FF27 /* WebFeedInspectorViewController.swift */,
519ED47B24488C6F007F8E94 /* ExtensionInspectorViewController.swift */,
5110C37C2373A8D100A9C04F /* InspectorIconHeaderView.swift */,
5141E7382373C18B0013FF27 /* WebFeedInspectorViewController.swift */,
);
path = Inspector;
sourceTree = "<group>";
@@ -2111,9 +2120,11 @@
51A16990235E10D600EB091F /* Settings.storyboard */,
51A16995235E10D600EB091F /* AboutViewController.swift */,
51A16992235E10D600EB091F /* AddAccountViewController.swift */,
519ED47924482AEB007F8E94 /* EnableExtensionPointViewController.swift */,
519ED455244828C3007F8E94 /* AddExtensionPointViewController.swift */,
516244E2241E19F000B61C47 /* ColorPaletteTableViewController.swift */,
516A09382360A2AE00EAE89B /* SettingsAccountTableViewCell.swift */,
516A091D23609A3600EAE89B /* SettingsAccountTableViewCell.xib */,
516A09382360A2AE00EAE89B /* SettingsComboTableViewCell.swift */,
516A091D23609A3600EAE89B /* SettingsComboTableViewCell.xib */,
516A093A2360A4A000EAE89B /* SettingsTableViewCell.xib */,
51A16993235E10D600EB091F /* SettingsViewController.swift */,
5108F6D12375EED2001ABC45 /* TimelineCustomizerViewController.swift */,
@@ -3824,7 +3835,7 @@
511D43D2231FA62C00FB1562 /* GlobalKeyboardShortcuts.plist in Resources */,
84C9FCA12262A1B300D921D6 /* Main.storyboard in Resources */,
51BB7C312335ACDE008E8144 /* page.html in Resources */,
516A093723609A3600EAE89B /* SettingsAccountTableViewCell.xib in Resources */,
516A093723609A3600EAE89B /* SettingsComboTableViewCell.xib in Resources */,
51F85BF32272531500C787DC /* Dedication.rtf in Resources */,
516A09422361248000EAE89B /* Inspector.storyboard in Resources */,
5103A9B424216A4200410853 /* blank.html in Resources */,
@@ -4254,6 +4265,7 @@
51F85BFD2275DCA800C787DC /* SingleLineUILabelSizer.swift in Sources */,
517630232336657E00E15FFF /* WebViewProvider.swift in Sources */,
51E43962238037C400015C31 /* AddWebFeedFolderViewController.swift in Sources */,
519ED47A24482AEB007F8E94 /* EnableExtensionPointViewController.swift in Sources */,
51C4528F226509BD00C03939 /* UnreadFeed.swift in Sources */,
51FD413B2342BD0500880194 /* MasterTimelineUnreadCountView.swift in Sources */,
513146B2235A81A400387FDC /* AddWebFeedIntentHandler.swift in Sources */,
@@ -4261,7 +4273,7 @@
51C452772265091600C03939 /* MultilineUILabelSizer.swift in Sources */,
51C452A522650A2D00C03939 /* SmallIconProvider.swift in Sources */,
51AB8AB323B7F4C6008F147D /* WebViewController.swift in Sources */,
516A09392360A2AE00EAE89B /* SettingsAccountTableViewCell.swift in Sources */,
516A09392360A2AE00EAE89B /* SettingsComboTableViewCell.swift in Sources */,
3B3A32A5238B820900314204 /* FeedWranglerAccountViewController.swift in Sources */,
51D5948722668EFA00DFC836 /* MarkStatusCommand.swift in Sources */,
51A1699C235E10D700EB091F /* AddAccountViewController.swift in Sources */,
@@ -4286,6 +4298,7 @@
51C45294226509C800C03939 /* SearchFeedDelegate.swift in Sources */,
5F323809231DF9F000706F6B /* VibrantTableViewCell.swift in Sources */,
51FE10042345529D0056195D /* UserNotificationManager.swift in Sources */,
519ED47C24488C6F007F8E94 /* ExtensionInspectorViewController.swift in Sources */,
51C452A022650A1900C03939 /* WebFeedIconDownloader.swift in Sources */,
51C4529E22650A1900C03939 /* ImageDownloader.swift in Sources */,
51A66685238075AE00CB272D /* AddWebFeedDefaultContainer.swift in Sources */,
@@ -4358,11 +4371,11 @@
51DC370B2405BC9A0095D371 /* PreloadedWebView.swift in Sources */,
C5A6ED5223C9AF4300AB6BE2 /* TitleActivityItemSource.swift in Sources */,
51DC37092402F1470095D371 /* MasterFeedDataSourceOperation.swift in Sources */,
515A517E243E90260089E588 /* SendToMarsEditCommand.swift in Sources */,
51C4529B22650A1000C03939 /* FaviconDownloader.swift in Sources */,
84DEE56622C32CA4005FC42C /* SmartFeedDelegate.swift in Sources */,
512E09012268907400BDCFDD /* MasterFeedTableViewSectionHeader.swift in Sources */,
516AE9E02372269A007DEEAA /* IconImage.swift in Sources */,
519ED456244828C3007F8E94 /* AddExtensionPointViewController.swift in Sources */,
51C45268226508F600C03939 /* MasterFeedUnreadCountView.swift in Sources */,
5183CCD0226E1E880010922C /* NonIntrinsicLabel.swift in Sources */,
51C4529F22650A1900C03939 /* AuthorAvatarDownloader.swift in Sources */,
@@ -4372,7 +4385,6 @@
51C452A322650A1E00C03939 /* HTMLMetadataDownloader.swift in Sources */,
51C4528D2265095F00C03939 /* AddFolderViewController.swift in Sources */,
51DC37072402153E0095D371 /* UpdateSelectionOperation.swift in Sources */,
515A517F243E90260089E588 /* SendToMicroBlogCommand.swift in Sources */,
51C452782265091600C03939 /* MasterTimelineCellData.swift in Sources */,
5148F4552336DB7000F8CD8B /* MasterTimelineTitleView.swift in Sources */,
515A517C243E90260089E588 /* ExtensionPointManager.swift in Sources */,

View File

@@ -6,7 +6,11 @@
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import Foundation
#if os(macOS)
import AppKit
#else
import UIKit
#endif
import RSCore
protocol ExtensionPoint {
@@ -35,11 +39,19 @@ extension ExtensionPoint {
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
#if os(macOS)
let attrs = [
NSAttributedString.Key.paragraphStyle: paragraphStyle,
NSAttributedString.Key.font: NSFont.systemFont(ofSize: NSFont.systemFontSize),
NSAttributedString.Key.foregroundColor: NSColor.textColor
]
#else
let attrs = [
NSAttributedString.Key.paragraphStyle: paragraphStyle,
NSAttributedString.Key.font: UIFont.preferredFont(forTextStyle: .body),
NSAttributedString.Key.foregroundColor: UIColor.label
]
#endif
return NSMutableAttributedString(string: text, attributes: attrs)
}

View File

@@ -11,16 +11,20 @@ import FeedProvider
import RSCore
enum ExtensionPointIdentifer: Hashable {
#if os(macOS)
case marsEdit
case microblog
#endif
case twitter(String, String)
var extensionPointType: ExtensionPoint.Type {
switch self {
#if os(macOS)
case .marsEdit:
return SendToMarsEditCommand.self
case .microblog:
return SendToMicroBlogCommand.self
#endif
case .twitter:
return TwitterFeedProvider.self
}
@@ -28,6 +32,7 @@ enum ExtensionPointIdentifer: Hashable {
public var userInfo: [AnyHashable: AnyHashable] {
switch self {
#if os(macOS)
case .marsEdit:
return [
"type": "marsEdit"
@@ -36,6 +41,7 @@ enum ExtensionPointIdentifer: Hashable {
return [
"type": "microblog"
]
#endif
case .twitter(let userID, let screenName):
return [
"type": "twitter",
@@ -49,10 +55,12 @@ enum ExtensionPointIdentifer: Hashable {
guard let type = userInfo["type"] as? String else { return nil }
switch type {
#if os(macOS)
case "marsEdit":
self = ExtensionPointIdentifer.marsEdit
case "microblog":
self = ExtensionPointIdentifer.microblog
#endif
case "twitter":
guard let userID = userInfo["userID"] as? String, let screenName = userInfo["screenName"] as? String else { return nil }
self = ExtensionPointIdentifer.twitter(userID, screenName)
@@ -63,10 +71,12 @@ enum ExtensionPointIdentifer: Hashable {
public func hash(into hasher: inout Hasher) {
switch self {
#if os(macOS)
case .marsEdit:
hasher.combine("marsEdit")
case .microblog:
hasher.combine("microblog")
#endif
case .twitter(let userID, let screenName):
hasher.combine("twitter")
hasher.combine(userID)

View File

@@ -103,10 +103,12 @@ private extension ExtensionPointManager {
func extensionPoint(for extensionPointType: ExtensionPoint.Type, tokenSuccess: OAuthSwift.TokenSuccess?) -> ExtensionPoint? {
switch extensionPointType {
#if os(macOS)
case is SendToMarsEditCommand.Type:
return SendToMarsEditCommand()
case is SendToMicroBlogCommand.Type:
return SendToMicroBlogCommand()
#endif
case is TwitterFeedProvider.Type:
if let tokenSuccess = tokenSuccess {
return TwitterFeedProvider(tokenSuccess: tokenSuccess)
@@ -121,10 +123,12 @@ private extension ExtensionPointManager {
func extensionPoint(for extensionPointID: ExtensionPointIdentifer) -> ExtensionPoint? {
switch extensionPointID {
#if os(macOS)
case .marsEdit:
return SendToMarsEditCommand()
case .microblog:
return SendToMicroBlogCommand()
#endif
case .twitter(let userID, let screenName):
return TwitterFeedProvider(userID: userID, screenName: screenName)
}

View File

@@ -18,13 +18,7 @@ extension TwitterFeedProvider: ExtensionPoint {
static var title = NSLocalizedString("Twitter", comment: "Twitter")
static var templateImage = AppAssets.extensionPointTwitter
static var description: NSAttributedString = {
let attrString = TwitterFeedProvider.makeAttrString("This extension enables you to subscribe to Twitter URL's as if they were RSS feeds.")
let range = NSRange(location: 43, length: 7)
attrString.beginEditing()
attrString.addAttribute(NSAttributedString.Key.link, value: "https://twitter.com", range: range)
attrString.addAttribute(NSAttributedString.Key.foregroundColor, value: NSColor.systemBlue, range: range)
attrString.endEditing()
return attrString
return TwitterFeedProvider.makeAttrString("This extension enables you to subscribe to Twitter URL's as if they were RSS feeds.")
}()
var extensionPointID: ExtensionPointIdentifer {

View File

@@ -28,10 +28,11 @@ struct CacheCleaner {
let tempDir = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!
let faviconsFolderURL = tempDir.appendingPathComponent("Favicons")
let imagesFolderURL = tempDir.appendingPathComponent("Images")
let feedURLToIconURL = tempDir.appendingPathComponent("FeedURLToIconURLCache.plist")
let homePageToIconURL = tempDir.appendingPathComponent("HomePageToIconURLCache.plist")
let homePagesWithNoIconURL = tempDir.appendingPathComponent("HomePagesWithNoIconURLCache.plist")
for tempItem in [faviconsFolderURL, imagesFolderURL, homePageToIconURL, homePagesWithNoIconURL] {
for tempItem in [faviconsFolderURL, imagesFolderURL, feedURLToIconURL, homePageToIconURL, homePagesWithNoIconURL] {
do {
os_log(.info, log: self.log, "Removing cache file: %@", tempItem.absoluteString)
try FileManager.default.removeItem(at: tempItem)

View File

@@ -2,7 +2,7 @@
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16086"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>

View File

@@ -9,6 +9,7 @@
import UIKit
import Account
import RSWeb
import Secrets
class FeedWranglerAccountViewController: UITableViewController {

View File

@@ -8,6 +8,7 @@
import UIKit
import Account
import Secrets
import RSWeb
class FeedbinAccountViewController: UITableViewController {

View File

@@ -8,6 +8,7 @@
import UIKit
import Account
import Secrets
import RSWeb
class NewsBlurAccountViewController: UITableViewController {

View File

@@ -101,6 +101,10 @@ struct AppAssets {
UIImage(systemName: "square.and.pencil")!
}()
static var extensionPointTwitter: UIImage = {
return UIImage(named: "extensionPointTwitter")!
}()
static var faviconTemplateImage: RSImage = {
return RSImage(named: "faviconTemplateImage")!
}()

View File

@@ -36,6 +36,7 @@ struct AppDefaults {
struct Key {
static let userInterfaceColorPalette = "userInterfaceColorPalette"
static let activeExtensionPointIDs = "activeExtensionPointIDs"
static let lastImageCacheFlushDate = "lastImageCacheFlushDate"
static let firstRunDate = "firstRunDate"
static let timelineGroupByFeed = "timelineGroupByFeed"
@@ -106,6 +107,15 @@ struct AppDefaults {
}
}
static var activeExtensionPointIDs: [[AnyHashable : AnyHashable]]? {
get {
return UserDefaults.standard.object(forKey: Key.activeExtensionPointIDs) as? [[AnyHashable : AnyHashable]]
}
set {
UserDefaults.standard.set(newValue, forKey: Key.activeExtensionPointIDs)
}
}
static var lastImageCacheFlushDate: Date? {
get {
return date(for: Key.lastImageCacheFlushDate)

View File

@@ -0,0 +1,63 @@
//
// ExtensionPointInspectorViewController.swift
// NetNewsWire-iOS
//
// Created by Maurice Parker on 4/16/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import UIKit
class ExtensionPointInspectorViewController: UITableViewController {
@IBOutlet weak var extensionDescription: UILabel!
var extensionPoint: ExtensionPoint?
override func viewDidLoad() {
super.viewDidLoad()
guard let extensionPoint = extensionPoint else { return }
navigationItem.title = extensionPoint.title
extensionDescription.attributedText = extensionPoint.description
tableView.register(ImageHeaderView.self, forHeaderFooterViewReuseIdentifier: "SectionHeader")
}
@IBAction func disable(_ sender: Any) {
guard let extensionPoint = extensionPoint else { return }
ExtensionPointManager.shared.deactivateExtensionPoint(extensionPoint.extensionPointID)
self.navigationController?.popViewController(animated: true)
}
}
// MARK: Table View
extension ExtensionPointInspectorViewController {
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return section == 0 ? ImageHeaderView.rowHeight : super.tableView(tableView, heightForHeaderInSection: section)
}
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
guard let extensionPoint = extensionPoint else { return nil }
if section == 0 {
let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "SectionHeader") as! ImageHeaderView
headerView.imageView.image = extensionPoint.templateImage
return headerView
} else {
return super.tableView(tableView, viewForHeaderInSection: section)
}
}
override func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
if indexPath.section > 0 {
return true
}
return false
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
}
}

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
@@ -25,10 +25,10 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" spacing="19" translatesAutoresizingMaskIntoConstraints="NO" id="mQa-0W-eVS">
<rect key="frame" x="20" y="11.5" width="334" height="21"/>
<rect key="frame" x="20" y="11" width="334" height="22"/>
<subviews>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Name (Optional)" adjustsFontForContentSizeCategory="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="LUW-uv-piz">
<rect key="frame" x="0.0" y="0.0" width="334" height="21"/>
<rect key="frame" x="0.0" y="0.0" width="334" height="22"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<textInputTraits key="textInputTraits" autocapitalizationType="words"/>
</textField>
@@ -176,7 +176,7 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Name" textAlignment="natural" adjustsFontForContentSizeCategory="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="ZdA-rl-9eP">
<rect key="frame" x="20" y="11.5" width="334" height="21"/>
<rect key="frame" x="20" y="11" width="334" height="22"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<textInputTraits key="textInputTraits" autocapitalizationType="words"/>
</textField>
@@ -377,10 +377,99 @@
</objects>
<point key="canvasLocation" x="157" y="-591"/>
</scene>
<!--Extension Point Inspector View Controller-->
<scene sceneID="OYN-w4-caJ">
<objects>
<tableViewController storyboardIdentifier="ExtensionPointInspectorViewController" id="1B7-3Y-VYf" customClass="ExtensionPointInspectorViewController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="insetGrouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="sMo-hq-Gps">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<sections>
<tableViewSection id="hGI-fH-ovr">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" id="hx7-HU-HV2" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="18" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="hx7-HU-HV2" id="fEV-cR-i6h">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="YJL-5w-N2S">
<rect key="frame" x="20" y="11" width="334" height="22"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstItem="YJL-5w-N2S" firstAttribute="leading" secondItem="fEV-cR-i6h" secondAttribute="leadingMargin" id="kx6-6v-VNw"/>
<constraint firstItem="YJL-5w-N2S" firstAttribute="top" secondItem="fEV-cR-i6h" secondAttribute="topMargin" id="l6Y-A0-BFs"/>
<constraint firstAttribute="bottomMargin" secondItem="YJL-5w-N2S" secondAttribute="bottom" id="nKi-1U-g6E"/>
<constraint firstAttribute="trailingMargin" secondItem="YJL-5w-N2S" secondAttribute="trailing" id="o5n-Co-7RG"/>
</constraints>
</tableViewCellContentView>
</tableViewCell>
</cells>
</tableViewSection>
<tableViewSection id="OcC-FF-jGv">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" id="k4j-va-uaO" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="98" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="k4j-va-uaO" id="bQ8-mc-QAj">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="IhW-3B-PM7" customClass="VibrantButton" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
<constraints>
<constraint firstAttribute="height" constant="44" id="qwy-Nb-VrG"/>
</constraints>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<state key="normal" title="Disable Extension">
<color key="titleColor" systemColor="systemRedColor" red="1" green="0.23137254900000001" blue="0.18823529410000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted">
<color key="titleColor" systemColor="systemRedColor" red="1" green="0.23137254900000001" blue="0.18823529410000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="color" keyPath="backgroundHighlightColor">
<color key="value" name="deleteBackgroundColor"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
<connections>
<action selector="disable:" destination="1B7-3Y-VYf" eventType="touchUpInside" id="hVd-LH-FhC"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="IhW-3B-PM7" firstAttribute="centerY" secondItem="bQ8-mc-QAj" secondAttribute="centerY" id="DLY-b7-amc"/>
<constraint firstItem="IhW-3B-PM7" firstAttribute="leading" secondItem="bQ8-mc-QAj" secondAttribute="leading" id="LlY-8t-XJf"/>
<constraint firstAttribute="trailing" secondItem="IhW-3B-PM7" secondAttribute="trailing" id="Ua9-qY-YaN"/>
</constraints>
</tableViewCellContentView>
</tableViewCell>
</cells>
</tableViewSection>
</sections>
<connections>
<outlet property="dataSource" destination="1B7-3Y-VYf" id="Ro3-xz-VDK"/>
<outlet property="delegate" destination="1B7-3Y-VYf" id="X3w-Zg-zKw"/>
</connections>
</tableView>
<navigationItem key="navigationItem" id="bBU-mK-vL1"/>
<connections>
<outlet property="extensionDescription" destination="YJL-5w-N2S" id="zam-r3-KIC"/>
</connections>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="cc3-yd-zmS" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1549" y="-591"/>
</scene>
</scenes>
<resources>
<image name="safari" catalog="system" width="64" height="60"/>
<image name="safari.fill" catalog="system" width="64" height="60"/>
<image name="safari" catalog="system" width="128" height="121"/>
<image name="safari.fill" catalog="system" width="128" height="121"/>
<namedColor name="deleteBackgroundColor">
<color red="1" green="0.23100000619888306" blue="0.18799999356269836" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>

View File

@@ -0,0 +1,15 @@
{
"images" : [
{
"filename" : "twitter.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}

View File

@@ -40,27 +40,27 @@ class AddAccountViewController: UITableViewController, AddAccountDismissDelegate
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SettingsAccountTableViewCell", for: indexPath) as! SettingsAccountTableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "SettingsAccountTableViewCell", for: indexPath) as! SettingsComboTableViewCell
switch addableAccountTypes[indexPath.row] {
case .onMyMac:
cell.accountNameLabel?.text = Account.defaultLocalAccountName
cell.accountImage?.image = AppAssets.image(for: .onMyMac)
cell.comboNameLabel?.text = Account.defaultLocalAccountName
cell.comboImage?.image = AppAssets.image(for: .onMyMac)
case .cloudKit:
cell.accountNameLabel?.text = NSLocalizedString("iCloud", comment: "iCloud")
cell.accountImage?.image = AppAssets.accountCloudKitImage
cell.comboNameLabel?.text = NSLocalizedString("iCloud", comment: "iCloud")
cell.comboImage?.image = AppAssets.accountCloudKitImage
case .feedbin:
cell.accountNameLabel?.text = NSLocalizedString("Feedbin", comment: "Feedbin")
cell.accountImage?.image = AppAssets.accountFeedbinImage
cell.comboNameLabel?.text = NSLocalizedString("Feedbin", comment: "Feedbin")
cell.comboImage?.image = AppAssets.accountFeedbinImage
case .feedWrangler:
cell.accountNameLabel?.text = NSLocalizedString("Feed Wrangler", comment: "Feed Wrangler")
cell.accountImage?.image = AppAssets.accountFeedWranglerImage
cell.comboNameLabel?.text = NSLocalizedString("Feed Wrangler", comment: "Feed Wrangler")
cell.comboImage?.image = AppAssets.accountFeedWranglerImage
case .feedly:
cell.accountNameLabel?.text = NSLocalizedString("Feedly", comment: "Feedly")
cell.accountImage?.image = AppAssets.accountFeedlyImage
cell.comboNameLabel?.text = NSLocalizedString("Feedly", comment: "Feedly")
cell.comboImage?.image = AppAssets.accountFeedlyImage
case .newsBlur:
cell.accountNameLabel?.text = NSLocalizedString("NewsBlur", comment: "NewsBlur")
cell.accountImage?.image = AppAssets.accountNewsBlurImage
cell.comboNameLabel?.text = NSLocalizedString("NewsBlur", comment: "NewsBlur")
cell.comboImage?.image = AppAssets.accountNewsBlurImage
default:
break
}

View File

@@ -0,0 +1,59 @@
//
// AddExtensionPointViewController.swift
// NetNewsWire-iOS
//
// Created by Maurice Parker on 4/16/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import UIKit
protocol AddExtensionPointDismissDelegate: UIViewController {
func dismiss()
}
class AddExtensionPointViewController: UITableViewController, AddExtensionPointDismissDelegate {
private var availableExtensionPointTypes = [ExtensionPoint.Type]()
override func viewDidLoad() {
super.viewDidLoad()
availableExtensionPointTypes = ExtensionPointManager.shared.availableExtensionPointTypes
}
override func numberOfSections(in tableView: UITableView) -> Int {
1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return availableExtensionPointTypes.count
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 52.0
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SettingsExtensionTableViewCell", for: indexPath) as! SettingsComboTableViewCell
let extensionPointType = availableExtensionPointTypes[indexPath.row]
cell.comboNameLabel?.text = extensionPointType.title
cell.comboImage?.image = extensionPointType.templateImage
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let navController = UIStoryboard.settings.instantiateViewController(withIdentifier: "EnableExtensionPointNavigationViewController") as! UINavigationController
navController.modalPresentationStyle = .currentContext
let enableViewController = navController.topViewController as! EnableExtensionPointViewController
enableViewController.delegate = self
enableViewController.extensionPointType = availableExtensionPointTypes[indexPath.row]
present(navController, animated: true)
}
func dismiss() {
navigationController?.popViewController(animated: false)
}
}

View File

@@ -0,0 +1,59 @@
//
// AddExtensionViewContrller.swift
// NetNewsWire-iOS
//
// Created by Maurice Parker on 4/16/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import UIKit
protocol AddExtensionDismissDelegate: UIViewController {
func dismiss()
}
class AddExtensionViewController: UITableViewController, AddExtensionDismissDelegate {
private var availableExtensionPointTypes = [ExtensionPoint.Type]()
override func viewDidLoad() {
super.viewDidLoad()
availableExtensionPointTypes = ExtensionPointManager.shared.availableExtensionPointTypes
}
override func numberOfSections(in tableView: UITableView) -> Int {
1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return availableExtensionPointTypes.count
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 52.0
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SettingsExtensionTableViewCell", for: indexPath) as! SettingsComboTableViewCell
let extensionPointType = availableExtensionPointTypes[indexPath.row]
cell.comboNameLabel?.text = extensionPointType.title
cell.comboImage?.image = extensionPointType.templateImage
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let navController = UIStoryboard.settings.instantiateViewController(withIdentifier: "EnableExtensiontNavigationViewController") as! UINavigationController
navController.modalPresentationStyle = .currentContext
let enableViewController = navController.topViewController as! EnableExtensionViewController
enableViewController.delegate = self
enableViewController.extensionPointType = availableExtensionPointTypes[indexPath.row]
present(navController, animated: true)
}
func dismiss() {
navigationController?.popViewController(animated: false)
}
}

View File

@@ -0,0 +1,132 @@
//
// EnableExtensionPointViewController.swift
// NetNewsWire-iOS
//
// Created by Maurice Parker on 4/16/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import UIKit
import AuthenticationServices
import Account
import OAuthSwift
import Secrets
class EnableExtensionPointViewController: UITableViewController {
@IBOutlet weak var extensionDescription: UILabel!
private let callbackURL = URL(string: "vincodennw://")!
private var oauth: OAuthSwift?
weak var delegate: AddExtensionPointDismissDelegate?
var extensionPointType: ExtensionPoint.Type?
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = extensionPointType?.title
extensionDescription.attributedText = extensionPointType?.description
tableView.register(ImageHeaderView.self, forHeaderFooterViewReuseIdentifier: "SectionHeader")
}
@IBAction func cancel(_ sender: Any) {
dismiss(animated: true, completion: nil)
delegate?.dismiss()
}
@IBAction func enable(_ sender: Any) {
guard let extensionPointType = extensionPointType else { return }
if let oauth1 = extensionPointType as? OAuth1SwiftProvider.Type {
enableOauth1(oauth1)
} else {
ExtensionPointManager.shared.activateExtensionPoint(extensionPointType)
dismiss(animated: true, completion: nil)
delegate?.dismiss()
}
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return section == 0 ? ImageHeaderView.rowHeight : super.tableView(tableView, heightForHeaderInSection: section)
}
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if section == 0 {
let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "SectionHeader") as! ImageHeaderView
headerView.imageView.image = extensionPointType?.templateImage
return headerView
} else {
return super.tableView(tableView, viewForHeaderInSection: section)
}
}
}
extension EnableExtensionPointViewController: OAuthSwiftURLHandlerType {
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 {
print("Login cancelled.")
} else {
self.presentError(error)
}
})
session.presentationContextProvider = self
if !session.start() {
print("Session failed to start!!!")
}
}
}
extension EnableExtensionPointViewController: ASWebAuthenticationPresentationContextProviding {
public func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
return view.window!
}
}
private extension EnableExtensionPointViewController {
func enableOauth1(_ provider: OAuth1SwiftProvider.Type) {
let oauth1 = provider.oauth1Swift
self.oauth = oauth1
oauth1.authorizeURLHandler = self
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)
self.dismiss(animated: true, completion: nil)
self.delegate?.dismiss()
case .failure(let oauthSwiftError):
self.presentError(oauthSwiftError)
}
self.oauth?.cancel()
self.oauth = nil
}
}
}

View File

@@ -0,0 +1,132 @@
//
// EnableExtensionViewController.swift
// NetNewsWire-iOS
//
// Created by Maurice Parker on 4/16/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import UIKit
import AuthenticationServices
import Account
import OAuthSwift
import Secrets
class EnableExtensionPointViewController: UITableViewController {
@IBOutlet weak var extensionDescription: UILabel!
private let callbackURL = URL(string: "vincodennw://")!
private var oauth: OAuthSwift?
weak var delegate: AddExtensionPointDismissDelegate?
var extensionPointType: ExtensionPoint.Type?
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = extensionPointType?.title ?? ""
extensionDescription = extensionPointType?.extensionDescription ?? ""
tableView.register(ImageHeaderView.self, forHeaderFooterViewReuseIdentifier: "SectionHeader")
}
@IBAction func cancel(_ sender: Any) {
dismiss(animated: true, completion: nil)
delegate?.dismiss()
}
@IBAction func enable(_ sender: Any) {
guard let extensionPointType = extensionPointType else { return }
if let oauth1 = extensionPointType as? OAuth1SwiftProvider.Type {
enableOauth1(oauth1)
} else {
ExtensionPointManager.shared.activateExtensionPoint(extensionPointType)
dismiss(animated: true, completion: nil)
delegate?.dismiss()
}
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return section == 0 ? ImageHeaderView.rowHeight : super.tableView(tableView, heightForHeaderInSection: section)
}
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if section == 0 {
let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "SectionHeader") as! ImageHeaderView
headerView.imageView.image = extensionPointType?.templateImage
return headerView
} else {
return super.tableView(tableView, viewForHeaderInSection: section)
}
}
}
extension EnableExtensionPointViewController: OAuthSwiftURLHandlerType {
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 {
print("Login cancelled.")
} else {
self.presentError(error)
}
})
session.presentationContextProvider = self
if !session.start() {
print("Session failed to start!!!")
}
}
}
extension EnableExtensionPointViewController: ASWebAuthenticationPresentationContextProviding {
public func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
return view.window!
}
}
private extension EnableExtensionPointViewController {
func enableOauth1(_ provider: OAuth1SwiftProvider.Type) {
let oauth1 = provider.oauth1Swift
self.oauth = oauth1
oauth1.authorizeURLHandler = self
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)
self.dismiss(animated: true, completion: nil)
self.delegate?.dismiss()
case .failure(let oauthSwiftError):
self.presentError(oauthSwiftError)
}
self.oauth?.cancel()
self.oauth = nil
}
}
}

View File

@@ -2,7 +2,7 @@
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="9cW-lu-HoC">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16086"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
@@ -58,10 +58,31 @@
</tableViewCell>
</cells>
</tableViewSection>
<tableViewSection headerTitle="Extensions" id="oRB-NZ-WpG">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="QFr-Rs-eW2" style="IBUITableViewCellStyleDefault" id="6QJ-fX-278" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="255.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="6QJ-fX-278" id="PDs-8c-XUa">
<rect key="frame" x="0.0" y="0.0" width="343" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Add Extension" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="QFr-Rs-eW2">
<rect key="frame" x="20" y="0.0" width="315" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
</tableViewCell>
</cells>
</tableViewSection>
<tableViewSection headerTitle="Feeds" id="hAC-uA-RbS">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="4Hg-B3-zAE" style="IBUITableViewCellStyleDefault" id="glf-Pg-s3P" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="255.5" width="374" height="44"/>
<rect key="frame" x="20" y="355.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="glf-Pg-s3P" id="bPA-43-Oqh">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
@@ -78,7 +99,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="25J-iX-3at" style="IBUITableViewCellStyleDefault" id="qke-Ha-PXl" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="299.5" width="374" height="44"/>
<rect key="frame" x="20" y="399.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="qke-Ha-PXl" id="pZi-ck-RV5">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
@@ -95,7 +116,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="dXN-Mw-yf2" style="IBUITableViewCellStyleDefault" id="F0L-Ut-reX" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="343.5" width="374" height="44"/>
<rect key="frame" x="20" y="443.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="F0L-Ut-reX" id="5SX-M2-2jR">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
@@ -116,7 +137,7 @@
<tableViewSection headerTitle="Timeline" id="9Pk-Y8-JVJ">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="MpA-w1-Wwh" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="443.5" width="374" height="44"/>
<rect key="frame" x="20" y="543.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="MpA-w1-Wwh" id="GhU-ib-Mz8">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
@@ -149,7 +170,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="f7r-AZ-aDn" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="487.5" width="374" height="44"/>
<rect key="frame" x="20" y="587.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="f7r-AZ-aDn" id="KHC-cc-tOC">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
@@ -182,7 +203,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="5wo-fM-0l6" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="531.5" width="374" height="44"/>
<rect key="frame" x="20" y="631.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="5wo-fM-0l6" id="XAn-lK-LoN">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
@@ -215,7 +236,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" id="8Gj-qz-NMY" customClass="VibrantBasicTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="575.5" width="374" height="44"/>
<rect key="frame" x="20" y="675.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="8Gj-qz-NMY" id="OTe-tG-sb4">
<rect key="frame" x="0.0" y="0.0" width="343" height="44"/>
@@ -242,7 +263,7 @@
<tableViewSection headerTitle="Articles" id="TRr-Ew-IvU">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="SXs-NQ-y3U" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="675.5" width="374" height="44"/>
<rect key="frame" x="20" y="775.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="SXs-NQ-y3U" id="BpI-Hz-KH2">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
@@ -275,7 +296,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="WR6-xo-ty2" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="719.5" width="374" height="44"/>
<rect key="frame" x="20" y="819.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="WR6-xo-ty2" id="zX8-l2-bVH">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
@@ -320,7 +341,7 @@
<tableViewSection headerTitle="Appearance" id="TkH-4v-yhk">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" id="EvG-yE-gDF" customClass="VibrantBasicTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="819.5" width="374" height="44"/>
<rect key="frame" x="20" y="919.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="EvG-yE-gDF" id="wBN-zJ-6pN">
<rect key="frame" x="0.0" y="0.0" width="343" height="44"/>
@@ -356,14 +377,14 @@
<tableViewSection headerTitle="Help" id="CS8-fJ-ghn">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="uGk-2d-oFc" style="IBUITableViewCellStyleDefault" id="Tle-IV-D40" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="919.5" width="374" height="44"/>
<rect key="frame" x="20" y="1019.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="Tle-IV-D40" id="IJD-ZB-8Wm">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="NetNewsWire Help" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="uGk-2d-oFc">
<rect key="frame" x="20" y="0.0" width="334" height="44"/>
<rect key="frame" x="15" y="0.0" width="351" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
@@ -373,14 +394,14 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="6G3-yV-Eyh" style="IBUITableViewCellStyleDefault" id="Tbf-fE-nfx" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="963.5" width="374" height="44"/>
<rect key="frame" x="20" y="1063.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="Tbf-fE-nfx" id="beV-vI-g3r">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Website" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="6G3-yV-Eyh">
<rect key="frame" x="20" y="0.0" width="334" height="44"/>
<rect key="frame" x="15" y="0.0" width="351" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
@@ -390,7 +411,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="lfL-bQ-sOp" style="IBUITableViewCellStyleDefault" id="mFn-fE-zqa" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="1007.5" width="374" height="44"/>
<rect key="frame" x="20" y="1107.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="mFn-fE-zqa" id="jTe-mf-MRj">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
@@ -407,7 +428,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="DDJ-8P-3YY" style="IBUITableViewCellStyleDefault" id="iGs-ze-4gQ" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="1051.5" width="374" height="44"/>
<rect key="frame" x="20" y="1151.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="iGs-ze-4gQ" id="EqZ-rF-N0l">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
@@ -424,7 +445,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="DsV-Qv-X4K" style="IBUITableViewCellStyleDefault" id="taJ-sg-wnU" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="1095.5" width="374" height="44"/>
<rect key="frame" x="20" y="1195.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="taJ-sg-wnU" id="axB-si-1KM">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
@@ -441,7 +462,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="zMz-hU-UYU" style="IBUITableViewCellStyleDefault" id="OXi-cg-ab9" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="1139.5" width="374" height="44"/>
<rect key="frame" x="20" y="1239.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="OXi-cg-ab9" id="npR-a0-9wv">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
@@ -458,7 +479,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="T7x-zl-6Yf" style="IBUITableViewCellStyleDefault" id="VpI-0o-3Px" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="1183.5" width="374" height="44"/>
<rect key="frame" x="20" y="1283.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="VpI-0o-3Px" id="xRH-i4-vne">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
@@ -475,7 +496,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="NeD-y8-KrM" style="IBUITableViewCellStyleDefault" id="TIX-yK-rC6" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="1227.5" width="374" height="44"/>
<rect key="frame" x="20" y="1327.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="TIX-yK-rC6" id="qr8-EN-Ofg">
<rect key="frame" x="0.0" y="0.0" width="355" height="44"/>
@@ -527,7 +548,7 @@
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="SettingsAccountTableViewCell" rowHeight="55" id="UFl-6I-ucw" customClass="SettingsAccountTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="SettingsAccountTableViewCell" rowHeight="55" id="UFl-6I-ucw" customClass="SettingsComboTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="55.5" width="374" height="55"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="UFl-6I-ucw" id="99i-Ge-guB">
@@ -560,8 +581,8 @@
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="accountImage" destination="tb2-dO-AhR" id="Ucm-F4-aev"/>
<outlet property="accountNameLabel" destination="116-rt-msI" id="nn5-2i-HqG"/>
<outlet property="comboImage" destination="tb2-dO-AhR" id="2L5-ha-jdX"/>
<outlet property="comboNameLabel" destination="116-rt-msI" id="EJb-1l-k4u"/>
</connections>
</tableViewCell>
</prototypes>
@@ -726,7 +747,7 @@
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="kRt-nH-nOf" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1680" y="151"/>
<point key="canvasLocation" x="2388" y="151"/>
</scene>
<!--Timeline Layout-->
<scene sceneID="XRu-Jc-bbU">
@@ -829,7 +850,7 @@
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iNo-Vj-YZx" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="2346" y="151"/>
<point key="canvasLocation" x="3072" y="151"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="Ezn-Ny-zye">
@@ -885,7 +906,7 @@
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Oq6-5f-Oa7" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="3096" y="151"/>
<point key="canvasLocation" x="3826" y="158"/>
</scene>
<!--Color Palette-->
<scene sceneID="1mT-fg-ezs">
@@ -926,9 +947,170 @@
</objects>
<point key="canvasLocation" x="3743" y="151"/>
</scene>
<!--Add Extension Point View Controller-->
<scene sceneID="e22-Tk-eWN">
<objects>
<tableViewController storyboardIdentifier="AddExtensionPointViewController" id="x52-Ls-0dI" customClass="AddExtensionPointViewController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="insetGrouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="X7z-0u-RKM">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="SettingsExtensionTableViewCell" rowHeight="55" id="SPQ-gc-wuP" customClass="SettingsComboTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="55.5" width="374" height="55"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="SPQ-gc-wuP" id="38G-tD-Eks">
<rect key="frame" x="0.0" y="0.0" width="374" height="55"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="gMc-YX-gQa">
<rect key="frame" x="20" y="11.5" width="165.5" height="32"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="gear" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="fQm-sU-5TF">
<rect key="frame" x="0.0" y="0.0" width="32" height="32.5"/>
<color key="tintColor" systemColor="labelColor" cocoaTouchSystemColor="darkTextColor"/>
<constraints>
<constraint firstAttribute="height" constant="32" id="QJW-VY-n7f"/>
<constraint firstAttribute="width" constant="32" id="T3S-8F-Clj"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Extension" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="zuQ-ty-Tf1">
<rect key="frame" x="48" y="0.0" width="117.5" height="32"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleTitle1"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
</subviews>
<constraints>
<constraint firstItem="gMc-YX-gQa" firstAttribute="leading" secondItem="38G-tD-Eks" secondAttribute="leading" constant="20" symbolic="YES" id="DAz-fZ-LFa"/>
<constraint firstItem="gMc-YX-gQa" firstAttribute="centerY" secondItem="38G-tD-Eks" secondAttribute="centerY" id="Qpo-pr-TGF"/>
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="comboImage" destination="fQm-sU-5TF" id="aFs-Li-lHU"/>
<outlet property="comboNameLabel" destination="zuQ-ty-Tf1" id="uty-Eq-1oX"/>
</connections>
</tableViewCell>
</prototypes>
<sections/>
<connections>
<outlet property="dataSource" destination="x52-Ls-0dI" id="vsT-sk-4aY"/>
<outlet property="delegate" destination="x52-Ls-0dI" id="4Vo-yb-5Mf"/>
</connections>
</tableView>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="A3X-mp-vlt" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1691" y="151"/>
</scene>
<!--Modal Navigation Controller-->
<scene sceneID="t9A-uP-4Dk">
<objects>
<navigationController storyboardIdentifier="EnableExtensionPointNavigationViewController" id="mA0-Yf-esc" customClass="ModalNavigationController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="iXJ-DA-pQC">
<rect key="frame" x="0.0" y="44" width="414" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<connections>
<segue destination="8Eu-UD-eCa" kind="relationship" relationship="rootViewController" id="zE1-0Q-l09"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="g07-xO-ryv" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1690" y="815"/>
</scene>
<!--Extension-->
<scene sceneID="sHq-4g-bAA">
<objects>
<tableViewController id="8Eu-UD-eCa" customClass="EnableExtensionPointViewController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="insetGrouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="hqD-G5-jzC">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<sections>
<tableViewSection id="rqj-gU-4He">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="ALK-Z6-aOR" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="18" width="374" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="ALK-Z6-aOR" id="Rqf-t4-F8q">
<rect key="frame" x="0.0" y="0.0" width="374" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VCu-Yi-0ts">
<rect key="frame" x="20" y="11" width="334" height="22"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstItem="VCu-Yi-0ts" firstAttribute="top" secondItem="Rqf-t4-F8q" secondAttribute="topMargin" id="CiI-mf-hfd"/>
<constraint firstAttribute="bottomMargin" secondItem="VCu-Yi-0ts" secondAttribute="bottom" id="QW3-Ty-Hnz"/>
<constraint firstItem="VCu-Yi-0ts" firstAttribute="leading" secondItem="Rqf-t4-F8q" secondAttribute="leadingMargin" id="R3c-n2-gAq"/>
<constraint firstAttribute="trailingMargin" secondItem="VCu-Yi-0ts" secondAttribute="trailing" id="kS4-Gc-Eaf"/>
</constraints>
</tableViewCellContentView>
</tableViewCell>
</cells>
</tableViewSection>
<tableViewSection id="7Nq-pj-Wqz">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="eZ5-P9-opw" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="97.5" width="374" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="eZ5-P9-opw" id="RlA-Zq-tRl">
<rect key="frame" x="0.0" y="0.0" width="374" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="cY9-Uk-Vlx" customClass="VibrantButton" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
<constraints>
<constraint firstAttribute="height" constant="44" id="KfT-5A-V6M"/>
</constraints>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<state key="normal" title="Enable">
<color key="titleColor" name="secondaryAccentColor"/>
</state>
<connections>
<action selector="enable:" destination="8Eu-UD-eCa" eventType="touchUpInside" id="ce5-pt-YN7"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="cY9-Uk-Vlx" secondAttribute="trailing" id="KpS-U0-BBK"/>
<constraint firstItem="cY9-Uk-Vlx" firstAttribute="leading" secondItem="RlA-Zq-tRl" secondAttribute="leading" id="eEr-9i-9OF"/>
<constraint firstItem="cY9-Uk-Vlx" firstAttribute="centerY" secondItem="RlA-Zq-tRl" secondAttribute="centerY" id="gCV-Df-MUK"/>
</constraints>
</tableViewCellContentView>
</tableViewCell>
</cells>
</tableViewSection>
</sections>
<connections>
<outlet property="dataSource" destination="8Eu-UD-eCa" id="cue-E2-LrE"/>
<outlet property="delegate" destination="8Eu-UD-eCa" id="Nai-Ve-JDb"/>
</connections>
</tableView>
<navigationItem key="navigationItem" title="Extension" id="xuT-vz-veD">
<barButtonItem key="leftBarButtonItem" systemItem="cancel" id="FjO-N8-twm">
<connections>
<action selector="cancel:" destination="8Eu-UD-eCa" id="3rh-fd-LDm"/>
</connections>
</barButtonItem>
</navigationItem>
<connections>
<outlet property="extensionDescription" destination="VCu-Yi-0ts" id="grq-97-i1H"/>
</connections>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="5G7-cc-L54" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1690" y="1512"/>
</scene>
</scenes>
<resources>
<image name="accountLocal" width="99" height="77"/>
<image name="gear" catalog="system" width="128" height="119"/>
<namedColor name="primaryAccentColor">
<color red="0.031372549019607843" green="0.41568627450980394" blue="0.93333333333333335" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>

View File

@@ -8,18 +8,18 @@
import UIKit
class SettingsAccountTableViewCell: VibrantTableViewCell {
class SettingsComboTableViewCell: VibrantTableViewCell {
@IBOutlet weak var accountImage: UIImageView!
@IBOutlet weak var accountNameLabel: UILabel!
@IBOutlet weak var comboImage: UIImageView!
@IBOutlet weak var comboNameLabel: UILabel!
override func updateVibrancy(animated: Bool) {
super.updateVibrancy(animated: animated)
updateLabelVibrancy(accountNameLabel, color: labelColor, animated: animated)
updateLabelVibrancy(comboNameLabel, color: labelColor, animated: animated)
let tintColor = isHighlighted || isSelected ? AppAssets.vibrantTextColor : UIColor.label
UIView.animate(withDuration: duration(animated: animated)) {
self.accountImage?.tintColor = tintColor
self.comboImage?.tintColor = tintColor
}
}

View File

@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15505" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15509"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" id="JCb-QB-CrO" customClass="SettingsAccountTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" id="JCb-QB-CrO" customClass="SettingsComboTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="414" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="JCb-QB-CrO" id="FzD-t2-JGy">
@@ -39,8 +39,8 @@
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="accountImage" destination="yiw-9t-gil" id="E8w-FW-Jc9"/>
<outlet property="accountNameLabel" destination="TRx-RV-za8" id="BOl-hK-2mT"/>
<outlet property="comboImage" destination="yiw-9t-gil" id="WqT-gf-Pwq"/>
<outlet property="comboNameLabel" destination="TRx-RV-za8" id="CX9-Cp-qZP"/>
</connections>
<point key="canvasLocation" x="7" y="-9"/>
</tableViewCell>

View File

@@ -34,8 +34,9 @@ class SettingsViewController: UITableViewController {
NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange), name: .UserDidAddAccount, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange), name: .UserDidDeleteAccount, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(displayNameDidChange), name: .DisplayNameDidChange, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(activeExtensionPointsDidChange), name: .ActiveExtensionPointsDidChange, object: nil)
tableView.register(UINib(nibName: "SettingsAccountTableViewCell", bundle: nil), forCellReuseIdentifier: "SettingsAccountTableViewCell")
tableView.register(UINib(nibName: "SettingsComboTableViewCell", bundle: nil), forCellReuseIdentifier: "SettingsComboTableViewCell")
tableView.register(UINib(nibName: "SettingsTableViewCell", bundle: nil), forCellReuseIdentifier: "SettingsTableViewCell")
tableView.rowHeight = UITableView.automaticDimension
@@ -110,12 +111,14 @@ class SettingsViewController: UITableViewController {
case 1:
return AccountManager.shared.accounts.count + 1
case 2:
return ExtensionPointManager.shared.activeExtensionPoints.count + 1
case 3:
let defaultNumberOfRows = super.tableView(tableView, numberOfRowsInSection: section)
if AccountManager.shared.activeAccounts.isEmpty || AccountManager.shared.anyAccountHasFeedWithURL(appNewsURLString) {
return defaultNumberOfRows - 1
}
return defaultNumberOfRows
case 4:
case 5:
return traitCollection.userInterfaceIdiom == .phone ? 2 : 1
default:
return super.tableView(tableView, numberOfRowsInSection: section)
@@ -133,11 +136,26 @@ class SettingsViewController: UITableViewController {
cell = tableView.dequeueReusableCell(withIdentifier: "SettingsTableViewCell", for: indexPath)
cell.textLabel?.text = NSLocalizedString("Add Account", comment: "Accounts")
} else {
let acctCell = tableView.dequeueReusableCell(withIdentifier: "SettingsAccountTableViewCell", for: indexPath) as! SettingsAccountTableViewCell
let acctCell = tableView.dequeueReusableCell(withIdentifier: "SettingsComboTableViewCell", for: indexPath) as! SettingsComboTableViewCell
acctCell.applyThemeProperties()
let account = sortedAccounts[indexPath.row]
acctCell.accountImage?.image = AppAssets.image(for: account.type)
acctCell.accountNameLabel?.text = account.nameForDisplay
acctCell.comboImage?.image = AppAssets.image(for: account.type)
acctCell.comboNameLabel?.text = account.nameForDisplay
cell = acctCell
}
case 2:
let extensionPoints = Array(ExtensionPointManager.shared.activeExtensionPoints.values)
if indexPath.row == extensionPoints.count {
cell = tableView.dequeueReusableCell(withIdentifier: "SettingsTableViewCell", for: indexPath)
cell.textLabel?.text = NSLocalizedString("Add Extension", comment: "Extensions")
} else {
let acctCell = tableView.dequeueReusableCell(withIdentifier: "SettingsComboTableViewCell", for: indexPath) as! SettingsComboTableViewCell
acctCell.applyThemeProperties()
let extensionPoint = extensionPoints[indexPath.row]
acctCell.comboImage?.image = extensionPoint.templateImage
acctCell.comboNameLabel?.text = extensionPoint.title
cell = acctCell
}
@@ -166,6 +184,16 @@ class SettingsViewController: UITableViewController {
self.navigationController?.pushViewController(controller, animated: true)
}
case 2:
let extensionPoints = Array(ExtensionPointManager.shared.activeExtensionPoints.values)
if indexPath.row == extensionPoints.count {
let controller = UIStoryboard.settings.instantiateController(ofType: AddExtensionPointViewController.self)
self.navigationController?.pushViewController(controller, animated: true)
} else {
let controller = UIStoryboard.inspector.instantiateController(ofType: ExtensionPointInspectorViewController.self)
controller.extensionPoint = extensionPoints[indexPath.row]
self.navigationController?.pushViewController(controller, animated: true)
}
case 3:
switch indexPath.row {
case 0:
tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
@@ -185,7 +213,7 @@ class SettingsViewController: UITableViewController {
default:
break
}
case 3:
case 4:
switch indexPath.row {
case 3:
let timeline = UIStoryboard.settings.instantiateController(ofType: TimelineCustomizerViewController.self)
@@ -193,10 +221,10 @@ class SettingsViewController: UITableViewController {
default:
break
}
case 5:
case 6:
let colorPalette = UIStoryboard.settings.instantiateController(ofType: ColorPaletteTableViewController.self)
self.navigationController?.pushViewController(colorPalette, animated: true)
case 6:
case 7:
switch indexPath.row {
case 0:
openURL("https://ranchero.com/netnewswire/help/ios/5.0/en/")
@@ -310,6 +338,10 @@ class SettingsViewController: UITableViewController {
tableView.reloadData()
}
@objc func activeExtensionPointsDidChange() {
tableView.reloadData()
}
}
// MARK: OPML Document Picker