Adds app default option

Adds app defaults option for controlling link opening preferences.

Adds browser logic and images.

Browser Manager Updates

- Handles deletion of current browser
- Fixes detection of installed browsers by moving URL Types to LSApplicationQuery
- Updates icons to glyphs
- Context menus update

tidy up

- removes browser specific options and offers in-app or default browser options (can be enabled via a bool)
- adds 1Password as an option
- removes custom wording on context menus

Fixes

- makes sure browser options are available on iPad
- uses VibrantCell
- Changes Settings title to "Open Links In"
This commit is contained in:
Stuart Breckenridge 2021-08-22 09:42:06 +08:00
parent 656782ff9e
commit 08a1120e00
No known key found for this signature in database
GPG Key ID: 1F11FD62007DC331
33 changed files with 803 additions and 80 deletions

View File

@ -72,6 +72,9 @@
173A642C2547BE9600267F6E /* AccountType+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 173A64162547BE0900267F6E /* AccountType+Helpers.swift */; };
175942AA24AD533200585066 /* RefreshInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5183CCE4226F4DFA0010922C /* RefreshInterval.swift */; };
175942AB24AD533200585066 /* RefreshInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5183CCE4226F4DFA0010922C /* RefreshInterval.swift */; };
175EBD7426D2405A009B5B23 /* BrowserConfigurationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 175EBD7326D2405A009B5B23 /* BrowserConfigurationViewController.swift */; };
175EBD7626D240D8009B5B23 /* BrowserCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 175EBD7526D240D8009B5B23 /* BrowserCell.swift */; };
1760888126D1F04500E853E9 /* BrowserManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1760888026D1F04500E853E9 /* BrowserManager.swift */; };
176813D02564BA5900D98635 /* WidgetData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 176813B62564B9F800D98635 /* WidgetData.swift */; };
176813D12564BA5900D98635 /* WidgetDataDecoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 176813C92564BA5400D98635 /* WidgetDataDecoder.swift */; };
176813D22564BA5900D98635 /* WidgetDataEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 176813BD2564BA2800D98635 /* WidgetDataEncoder.swift */; };
@ -1210,6 +1213,7 @@
DF98E2B02578AA5C00F18944 /* AddFeedWranglerAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF98E2AF2578AA5C00F18944 /* AddFeedWranglerAccountView.swift */; };
DF98E2BE2578AC0000F18944 /* AddNewsBlurAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF98E2BD2578AC0000F18944 /* AddNewsBlurAccountView.swift */; };
DF98E2C62578AD1B00F18944 /* AddReaderAPIAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF98E2C52578AD1B00F18944 /* AddReaderAPIAccountView.swift */; };
DFC05D2226D3E0770047E788 /* Browser.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFC05D2126D3E0770047E788 /* Browser.swift */; };
FA80C11724B0728000974098 /* AddFolderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA80C11624B0728000974098 /* AddFolderView.swift */; };
FA80C11824B0728000974098 /* AddFolderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA80C11624B0728000974098 /* AddFolderView.swift */; };
FA80C13E24B072AA00974098 /* AddFolderModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA80C13D24B072AA00974098 /* AddFolderModel.swift */; };
@ -1552,6 +1556,9 @@
17386B792577C4BF0014C8B2 /* AddLocalAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddLocalAccountView.swift; sourceTree = "<group>"; };
17386BC32577CC600014C8B2 /* AddFeedbinAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddFeedbinAccountView.swift; sourceTree = "<group>"; };
173A64162547BE0900267F6E /* AccountType+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AccountType+Helpers.swift"; sourceTree = "<group>"; };
175EBD7326D2405A009B5B23 /* BrowserConfigurationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowserConfigurationViewController.swift; sourceTree = "<group>"; };
175EBD7526D240D8009B5B23 /* BrowserCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowserCell.swift; sourceTree = "<group>"; };
1760888026D1F04500E853E9 /* BrowserManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowserManager.swift; sourceTree = "<group>"; };
176813B62564B9F800D98635 /* WidgetData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetData.swift; sourceTree = "<group>"; };
176813BD2564BA2800D98635 /* WidgetDataEncoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetDataEncoder.swift; sourceTree = "<group>"; };
176813C92564BA5400D98635 /* WidgetDataDecoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetDataDecoder.swift; sourceTree = "<group>"; };
@ -2137,6 +2144,7 @@
DF98E2AF2578AA5C00F18944 /* AddFeedWranglerAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddFeedWranglerAccountView.swift; sourceTree = "<group>"; };
DF98E2BD2578AC0000F18944 /* AddNewsBlurAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddNewsBlurAccountView.swift; sourceTree = "<group>"; };
DF98E2C52578AD1B00F18944 /* AddReaderAPIAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddReaderAPIAccountView.swift; sourceTree = "<group>"; };
DFC05D2126D3E0770047E788 /* Browser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Browser.swift; sourceTree = "<group>"; };
FA80C11624B0728000974098 /* AddFolderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddFolderView.swift; sourceTree = "<group>"; };
FA80C13D24B072AA00974098 /* AddFolderModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddFolderModel.swift; sourceTree = "<group>"; };
FF3ABF09232599450074C542 /* ArticleSorterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleSorterTests.swift; sourceTree = "<group>"; };
@ -2793,6 +2801,10 @@
51A16992235E10D600EB091F /* AddAccountViewController.swift */,
519ED47924482AEB007F8E94 /* EnableExtensionPointViewController.swift */,
519ED455244828C3007F8E94 /* AddExtensionPointViewController.swift */,
DFC05D2126D3E0770047E788 /* Browser.swift */,
1760888026D1F04500E853E9 /* BrowserManager.swift */,
175EBD7326D2405A009B5B23 /* BrowserConfigurationViewController.swift */,
175EBD7526D240D8009B5B23 /* BrowserCell.swift */,
516244E2241E19F000B61C47 /* ColorPaletteTableViewController.swift */,
516A09382360A2AE00EAE89B /* SettingsComboTableViewCell.swift */,
516A091D23609A3600EAE89B /* SettingsComboTableViewCell.xib */,
@ -4609,7 +4621,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "if ! command -v swiftgen &> /dev/null\nthen\n echo \"swiftgen could not be found\"\n exit\nfi\n\narch -x86_64 swiftgen run strings -t structured-swift5 \"$PROJECT_DIR/Widget/Resources/en.lproj/Localizable.strings\" \"$PROJECT_DIR/Widget/Resources/Localizable.stringsdict\" --output \"$PROJECT_DIR/Widget/Resources/Localized.swift\";\n";
shellScript = "if ! command -v swiftgen &> /dev/null\nthen\n echo \"swiftgen could not be found\"\n exit\nfi\n\nswiftgen run strings -t structured-swift5 \"$PROJECT_DIR/Widget/Resources/en.lproj/Localizable.strings\" \"$PROJECT_DIR/Widget/Resources/Localizable.stringsdict\" --output \"$PROJECT_DIR/Widget/Resources/Localized.swift\";\n";
};
513F328A2593EFCE0003048F /* Delete Unnecessary Frameworks */ = {
isa = PBXShellScriptBuildPhase;
@ -5490,6 +5502,7 @@
510289CD24519A1D00426DDF /* SelectComboTableViewCell.swift in Sources */,
514B7C8323205EFB00BAC947 /* RootSplitViewController.swift in Sources */,
51FA73A52332BE110090D516 /* ArticleExtractor.swift in Sources */,
DFC05D2226D3E0770047E788 /* Browser.swift in Sources */,
51314704235C41FC00387FDC /* Intents.intentdefinition in Sources */,
FF3ABF162325AF5D0074C542 /* ArticleSorter.swift in Sources */,
51C4525C226508DF00C03939 /* String-Extensions.swift in Sources */,
@ -5546,6 +5559,7 @@
51C4528E2265099C00C03939 /* SmartFeedsController.swift in Sources */,
51C9DE5823EA2EF4003D5A6D /* WrapperScriptMessageHandler.swift in Sources */,
51627A6B238629D8007B3B4B /* MasterFeedDataSource.swift in Sources */,
175EBD7626D240D8009B5B23 /* BrowserCell.swift in Sources */,
51B5C87D23F2346200032075 /* ExtensionContainersFile.swift in Sources */,
51102165233A7D6C0007A5F7 /* ArticleExtractorButton.swift in Sources */,
5141E7392373C18B0013FF27 /* WebFeedInspectorViewController.swift in Sources */,
@ -5602,11 +5616,13 @@
516AE9E02372269A007DEEAA /* IconImage.swift in Sources */,
519ED456244828C3007F8E94 /* AddExtensionPointViewController.swift in Sources */,
51C45268226508F600C03939 /* MasterFeedUnreadCountView.swift in Sources */,
1760888126D1F04500E853E9 /* BrowserManager.swift in Sources */,
D3A39865246505DF00F9A366 /* FindInArticleActivity.swift in Sources */,
5183CCD0226E1E880010922C /* NonIntrinsicLabel.swift in Sources */,
51C4529F22650A1900C03939 /* AuthorAvatarDownloader.swift in Sources */,
5108F6D22375EED2001ABC45 /* TimelineCustomizerViewController.swift in Sources */,
519E743D22C663F900A78E47 /* SceneDelegate.swift in Sources */,
175EBD7426D2405A009B5B23 /* BrowserConfigurationViewController.swift in Sources */,
FFD43E412340F488009E5CA3 /* MarkAsReadAlertController.swift in Sources */,
51C452A322650A1E00C03939 /* HTMLMetadataDownloader.swift in Sources */,
51C4528D2265095F00C03939 /* AddFolderViewController.swift in Sources */,

View File

@ -54,6 +54,7 @@ final class AppDefaults {
static let addWebFeedAccountID = "addWebFeedAccountID"
static let addWebFeedFolderName = "addWebFeedFolderName"
static let addFolderAccountID = "addFolderAccountID"
static let browserPreference = "browserPreference"
}
let isDeveloperBuild: Bool = {
@ -119,6 +120,18 @@ final class AppDefaults {
}
}
var browserPreference: String {
get {
guard let preference = UserDefaults.standard.string(forKey: Key.browserPreference) else {
return "browser.inapp"
}
return preference
}
set {
UserDefaults.standard.setValue(newValue, forKey: Key.browserPreference)
}
}
var lastImageCacheFlushDate: Date? {
get {
return AppDefaults.date(for: Key.lastImageCacheFlushDate)
@ -191,6 +204,20 @@ final class AppDefaults {
}
}
/// The default behaviour is to open links in the in-app browser, as such, `Browsers.inApp.browserID` is the default.
// var openLinksPreferredBrowser: String {
// get {
// if AppDefaults.store.string(forKey: Key.openLinksPreferredBrowser) == nil {
// return Browsers.inApp.browserID
// } else {
// return AppDefaults.store.string(forKey: Key.openLinksPreferredBrowser)!
// }
// }
//
// set { AppDefaults.store.setValue(newValue, forKey: Key.openLinksPreferredBrowser) }
// }
var timelineNumberOfLines: Int {
get {
return AppDefaults.int(for: Key.timelineNumberOfLines)

View File

@ -250,8 +250,12 @@ class WebViewController: UIViewController {
func openInAppBrowser() {
guard let url = article?.preferredURL else { return }
let vc = SFSafariViewController(url: url)
present(vc, animated: true)
if BrowserManager.shared.currentBrowser() == .inApp {
let vc = SFSafariViewController(url: url)
present(vc, animated: true)
} else {
BrowserManager.shared.openURL(urlString: url.absoluteString)
}
}
}
@ -344,7 +348,12 @@ extension WebViewController: WKNavigationDelegate {
let components = URLComponents(url: url, resolvingAgainstBaseURL: false)
if components?.scheme == "http" || components?.scheme == "https" {
decisionHandler(.cancel)
openURL(url)
if BrowserManager.shared.currentBrowser() == .inApp {
openURL(url)
} else {
BrowserManager.shared.openURL(urlString: url.absoluteString)
}
} else if components?.scheme == "mailto" {
decisionHandler(.cancel)

View File

@ -899,7 +899,9 @@ private extension MasterTimelineViewController {
func openInBrowserAlertAction(_ article: Article, completion: @escaping (Bool) -> Void) -> UIAlertAction? {
guard let _ = article.preferredURL else { return nil }
let title = NSLocalizedString("Open in Browser", comment: "Open in Browser")
var displayName: String
BrowserManager.shared.currentBrowser() == .inApp ? (displayName = Browser.safari.displayName) : (displayName = BrowserManager.shared.currentBrowser().displayName)
let title = NSLocalizedString("Open in \(displayName)", comment: "Open in Browser")
let action = UIAlertAction(title: title, style: .default) { [weak self] action in
self?.coordinator.showBrowserForArticle(article)
completion(true)

View File

@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,15 @@
{
"images" : [
{
"filename" : "icons8-brave-web-browser.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}

View File

@ -0,0 +1,15 @@
{
"images" : [
{
"filename" : "icons8-chrome.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}

View File

@ -0,0 +1,15 @@
{
"images" : [
{
"filename" : "icons8-microsoft-edge.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}

View File

@ -0,0 +1,16 @@
{
"images" : [
{
"filename" : "firefox-logo-glyph.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "template"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "AppIcon-40px-40pt@1x.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "AppIcon-80px-40pt@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "AppIcon-120px-40pt@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,15 @@
{
"images" : [
{
"filename" : "1password.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}

View File

@ -0,0 +1,15 @@
{
"images" : [
{
"filename" : "icons8-opera.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}

View File

@ -0,0 +1,72 @@
%PDF-1.4
%µí®û
4 0 obj
<< /Length 5 0 R
/Filter /FlateDecode
>>
stream
xœmTAŽ1 »ûþ@]Kû„"@·—=´ý?PRžLr($æŒ$S©Ÿo¯Ùëã«ü.=ýù¬ßôúù·¨µè <0B>¾ªH[<i•Þzà/·K}à8v ›Œ¢¬v%²nÞJ!0?¡ÁÓ<C381><C393>s´X“}Ìz§3ûד„’» m¯:+$ùØ} “q*<2A>*Ú,XFv^é,™mh[s<>ÏÍo4&(
¨¨"V.¨Ò46ÀöYú,­;ßàRo®^½éÞUн—lWÆNÕÜŒ«Éò*³­>ùã;«é¾<C3A9>5‡Ç…KU”•ÉÌ®£ŽÝ£®LjÁÀÝ6ßxPr™sVëmƒ®Ds„2¼p<C2BC>Òú®6Ú”Åd$Ÿ:ôHì¢}¨À²@k³/âˆÄC‰t<E280B0>D´ÑÌ =^ÚM!°,ËþBÈȬCãYòu§±$É hWóG
Í©Ž3ÌÚp¶”hâ¹%EÊ7íFOu/,gLHÙ”\=
+O”ÄÔfØa]1ÒMÿI:Ø<C398>Þ"9¬ƒtqÙÔ4 M»šOT»üóî­7³í§ÙV1/‰àà<C3A0>VFMRöçT"%ŽÓUÊUè깉hjx[%í½ÓX6ÅÓÛºOtë8§! ÁŽSa_Y—ΫÙʺu½ÏÍ™ÐJH'ÎK´œa/Ô3É A“Úa¼ï†Ó—áV{½u®q¢ð8ù
ÇcÀSédí#¯¡ã$­vX0Ex3çò>ÿc"Çær„ØŸ¾R-WãnåRB•uƒ£YyÜ:—‚™”Ž{+Y—øtêÆ)Ø<>7zn)fI‡€/•õ+Í î(Þ¾x÷ÌLô³|”ò"D
endstream
endobj
5 0 obj
656
endobj
3 0 obj
<<
/ExtGState <<
/a0 << /CA 1 /ca 1 >>
>>
>>
endobj
2 0 obj
<< /Type /Page % 1
/Parent 1 0 R
/MediaBox [ 0 0 50 50 ]
/Contents 4 0 R
/Group <<
/Type /Group
/S /Transparency
/I true
/CS /DeviceRGB
>>
/Resources 3 0 R
>>
endobj
1 0 obj
<< /Type /Pages
/Kids [ 2 0 R ]
/Count 1
>>
endobj
6 0 obj
<< /Producer (cairo 1.16.0 (https://cairographics.org))
/CreationDate (D:20210822124817Z)
>>
endobj
7 0 obj
<< /Type /Catalog
/Pages 1 0 R
>>
endobj
xref
0 8
0000000000 65535 f
0000001058 00000 n
0000000842 00000 n
0000000770 00000 n
0000000015 00000 n
0000000748 00000 n
0000001123 00000 n
0000001234 00000 n
trailer
<< /Size 8
/Root 7 0 R
/Info 6 0 R
>>
startxref
1286
%%EOF

View File

@ -0,0 +1,15 @@
{
"images" : [
{
"filename" : "safari.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}

View File

@ -2,10 +2,6 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>OrganizationIdentifier</key>
<string>$(ORGANIZATION_IDENTIFIER)</string>
<key>DeveloperEntitlements</key>
<string>$(DEVELOPER_ENTITLEMENTS)</string>
<key>AppGroup</key>
<string>group.$(ORGANIZATION_IDENTIFIER).NetNewsWire.iOS</string>
<key>AppIdentifierPrefix</key>
@ -54,10 +50,18 @@
</array>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>DeveloperEntitlements</key>
<string>$(DEVELOPER_ENTITLEMENTS)</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>mailto</string>
<string>org-appextension-feature-password-management</string>
<string>brave</string>
<string>touch-http</string>
<string>googlechrome</string>
<string>microsoft-edge-https</string>
<string>firefox</string>
<string>ophttps</string>
</array>
<key>LSRequiresIPhoneOS</key>
<true/>
@ -76,6 +80,8 @@
<string>Restoration</string>
<string>SelectFeed</string>
</array>
<key>OrganizationIdentifier</key>
<string>$(ORGANIZATION_IDENTIFIER)</string>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>

View File

@ -1229,7 +1229,12 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
func showBrowserForArticle(_ article: Article) {
guard let url = article.preferredURL else { return }
UIApplication.shared.open(url, options: [:])
if BrowserManager.shared.currentBrowser() == .inApp {
UIApplication.shared.open(url, options: [:])
} else {
BrowserManager.shared.openURL(urlString: url.absoluteString)
}
}
func showBrowserForCurrentArticle() {

View File

@ -77,6 +77,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
appDelegate.prepareAccountsForForeground()
coordinator.configurePanelMode(for: window!.frame.size)
coordinator.resetFocus()
BrowserManager.shared.configureAvailableBrowsers()
}
func stateRestorationActivity(for scene: UIScene) -> NSUserActivity? {

113
iOS/Settings/Browser.swift Normal file
View File

@ -0,0 +1,113 @@
//
// Browser.swift
// NetNewsWire-iOS
//
// Created by Stuart Breckenridge on 23/08/2021.
// Copyright © 2021 Ranchero Software. All rights reserved.
//
import Foundation
/// The `Browser` enum contains browsers supported by NetNewsWire.
///
/// To support a new browser, create a case, configure it, add its URL scheme
/// to `LSApplicationQueriesSchemes` in `Info.plist`, and add an
/// appropriate image to the Asset catalog. The browserID should be used as the
/// image filename.
public enum Browser: CaseIterable {
case inApp
case safari
case brave
case chrome
case edge
case firefox
case opera
case onePassword
var urlScheme: String {
switch self {
case .inApp:
return "" // not required, will open in SFSafariViewController
case .safari:
return "" // not required, will use openURL
case .brave:
return "brave://open-url?url="
case .chrome:
return "googlechrome://"
case .edge:
return "microsoft-edge-https://"
case .firefox:
return "firefox://open-url?url="
case .opera:
return "touch-http://"
case .onePassword:
return "ophttps://"
}
}
var canOpenURL: Bool {
switch self {
case .inApp:
return true
case .safari:
return UIApplication.shared.canOpenURL(URL(string: "https://apple.com")!)
case .brave:
return UIApplication.shared.canOpenURL(URL(string: Browser.brave.urlScheme)!)
case .chrome:
return UIApplication.shared.canOpenURL(URL(string: Browser.chrome.urlScheme)!)
case .edge:
return UIApplication.shared.canOpenURL(URL(string: Browser.edge.urlScheme)!)
case .firefox:
return UIApplication.shared.canOpenURL(URL(string: Browser.firefox.urlScheme)!)
case .opera:
return UIApplication.shared.canOpenURL(URL(string: Browser.opera.urlScheme)!)
case .onePassword:
return UIApplication.shared.canOpenURL(URL(string: Browser.onePassword.urlScheme)!)
}
}
var browserID: String {
switch self {
case .inApp:
return "browser.inapp"
case .safari:
return "browser.safari"
case .brave:
return "browser.brave"
case .chrome:
return "browser.chrome"
case .edge:
return "browser.edge"
case .firefox:
return "browser.firefox"
case .opera:
return "browser.opera"
case .onePassword:
return "browser.onepassword"
}
}
var displayName: String {
switch self {
case .inApp:
return NSLocalizedString("NetNewsWire", comment: "In-app")
case .safari:
return NSLocalizedString("Default Browser", comment: "Default")
case .brave:
return NSLocalizedString("Brave", comment: "Brave")
case .chrome:
return NSLocalizedString("Chrome", comment: "Chrome")
case .edge:
return NSLocalizedString("Edge", comment: "Edge")
case .firefox:
return NSLocalizedString("Firefox", comment: "Firefox")
case .opera:
return NSLocalizedString("Opera", comment: "Opera")
case .onePassword:
return NSLocalizedString("1Password", comment: "1Password")
}
}
}

View File

@ -0,0 +1,47 @@
//
// BrowserCell.swift
// NetNewsWire-iOS
//
// Created by Stuart Breckenridge on 22/8/21.
// Copyright © 2021 Ranchero Software. All rights reserved.
//
import UIKit
class BrowserCell: VibrantTableViewCell {
@IBOutlet weak var browserName: UILabel!
private var browser: Browser!
override func updateVibrancy(animated: Bool) {
super.updateVibrancy(animated: animated)
updateLabelVibrancy(browserName, color: labelColor, animated: animated)
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
func configure(with browser: Browser) {
browserName.text = browser.displayName
self.browser = browser
if BrowserManager.shared.currentBrowser().browserID == browser.browserID {
accessoryType = .checkmark
} else {
accessoryType = .none
}
}
func updateBrowserSelection() {
BrowserManager.shared.currentBrowserPreference = self.browser.browserID
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}

View File

@ -0,0 +1,89 @@
//
// BrowserConfigurationViewController.swift
// NetNewsWire-iOS
//
// Created by Stuart Breckenridge on 22/8/21.
// Copyright © 2021 Ranchero Software. All rights reserved.
//
import UIKit
class BrowserConfigurationViewController: UITableViewController {
let browserManager = BrowserManager.shared
override func viewDidLoad() {
super.viewDidLoad()
title = NSLocalizedString("Browser Selection", comment: "Browser")
NotificationCenter.default.addObserver(self, selector: #selector(browserPreferenceDidChange), name: .browserPreferenceDidChange, object: nil)
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 3
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 { return 1 }
if section == 1 { return 1 }
return browserManager.availableBrowsers.count - 2
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "BrowserCell", for: indexPath) as! BrowserCell
cell.configure(with: browserManager.availableBrowsers[indexPath.row])
return cell
}
if indexPath.section == 1 {
let cell = tableView.dequeueReusableCell(withIdentifier: "BrowserCell", for: indexPath) as! BrowserCell
cell.configure(with: browserManager.availableBrowsers[indexPath.row + 1])
return cell
}
if indexPath.section == 2 {
let cell = tableView.dequeueReusableCell(withIdentifier: "BrowserCell", for: indexPath) as! BrowserCell
cell.configure(with: browserManager.availableBrowsers[indexPath.row + 2])
return cell
}
return tableView.dequeueReusableCell(withIdentifier: "BrowserCell") ?? UITableViewCell()
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
guard let cell = tableView.cellForRow(at: indexPath) as? BrowserCell else {
return
}
cell.updateBrowserSelection()
navigationController?.popViewController(animated: true)
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if section == 0 {
return NSLocalizedString("Open Links In", comment: "Open Links")
}
return nil
}
override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
if section == 0 {
return NSLocalizedString("Links will open in NetNewsWire.", comment: "NNW browser footer.")
}
if section == 1 {
return NSLocalizedString("Links will open in the default system browser configured in Settings.", comment: "Default browser footer.")
}
return nil
}
// MARK: - Notifications
@objc func browserPreferenceDidChange() {
tableView.reloadData()
}
}

View File

@ -0,0 +1,97 @@
//
// BrowserManager.swift
// NetNewsWire-iOS
//
// Created by Stuart Breckenridge on 22/8/21.
// Copyright © 2021 Ranchero Software. All rights reserved.
//
import Foundation
import UIKit
extension Notification.Name {
static let browserPreferenceDidChange = Notification.Name("browserPreferenceDidChange")
}
public final class BrowserManager {
/// The available browsers supported by the application. If `enableExtendedBrowserPreferences`
/// is `false`, this will only contain in-app and system browser options.
public private(set) var availableBrowsers = [Browser]()
/// The currently selected `BrowserID`. The default is `Browser.inApp`.
public var currentBrowserPreference: String {
get {
return AppDefaults.shared.browserPreference
}
set {
AppDefaults.shared.browserPreference = newValue
NotificationCenter.default.post(name: .browserPreferenceDidChange, object: nil)
}
}
/// When `true`, the user can select a specific browser instead of the system default browser.
private var enableExtendedBrowserPreferences = false
public static let shared = BrowserManager()
private init() {
configureAvailableBrowsers()
}
/// Refreshes the available browsers. This is called when BrowserManager is inited,
/// and when the application returns to the foreground.
func configureAvailableBrowsers() {
if !enableExtendedBrowserPreferences {
availableBrowsers = [.inApp, .safari]
} else {
availableBrowsers = Browser.allCases.filter({ $0.canOpenURL == true })
}
resetBrowserPreferenceIfRequired()
}
/// Opens the URL in the specified browser.
/// - Parameter urlString: the url to open.
func openURL(urlString: String) {
guard let url = URL(string: urlString) else {
return
}
if currentBrowser() == .safari {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
return
}
switch currentBrowser() {
case .edge, .chrome, .opera, .onePassword:
var string = urlString
string = string.replacingOccurrences(of: "https://", with: "")
string = string.replacingOccurrences(of: "http://", with: "")
guard let browserURL = URL(string: currentBrowser().urlScheme + string) else {
return
}
UIApplication.shared.open(browserURL, options: [:], completionHandler: nil)
default:
guard let browserURL = URL(string: currentBrowser().urlScheme + urlString) else {
return
}
UIApplication.shared.open(browserURL, options: [:], completionHandler: nil)
}
}
/// If the user has uninstalled a browser this will reset the browser back to the in-app default.
private func resetBrowserPreferenceIfRequired() {
if availableBrowsers.filter({ $0.browserID == currentBrowserPreference }).count == 0 {
currentBrowserPreference = Browser.inApp.browserID
}
}
/// The currently selected browser.
/// - Returns: `Browser`
func currentBrowser() -> Browser {
guard let browser = Browser.allCases.filter({ $0.browserID == currentBrowserPreference }).first else {
resetBrowserPreferenceIfRequired()
return currentBrowser()
}
return browser
}
}

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="9cW-lu-HoC">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="18122" 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>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
@ -21,7 +21,7 @@
<tableViewSection headerTitle="Notifications, Badge, Data, &amp; More" id="Bmb-Oi-RZK">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="F9H-Kr-npj" style="IBUITableViewCellStyleDefault" id="zvg-7C-BlH" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="55.5" width="374" height="44"/>
<rect key="frame" x="20" y="49.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="zvg-7C-BlH" id="Tqk-Tu-E6K">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
@ -42,14 +42,14 @@
<tableViewSection headerTitle="Accounts" id="0ac-Ze-Dh4">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="6sn-wY-hHH" style="IBUITableViewCellStyleDefault" id="XHc-rQ-7FK" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="155.5" width="374" height="44"/>
<rect key="frame" x="20" y="143.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="XHc-rQ-7FK" id="nmL-EM-Bsi">
<rect key="frame" x="0.0" y="0.0" width="343" height="44"/>
<rect key="frame" x="0.0" y="0.0" width="344.5" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Add Account" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="6sn-wY-hHH">
<rect key="frame" x="20" y="0.0" width="315" height="44"/>
<rect key="frame" x="20" y="0.0" width="316.5" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
@ -63,14 +63,14 @@
<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"/>
<rect key="frame" x="20" y="237.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"/>
<rect key="frame" x="0.0" y="0.0" width="344.5" 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"/>
<rect key="frame" x="20" y="0.0" width="316.5" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
@ -84,7 +84,7 @@
<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="355.5" width="374" height="44"/>
<rect key="frame" x="20" y="331.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"/>
@ -101,7 +101,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="399.5" width="374" height="44"/>
<rect key="frame" x="20" y="375.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"/>
@ -118,7 +118,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="443.5" width="374" height="44"/>
<rect key="frame" x="20" y="419.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"/>
@ -139,14 +139,14 @@
<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="543.5" width="374" height="44"/>
<rect key="frame" x="20" y="513.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"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="250" text="Sort Oldest to Newest" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="c9W-IF-u6i" customClass="VibrantLabel" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="11" width="168" height="22"/>
<rect key="frame" x="20" y="11" width="143" height="22"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
@ -172,14 +172,14 @@
</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="587.5" width="374" height="44"/>
<rect key="frame" x="20" y="557.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"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="250" text="Group by Feed" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="cit-i1-0Hp" customClass="VibrantLabel" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="11" width="113" height="22"/>
<rect key="frame" x="20" y="11" width="95.5" height="22"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
@ -205,14 +205,14 @@
</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="631.5" width="374" height="44"/>
<rect key="frame" x="20" y="601.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"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="749" text="Refresh to Clear Read Articles" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="KtJ-tk-DlD">
<rect key="frame" x="20" y="11" width="227.5" height="22"/>
<rect key="frame" x="20" y="11" width="193.5" height="22"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
@ -238,14 +238,14 @@
</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="675.5" width="374" height="44"/>
<rect key="frame" x="20" y="645.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"/>
<rect key="frame" x="0.0" y="0.0" width="344.5" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Timeline Layout" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="YHt-eS-KrX">
<rect key="frame" x="20" y="11.5" width="120" height="21"/>
<rect key="frame" x="20" y="13.5" width="101.5" height="17"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
@ -265,14 +265,14 @@
<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="775.5" width="374" height="44"/>
<rect key="frame" x="20" y="739.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"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="749" text="Confirm Mark All as Read" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5tY-5k-v2g">
<rect key="frame" x="20" y="11" width="191.5" height="22"/>
<rect key="frame" x="20" y="11" width="163" height="22"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
@ -297,15 +297,47 @@
</constraints>
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" id="EYf-v1-lNi" customClass="VibrantBasicTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="783.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="EYf-v1-lNi" id="7nz-0Y-HaW">
<rect key="frame" x="0.0" y="0.0" width="344.5" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Open Links In" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Wm4-Y1-7nX">
<rect key="frame" x="20" y="13.5" width="88" height="17"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Automatic" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hiN-zh-oaN">
<rect key="frame" x="271" y="13.5" width="65.5" height="17"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstItem="Wm4-Y1-7nX" firstAttribute="leading" secondItem="7nz-0Y-HaW" secondAttribute="leadingMargin" id="3wx-86-EDc"/>
<constraint firstItem="hiN-zh-oaN" firstAttribute="trailing" secondItem="7nz-0Y-HaW" secondAttribute="trailingMargin" id="Ul9-ln-7Fe"/>
<constraint firstItem="hiN-zh-oaN" firstAttribute="centerY" secondItem="7nz-0Y-HaW" secondAttribute="centerY" id="Yzy-6V-qms"/>
<constraint firstItem="Wm4-Y1-7nX" firstAttribute="centerY" secondItem="7nz-0Y-HaW" secondAttribute="centerY" id="cXY-1K-qKs"/>
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="detail" destination="hiN-zh-oaN" id="RsV-MA-cFK"/>
<outlet property="label" destination="Wm4-Y1-7nX" id="R62-za-yVz"/>
</connections>
</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="819.5" width="374" height="44"/>
<rect key="frame" x="20" y="827.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"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="749" verticalCompressionResistancePriority="751" text="Enable Full Screen Articles" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="79e-5s-vd0">
<rect key="frame" x="20" y="11" width="202" height="15.5"/>
<rect key="frame" x="20" y="11" width="172" height="15.5"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
@ -318,7 +350,7 @@
</connections>
</switch>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="749" text="Tap the article top bar to enter Full Screen. Tap the top or bottom to exit." textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="a30-nc-ZS4">
<rect key="frame" x="20" y="33" width="263" height="0.0"/>
<rect key="frame" x="20" y="33" width="269.5" height="0.0"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleFootnote"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
@ -343,20 +375,20 @@
<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="919.5" width="374" height="44"/>
<rect key="frame" x="20" y="921.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"/>
<rect key="frame" x="0.0" y="0.0" width="344.5" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Color Palette" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2Fp-li-dGP">
<rect key="frame" x="20" y="11.5" width="98" height="21"/>
<rect key="frame" x="20" y="13.5" width="83.5" height="17"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Automatic" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="16m-Ns-Y8V">
<rect key="frame" x="257" y="11.5" width="78" height="21"/>
<rect key="frame" x="271" y="13.5" width="65.5" height="17"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
@ -379,14 +411,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="1019.5" width="374" height="44"/>
<rect key="frame" x="20" y="1015.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="15" y="0.0" width="351" height="44"/>
<rect key="frame" x="20" y="0.0" width="334" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
@ -396,14 +428,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="1063.5" width="374" height="44"/>
<rect key="frame" x="20" y="1059.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="15" y="0.0" width="351" height="44"/>
<rect key="frame" x="20" y="0.0" width="334" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
@ -413,14 +445,14 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="NeD-y8-KrM" style="IBUITableViewCellStyleDefault" id="TIX-yK-rC6" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="1107.5" width="374" height="44"/>
<rect key="frame" x="20" y="1103.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="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Release Notes" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="NeD-y8-KrM">
<rect key="frame" x="15" y="0.0" width="351" height="44"/>
<rect key="frame" x="20" y="0.0" width="334" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
@ -430,7 +462,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="1151.5" width="374" height="44"/>
<rect key="frame" x="20" y="1147.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"/>
@ -447,7 +479,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="1195.5" width="374" height="44"/>
<rect key="frame" x="20" y="1191.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"/>
@ -464,7 +496,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="1239.5" width="374" height="44"/>
<rect key="frame" x="20" y="1235.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"/>
@ -481,7 +513,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="1283.5" width="374" height="44"/>
<rect key="frame" x="20" y="1279.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"/>
@ -498,7 +530,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="1327.5" width="374" height="44"/>
<rect key="frame" x="20" y="1323.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"/>
@ -515,14 +547,14 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="76A-Ng-kfs" style="IBUITableViewCellStyleDefault" id="jK8-tv-hBD" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="1371.5" width="374" height="44"/>
<rect key="frame" x="20" y="1367.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="jK8-tv-hBD" id="I7Q-GQ-u8Y">
<rect key="frame" x="0.0" y="0.0" width="355" height="44"/>
<rect key="frame" x="0.0" y="0.0" width="356.5" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="About NetNewsWire" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="76A-Ng-kfs">
<rect key="frame" x="15" y="0.0" width="332" height="44"/>
<rect key="frame" x="15" y="0.0" width="333.5" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
@ -549,6 +581,7 @@
<connections>
<outlet property="colorPaletteDetailLabel" destination="16m-Ns-Y8V" id="zdj-Ag-ZUw"/>
<outlet property="confirmMarkAllAsReadSwitch" destination="UOo-9z-IuL" id="yLZ-Kf-wDt"/>
<outlet property="currentBrowserLabel" destination="hiN-zh-oaN" id="Qqg-Q7-2Cv"/>
<outlet property="groupByFeedSwitch" destination="JNi-Wz-RbU" id="TwH-Kd-o6N"/>
<outlet property="refreshClearsReadArticlesSwitch" destination="duV-CN-JmH" id="xTd-jF-Ei1"/>
<outlet property="showFullscreenArticlesSwitch" destination="2Md-2E-7Z4" id="lEN-VP-wEO"/>
@ -568,14 +601,14 @@
<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="SettingsComboTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="55.5" width="374" height="55"/>
<rect key="frame" x="20" y="49.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">
<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="iTt-HT-Ane">
<rect key="frame" x="20" y="15" width="147.5" height="25"/>
<rect key="frame" x="20" y="15" width="131" height="25"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="accountLocal" translatesAutoresizingMaskIntoConstraints="NO" id="tb2-dO-AhR">
<rect key="frame" x="0.0" y="0.0" width="25" height="25"/>
@ -586,7 +619,7 @@
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="On My iPhone" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="116-rt-msI">
<rect key="frame" x="41" y="0.0" width="106.5" height="25"/>
<rect key="frame" x="41" y="0.0" width="90" height="25"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
@ -675,7 +708,7 @@
<tableViewSection headerTitle="CREDITS" id="O1X-Iq-ibE">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" rowHeight="62" id="ZY4-id-Iia">
<rect key="frame" x="20" y="198" width="374" height="62"/>
<rect key="frame" x="20" y="192" width="374" height="62"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="ZY4-id-Iia" id="IPw-QQ-LYI">
<rect key="frame" x="0.0" y="0.0" width="374" height="62"/>
@ -701,7 +734,7 @@
<tableViewSection headerTitle="THANKS" id="Sgx-f1-hsT">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" rowHeight="62" id="bLz-mu-psL">
<rect key="frame" x="20" y="316" width="374" height="62"/>
<rect key="frame" x="20" y="304" width="374" height="62"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="bLz-mu-psL" id="cxy-IZ-zFZ">
<rect key="frame" x="0.0" y="0.0" width="374" height="62"/>
@ -727,7 +760,7 @@
<tableViewSection headerTitle="DEDICATION" id="nbm-Bs-te6">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" rowHeight="62" id="aab-HD-ce6">
<rect key="frame" x="20" y="434" width="374" height="62"/>
<rect key="frame" x="20" y="416" width="374" height="62"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="aab-HD-ce6" id="6pH-5O-3V8">
<rect key="frame" x="0.0" y="0.0" width="374" height="62"/>
@ -777,7 +810,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Q4t-3M-goU">
<rect key="frame" x="20" y="56" width="374" height="44"/>
<rect key="frame" x="20" y="54.5" width="374" height="44"/>
<subviews>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="1" maxValue="3" translatesAutoresizingMaskIntoConstraints="NO" id="AW6-CH-AXP" customClass="TickMarkSlider" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="18" y="7" width="338" height="31"/>
@ -797,19 +830,19 @@
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="ICON SIZE" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VLq-TU-3d6">
<rect key="frame" x="40" y="32" width="64" height="16"/>
<rect key="frame" x="40" y="32" width="59.5" height="14.5"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleFootnote"/>
<color key="textColor" systemColor="secondaryLabelColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="NUMBER OF LINES" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="mER-Fl-iHI">
<rect key="frame" x="40" y="132" width="116" height="16"/>
<rect key="frame" x="40" y="130.5" width="108" height="14.5"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleFootnote"/>
<color key="textColor" systemColor="secondaryLabelColor"/>
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="oQi-VX-CMV">
<rect key="frame" x="20" y="156" width="374" height="44"/>
<rect key="frame" x="20" y="153" width="374" height="44"/>
<subviews>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="1" maxValue="6" translatesAutoresizingMaskIntoConstraints="NO" id="AIu-s5-Hvq" customClass="TickMarkSlider" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="18" y="7" width="338" height="31"/>
@ -829,7 +862,7 @@
</constraints>
</view>
<containerView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Ou4-Yv-dXA">
<rect key="frame" x="57" y="232" width="300" height="128"/>
<rect key="frame" x="57" y="229" width="300" height="128"/>
<constraints>
<constraint firstAttribute="width" constant="300" id="BfC-yc-CAa"/>
<constraint firstAttribute="height" constant="128" id="wxz-ZX-8fe"/>
@ -900,7 +933,7 @@
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="Cell" id="Zaq-yo-L5h" customClass="MasterTimelineTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="0.0" y="28" width="300" height="43.5"/>
<rect key="frame" x="0.0" y="24.5" width="300" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="Zaq-yo-L5h" id="fD5-nw-z0z">
<rect key="frame" x="0.0" y="0.0" width="300" height="43.5"/>
@ -937,7 +970,7 @@
<color key="backgroundColor" systemColor="groupTableViewBackgroundColor"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="Cell" textLabel="6tf-Xb-7b8" style="IBUITableViewCellStyleDefault" id="BIC-Zk-QMD" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="55.5" width="374" height="43.5"/>
<rect key="frame" x="20" y="49.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="BIC-Zk-QMD" id="7xj-8Y-ejz">
<rect key="frame" x="0.0" y="0.0" width="374" height="43.5"/>
@ -966,6 +999,52 @@
</objects>
<point key="canvasLocation" x="3743" y="151"/>
</scene>
<!--Browser Configuration View Controller-->
<scene sceneID="XgR-1K-mcJ">
<objects>
<tableViewController storyboardIdentifier="BrowserConfigurationViewController" id="YgN-F2-XRN" customClass="BrowserConfigurationViewController" 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="AaT-rg-yqK">
<rect key="frame" x="0.0" y="0.0" width="414" height="808"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemGroupedBackgroundColor"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="checkmark" indentationWidth="10" reuseIdentifier="BrowserCell" id="ec8-pH-8WV" customClass="BrowserCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="49.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="ec8-pH-8WV" id="WwZ-5H-APR">
<rect key="frame" x="0.0" y="0.0" width="333.5" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="browser.name" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6GG-kE-13U">
<rect key="frame" x="20" y="12" width="306" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstAttribute="bottom" secondItem="6GG-kE-13U" secondAttribute="bottom" constant="10.5" id="dzm-hx-yIR"/>
<constraint firstItem="6GG-kE-13U" firstAttribute="leading" secondItem="WwZ-5H-APR" secondAttribute="leading" constant="20" symbolic="YES" id="x9L-in-bBu"/>
<constraint firstAttribute="trailing" secondItem="6GG-kE-13U" secondAttribute="trailing" constant="7.5" id="z1A-CB-nUE"/>
</constraints>
</tableViewCellContentView>
<color key="tintColor" name="AccentColor"/>
<connections>
<outlet property="browserName" destination="6GG-kE-13U" id="Yp6-Ta-cSZ"/>
</connections>
</tableViewCell>
</prototypes>
<connections>
<outlet property="dataSource" destination="YgN-F2-XRN" id="a00-rb-4FQ"/>
<outlet property="delegate" destination="YgN-F2-XRN" id="bue-ih-Lng"/>
</connections>
</tableView>
<simulatedNavigationBarMetrics key="simulatedTopBarMetrics" translucent="NO" prompted="NO"/>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="I2N-LH-r02" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="4488.4057971014499" y="150.66964285714286"/>
</scene>
<!--Add Extension-->
<scene sceneID="e22-Tk-eWN">
<objects>
@ -975,14 +1054,14 @@
<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"/>
<rect key="frame" x="20" y="49.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="15" width="115" height="25"/>
<rect key="frame" x="20" y="15" width="104" height="25"/>
<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="25" height="25.5"/>
@ -993,7 +1072,7 @@
</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="41" y="0.0" width="74" height="25"/>
<rect key="frame" x="41" y="0.0" width="63" height="25"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
@ -1130,6 +1209,9 @@
<resources>
<image name="accountLocal" width="119" height="102"/>
<image name="gear" catalog="system" width="128" height="119"/>
<namedColor name="AccentColor">
<color red="0.030999999493360519" green="0.41600000858306885" blue="0.93300002813339233" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>
<namedColor name="primaryAccentColor">
<color red="0.031372549019607843" green="0.41568627450980394" blue="0.93333333333333335" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>

View File

@ -1,37 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18122" 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="15508"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<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" textLabel="f73-v7-eum" detailTextLabel="Cak-zN-D7k" style="IBUITableViewCellStyleValue1" id="JCb-QB-CrO" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="SettingsTableViewCell" textLabel="f73-v7-eum" detailTextLabel="Cak-zN-D7k" style="IBUITableViewCellStyleValue1" id="JCb-QB-CrO" customClass="VibrantTableViewCell" 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">
<rect key="frame" x="0.0" y="0.0" width="383" height="44"/>
<rect key="frame" x="0.0" y="0.0" width="384.5" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="f73-v7-eum">
<rect key="frame" x="20" y="12" width="33.5" height="20.5"/>
<rect key="frame" x="20" y="14" width="28.5" height="17"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="Cak-zN-D7k">
<rect key="frame" x="331" y="12" width="44" height="20.5"/>
<rect key="frame" x="339" y="14" width="37.5" height="17"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
<color key="textColor" systemColor="secondaryLabelColor"/>
<color key="highlightedColor" systemColor="secondaryLabelColor"/>
</label>
</subviews>
</tableViewCellContentView>
<point key="canvasLocation" x="7" y="-9"/>
</tableViewCell>
</objects>
<resources>
<systemColor name="secondaryLabelColor">
<color red="0.23529411764705882" green="0.23529411764705882" blue="0.2627450980392157" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
</resources>
</document>

View File

@ -10,6 +10,7 @@ import UIKit
import Account
import CoreServices
import SafariServices
import SwiftUI
class SettingsViewController: UITableViewController {
@ -21,10 +22,14 @@ class SettingsViewController: UITableViewController {
@IBOutlet weak var confirmMarkAllAsReadSwitch: UISwitch!
@IBOutlet weak var showFullscreenArticlesSwitch: UISwitch!
@IBOutlet weak var colorPaletteDetailLabel: UILabel!
@IBOutlet weak var currentBrowserLabel: UILabel!
var scrollToArticlesSection = false
weak var presentingParentController: UIViewController?
let browserManger = BrowserManager.shared
override func viewDidLoad() {
// This hack mostly works around a bug in static tables with dynamic type. See: https://spin.atomicobject.com/2018/10/15/dynamic-type-static-uitableview/
NotificationCenter.default.removeObserver(tableView!, name: UIContentSizeCategory.didChangeNotification, object: nil)
@ -34,6 +39,7 @@ class SettingsViewController: UITableViewController {
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)
NotificationCenter.default.addObserver(self, selector: #selector(browserPreferenceDidChange), name: .browserPreferenceDidChange, object: nil)
tableView.register(UINib(nibName: "SettingsComboTableViewCell", bundle: nil), forCellReuseIdentifier: "SettingsComboTableViewCell")
tableView.register(UINib(nibName: "SettingsTableViewCell", bundle: nil), forCellReuseIdentifier: "SettingsTableViewCell")
@ -76,6 +82,7 @@ class SettingsViewController: UITableViewController {
}
colorPaletteDetailLabel.text = String(describing: AppDefaults.userInterfaceColorPalette)
currentBrowserLabel.text = browserManger.currentBrowser().displayName
let buildLabel = NonIntrinsicLabel(frame: CGRect(x: 32.0, y: 0.0, width: 0.0, height: 0.0))
buildLabel.font = UIFont.systemFont(ofSize: 11.0)
@ -118,7 +125,7 @@ class SettingsViewController: UITableViewController {
}
return defaultNumberOfRows
case 5:
return traitCollection.userInterfaceIdiom == .phone ? 2 : 1
return traitCollection.userInterfaceIdiom == .phone ? 3 : 2
default:
return super.tableView(tableView, numberOfRowsInSection: section)
}
@ -157,7 +164,6 @@ class SettingsViewController: UITableViewController {
acctCell.comboNameLabel?.text = extensionPoint.title
cell = acctCell
}
default:
cell = super.tableView(tableView, cellForRowAt: indexPath)
@ -220,6 +226,11 @@ class SettingsViewController: UITableViewController {
default:
break
}
case 5:
if indexPath.row == 1 {
let browser = UIStoryboard.settings.instantiateController(ofType: BrowserConfigurationViewController.self)
self.navigationController?.pushViewController(browser, animated: true)
}
case 6:
let colorPalette = UIStoryboard.settings.instantiateController(ofType: ColorPaletteTableViewController.self)
self.navigationController?.pushViewController(colorPalette, animated: true)
@ -344,6 +355,10 @@ class SettingsViewController: UITableViewController {
tableView.reloadData()
}
@objc func browserPreferenceDidChange() {
tableView.reloadData()
}
}
// MARK: OPML Document Picker