mirror of
https://github.com/Ranchero-Software/NetNewsWire.git
synced 2025-02-02 03:56:55 +01:00
Merge branch 'ios-release'
This commit is contained in:
commit
770206df60
@ -8,6 +8,7 @@
|
||||
|
||||
import AppKit
|
||||
import WebKit
|
||||
import RSCore
|
||||
import RSWeb
|
||||
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(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
|
||||
@ -202,12 +202,6 @@ extension DetailWebViewController: WKNavigationDelegate {
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
struct TemplateData: Codable {
|
||||
let style: String
|
||||
let body: String
|
||||
let title: String
|
||||
let baseURL: String
|
||||
}
|
||||
|
||||
private extension DetailWebViewController {
|
||||
|
||||
@ -242,16 +236,15 @@ private extension DetailWebViewController {
|
||||
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()
|
||||
var render = "error();"
|
||||
if let data = try? encoder.encode(templateData) {
|
||||
let json = String(data: data, encoding: .utf8)!
|
||||
render = "render(\(json), 0);"
|
||||
}
|
||||
|
||||
webView.evaluateJavaScript(render)
|
||||
let html = try! MacroProcessor.renderedText(withTemplate: ArticleRenderer.page.html, substitutions: substitutions)
|
||||
webView.loadHTMLString(html, baseURL: ArticleRenderer.page.baseURL)
|
||||
}
|
||||
|
||||
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>
|
||||
<head>
|
||||
<title></title>
|
||||
<base href="">
|
||||
<title>[[title]]</title>
|
||||
<style>
|
||||
[[style]]
|
||||
</style>
|
||||
<script src="main.js"></script>
|
||||
<script src="main_mac.js"></script>
|
||||
<script src="newsfoot.js" async="async"></script>
|
||||
<script type="text/javascript">
|
||||
document.addEventListener("DOMContentLoaded", function(event) {
|
||||
processPage();
|
||||
})
|
||||
</script>
|
||||
<base href="[[baseURL]]">
|
||||
</head>
|
||||
<body>
|
||||
[[body]]
|
||||
</body>
|
||||
</html>
|
||||
|
@ -14,6 +14,9 @@
|
||||
3B826DCE2385C89600FC1ADB /* AccountsFeedWranglerWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B826DCA2385C84800FC1ADB /* AccountsFeedWranglerWindowController.swift */; };
|
||||
49F40DF82335B71000552BF4 /* 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 */; };
|
||||
5108F6B72375E612001ABC45 /* CacheCleaner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5108F6B52375E612001ABC45 /* CacheCleaner.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 */; };
|
||||
515D4FCA23257CB500EE1167 /* Node-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849A97971ED9EFAA007D329B /* Node-Extensions.swift */; };
|
||||
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 */; };
|
||||
51627A6923861DED007B3B4B /* MasterFeedViewController+Drop.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51627A6823861DED007B3B4B /* MasterFeedViewController+Drop.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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
@ -1303,6 +1309,7 @@
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
@ -1875,6 +1882,7 @@
|
||||
51A16990235E10D600EB091F /* Settings.storyboard */,
|
||||
51A16995235E10D600EB091F /* AboutViewController.swift */,
|
||||
51A16992235E10D600EB091F /* AddAccountViewController.swift */,
|
||||
516244E2241E19F000B61C47 /* ColorPaletteTableViewController.swift */,
|
||||
516A09382360A2AE00EAE89B /* SettingsAccountTableViewCell.swift */,
|
||||
516A091D23609A3600EAE89B /* SettingsAccountTableViewCell.xib */,
|
||||
516A093A2360A4A000EAE89B /* SettingsTableViewCell.xib */,
|
||||
@ -2367,6 +2375,7 @@
|
||||
84E8E0EA202F693600562D8F /* DetailWebView.swift */,
|
||||
84D52E941FE588BB00D14F5B /* DetailStatusBarView.swift */,
|
||||
5141E7552374A2890013FF27 /* DetailIconSchemeHandler.swift */,
|
||||
5103A9972421643300410853 /* blank.html */,
|
||||
B528F81D23333C7E00E735DD /* page.html */,
|
||||
5142194A2353C1CF00E07E2C /* main_mac.js */,
|
||||
848362FC2262A30800DA1D35 /* styleSheet.css */,
|
||||
@ -2674,6 +2683,7 @@
|
||||
51F85BF02272524100C787DC /* Credits.rtf */,
|
||||
51F85BEE2272520B00C787DC /* Thanks.rtf */,
|
||||
51F85BF22272531500C787DC /* Dedication.rtf */,
|
||||
5103A9B324216A4200410853 /* blank.html */,
|
||||
51BB7C302335ACDE008E8144 /* page.html */,
|
||||
514219572353C28900E07E2C /* main_ios.js */,
|
||||
51C452B72265178500C03939 /* styleSheet.css */,
|
||||
@ -3472,6 +3482,7 @@
|
||||
3B826DCD2385C89600FC1ADB /* AccountsFeedWrangler.xib in Resources */,
|
||||
65ED4069235DEF6C0081F399 /* AccountsReaderAPI.xib in Resources */,
|
||||
65ED406A235DEF6C0081F399 /* newsfoot.js in Resources */,
|
||||
5103A9992421643300410853 /* blank.html in Resources */,
|
||||
65ED406B235DEF6C0081F399 /* CrashReporterWindow.xib in Resources */,
|
||||
65ED406C235DEF6C0081F399 /* Credits.rtf in Resources */,
|
||||
65ED406D235DEF6C0081F399 /* Inspector.storyboard in Resources */,
|
||||
@ -3504,6 +3515,7 @@
|
||||
516A093723609A3600EAE89B /* SettingsAccountTableViewCell.xib in Resources */,
|
||||
51F85BF32272531500C787DC /* Dedication.rtf in Resources */,
|
||||
516A09422361248000EAE89B /* Inspector.storyboard in Resources */,
|
||||
5103A9B424216A4200410853 /* blank.html in Resources */,
|
||||
84C9FCA42262A1B800D921D6 /* LaunchScreenPhone.storyboard in Resources */,
|
||||
51F85BEB22724CB600C787DC /* About.rtf in Resources */,
|
||||
516A093B2360A4A000EAE89B /* SettingsTableViewCell.xib in Resources */,
|
||||
@ -3558,6 +3570,7 @@
|
||||
3B826DCB2385C84800FC1ADB /* AccountsFeedWrangler.xib in Resources */,
|
||||
55E15BCB229D65A900D6602A /* AccountsReaderAPI.xib in Resources */,
|
||||
49F40DF82335B71000552BF4 /* newsfoot.js in Resources */,
|
||||
5103A9982421643300410853 /* blank.html in Resources */,
|
||||
84BAE64921CEDAF20046DB56 /* CrashReporterWindow.xib in Resources */,
|
||||
84C9FC8E22629E8F00D921D6 /* Credits.rtf in Resources */,
|
||||
84BBB12D20142A4700F054F5 /* Inspector.storyboard in Resources */,
|
||||
@ -3957,6 +3970,7 @@
|
||||
5183CCE5226F4DFA0010922C /* RefreshInterval.swift in Sources */,
|
||||
51C4529D22650A1000C03939 /* FaviconURLFinder.swift in Sources */,
|
||||
5142192A23522B5500E07E2C /* ImageViewController.swift in Sources */,
|
||||
516244E3241E19F000B61C47 /* ColorPaletteTableViewController.swift in Sources */,
|
||||
51C45258226508CF00C03939 /* AppAssets.swift in Sources */,
|
||||
51FA73A82332BE880090D516 /* ExtractedArticle.swift in Sources */,
|
||||
51C4527C2265091600C03939 /* MasterTimelineDefaultCellLayout.swift in Sources */,
|
||||
|
@ -17,15 +17,23 @@ import Account
|
||||
struct ArticleRenderer {
|
||||
|
||||
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 page: Page = {
|
||||
let url = Bundle.main.url(forResource: "page", withExtension: "html")!
|
||||
let baseURL = url.deletingLastPathComponent()
|
||||
return Page(url: url, baseURL: baseURL)
|
||||
}()
|
||||
static var blank = Page(name: "blank")
|
||||
static var page = Page(name: "page")
|
||||
|
||||
private let article: Article?
|
||||
private let extractedArticle: ExtractedArticle?
|
||||
|
@ -117,25 +117,12 @@ function styleLocalFootnotes() {
|
||||
}
|
||||
}
|
||||
|
||||
function render(data, scrollY) {
|
||||
document.getElementsByTagName("style")[0].innerHTML = data.style;
|
||||
|
||||
let title = document.getElementsByTagName("title")[0];
|
||||
title.textContent = data.title
|
||||
|
||||
let base = document.getElementsByTagName("base")[0];
|
||||
base.href = data.baseURL
|
||||
|
||||
document.body.innerHTML = data.body;
|
||||
|
||||
window.scrollTo(0, scrollY);
|
||||
|
||||
wrapFrames()
|
||||
wrapTables()
|
||||
stripStyles()
|
||||
convertImgSrc()
|
||||
flattenPreElements()
|
||||
styleLocalFootnotes()
|
||||
|
||||
postRenderProcessing()
|
||||
function processPage() {
|
||||
wrapFrames();
|
||||
wrapTables();
|
||||
stripStyles();
|
||||
convertImgSrc();
|
||||
flattenPreElements();
|
||||
styleLocalFootnotes();
|
||||
postRenderProcessing();
|
||||
}
|
||||
|
@ -8,6 +8,24 @@
|
||||
|
||||
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 {
|
||||
|
||||
static var shared: UserDefaults = {
|
||||
@ -17,6 +35,7 @@ struct AppDefaults {
|
||||
}()
|
||||
|
||||
struct Key {
|
||||
static let userInterfaceColorPalette = "userInterfaceColorPalette"
|
||||
static let lastImageCacheFlushDate = "lastImageCacheFlushDate"
|
||||
static let firstRunDate = "firstRunDate"
|
||||
static let timelineGroupByFeed = "timelineGroupByFeed"
|
||||
@ -40,6 +59,18 @@ struct AppDefaults {
|
||||
firstRunDate = Date()
|
||||
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? {
|
||||
get {
|
||||
@ -160,7 +191,8 @@ struct AppDefaults {
|
||||
}
|
||||
|
||||
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.timelineNumberOfLines: 2,
|
||||
Key.timelineIconSize: IconSize.medium.rawValue,
|
||||
|
@ -135,7 +135,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
||||
|
||||
func manualRefresh(errorHandler: @escaping (Error) -> ()) {
|
||||
UIApplication.shared.connectedScenes.compactMap( { $0.delegate as? SceneDelegate } ).forEach {
|
||||
$0.refreshInterface()
|
||||
$0.cleanUp()
|
||||
}
|
||||
AccountManager.shared.refreshAll(errorHandler: errorHandler)
|
||||
}
|
||||
|
@ -103,13 +103,17 @@ class ArticleViewController: UIViewController {
|
||||
view.bottomAnchor.constraint(equalTo: pageViewController.view.bottomAnchor)
|
||||
])
|
||||
|
||||
let controller = createWebViewController(article, updateView: false)
|
||||
let controller: WebViewController
|
||||
if let state = restoreState {
|
||||
controller = createWebViewController(article, updateView: false)
|
||||
controller.extractedArticle = state.extractedArticle
|
||||
controller.isShowingExtractedArticle = state.isShowingExtractedArticle
|
||||
controller.articleExtractorButtonState = state.articleExtractorButtonState
|
||||
controller.windowScrollY = state.windowScrollY
|
||||
} else {
|
||||
controller = createWebViewController(article, updateView: true)
|
||||
}
|
||||
|
||||
articleExtractorButton.buttonState = controller.articleExtractorButtonState
|
||||
|
||||
self.pageViewController.setViewControllers([controller], direction: .forward, animated: false, completion: nil)
|
||||
|
@ -11,10 +11,6 @@ import WebKit
|
||||
|
||||
class PreloadedWebView: WKWebView {
|
||||
|
||||
private struct MessageName {
|
||||
static let domContentLoaded = "domContentLoaded"
|
||||
}
|
||||
|
||||
private var isReady: Bool = false
|
||||
private var readyCompletion: ((PreloadedWebView) -> Void)?
|
||||
|
||||
@ -38,8 +34,8 @@ class PreloadedWebView: WKWebView {
|
||||
}
|
||||
|
||||
func preload() {
|
||||
configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.domContentLoaded)
|
||||
loadFileURL(ArticleRenderer.page.url, allowingReadAccessTo: ArticleRenderer.page.baseURL)
|
||||
navigationDelegate = self
|
||||
loadFileURL(ArticleRenderer.blank.url, allowingReadAccessTo: ArticleRenderer.blank.baseURL)
|
||||
}
|
||||
|
||||
func ready(completion: @escaping (PreloadedWebView) -> Void) {
|
||||
@ -54,18 +50,16 @@ class PreloadedWebView: WKWebView {
|
||||
|
||||
// MARK: WKScriptMessageHandler
|
||||
|
||||
extension PreloadedWebView: WKScriptMessageHandler {
|
||||
extension PreloadedWebView: WKNavigationDelegate {
|
||||
|
||||
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
|
||||
if message.name == MessageName.domContentLoaded {
|
||||
isReady = true
|
||||
if let completion = readyCompletion {
|
||||
completeRequest(completion: completion)
|
||||
readyCompletion = nil
|
||||
}
|
||||
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
||||
isReady = true
|
||||
if let completion = readyCompletion {
|
||||
completeRequest(completion: completion)
|
||||
readyCompletion = nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// MARK: Private
|
||||
@ -74,7 +68,7 @@ private extension PreloadedWebView {
|
||||
|
||||
func completeRequest(completion: @escaping (PreloadedWebView) -> Void) {
|
||||
isReady = false
|
||||
configuration.userContentController.removeScriptMessageHandler(forName: MessageName.domContentLoaded)
|
||||
navigationDelegate = nil
|
||||
completion(self)
|
||||
}
|
||||
|
||||
|
@ -325,7 +325,7 @@ extension WebViewController: WKNavigationDelegate {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// MARK: WKUIDelegate
|
||||
@ -393,13 +393,6 @@ extension WebViewController: UIScrollViewDelegate {
|
||||
|
||||
// MARK: JSON
|
||||
|
||||
private struct TemplateData: Codable {
|
||||
let style: String
|
||||
let body: String
|
||||
let title: String
|
||||
let baseURL: String
|
||||
}
|
||||
|
||||
private struct ImageClickMessage: Codable {
|
||||
let x: Float
|
||||
let y: Float
|
||||
@ -416,11 +409,13 @@ private extension WebViewController {
|
||||
func loadWebView() {
|
||||
guard isViewLoaded else { return }
|
||||
|
||||
if let webView = webView {
|
||||
self.renderPage(webView)
|
||||
return
|
||||
}
|
||||
|
||||
coordinator.webViewProvider.dequeueWebView() { webView in
|
||||
|
||||
let webViewToRecycle = self.webView
|
||||
self.renderPage(webViewToRecycle)
|
||||
|
||||
// Add the webview
|
||||
webView.translatesAutoresizingMaskIntoConstraints = false
|
||||
self.view.insertSubview(webView, at: 0)
|
||||
@ -451,9 +446,6 @@ private extension WebViewController {
|
||||
webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.imageWasShown)
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
let templateData = TemplateData(style: rendering.style, body: rendering.html, title: rendering.title, baseURL: rendering.baseURL)
|
||||
|
||||
let encoder = JSONEncoder()
|
||||
var render = "error();"
|
||||
if let data = try? encoder.encode(templateData) {
|
||||
let json = String(data: data, encoding: .utf8)!
|
||||
render = "render(\(json), \(windowScrollY));"
|
||||
}
|
||||
let substitutions = [
|
||||
"title": rendering.title,
|
||||
"baseURL": rendering.baseURL,
|
||||
"style": rendering.style,
|
||||
"body": rendering.html,
|
||||
"windowScrollY": String(windowScrollY)
|
||||
]
|
||||
|
||||
webView.evaluateJavaScript(render)
|
||||
let html = try! MacroProcessor.renderedText(withTemplate: ArticleRenderer.page.html, substitutions: substitutions)
|
||||
webView.loadHTMLString(html, baseURL: ArticleRenderer.page.baseURL)
|
||||
|
||||
}
|
||||
|
||||
|
@ -144,6 +144,9 @@ private extension KeyboardManager {
|
||||
let markAllAsReadTitle = NSLocalizedString("Mark All as Read", comment: "Mark All as Read")
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner
|
||||
tableView.dataSource = dataSource
|
||||
numberOfTextLines = AppDefaults.timelineNumberOfLines
|
||||
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 {
|
||||
navigationItem.titleView = titleView
|
||||
@ -443,7 +443,7 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner
|
||||
if numberOfTextLines != AppDefaults.timelineNumberOfLines || iconSize != AppDefaults.timelineIconSize {
|
||||
numberOfTextLines = AppDefaults.timelineNumberOfLines
|
||||
iconSize = AppDefaults.timelineIconSize
|
||||
resetEstimatedRowHeight()
|
||||
tableView.rowHeight = calculateEstimatedRowHeight(forId: PrototypeFeedContent.feedId, withTitle: PrototypeFeedContent.longTitle, andFeed: PrototypeFeedContent.feedname)
|
||||
reloadAllVisibleCells()
|
||||
}
|
||||
}
|
||||
@ -487,26 +487,21 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner
|
||||
|
||||
// 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 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 {
|
||||
let layout = MasterTimelineAccessibilityCellLayout(width: tableView.bounds.width, insets: tableView.safeAreaInsets, cellData: prototypeCellData)
|
||||
tableView.estimatedRowHeight = layout.height
|
||||
return layout.height
|
||||
} else {
|
||||
let layout = MasterTimelineDefaultCellLayout(width: tableView.bounds.width, insets: tableView.safeAreaInsets, cellData: prototypeCellData)
|
||||
tableView.estimatedRowHeight = layout.height
|
||||
return layout.height
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: Searching
|
||||
@ -633,7 +628,9 @@ private extension MasterTimelineViewController {
|
||||
var snapshot = NSDiffableDataSourceSnapshot<Int, Article>()
|
||||
snapshot.appendSections([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
|
||||
self?.restoreSelectionIfNecessary(adjustScroll: false)
|
||||
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>
|
||||
</array>
|
||||
<key>UserAgent</key>
|
||||
<string>NetNewsWire (RSS Reader; https://ranchero.com/netnewswire/)</string>
|
||||
</dict>
|
||||
</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>
|
||||
<head>
|
||||
<title></title>
|
||||
<base href="">
|
||||
<title>[[title]]</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<style>
|
||||
:root {
|
||||
color-scheme: light dark;
|
||||
}
|
||||
[[style]]
|
||||
</style>
|
||||
<script src="main.js"></script>
|
||||
<script src="main_ios.js"></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>
|
||||
<body>
|
||||
[[body]]
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,4 +1,5 @@
|
||||
:root {
|
||||
color-scheme: light dark;
|
||||
font: -apple-system-body;
|
||||
font-size: [[font-size]]px;
|
||||
}
|
||||
|
@ -90,6 +90,10 @@ class RootSplitViewController: UISplitViewController {
|
||||
coordinator.showAdd(.folder)
|
||||
}
|
||||
|
||||
@objc func cleanUp(_ sender: Any?) {
|
||||
coordinator.cleanUp()
|
||||
}
|
||||
|
||||
@objc func refresh(_ sender: Any?) {
|
||||
appDelegate.manualRefresh(errorHandler: ErrorHandler.present(self))
|
||||
}
|
||||
|
@ -572,7 +572,7 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
|
||||
fetchRequestQueue.cancelAllRequests()
|
||||
}
|
||||
|
||||
func refreshInterface() {
|
||||
func cleanUp() {
|
||||
if isReadFeedsFiltered {
|
||||
rebuildBackingStores()
|
||||
}
|
||||
|
@ -21,10 +21,13 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
|
||||
window = UIWindow(windowScene: scene as! UIWindowScene)
|
||||
window!.tintColor = AppAssets.primaryAccentColor
|
||||
updateUserInterfaceStyle()
|
||||
window!.rootViewController = coordinator.start(for: window!.frame.size)
|
||||
|
||||
coordinator.restoreWindowState(session.stateRestorationActivity)
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(userDefaultsDidChange), name: UserDefaults.didChangeNotification, object: nil)
|
||||
|
||||
if let shortcutItem = connectionOptions.shortcutItem {
|
||||
window!.makeKeyAndVisible()
|
||||
handleShortcutItem(shortcutItem)
|
||||
@ -81,8 +84,8 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
coordinator.suspend()
|
||||
}
|
||||
|
||||
func refreshInterface() {
|
||||
coordinator.refreshInterface()
|
||||
func cleanUp() {
|
||||
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"?>
|
||||
<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"/>
|
||||
<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="Safe area layout guides" minToolsVersion="9.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">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="F9H-Kr-npj" style="IBUITableViewCellStyleDefault" id="zvg-7C-BlH" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="55.5" width="374" height="44"/>
|
||||
<rect key="frame" x="20" y="55.5" width="374" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="zvg-7C-BlH" id="Tqk-Tu-E6K">
|
||||
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
|
||||
@ -40,7 +40,7 @@
|
||||
<tableViewSection headerTitle="Accounts" id="0ac-Ze-Dh4">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="6sn-wY-hHH" style="IBUITableViewCellStyleDefault" id="XHc-rQ-7FK" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="155.5" width="374" height="44"/>
|
||||
<rect key="frame" x="20" y="155.5" width="374" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="XHc-rQ-7FK" id="nmL-EM-Bsi">
|
||||
<rect key="frame" x="0.0" y="0.0" width="343" height="44"/>
|
||||
@ -61,7 +61,7 @@
|
||||
<tableViewSection headerTitle="Feeds" id="hAC-uA-RbS">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="4Hg-B3-zAE" style="IBUITableViewCellStyleDefault" id="glf-Pg-s3P" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="255.5" width="374" height="44"/>
|
||||
<rect key="frame" x="20" y="255.5" width="374" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="glf-Pg-s3P" id="bPA-43-Oqh">
|
||||
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
|
||||
@ -317,136 +317,172 @@
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
<tableViewSection headerTitle="Help" id="TkH-4v-yhk">
|
||||
<tableViewSection headerTitle="Appearance" id="TkH-4v-yhk">
|
||||
<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">
|
||||
<rect key="frame" x="20" y="819.5" width="374" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="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"/>
|
||||
<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="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="EvG-yE-gDF" id="wBN-zJ-6pN">
|
||||
<rect key="frame" x="0.0" y="0.0" width="343" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="About NetNewsWire" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="Uwu-af-31r">
|
||||
<rect key="frame" x="20" y="0.0" width="315" height="44"/>
|
||||
<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="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"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<nil key="textColor"/>
|
||||
@ -471,6 +507,7 @@
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
<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="groupByFeedSwitch" destination="JNi-Wz-RbU" id="TwH-Kd-o6N"/>
|
||||
<outlet property="refreshClearsReadArticlesSwitch" destination="duV-CN-JmH" id="xTd-jF-Ei1"/>
|
||||
@ -968,6 +1005,45 @@
|
||||
</objects>
|
||||
<point key="canvasLocation" x="3096" y="151"/>
|
||||
</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>
|
||||
<resources>
|
||||
<image name="accountFeedWrangler" width="512" height="512"/>
|
||||
|
@ -21,6 +21,7 @@ class SettingsViewController: UITableViewController {
|
||||
@IBOutlet weak var refreshClearsReadArticlesSwitch: UISwitch!
|
||||
@IBOutlet weak var confirmMarkAllAsReadSwitch: UISwitch!
|
||||
@IBOutlet weak var showFullscreenArticlesSwitch: UISwitch!
|
||||
@IBOutlet weak var colorPaletteDetailLabel: UILabel!
|
||||
|
||||
var scrollToArticlesSection = false
|
||||
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: .UserDidDeleteAccount, 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: "SettingsTableViewCell", bundle: nil), forCellReuseIdentifier: "SettingsTableViewCell")
|
||||
@ -74,6 +74,8 @@ class SettingsViewController: UITableViewController {
|
||||
} else {
|
||||
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))
|
||||
buildLabel.font = UIFont.systemFont(ofSize: 11.0)
|
||||
@ -192,6 +194,9 @@ class SettingsViewController: UITableViewController {
|
||||
break
|
||||
}
|
||||
case 5:
|
||||
let colorPalette = UIStoryboard.settings.instantiateController(ofType: ColorPaletteTableViewController.self)
|
||||
self.navigationController?.pushViewController(colorPalette, animated: true)
|
||||
case 6:
|
||||
switch indexPath.row {
|
||||
case 0:
|
||||
openURL("https://ranchero.com/netnewswire/help/ios/5.0/en/")
|
||||
@ -304,10 +309,6 @@ class SettingsViewController: UITableViewController {
|
||||
@objc func displayNameDidChange() {
|
||||
tableView.reloadData()
|
||||
}
|
||||
|
||||
@objc func userDefaultsDidChange() {
|
||||
tableView.reloadData()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -17,13 +17,13 @@ extension UITableView {
|
||||
selectRow(at: indexPath, animated: animations.contains(.select), scrollPosition: .none)
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func cellCompletelyVisable(_ indexPath: IndexPath) -> Bool {
|
||||
func cellCompletelyVisible(_ indexPath: IndexPath) -> Bool {
|
||||
let rect = rectForRow(at: indexPath)
|
||||
return safeAreaLayoutGuide.layoutFrame.contains(rect)
|
||||
}
|
||||
|
@ -71,6 +71,7 @@ class VibrantTableViewCell: UITableViewCell {
|
||||
class VibrantBasicTableViewCell: VibrantTableViewCell {
|
||||
|
||||
@IBOutlet private var label: UILabel!
|
||||
@IBOutlet private var detail: UILabel!
|
||||
@IBOutlet private var icon: UIImageView!
|
||||
|
||||
@IBInspectable var imageNormal: UIImage?
|
||||
@ -88,6 +89,7 @@ class VibrantBasicTableViewCell: VibrantTableViewCell {
|
||||
super.updateVibrancy(animated: animated)
|
||||
updateIconVibrancy(icon, color: iconTint, image: iconImage, 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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user