mirror of
https://github.com/Ranchero-Software/NetNewsWire.git
synced 2025-02-02 12:06:58 +01:00
Merge branch 'ios-release'
This commit is contained in:
commit
770206df60
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
import AppKit
|
import AppKit
|
||||||
import WebKit
|
import WebKit
|
||||||
|
import RSCore
|
||||||
import RSWeb
|
import RSWeb
|
||||||
import Articles
|
import Articles
|
||||||
|
|
||||||
@ -118,8 +119,7 @@ final class DetailWebViewController: NSViewController, WKUIDelegate {
|
|||||||
NotificationCenter.default.addObserver(self, selector: #selector(avatarDidBecomeAvailable(_:)), name: .AvatarDidBecomeAvailable, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(avatarDidBecomeAvailable(_:)), name: .AvatarDidBecomeAvailable, object: nil)
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(faviconDidBecomeAvailable(_:)), name: .FaviconDidBecomeAvailable, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(faviconDidBecomeAvailable(_:)), name: .FaviconDidBecomeAvailable, object: nil)
|
||||||
|
|
||||||
webView.loadFileURL(ArticleRenderer.page.url, allowingReadAccessTo: ArticleRenderer.page.baseURL)
|
webView.loadFileURL(ArticleRenderer.blank.url, allowingReadAccessTo: ArticleRenderer.blank.baseURL)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Notifications
|
// MARK: Notifications
|
||||||
@ -202,12 +202,6 @@ extension DetailWebViewController: WKNavigationDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
struct TemplateData: Codable {
|
|
||||||
let style: String
|
|
||||||
let body: String
|
|
||||||
let title: String
|
|
||||||
let baseURL: String
|
|
||||||
}
|
|
||||||
|
|
||||||
private extension DetailWebViewController {
|
private extension DetailWebViewController {
|
||||||
|
|
||||||
@ -242,16 +236,15 @@ private extension DetailWebViewController {
|
|||||||
rendering = ArticleRenderer.articleHTML(article: article, extractedArticle: extractedArticle, style: style)
|
rendering = ArticleRenderer.articleHTML(article: article, extractedArticle: extractedArticle, style: style)
|
||||||
}
|
}
|
||||||
|
|
||||||
let templateData = TemplateData(style: rendering.style, body: rendering.html, title: rendering.title, baseURL: rendering.baseURL)
|
let substitutions = [
|
||||||
|
"title": rendering.title,
|
||||||
|
"baseURL": rendering.baseURL,
|
||||||
|
"style": rendering.style,
|
||||||
|
"body": rendering.html
|
||||||
|
]
|
||||||
|
|
||||||
let encoder = JSONEncoder()
|
let html = try! MacroProcessor.renderedText(withTemplate: ArticleRenderer.page.html, substitutions: substitutions)
|
||||||
var render = "error();"
|
webView.loadHTMLString(html, baseURL: ArticleRenderer.page.baseURL)
|
||||||
if let data = try? encoder.encode(templateData) {
|
|
||||||
let json = String(data: data, encoding: .utf8)!
|
|
||||||
render = "render(\(json), 0);"
|
|
||||||
}
|
|
||||||
|
|
||||||
webView.evaluateJavaScript(render)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchScrollInfo(_ completion: @escaping (ScrollInfo?) -> Void) {
|
func fetchScrollInfo(_ completion: @escaping (ScrollInfo?) -> Void) {
|
||||||
|
6
Mac/MainWindow/Detail/blank.html
Normal file
6
Mac/MainWindow/Detail/blank.html
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,13 +1,20 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title></title>
|
<title>[[title]]</title>
|
||||||
<base href="">
|
|
||||||
<style>
|
<style>
|
||||||
|
[[style]]
|
||||||
</style>
|
</style>
|
||||||
<script src="main.js"></script>
|
<script src="main.js"></script>
|
||||||
<script src="main_mac.js"></script>
|
<script src="main_mac.js"></script>
|
||||||
<script src="newsfoot.js" async="async"></script>
|
<script src="newsfoot.js" async="async"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
document.addEventListener("DOMContentLoaded", function(event) {
|
||||||
|
processPage();
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<base href="[[baseURL]]">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
[[body]]
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -14,6 +14,9 @@
|
|||||||
3B826DCE2385C89600FC1ADB /* AccountsFeedWranglerWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B826DCA2385C84800FC1ADB /* AccountsFeedWranglerWindowController.swift */; };
|
3B826DCE2385C89600FC1ADB /* AccountsFeedWranglerWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B826DCA2385C84800FC1ADB /* AccountsFeedWranglerWindowController.swift */; };
|
||||||
49F40DF82335B71000552BF4 /* newsfoot.js in Resources */ = {isa = PBXBuildFile; fileRef = 49F40DEF2335B71000552BF4 /* newsfoot.js */; };
|
49F40DF82335B71000552BF4 /* newsfoot.js in Resources */ = {isa = PBXBuildFile; fileRef = 49F40DEF2335B71000552BF4 /* newsfoot.js */; };
|
||||||
49F40DF92335B71000552BF4 /* newsfoot.js in Resources */ = {isa = PBXBuildFile; fileRef = 49F40DEF2335B71000552BF4 /* newsfoot.js */; };
|
49F40DF92335B71000552BF4 /* newsfoot.js in Resources */ = {isa = PBXBuildFile; fileRef = 49F40DEF2335B71000552BF4 /* newsfoot.js */; };
|
||||||
|
5103A9982421643300410853 /* blank.html in Resources */ = {isa = PBXBuildFile; fileRef = 5103A9972421643300410853 /* blank.html */; };
|
||||||
|
5103A9992421643300410853 /* blank.html in Resources */ = {isa = PBXBuildFile; fileRef = 5103A9972421643300410853 /* blank.html */; };
|
||||||
|
5103A9B424216A4200410853 /* blank.html in Resources */ = {isa = PBXBuildFile; fileRef = 5103A9B324216A4200410853 /* blank.html */; };
|
||||||
5108F6B62375E612001ABC45 /* CacheCleaner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5108F6B52375E612001ABC45 /* CacheCleaner.swift */; };
|
5108F6B62375E612001ABC45 /* CacheCleaner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5108F6B52375E612001ABC45 /* CacheCleaner.swift */; };
|
||||||
5108F6B72375E612001ABC45 /* CacheCleaner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5108F6B52375E612001ABC45 /* CacheCleaner.swift */; };
|
5108F6B72375E612001ABC45 /* CacheCleaner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5108F6B52375E612001ABC45 /* CacheCleaner.swift */; };
|
||||||
5108F6D22375EED2001ABC45 /* TimelineCustomizerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5108F6D12375EED2001ABC45 /* TimelineCustomizerViewController.swift */; };
|
5108F6D22375EED2001ABC45 /* TimelineCustomizerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5108F6D12375EED2001ABC45 /* TimelineCustomizerViewController.swift */; };
|
||||||
@ -95,6 +98,7 @@
|
|||||||
515D4FC123257A3200EE1167 /* FolderTreeControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849A97A11ED9F180007D329B /* FolderTreeControllerDelegate.swift */; };
|
515D4FC123257A3200EE1167 /* FolderTreeControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849A97A11ED9F180007D329B /* FolderTreeControllerDelegate.swift */; };
|
||||||
515D4FCA23257CB500EE1167 /* Node-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849A97971ED9EFAA007D329B /* Node-Extensions.swift */; };
|
515D4FCA23257CB500EE1167 /* Node-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849A97971ED9EFAA007D329B /* Node-Extensions.swift */; };
|
||||||
515D4FCC2325815A00EE1167 /* SafariExt.js in Resources */ = {isa = PBXBuildFile; fileRef = 515D4FCB2325815A00EE1167 /* SafariExt.js */; };
|
515D4FCC2325815A00EE1167 /* SafariExt.js in Resources */ = {isa = PBXBuildFile; fileRef = 515D4FCB2325815A00EE1167 /* SafariExt.js */; };
|
||||||
|
516244E3241E19F000B61C47 /* ColorPaletteTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 516244E2241E19F000B61C47 /* ColorPaletteTableViewController.swift */; };
|
||||||
51627A6723861DA3007B3B4B /* MasterFeedViewController+Drag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51627A6623861DA3007B3B4B /* MasterFeedViewController+Drag.swift */; };
|
51627A6723861DA3007B3B4B /* MasterFeedViewController+Drag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51627A6623861DA3007B3B4B /* MasterFeedViewController+Drag.swift */; };
|
||||||
51627A6923861DED007B3B4B /* MasterFeedViewController+Drop.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51627A6823861DED007B3B4B /* MasterFeedViewController+Drop.swift */; };
|
51627A6923861DED007B3B4B /* MasterFeedViewController+Drop.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51627A6823861DED007B3B4B /* MasterFeedViewController+Drop.swift */; };
|
||||||
51627A6B238629D8007B3B4B /* MasterFeedDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51627A6A238629D8007B3B4B /* MasterFeedDataSource.swift */; };
|
51627A6B238629D8007B3B4B /* MasterFeedDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51627A6A238629D8007B3B4B /* MasterFeedDataSource.swift */; };
|
||||||
@ -1249,6 +1253,8 @@
|
|||||||
3B826DB02385C84800FC1ADB /* AccountsFeedWrangler.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AccountsFeedWrangler.xib; sourceTree = "<group>"; };
|
3B826DB02385C84800FC1ADB /* AccountsFeedWrangler.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AccountsFeedWrangler.xib; sourceTree = "<group>"; };
|
||||||
3B826DCA2385C84800FC1ADB /* AccountsFeedWranglerWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountsFeedWranglerWindowController.swift; sourceTree = "<group>"; };
|
3B826DCA2385C84800FC1ADB /* AccountsFeedWranglerWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountsFeedWranglerWindowController.swift; sourceTree = "<group>"; };
|
||||||
49F40DEF2335B71000552BF4 /* newsfoot.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = newsfoot.js; sourceTree = "<group>"; };
|
49F40DEF2335B71000552BF4 /* newsfoot.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = newsfoot.js; sourceTree = "<group>"; };
|
||||||
|
5103A9972421643300410853 /* blank.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = blank.html; sourceTree = "<group>"; };
|
||||||
|
5103A9B324216A4200410853 /* blank.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = blank.html; sourceTree = "<group>"; };
|
||||||
5108F6B52375E612001ABC45 /* CacheCleaner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CacheCleaner.swift; sourceTree = "<group>"; };
|
5108F6B52375E612001ABC45 /* CacheCleaner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CacheCleaner.swift; sourceTree = "<group>"; };
|
||||||
5108F6D12375EED2001ABC45 /* TimelineCustomizerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineCustomizerViewController.swift; sourceTree = "<group>"; };
|
5108F6D12375EED2001ABC45 /* TimelineCustomizerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineCustomizerViewController.swift; sourceTree = "<group>"; };
|
||||||
5108F6D32375EEEF001ABC45 /* TimelinePreviewTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelinePreviewTableViewController.swift; sourceTree = "<group>"; };
|
5108F6D32375EEEF001ABC45 /* TimelinePreviewTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelinePreviewTableViewController.swift; sourceTree = "<group>"; };
|
||||||
@ -1303,6 +1309,7 @@
|
|||||||
515D4FCB2325815A00EE1167 /* SafariExt.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = SafariExt.js; sourceTree = "<group>"; };
|
515D4FCB2325815A00EE1167 /* SafariExt.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = SafariExt.js; sourceTree = "<group>"; };
|
||||||
515D4FCD2325909200EE1167 /* NetNewsWire_iOS_ShareExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NetNewsWire_iOS_ShareExtension.entitlements; sourceTree = "<group>"; };
|
515D4FCD2325909200EE1167 /* NetNewsWire_iOS_ShareExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NetNewsWire_iOS_ShareExtension.entitlements; sourceTree = "<group>"; };
|
||||||
515D4FCE2325B3D000EE1167 /* NetNewsWire_iOSshareextension_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = NetNewsWire_iOSshareextension_target.xcconfig; sourceTree = "<group>"; };
|
515D4FCE2325B3D000EE1167 /* NetNewsWire_iOSshareextension_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = NetNewsWire_iOSshareextension_target.xcconfig; sourceTree = "<group>"; };
|
||||||
|
516244E2241E19F000B61C47 /* ColorPaletteTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPaletteTableViewController.swift; sourceTree = "<group>"; };
|
||||||
51627A6623861DA3007B3B4B /* MasterFeedViewController+Drag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MasterFeedViewController+Drag.swift"; sourceTree = "<group>"; };
|
51627A6623861DA3007B3B4B /* MasterFeedViewController+Drag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MasterFeedViewController+Drag.swift"; sourceTree = "<group>"; };
|
||||||
51627A6823861DED007B3B4B /* MasterFeedViewController+Drop.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MasterFeedViewController+Drop.swift"; sourceTree = "<group>"; };
|
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>"; };
|
51627A6A238629D8007B3B4B /* MasterFeedDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MasterFeedDataSource.swift; sourceTree = "<group>"; };
|
||||||
@ -1875,6 +1882,7 @@
|
|||||||
51A16990235E10D600EB091F /* Settings.storyboard */,
|
51A16990235E10D600EB091F /* Settings.storyboard */,
|
||||||
51A16995235E10D600EB091F /* AboutViewController.swift */,
|
51A16995235E10D600EB091F /* AboutViewController.swift */,
|
||||||
51A16992235E10D600EB091F /* AddAccountViewController.swift */,
|
51A16992235E10D600EB091F /* AddAccountViewController.swift */,
|
||||||
|
516244E2241E19F000B61C47 /* ColorPaletteTableViewController.swift */,
|
||||||
516A09382360A2AE00EAE89B /* SettingsAccountTableViewCell.swift */,
|
516A09382360A2AE00EAE89B /* SettingsAccountTableViewCell.swift */,
|
||||||
516A091D23609A3600EAE89B /* SettingsAccountTableViewCell.xib */,
|
516A091D23609A3600EAE89B /* SettingsAccountTableViewCell.xib */,
|
||||||
516A093A2360A4A000EAE89B /* SettingsTableViewCell.xib */,
|
516A093A2360A4A000EAE89B /* SettingsTableViewCell.xib */,
|
||||||
@ -2367,6 +2375,7 @@
|
|||||||
84E8E0EA202F693600562D8F /* DetailWebView.swift */,
|
84E8E0EA202F693600562D8F /* DetailWebView.swift */,
|
||||||
84D52E941FE588BB00D14F5B /* DetailStatusBarView.swift */,
|
84D52E941FE588BB00D14F5B /* DetailStatusBarView.swift */,
|
||||||
5141E7552374A2890013FF27 /* DetailIconSchemeHandler.swift */,
|
5141E7552374A2890013FF27 /* DetailIconSchemeHandler.swift */,
|
||||||
|
5103A9972421643300410853 /* blank.html */,
|
||||||
B528F81D23333C7E00E735DD /* page.html */,
|
B528F81D23333C7E00E735DD /* page.html */,
|
||||||
5142194A2353C1CF00E07E2C /* main_mac.js */,
|
5142194A2353C1CF00E07E2C /* main_mac.js */,
|
||||||
848362FC2262A30800DA1D35 /* styleSheet.css */,
|
848362FC2262A30800DA1D35 /* styleSheet.css */,
|
||||||
@ -2674,6 +2683,7 @@
|
|||||||
51F85BF02272524100C787DC /* Credits.rtf */,
|
51F85BF02272524100C787DC /* Credits.rtf */,
|
||||||
51F85BEE2272520B00C787DC /* Thanks.rtf */,
|
51F85BEE2272520B00C787DC /* Thanks.rtf */,
|
||||||
51F85BF22272531500C787DC /* Dedication.rtf */,
|
51F85BF22272531500C787DC /* Dedication.rtf */,
|
||||||
|
5103A9B324216A4200410853 /* blank.html */,
|
||||||
51BB7C302335ACDE008E8144 /* page.html */,
|
51BB7C302335ACDE008E8144 /* page.html */,
|
||||||
514219572353C28900E07E2C /* main_ios.js */,
|
514219572353C28900E07E2C /* main_ios.js */,
|
||||||
51C452B72265178500C03939 /* styleSheet.css */,
|
51C452B72265178500C03939 /* styleSheet.css */,
|
||||||
@ -3472,6 +3482,7 @@
|
|||||||
3B826DCD2385C89600FC1ADB /* AccountsFeedWrangler.xib in Resources */,
|
3B826DCD2385C89600FC1ADB /* AccountsFeedWrangler.xib in Resources */,
|
||||||
65ED4069235DEF6C0081F399 /* AccountsReaderAPI.xib in Resources */,
|
65ED4069235DEF6C0081F399 /* AccountsReaderAPI.xib in Resources */,
|
||||||
65ED406A235DEF6C0081F399 /* newsfoot.js in Resources */,
|
65ED406A235DEF6C0081F399 /* newsfoot.js in Resources */,
|
||||||
|
5103A9992421643300410853 /* blank.html in Resources */,
|
||||||
65ED406B235DEF6C0081F399 /* CrashReporterWindow.xib in Resources */,
|
65ED406B235DEF6C0081F399 /* CrashReporterWindow.xib in Resources */,
|
||||||
65ED406C235DEF6C0081F399 /* Credits.rtf in Resources */,
|
65ED406C235DEF6C0081F399 /* Credits.rtf in Resources */,
|
||||||
65ED406D235DEF6C0081F399 /* Inspector.storyboard in Resources */,
|
65ED406D235DEF6C0081F399 /* Inspector.storyboard in Resources */,
|
||||||
@ -3504,6 +3515,7 @@
|
|||||||
516A093723609A3600EAE89B /* SettingsAccountTableViewCell.xib in Resources */,
|
516A093723609A3600EAE89B /* SettingsAccountTableViewCell.xib in Resources */,
|
||||||
51F85BF32272531500C787DC /* Dedication.rtf in Resources */,
|
51F85BF32272531500C787DC /* Dedication.rtf in Resources */,
|
||||||
516A09422361248000EAE89B /* Inspector.storyboard in Resources */,
|
516A09422361248000EAE89B /* Inspector.storyboard in Resources */,
|
||||||
|
5103A9B424216A4200410853 /* blank.html in Resources */,
|
||||||
84C9FCA42262A1B800D921D6 /* LaunchScreenPhone.storyboard in Resources */,
|
84C9FCA42262A1B800D921D6 /* LaunchScreenPhone.storyboard in Resources */,
|
||||||
51F85BEB22724CB600C787DC /* About.rtf in Resources */,
|
51F85BEB22724CB600C787DC /* About.rtf in Resources */,
|
||||||
516A093B2360A4A000EAE89B /* SettingsTableViewCell.xib in Resources */,
|
516A093B2360A4A000EAE89B /* SettingsTableViewCell.xib in Resources */,
|
||||||
@ -3558,6 +3570,7 @@
|
|||||||
3B826DCB2385C84800FC1ADB /* AccountsFeedWrangler.xib in Resources */,
|
3B826DCB2385C84800FC1ADB /* AccountsFeedWrangler.xib in Resources */,
|
||||||
55E15BCB229D65A900D6602A /* AccountsReaderAPI.xib in Resources */,
|
55E15BCB229D65A900D6602A /* AccountsReaderAPI.xib in Resources */,
|
||||||
49F40DF82335B71000552BF4 /* newsfoot.js in Resources */,
|
49F40DF82335B71000552BF4 /* newsfoot.js in Resources */,
|
||||||
|
5103A9982421643300410853 /* blank.html in Resources */,
|
||||||
84BAE64921CEDAF20046DB56 /* CrashReporterWindow.xib in Resources */,
|
84BAE64921CEDAF20046DB56 /* CrashReporterWindow.xib in Resources */,
|
||||||
84C9FC8E22629E8F00D921D6 /* Credits.rtf in Resources */,
|
84C9FC8E22629E8F00D921D6 /* Credits.rtf in Resources */,
|
||||||
84BBB12D20142A4700F054F5 /* Inspector.storyboard in Resources */,
|
84BBB12D20142A4700F054F5 /* Inspector.storyboard in Resources */,
|
||||||
@ -3957,6 +3970,7 @@
|
|||||||
5183CCE5226F4DFA0010922C /* RefreshInterval.swift in Sources */,
|
5183CCE5226F4DFA0010922C /* RefreshInterval.swift in Sources */,
|
||||||
51C4529D22650A1000C03939 /* FaviconURLFinder.swift in Sources */,
|
51C4529D22650A1000C03939 /* FaviconURLFinder.swift in Sources */,
|
||||||
5142192A23522B5500E07E2C /* ImageViewController.swift in Sources */,
|
5142192A23522B5500E07E2C /* ImageViewController.swift in Sources */,
|
||||||
|
516244E3241E19F000B61C47 /* ColorPaletteTableViewController.swift in Sources */,
|
||||||
51C45258226508CF00C03939 /* AppAssets.swift in Sources */,
|
51C45258226508CF00C03939 /* AppAssets.swift in Sources */,
|
||||||
51FA73A82332BE880090D516 /* ExtractedArticle.swift in Sources */,
|
51FA73A82332BE880090D516 /* ExtractedArticle.swift in Sources */,
|
||||||
51C4527C2265091600C03939 /* MasterTimelineDefaultCellLayout.swift in Sources */,
|
51C4527C2265091600C03939 /* MasterTimelineDefaultCellLayout.swift in Sources */,
|
||||||
|
@ -17,15 +17,23 @@ import Account
|
|||||||
struct ArticleRenderer {
|
struct ArticleRenderer {
|
||||||
|
|
||||||
typealias Rendering = (style: String, html: String, title: String, baseURL: String)
|
typealias Rendering = (style: String, html: String, title: String, baseURL: String)
|
||||||
typealias Page = (url: URL, baseURL: URL)
|
|
||||||
|
struct Page {
|
||||||
|
let url: URL
|
||||||
|
let baseURL: URL
|
||||||
|
let html: String
|
||||||
|
|
||||||
|
init(name: String) {
|
||||||
|
url = Bundle.main.url(forResource: name, withExtension: "html")!
|
||||||
|
baseURL = url.deletingLastPathComponent()
|
||||||
|
html = try! NSString(contentsOfFile: url.path, encoding: String.Encoding.utf8.rawValue) as String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static var imageIconScheme = "nnwImageIcon"
|
static var imageIconScheme = "nnwImageIcon"
|
||||||
|
|
||||||
static var page: Page = {
|
static var blank = Page(name: "blank")
|
||||||
let url = Bundle.main.url(forResource: "page", withExtension: "html")!
|
static var page = Page(name: "page")
|
||||||
let baseURL = url.deletingLastPathComponent()
|
|
||||||
return Page(url: url, baseURL: baseURL)
|
|
||||||
}()
|
|
||||||
|
|
||||||
private let article: Article?
|
private let article: Article?
|
||||||
private let extractedArticle: ExtractedArticle?
|
private let extractedArticle: ExtractedArticle?
|
||||||
|
@ -117,25 +117,12 @@ function styleLocalFootnotes() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function render(data, scrollY) {
|
function processPage() {
|
||||||
document.getElementsByTagName("style")[0].innerHTML = data.style;
|
wrapFrames();
|
||||||
|
wrapTables();
|
||||||
let title = document.getElementsByTagName("title")[0];
|
stripStyles();
|
||||||
title.textContent = data.title
|
convertImgSrc();
|
||||||
|
flattenPreElements();
|
||||||
let base = document.getElementsByTagName("base")[0];
|
styleLocalFootnotes();
|
||||||
base.href = data.baseURL
|
postRenderProcessing();
|
||||||
|
|
||||||
document.body.innerHTML = data.body;
|
|
||||||
|
|
||||||
window.scrollTo(0, scrollY);
|
|
||||||
|
|
||||||
wrapFrames()
|
|
||||||
wrapTables()
|
|
||||||
stripStyles()
|
|
||||||
convertImgSrc()
|
|
||||||
flattenPreElements()
|
|
||||||
styleLocalFootnotes()
|
|
||||||
|
|
||||||
postRenderProcessing()
|
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,24 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
|
enum UserInterfaceColorPalette: Int, CustomStringConvertible, CaseIterable {
|
||||||
|
case automatic = 0
|
||||||
|
case light = 1
|
||||||
|
case dark = 2
|
||||||
|
|
||||||
|
var description: String {
|
||||||
|
switch self {
|
||||||
|
case .automatic:
|
||||||
|
return NSLocalizedString("Automatic", comment: "Automatic")
|
||||||
|
case .light:
|
||||||
|
return NSLocalizedString("Light", comment: "Light")
|
||||||
|
case .dark:
|
||||||
|
return NSLocalizedString("Dark", comment: "Dark")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
struct AppDefaults {
|
struct AppDefaults {
|
||||||
|
|
||||||
static var shared: UserDefaults = {
|
static var shared: UserDefaults = {
|
||||||
@ -17,6 +35,7 @@ struct AppDefaults {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
struct Key {
|
struct Key {
|
||||||
|
static let userInterfaceColorPalette = "userInterfaceColorPalette"
|
||||||
static let lastImageCacheFlushDate = "lastImageCacheFlushDate"
|
static let lastImageCacheFlushDate = "lastImageCacheFlushDate"
|
||||||
static let firstRunDate = "firstRunDate"
|
static let firstRunDate = "firstRunDate"
|
||||||
static let timelineGroupByFeed = "timelineGroupByFeed"
|
static let timelineGroupByFeed = "timelineGroupByFeed"
|
||||||
@ -41,6 +60,18 @@ struct AppDefaults {
|
|||||||
return true
|
return true
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
static var userInterfaceColorPalette: UserInterfaceColorPalette {
|
||||||
|
get {
|
||||||
|
if let result = UserInterfaceColorPalette(rawValue: int(for: Key.userInterfaceColorPalette)) {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
return .automatic
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
setInt(for: Key.userInterfaceColorPalette, newValue.rawValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static var addWebFeedAccountID: String? {
|
static var addWebFeedAccountID: String? {
|
||||||
get {
|
get {
|
||||||
return string(for: Key.addWebFeedAccountID)
|
return string(for: Key.addWebFeedAccountID)
|
||||||
@ -160,7 +191,8 @@ struct AppDefaults {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static func registerDefaults() {
|
static func registerDefaults() {
|
||||||
let defaults: [String : Any] = [Key.timelineGroupByFeed: false,
|
let defaults: [String : Any] = [Key.userInterfaceColorPalette: UserInterfaceColorPalette.automatic.rawValue,
|
||||||
|
Key.timelineGroupByFeed: false,
|
||||||
Key.refreshClearsReadArticles: false,
|
Key.refreshClearsReadArticles: false,
|
||||||
Key.timelineNumberOfLines: 2,
|
Key.timelineNumberOfLines: 2,
|
||||||
Key.timelineIconSize: IconSize.medium.rawValue,
|
Key.timelineIconSize: IconSize.medium.rawValue,
|
||||||
|
@ -135,7 +135,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|||||||
|
|
||||||
func manualRefresh(errorHandler: @escaping (Error) -> ()) {
|
func manualRefresh(errorHandler: @escaping (Error) -> ()) {
|
||||||
UIApplication.shared.connectedScenes.compactMap( { $0.delegate as? SceneDelegate } ).forEach {
|
UIApplication.shared.connectedScenes.compactMap( { $0.delegate as? SceneDelegate } ).forEach {
|
||||||
$0.refreshInterface()
|
$0.cleanUp()
|
||||||
}
|
}
|
||||||
AccountManager.shared.refreshAll(errorHandler: errorHandler)
|
AccountManager.shared.refreshAll(errorHandler: errorHandler)
|
||||||
}
|
}
|
||||||
|
@ -103,13 +103,17 @@ class ArticleViewController: UIViewController {
|
|||||||
view.bottomAnchor.constraint(equalTo: pageViewController.view.bottomAnchor)
|
view.bottomAnchor.constraint(equalTo: pageViewController.view.bottomAnchor)
|
||||||
])
|
])
|
||||||
|
|
||||||
let controller = createWebViewController(article, updateView: false)
|
let controller: WebViewController
|
||||||
if let state = restoreState {
|
if let state = restoreState {
|
||||||
|
controller = createWebViewController(article, updateView: false)
|
||||||
controller.extractedArticle = state.extractedArticle
|
controller.extractedArticle = state.extractedArticle
|
||||||
controller.isShowingExtractedArticle = state.isShowingExtractedArticle
|
controller.isShowingExtractedArticle = state.isShowingExtractedArticle
|
||||||
controller.articleExtractorButtonState = state.articleExtractorButtonState
|
controller.articleExtractorButtonState = state.articleExtractorButtonState
|
||||||
controller.windowScrollY = state.windowScrollY
|
controller.windowScrollY = state.windowScrollY
|
||||||
|
} else {
|
||||||
|
controller = createWebViewController(article, updateView: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
articleExtractorButton.buttonState = controller.articleExtractorButtonState
|
articleExtractorButton.buttonState = controller.articleExtractorButtonState
|
||||||
|
|
||||||
self.pageViewController.setViewControllers([controller], direction: .forward, animated: false, completion: nil)
|
self.pageViewController.setViewControllers([controller], direction: .forward, animated: false, completion: nil)
|
||||||
|
@ -11,10 +11,6 @@ import WebKit
|
|||||||
|
|
||||||
class PreloadedWebView: WKWebView {
|
class PreloadedWebView: WKWebView {
|
||||||
|
|
||||||
private struct MessageName {
|
|
||||||
static let domContentLoaded = "domContentLoaded"
|
|
||||||
}
|
|
||||||
|
|
||||||
private var isReady: Bool = false
|
private var isReady: Bool = false
|
||||||
private var readyCompletion: ((PreloadedWebView) -> Void)?
|
private var readyCompletion: ((PreloadedWebView) -> Void)?
|
||||||
|
|
||||||
@ -38,8 +34,8 @@ class PreloadedWebView: WKWebView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func preload() {
|
func preload() {
|
||||||
configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.domContentLoaded)
|
navigationDelegate = self
|
||||||
loadFileURL(ArticleRenderer.page.url, allowingReadAccessTo: ArticleRenderer.page.baseURL)
|
loadFileURL(ArticleRenderer.blank.url, allowingReadAccessTo: ArticleRenderer.blank.baseURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ready(completion: @escaping (PreloadedWebView) -> Void) {
|
func ready(completion: @escaping (PreloadedWebView) -> Void) {
|
||||||
@ -54,17 +50,15 @@ class PreloadedWebView: WKWebView {
|
|||||||
|
|
||||||
// MARK: WKScriptMessageHandler
|
// MARK: WKScriptMessageHandler
|
||||||
|
|
||||||
extension PreloadedWebView: WKScriptMessageHandler {
|
extension PreloadedWebView: WKNavigationDelegate {
|
||||||
|
|
||||||
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
|
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
||||||
if message.name == MessageName.domContentLoaded {
|
|
||||||
isReady = true
|
isReady = true
|
||||||
if let completion = readyCompletion {
|
if let completion = readyCompletion {
|
||||||
completeRequest(completion: completion)
|
completeRequest(completion: completion)
|
||||||
readyCompletion = nil
|
readyCompletion = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +68,7 @@ private extension PreloadedWebView {
|
|||||||
|
|
||||||
func completeRequest(completion: @escaping (PreloadedWebView) -> Void) {
|
func completeRequest(completion: @escaping (PreloadedWebView) -> Void) {
|
||||||
isReady = false
|
isReady = false
|
||||||
configuration.userContentController.removeScriptMessageHandler(forName: MessageName.domContentLoaded)
|
navigationDelegate = nil
|
||||||
completion(self)
|
completion(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,13 +393,6 @@ extension WebViewController: UIScrollViewDelegate {
|
|||||||
|
|
||||||
// MARK: JSON
|
// MARK: JSON
|
||||||
|
|
||||||
private struct TemplateData: Codable {
|
|
||||||
let style: String
|
|
||||||
let body: String
|
|
||||||
let title: String
|
|
||||||
let baseURL: String
|
|
||||||
}
|
|
||||||
|
|
||||||
private struct ImageClickMessage: Codable {
|
private struct ImageClickMessage: Codable {
|
||||||
let x: Float
|
let x: Float
|
||||||
let y: Float
|
let y: Float
|
||||||
@ -416,10 +409,12 @@ private extension WebViewController {
|
|||||||
func loadWebView() {
|
func loadWebView() {
|
||||||
guard isViewLoaded else { return }
|
guard isViewLoaded else { return }
|
||||||
|
|
||||||
coordinator.webViewProvider.dequeueWebView() { webView in
|
if let webView = webView {
|
||||||
|
self.renderPage(webView)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
let webViewToRecycle = self.webView
|
coordinator.webViewProvider.dequeueWebView() { webView in
|
||||||
self.renderPage(webViewToRecycle)
|
|
||||||
|
|
||||||
// Add the webview
|
// Add the webview
|
||||||
webView.translatesAutoresizingMaskIntoConstraints = false
|
webView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
@ -451,9 +446,6 @@ private extension WebViewController {
|
|||||||
webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.imageWasShown)
|
webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.imageWasShown)
|
||||||
|
|
||||||
self.renderPage(webView)
|
self.renderPage(webView)
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
|
|
||||||
self.recycleWebView(webViewToRecycle)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -498,16 +490,16 @@ private extension WebViewController {
|
|||||||
rendering = ArticleRenderer.noSelectionHTML(style: style)
|
rendering = ArticleRenderer.noSelectionHTML(style: style)
|
||||||
}
|
}
|
||||||
|
|
||||||
let templateData = TemplateData(style: rendering.style, body: rendering.html, title: rendering.title, baseURL: rendering.baseURL)
|
let substitutions = [
|
||||||
|
"title": rendering.title,
|
||||||
|
"baseURL": rendering.baseURL,
|
||||||
|
"style": rendering.style,
|
||||||
|
"body": rendering.html,
|
||||||
|
"windowScrollY": String(windowScrollY)
|
||||||
|
]
|
||||||
|
|
||||||
let encoder = JSONEncoder()
|
let html = try! MacroProcessor.renderedText(withTemplate: ArticleRenderer.page.html, substitutions: substitutions)
|
||||||
var render = "error();"
|
webView.loadHTMLString(html, baseURL: ArticleRenderer.page.baseURL)
|
||||||
if let data = try? encoder.encode(templateData) {
|
|
||||||
let json = String(data: data, encoding: .utf8)!
|
|
||||||
render = "render(\(json), \(windowScrollY));"
|
|
||||||
}
|
|
||||||
|
|
||||||
webView.evaluateJavaScript(render)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,6 +144,9 @@ private extension KeyboardManager {
|
|||||||
let markAllAsReadTitle = NSLocalizedString("Mark All as Read", comment: "Mark All as Read")
|
let markAllAsReadTitle = NSLocalizedString("Mark All as Read", comment: "Mark All as Read")
|
||||||
keys.append(KeyboardManager.createKeyCommand(title: markAllAsReadTitle, action: "markAllAsRead:", input: "k", modifiers: [.command]))
|
keys.append(KeyboardManager.createKeyCommand(title: markAllAsReadTitle, action: "markAllAsRead:", input: "k", modifiers: [.command]))
|
||||||
|
|
||||||
|
let cleanUp = NSLocalizedString("Clean Up", comment: "Clean Up")
|
||||||
|
keys.append(KeyboardManager.createKeyCommand(title: cleanUp, action: "cleanUp:", input: "h", modifiers: [.command, .shift]))
|
||||||
|
|
||||||
return keys
|
return keys
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner
|
|||||||
tableView.dataSource = dataSource
|
tableView.dataSource = dataSource
|
||||||
numberOfTextLines = AppDefaults.timelineNumberOfLines
|
numberOfTextLines = AppDefaults.timelineNumberOfLines
|
||||||
iconSize = AppDefaults.timelineIconSize
|
iconSize = AppDefaults.timelineIconSize
|
||||||
resetEstimatedRowHeight()
|
tableView.rowHeight = calculateEstimatedRowHeight(forId: PrototypeFeedContent.feedId, withTitle: PrototypeFeedContent.longTitle, andFeed: PrototypeFeedContent.feedname)
|
||||||
|
|
||||||
if let titleView = Bundle.main.loadNibNamed("MasterTimelineTitleView", owner: self, options: nil)?[0] as? MasterTimelineTitleView {
|
if let titleView = Bundle.main.loadNibNamed("MasterTimelineTitleView", owner: self, options: nil)?[0] as? MasterTimelineTitleView {
|
||||||
navigationItem.titleView = titleView
|
navigationItem.titleView = titleView
|
||||||
@ -443,7 +443,7 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner
|
|||||||
if numberOfTextLines != AppDefaults.timelineNumberOfLines || iconSize != AppDefaults.timelineIconSize {
|
if numberOfTextLines != AppDefaults.timelineNumberOfLines || iconSize != AppDefaults.timelineIconSize {
|
||||||
numberOfTextLines = AppDefaults.timelineNumberOfLines
|
numberOfTextLines = AppDefaults.timelineNumberOfLines
|
||||||
iconSize = AppDefaults.timelineIconSize
|
iconSize = AppDefaults.timelineIconSize
|
||||||
resetEstimatedRowHeight()
|
tableView.rowHeight = calculateEstimatedRowHeight(forId: PrototypeFeedContent.feedId, withTitle: PrototypeFeedContent.longTitle, andFeed: PrototypeFeedContent.feedname)
|
||||||
reloadAllVisibleCells()
|
reloadAllVisibleCells()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -487,26 +487,21 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner
|
|||||||
|
|
||||||
// MARK: Cell Configuring
|
// MARK: Cell Configuring
|
||||||
|
|
||||||
private func resetEstimatedRowHeight() {
|
private func calculateEstimatedRowHeight(forId prototypeID: String, withTitle title: String, andFeed feedName: String) -> CGFloat {
|
||||||
|
|
||||||
let longTitle = "But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?"
|
|
||||||
|
|
||||||
let prototypeID = "prototype"
|
|
||||||
let status = ArticleStatus(articleID: prototypeID, read: false, starred: false, userDeleted: false, dateArrived: Date())
|
let status = ArticleStatus(articleID: prototypeID, read: false, starred: false, userDeleted: false, dateArrived: Date())
|
||||||
let prototypeArticle = Article(accountID: prototypeID, articleID: prototypeID, webFeedID: prototypeID, uniqueID: prototypeID, title: longTitle, contentHTML: nil, contentText: nil, url: nil, externalURL: nil, summary: nil, imageURL: nil, datePublished: nil, dateModified: nil, authors: nil, status: status)
|
let prototypeArticle = Article(accountID: prototypeID, articleID: prototypeID, webFeedID: prototypeID, uniqueID: prototypeID, title: title, contentHTML: nil, contentText: nil, url: nil, externalURL: nil, summary: nil, imageURL: nil, datePublished: nil, dateModified: nil, authors: nil, status: status)
|
||||||
|
|
||||||
let prototypeCellData = MasterTimelineCellData(article: prototypeArticle, showFeedName: true, feedName: "Prototype Feed Name", iconImage: nil, showIcon: false, featuredImage: nil, numberOfLines: numberOfTextLines, iconSize: iconSize)
|
let prototypeCellData = MasterTimelineCellData(article: prototypeArticle, showFeedName: true, feedName: feedName, iconImage: nil, showIcon: false, featuredImage: nil, numberOfLines: numberOfTextLines, iconSize: iconSize)
|
||||||
|
|
||||||
if UIApplication.shared.preferredContentSizeCategory.isAccessibilityCategory {
|
if UIApplication.shared.preferredContentSizeCategory.isAccessibilityCategory {
|
||||||
let layout = MasterTimelineAccessibilityCellLayout(width: tableView.bounds.width, insets: tableView.safeAreaInsets, cellData: prototypeCellData)
|
let layout = MasterTimelineAccessibilityCellLayout(width: tableView.bounds.width, insets: tableView.safeAreaInsets, cellData: prototypeCellData)
|
||||||
tableView.estimatedRowHeight = layout.height
|
return layout.height
|
||||||
} else {
|
} else {
|
||||||
let layout = MasterTimelineDefaultCellLayout(width: tableView.bounds.width, insets: tableView.safeAreaInsets, cellData: prototypeCellData)
|
let layout = MasterTimelineDefaultCellLayout(width: tableView.bounds.width, insets: tableView.safeAreaInsets, cellData: prototypeCellData)
|
||||||
tableView.estimatedRowHeight = layout.height
|
return layout.height
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Searching
|
// MARK: Searching
|
||||||
@ -633,7 +628,9 @@ private extension MasterTimelineViewController {
|
|||||||
var snapshot = NSDiffableDataSourceSnapshot<Int, Article>()
|
var snapshot = NSDiffableDataSourceSnapshot<Int, Article>()
|
||||||
snapshot.appendSections([0])
|
snapshot.appendSections([0])
|
||||||
snapshot.appendItems(coordinator.articles, toSection: 0)
|
snapshot.appendItems(coordinator.articles, toSection: 0)
|
||||||
|
if coordinator.articles.count == 0 {
|
||||||
|
tableView.rowHeight = calculateEstimatedRowHeight(forId: PrototypeFeedContent.feedId, withTitle: PrototypeFeedContent.longTitle, andFeed: PrototypeFeedContent.feedname)
|
||||||
|
}
|
||||||
dataSource.apply(snapshot, animatingDifferences: animated) { [weak self] in
|
dataSource.apply(snapshot, animatingDifferences: animated) { [weak self] in
|
||||||
self?.restoreSelectionIfNecessary(adjustScroll: false)
|
self?.restoreSelectionIfNecessary(adjustScroll: false)
|
||||||
completion?()
|
completion?()
|
||||||
@ -904,3 +901,10 @@ private extension MasterTimelineViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fileprivate struct PrototypeFeedContent {
|
||||||
|
static let longTitle = "But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?"
|
||||||
|
static let shortTitle = "prototype"
|
||||||
|
static let feedId = "feedId"
|
||||||
|
static let feedname = "prototype"
|
||||||
|
}
|
||||||
|
@ -164,5 +164,7 @@
|
|||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
|
<key>UserAgent</key>
|
||||||
|
<string>NetNewsWire (RSS Reader; https://ranchero.com/netnewswire/)</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
11
iOS/Resources/blank.html
Normal file
11
iOS/Resources/blank.html
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
color-scheme: light dark;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,17 +1,22 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title></title>
|
<title>[[title]]</title>
|
||||||
<base href="">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<style>
|
<style>
|
||||||
:root {
|
[[style]]
|
||||||
color-scheme: light dark;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
<script src="main.js"></script>
|
<script src="main.js"></script>
|
||||||
<script src="main_ios.js"></script>
|
<script src="main_ios.js"></script>
|
||||||
<script src="newsfoot.js" async="async"></script>
|
<script src="newsfoot.js" async="async"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
document.addEventListener("DOMContentLoaded", function(event) {
|
||||||
|
window.scrollTo(0, [[windowScrollY]]);
|
||||||
|
processPage();
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<base href="[[baseURL]]">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
[[body]]
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
:root {
|
:root {
|
||||||
|
color-scheme: light dark;
|
||||||
font: -apple-system-body;
|
font: -apple-system-body;
|
||||||
font-size: [[font-size]]px;
|
font-size: [[font-size]]px;
|
||||||
}
|
}
|
||||||
|
@ -90,6 +90,10 @@ class RootSplitViewController: UISplitViewController {
|
|||||||
coordinator.showAdd(.folder)
|
coordinator.showAdd(.folder)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc func cleanUp(_ sender: Any?) {
|
||||||
|
coordinator.cleanUp()
|
||||||
|
}
|
||||||
|
|
||||||
@objc func refresh(_ sender: Any?) {
|
@objc func refresh(_ sender: Any?) {
|
||||||
appDelegate.manualRefresh(errorHandler: ErrorHandler.present(self))
|
appDelegate.manualRefresh(errorHandler: ErrorHandler.present(self))
|
||||||
}
|
}
|
||||||
|
@ -572,7 +572,7 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
|
|||||||
fetchRequestQueue.cancelAllRequests()
|
fetchRequestQueue.cancelAllRequests()
|
||||||
}
|
}
|
||||||
|
|
||||||
func refreshInterface() {
|
func cleanUp() {
|
||||||
if isReadFeedsFiltered {
|
if isReadFeedsFiltered {
|
||||||
rebuildBackingStores()
|
rebuildBackingStores()
|
||||||
}
|
}
|
||||||
|
@ -21,10 +21,13 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|||||||
|
|
||||||
window = UIWindow(windowScene: scene as! UIWindowScene)
|
window = UIWindow(windowScene: scene as! UIWindowScene)
|
||||||
window!.tintColor = AppAssets.primaryAccentColor
|
window!.tintColor = AppAssets.primaryAccentColor
|
||||||
|
updateUserInterfaceStyle()
|
||||||
window!.rootViewController = coordinator.start(for: window!.frame.size)
|
window!.rootViewController = coordinator.start(for: window!.frame.size)
|
||||||
|
|
||||||
coordinator.restoreWindowState(session.stateRestorationActivity)
|
coordinator.restoreWindowState(session.stateRestorationActivity)
|
||||||
|
|
||||||
|
NotificationCenter.default.addObserver(self, selector: #selector(userDefaultsDidChange), name: UserDefaults.didChangeNotification, object: nil)
|
||||||
|
|
||||||
if let shortcutItem = connectionOptions.shortcutItem {
|
if let shortcutItem = connectionOptions.shortcutItem {
|
||||||
window!.makeKeyAndVisible()
|
window!.makeKeyAndVisible()
|
||||||
handleShortcutItem(shortcutItem)
|
handleShortcutItem(shortcutItem)
|
||||||
@ -81,8 +84,8 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|||||||
coordinator.suspend()
|
coordinator.suspend()
|
||||||
}
|
}
|
||||||
|
|
||||||
func refreshInterface() {
|
func cleanUp() {
|
||||||
coordinator.refreshInterface()
|
coordinator.cleanUp()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -102,4 +105,19 @@ private extension SceneDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc func userDefaultsDidChange() {
|
||||||
|
updateUserInterfaceStyle()
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateUserInterfaceStyle() {
|
||||||
|
switch AppDefaults.userInterfaceColorPalette {
|
||||||
|
case .automatic:
|
||||||
|
window!.overrideUserInterfaceStyle = .unspecified
|
||||||
|
case .light:
|
||||||
|
window!.overrideUserInterfaceStyle = .light
|
||||||
|
case .dark:
|
||||||
|
window!.overrideUserInterfaceStyle = .dark
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
42
iOS/Settings/ColorPaletteTableViewController.swift
Normal file
42
iOS/Settings/ColorPaletteTableViewController.swift
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
//
|
||||||
|
// ColorPaletteTableViewController.swift
|
||||||
|
// NetNewsWire-iOS
|
||||||
|
//
|
||||||
|
// Created by Maurice Parker on 3/15/20.
|
||||||
|
// Copyright © 2020 Ranchero Software. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class ColorPaletteTableViewController: UITableViewController {
|
||||||
|
|
||||||
|
// MARK: - Table view data source
|
||||||
|
|
||||||
|
override func numberOfSections(in tableView: UITableView) -> Int {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||||
|
return UserInterfaceColorPalette.allCases.count
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||||
|
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
|
||||||
|
let rowColorPalette = UserInterfaceColorPalette.allCases[indexPath.row]
|
||||||
|
cell.textLabel?.text = String(describing: rowColorPalette)
|
||||||
|
if rowColorPalette == AppDefaults.userInterfaceColorPalette {
|
||||||
|
cell.accessoryType = .checkmark
|
||||||
|
} else {
|
||||||
|
cell.accessoryType = .none
|
||||||
|
}
|
||||||
|
return cell
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||||
|
if let colorPalette = UserInterfaceColorPalette(rawValue: indexPath.row) {
|
||||||
|
AppDefaults.userInterfaceColorPalette = colorPalette
|
||||||
|
}
|
||||||
|
navigationController?.popViewController(animated: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15705" 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="15505" 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"/>
|
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15706"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15509"/>
|
||||||
<capability name="Named colors" minToolsVersion="9.0"/>
|
<capability name="Named colors" minToolsVersion="9.0"/>
|
||||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
@ -19,7 +19,7 @@
|
|||||||
<tableViewSection headerTitle="Notifications, Badge, Data, & More" id="Bmb-Oi-RZK">
|
<tableViewSection headerTitle="Notifications, Badge, Data, & More" id="Bmb-Oi-RZK">
|
||||||
<cells>
|
<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">
|
<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="0.0" y="55.5" width="374" height="44"/>
|
<rect key="frame" x="20" y="55.5" width="374" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<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">
|
<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"/>
|
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
|
||||||
@ -40,7 +40,7 @@
|
|||||||
<tableViewSection headerTitle="Accounts" id="0ac-Ze-Dh4">
|
<tableViewSection headerTitle="Accounts" id="0ac-Ze-Dh4">
|
||||||
<cells>
|
<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">
|
<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="0.0" y="155.5" width="374" height="44"/>
|
<rect key="frame" x="20" y="155.5" width="374" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<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">
|
<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="343" height="44"/>
|
||||||
@ -61,7 +61,7 @@
|
|||||||
<tableViewSection headerTitle="Feeds" id="hAC-uA-RbS">
|
<tableViewSection headerTitle="Feeds" id="hAC-uA-RbS">
|
||||||
<cells>
|
<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">
|
<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="0.0" y="255.5" width="374" height="44"/>
|
<rect key="frame" x="20" y="255.5" width="374" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<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">
|
<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"/>
|
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
|
||||||
@ -317,136 +317,172 @@
|
|||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
</cells>
|
</cells>
|
||||||
</tableViewSection>
|
</tableViewSection>
|
||||||
<tableViewSection headerTitle="Help" id="TkH-4v-yhk">
|
<tableViewSection headerTitle="Appearance" id="TkH-4v-yhk">
|
||||||
<cells>
|
<cells>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="40W-2p-ne4" style="IBUITableViewCellStyleDefault" id="Om7-lH-RUh" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
|
<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="0.0" 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="Om7-lH-RUh" id="vrJ-nE-HMP">
|
|
||||||
<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="40W-2p-ne4">
|
|
||||||
<rect key="frame" x="20" y="0.0" width="334" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
|
||||||
<nil key="textColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
</tableViewCell>
|
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="lOk-Dh-GfZ" style="IBUITableViewCellStyleDefault" id="GWZ-jk-qU6" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
|
|
||||||
<rect key="frame" x="20" y="863.5" width="374" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="GWZ-jk-qU6" id="ZgS-bo-xDl">
|
|
||||||
<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="lOk-Dh-GfZ">
|
|
||||||
<rect key="frame" x="20" y="0.0" width="334" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
|
||||||
<nil key="textColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
</tableViewCell>
|
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="Pm8-6D-fdE" style="IBUITableViewCellStyleDefault" id="3cU-BG-6kK" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
|
|
||||||
<rect key="frame" x="20" y="907.5" width="374" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="3cU-BG-6kK" id="Qm0-SY-0vx">
|
|
||||||
<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="How To Support NetNewsWire" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="Pm8-6D-fdE">
|
|
||||||
<rect key="frame" x="20" y="0.0" width="334" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
|
||||||
<nil key="textColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
</tableViewCell>
|
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="TEA-EG-V6d" style="IBUITableViewCellStyleDefault" id="4yc-ig-I61" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
|
|
||||||
<rect key="frame" x="20" y="951.5" width="374" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="4yc-ig-I61" id="uQl-VP-9p9">
|
|
||||||
<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="GitHub Repository" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="TEA-EG-V6d">
|
|
||||||
<rect key="frame" x="20" y="0.0" width="334" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
|
||||||
<nil key="textColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
</tableViewCell>
|
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="Q9a-Pi-uCc" style="IBUITableViewCellStyleDefault" id="mSW-A7-8lf" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
|
|
||||||
<rect key="frame" x="20" y="995.5" width="374" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="mSW-A7-8lf" id="shF-ro-Zpx">
|
|
||||||
<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="Bug Tracker" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="Q9a-Pi-uCc">
|
|
||||||
<rect key="frame" x="20" y="0.0" width="334" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
|
||||||
<nil key="textColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
</tableViewCell>
|
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="dWz-1o-EpJ" style="IBUITableViewCellStyleDefault" id="2MG-qn-idJ" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
|
|
||||||
<rect key="frame" x="20" y="1039.5" width="374" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="2MG-qn-idJ" id="gP9-ry-keC">
|
|
||||||
<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="Technotes" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="dWz-1o-EpJ">
|
|
||||||
<rect key="frame" x="20" y="0.0" width="334" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
|
||||||
<nil key="textColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
</tableViewCell>
|
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="2o6-8W-nyK" style="IBUITableViewCellStyleDefault" id="he9-Ql-yfa" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
|
|
||||||
<rect key="frame" x="20" y="1083.5" width="374" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="he9-Ql-yfa" id="q6L-C8-H9a">
|
|
||||||
<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 Slack" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="2o6-8W-nyK">
|
|
||||||
<rect key="frame" x="20" y="0.0" width="334" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
|
||||||
<nil key="textColor"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
</tableViewCellContentView>
|
|
||||||
</tableViewCell>
|
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="Uwu-af-31r" style="IBUITableViewCellStyleDefault" id="EvG-yE-gDF" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
|
|
||||||
<rect key="frame" x="20" y="1127.5" width="374" height="44"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<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">
|
<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="343" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="About NetNewsWire" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="Uwu-af-31r">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Color Palette" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2Fp-li-dGP">
|
||||||
<rect key="frame" x="20" y="0.0" width="315" height="44"/>
|
<rect key="frame" x="20" y="11.5" width="99" height="21"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
|
<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" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="16m-Ns-Y8V">
|
||||||
|
<rect key="frame" x="257" y="11.5" width="78" height="21"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
|
<nil key="textColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
</subviews>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstItem="16m-Ns-Y8V" firstAttribute="trailing" secondItem="wBN-zJ-6pN" secondAttribute="trailingMargin" id="R1e-JV-gyn"/>
|
||||||
|
<constraint firstItem="16m-Ns-Y8V" firstAttribute="centerY" secondItem="wBN-zJ-6pN" secondAttribute="centerY" id="SXW-Hv-5bK"/>
|
||||||
|
<constraint firstItem="2Fp-li-dGP" firstAttribute="leading" secondItem="wBN-zJ-6pN" secondAttribute="leadingMargin" id="g40-ob-1IK"/>
|
||||||
|
<constraint firstItem="2Fp-li-dGP" firstAttribute="centerY" secondItem="wBN-zJ-6pN" secondAttribute="centerY" id="geh-mE-9X7"/>
|
||||||
|
</constraints>
|
||||||
|
</tableViewCellContentView>
|
||||||
|
<connections>
|
||||||
|
<outlet property="detail" destination="16m-Ns-Y8V" id="Z0c-2s-usf"/>
|
||||||
|
<outlet property="label" destination="2Fp-li-dGP" id="gyE-t6-U2X"/>
|
||||||
|
</connections>
|
||||||
|
</tableViewCell>
|
||||||
|
</cells>
|
||||||
|
</tableViewSection>
|
||||||
|
<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="0.0" 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="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"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||||
|
<nil key="textColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
</subviews>
|
||||||
|
</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="0.0" y="963.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"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||||
|
<nil key="textColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
</subviews>
|
||||||
|
</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="0.0" y="1007.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"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<subviews>
|
||||||
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="How To Support NetNewsWire" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="lfL-bQ-sOp">
|
||||||
|
<rect key="frame" x="15" y="0.0" width="351" height="44"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||||
|
<nil key="textColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
</subviews>
|
||||||
|
</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="0.0" y="1051.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"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<subviews>
|
||||||
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="GitHub Repository" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="DDJ-8P-3YY">
|
||||||
|
<rect key="frame" x="15" y="0.0" width="351" height="44"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||||
|
<nil key="textColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
</subviews>
|
||||||
|
</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="0.0" y="1095.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"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<subviews>
|
||||||
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Bug Tracker" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="DsV-Qv-X4K">
|
||||||
|
<rect key="frame" x="15" y="0.0" width="351" height="44"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||||
|
<nil key="textColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
</subviews>
|
||||||
|
</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="0.0" y="1139.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"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<subviews>
|
||||||
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Technotes" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="zMz-hU-UYU">
|
||||||
|
<rect key="frame" x="15" y="0.0" width="351" height="44"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||||
|
<nil key="textColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
</subviews>
|
||||||
|
</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="0.0" y="1183.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"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<subviews>
|
||||||
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="NetNewsWire Slack" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="T7x-zl-6Yf">
|
||||||
|
<rect key="frame" x="15" y="0.0" width="351" height="44"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||||
|
<nil key="textColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
</subviews>
|
||||||
|
</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="0.0" y="1227.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"/>
|
||||||
|
<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="NeD-y8-KrM">
|
||||||
|
<rect key="frame" x="15" y="0.0" width="332" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||||
<nil key="textColor"/>
|
<nil key="textColor"/>
|
||||||
@ -471,6 +507,7 @@
|
|||||||
</barButtonItem>
|
</barButtonItem>
|
||||||
</navigationItem>
|
</navigationItem>
|
||||||
<connections>
|
<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="confirmMarkAllAsReadSwitch" destination="UOo-9z-IuL" id="yLZ-Kf-wDt"/>
|
||||||
<outlet property="groupByFeedSwitch" destination="JNi-Wz-RbU" id="TwH-Kd-o6N"/>
|
<outlet property="groupByFeedSwitch" destination="JNi-Wz-RbU" id="TwH-Kd-o6N"/>
|
||||||
<outlet property="refreshClearsReadArticlesSwitch" destination="duV-CN-JmH" id="xTd-jF-Ei1"/>
|
<outlet property="refreshClearsReadArticlesSwitch" destination="duV-CN-JmH" id="xTd-jF-Ei1"/>
|
||||||
@ -968,6 +1005,45 @@
|
|||||||
</objects>
|
</objects>
|
||||||
<point key="canvasLocation" x="3096" y="151"/>
|
<point key="canvasLocation" x="3096" y="151"/>
|
||||||
</scene>
|
</scene>
|
||||||
|
<!--Color Palette-->
|
||||||
|
<scene sceneID="1mT-fg-ezs">
|
||||||
|
<objects>
|
||||||
|
<tableViewController storyboardIdentifier="ColorPaletteTableViewController" title="Color Palette" id="fO4-og-e41" customClass="ColorPaletteTableViewController" 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="I8p-P9-C8h">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="414" height="808"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<color key="backgroundColor" cocoaTouchSystemColor="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"/>
|
||||||
|
<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"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<subviews>
|
||||||
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="6tf-Xb-7b8">
|
||||||
|
<rect key="frame" x="20" y="0.0" width="334" height="43.5"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
|
<nil key="textColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
</subviews>
|
||||||
|
</tableViewCellContentView>
|
||||||
|
</tableViewCell>
|
||||||
|
</prototypes>
|
||||||
|
<sections/>
|
||||||
|
<connections>
|
||||||
|
<outlet property="dataSource" destination="fO4-og-e41" id="155-KJ-Ps6"/>
|
||||||
|
<outlet property="delegate" destination="fO4-og-e41" id="zBh-hF-yaJ"/>
|
||||||
|
</connections>
|
||||||
|
</tableView>
|
||||||
|
<simulatedNavigationBarMetrics key="simulatedTopBarMetrics" translucent="NO" prompted="NO"/>
|
||||||
|
</tableViewController>
|
||||||
|
<placeholder placeholderIdentifier="IBFirstResponder" id="ODK-C8-FL4" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
||||||
|
</objects>
|
||||||
|
<point key="canvasLocation" x="3743" y="151"/>
|
||||||
|
</scene>
|
||||||
</scenes>
|
</scenes>
|
||||||
<resources>
|
<resources>
|
||||||
<image name="accountFeedWrangler" width="512" height="512"/>
|
<image name="accountFeedWrangler" width="512" height="512"/>
|
||||||
|
@ -21,6 +21,7 @@ class SettingsViewController: UITableViewController {
|
|||||||
@IBOutlet weak var refreshClearsReadArticlesSwitch: UISwitch!
|
@IBOutlet weak var refreshClearsReadArticlesSwitch: UISwitch!
|
||||||
@IBOutlet weak var confirmMarkAllAsReadSwitch: UISwitch!
|
@IBOutlet weak var confirmMarkAllAsReadSwitch: UISwitch!
|
||||||
@IBOutlet weak var showFullscreenArticlesSwitch: UISwitch!
|
@IBOutlet weak var showFullscreenArticlesSwitch: UISwitch!
|
||||||
|
@IBOutlet weak var colorPaletteDetailLabel: UILabel!
|
||||||
|
|
||||||
var scrollToArticlesSection = false
|
var scrollToArticlesSection = false
|
||||||
weak var presentingParentController: UIViewController?
|
weak var presentingParentController: UIViewController?
|
||||||
@ -33,7 +34,6 @@ class SettingsViewController: UITableViewController {
|
|||||||
NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange), name: .UserDidAddAccount, object: nil)
|
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(accountsDidChange), name: .UserDidDeleteAccount, object: nil)
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(displayNameDidChange), name: .DisplayNameDidChange, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(displayNameDidChange), name: .DisplayNameDidChange, object: nil)
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(userDefaultsDidChange), name: UserDefaults.didChangeNotification, object: nil)
|
|
||||||
|
|
||||||
tableView.register(UINib(nibName: "SettingsAccountTableViewCell", bundle: nil), forCellReuseIdentifier: "SettingsAccountTableViewCell")
|
tableView.register(UINib(nibName: "SettingsAccountTableViewCell", bundle: nil), forCellReuseIdentifier: "SettingsAccountTableViewCell")
|
||||||
tableView.register(UINib(nibName: "SettingsTableViewCell", bundle: nil), forCellReuseIdentifier: "SettingsTableViewCell")
|
tableView.register(UINib(nibName: "SettingsTableViewCell", bundle: nil), forCellReuseIdentifier: "SettingsTableViewCell")
|
||||||
@ -75,6 +75,8 @@ class SettingsViewController: UITableViewController {
|
|||||||
showFullscreenArticlesSwitch.isOn = false
|
showFullscreenArticlesSwitch.isOn = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
colorPaletteDetailLabel.text = String(describing: AppDefaults.userInterfaceColorPalette)
|
||||||
|
|
||||||
let buildLabel = NonIntrinsicLabel(frame: CGRect(x: 32.0, y: 0.0, width: 0.0, height: 0.0))
|
let buildLabel = NonIntrinsicLabel(frame: CGRect(x: 32.0, y: 0.0, width: 0.0, height: 0.0))
|
||||||
buildLabel.font = UIFont.systemFont(ofSize: 11.0)
|
buildLabel.font = UIFont.systemFont(ofSize: 11.0)
|
||||||
buildLabel.textColor = UIColor.gray
|
buildLabel.textColor = UIColor.gray
|
||||||
@ -192,6 +194,9 @@ class SettingsViewController: UITableViewController {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
case 5:
|
case 5:
|
||||||
|
let colorPalette = UIStoryboard.settings.instantiateController(ofType: ColorPaletteTableViewController.self)
|
||||||
|
self.navigationController?.pushViewController(colorPalette, animated: true)
|
||||||
|
case 6:
|
||||||
switch indexPath.row {
|
switch indexPath.row {
|
||||||
case 0:
|
case 0:
|
||||||
openURL("https://ranchero.com/netnewswire/help/ios/5.0/en/")
|
openURL("https://ranchero.com/netnewswire/help/ios/5.0/en/")
|
||||||
@ -305,10 +310,6 @@ class SettingsViewController: UITableViewController {
|
|||||||
tableView.reloadData()
|
tableView.reloadData()
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func userDefaultsDidChange() {
|
|
||||||
tableView.reloadData()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: OPML Document Picker
|
// MARK: OPML Document Picker
|
||||||
|
@ -17,13 +17,13 @@ extension UITableView {
|
|||||||
selectRow(at: indexPath, animated: animations.contains(.select), scrollPosition: .none)
|
selectRow(at: indexPath, animated: animations.contains(.select), scrollPosition: .none)
|
||||||
|
|
||||||
if let visibleIndexPaths = indexPathsForRows(in: safeAreaLayoutGuide.layoutFrame) {
|
if let visibleIndexPaths = indexPathsForRows(in: safeAreaLayoutGuide.layoutFrame) {
|
||||||
if !(visibleIndexPaths.contains(indexPath) && cellCompletelyVisable(indexPath)) {
|
if !(visibleIndexPaths.contains(indexPath) && cellCompletelyVisible(indexPath)) {
|
||||||
scrollToRow(at: indexPath, at: .middle, animated: animations.contains(.scroll))
|
scrollToRow(at: indexPath, at: .middle, animated: animations.contains(.scroll))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func cellCompletelyVisable(_ indexPath: IndexPath) -> Bool {
|
func cellCompletelyVisible(_ indexPath: IndexPath) -> Bool {
|
||||||
let rect = rectForRow(at: indexPath)
|
let rect = rectForRow(at: indexPath)
|
||||||
return safeAreaLayoutGuide.layoutFrame.contains(rect)
|
return safeAreaLayoutGuide.layoutFrame.contains(rect)
|
||||||
}
|
}
|
||||||
|
@ -71,6 +71,7 @@ class VibrantTableViewCell: UITableViewCell {
|
|||||||
class VibrantBasicTableViewCell: VibrantTableViewCell {
|
class VibrantBasicTableViewCell: VibrantTableViewCell {
|
||||||
|
|
||||||
@IBOutlet private var label: UILabel!
|
@IBOutlet private var label: UILabel!
|
||||||
|
@IBOutlet private var detail: UILabel!
|
||||||
@IBOutlet private var icon: UIImageView!
|
@IBOutlet private var icon: UIImageView!
|
||||||
|
|
||||||
@IBInspectable var imageNormal: UIImage?
|
@IBInspectable var imageNormal: UIImage?
|
||||||
@ -88,6 +89,7 @@ class VibrantBasicTableViewCell: VibrantTableViewCell {
|
|||||||
super.updateVibrancy(animated: animated)
|
super.updateVibrancy(animated: animated)
|
||||||
updateIconVibrancy(icon, color: iconTint, image: iconImage, animated: animated)
|
updateIconVibrancy(icon, color: iconTint, image: iconImage, animated: animated)
|
||||||
updateLabelVibrancy(label, color: labelColor, animated: animated)
|
updateLabelVibrancy(label, color: labelColor, animated: animated)
|
||||||
|
updateLabelVibrancy(detail, color: secondaryLabelColor, animated: animated)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateIconVibrancy(_ icon: UIImageView?, color: UIColor, image: UIImage?, animated: Bool) {
|
private func updateIconVibrancy(_ icon: UIImageView?, color: UIColor, image: UIImage?, animated: Bool) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user