Add confirmation for Mark As Read actions. Issue #1603

This commit is contained in:
Maurice Parker 2020-01-11 11:30:16 -07:00
parent e93b916c50
commit 21cf8415d2
9 changed files with 208 additions and 82 deletions

View File

@ -651,7 +651,7 @@
FF3ABF13232599810074C542 /* ArticleSorterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF3ABF09232599450074C542 /* ArticleSorterTests.swift */; };
FF3ABF1523259DDB0074C542 /* ArticleSorter.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF3ABF1423259DDB0074C542 /* ArticleSorter.swift */; };
FF3ABF162325AF5D0074C542 /* ArticleSorter.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF3ABF1423259DDB0074C542 /* ArticleSorter.swift */; };
FFD43E412340F488009E5CA3 /* UndoAvailableAlertController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFD43E372340F320009E5CA3 /* UndoAvailableAlertController.swift */; };
FFD43E412340F488009E5CA3 /* MarkAsReadAlertController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFD43E372340F320009E5CA3 /* MarkAsReadAlertController.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -1592,7 +1592,7 @@
DD82AB09231003F6002269DF /* SharingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SharingTests.swift; sourceTree = "<group>"; };
FF3ABF09232599450074C542 /* ArticleSorterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleSorterTests.swift; sourceTree = "<group>"; };
FF3ABF1423259DDB0074C542 /* ArticleSorter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleSorter.swift; sourceTree = "<group>"; };
FFD43E372340F320009E5CA3 /* UndoAvailableAlertController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UndoAvailableAlertController.swift; sourceTree = "<group>"; };
FFD43E372340F320009E5CA3 /* MarkAsReadAlertController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarkAsReadAlertController.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -1929,7 +1929,7 @@
5148F4542336DB7000F8CD8B /* MasterTimelineTitleView.swift */,
5148F44A2336DB4700F8CD8B /* MasterTimelineTitleView.xib */,
51FD413A2342BD0500880194 /* MasterTimelineUnreadCountView.swift */,
FFD43E372340F320009E5CA3 /* UndoAvailableAlertController.swift */,
FFD43E372340F320009E5CA3 /* MarkAsReadAlertController.swift */,
51C4526F2265091600C03939 /* Cell */,
);
path = MasterTimeline;
@ -3941,7 +3941,7 @@
51C4529F22650A1900C03939 /* AuthorAvatarDownloader.swift in Sources */,
5108F6D22375EED2001ABC45 /* TimelineCustomizerViewController.swift in Sources */,
519E743D22C663F900A78E47 /* SceneDelegate.swift in Sources */,
FFD43E412340F488009E5CA3 /* UndoAvailableAlertController.swift in Sources */,
FFD43E412340F488009E5CA3 /* MarkAsReadAlertController.swift in Sources */,
51C452A322650A1E00C03939 /* HTMLMetadataDownloader.swift in Sources */,
51C4528D2265095F00C03939 /* AddFolderViewController.swift in Sources */,
51C452782265091600C03939 /* MasterTimelineCellData.swift in Sources */,

View File

@ -25,7 +25,7 @@ struct AppDefaults {
static let timelineIconSize = "timelineIconSize"
static let timelineSortDirection = "timelineSortDirection"
static let articleFullscreenEnabled = "articleFullscreenEnabled"
static let displayUndoAvailableTip = "displayUndoAvailableTip"
static let confirmMarkAllAsRead = "confirmMarkAllAsRead"
static let lastRefresh = "lastRefresh"
static let addWebFeedAccountID = "addWebFeedAccountID"
static let addWebFeedFolderName = "addWebFeedFolderName"
@ -112,12 +112,12 @@ struct AppDefaults {
}
}
static var displayUndoAvailableTip: Bool {
static var confirmMarkAllAsRead: Bool {
get {
return bool(for: Key.displayUndoAvailableTip)
return bool(for: Key.confirmMarkAllAsRead)
}
set {
setBool(for: Key.displayUndoAvailableTip, newValue)
setBool(for: Key.confirmMarkAllAsRead, newValue)
}
}
@ -157,7 +157,7 @@ struct AppDefaults {
Key.timelineIconSize: IconSize.medium.rawValue,
Key.timelineSortDirection: ComparisonResult.orderedDescending.rawValue,
Key.articleFullscreenEnabled: false,
Key.displayUndoAvailableTip: true]
Key.confirmMarkAllAsRead: true]
AppDefaults.shared.register(defaults: defaults)
}

View File

@ -281,6 +281,10 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
alert.addAction(action)
}
if let action = self.markAllAsReadAlertAction(indexPath: indexPath, completion: completion) {
alert.addAction(action)
}
let cancelTitle = NSLocalizedString("Cancel", comment: "Cancel")
alert.addAction(UIAlertAction(title: cancelTitle, style: .cancel) { _ in
completion(true)
@ -1017,6 +1021,29 @@ private extension MasterFeedViewController {
return action
}
func markAllAsReadAlertAction(indexPath: IndexPath, completion: @escaping (Bool) -> Void) -> UIAlertAction? {
guard let node = dataSource.itemIdentifier(for: indexPath),
coordinator.unreadCountFor(node) > 0,
let feed = node.representedObject as? WebFeed,
let articles = try? feed.fetchArticles() else {
return nil
}
let localizedMenuText = NSLocalizedString("Mark All as Read in “%@”", comment: "Command")
let title = NSString.localizedStringWithFormat(localizedMenuText as NSString, feed.nameForDisplay) as String
let cancel = {
completion(true)
}
let action = UIAlertAction(title: title, style: .default) { [weak self] action in
MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title, cancelCompletion: cancel) { [weak self] in
self?.coordinator.markAllAsRead(Array(articles))
completion(true)
}
}
return action
}
func deleteAction(indexPath: IndexPath) -> UIAction {
let title = NSLocalizedString("Delete", comment: "Delete")
@ -1108,7 +1135,9 @@ private extension MasterFeedViewController {
let title = NSString.localizedStringWithFormat(localizedMenuText as NSString, nameForDisplay) as String
let action = UIAction(title: title, image: AppAssets.markAllAsReadImage) { [weak self] action in
self?.coordinator.markAllAsRead(articles)
MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title) { [weak self] in
self?.coordinator.markAllAsRead(articles)
}
}
return action

View File

@ -0,0 +1,62 @@
//
// UndoAvailableAlertController.swift
// NetNewsWire
//
// Created by Phil Viso on 9/29/19.
// Copyright © 2019 Ranchero Software. All rights reserved.
//
import Foundation
import UIKit
struct MarkAsReadAlertController {
static func confirm(_ controller: UIViewController?,
coordinator: SceneCoordinator?,
confirmTitle: String,
cancelCompletion: (() -> Void)? = nil,
completion: @escaping () -> Void) {
guard let controller = controller, let coordinator = coordinator else {
completion()
return
}
if AppDefaults.confirmMarkAllAsRead {
let alertController = MarkAsReadAlertController.alert(coordinator: coordinator, confirmTitle: confirmTitle, cancelCompletion: cancelCompletion) { _ in
completion()
}
controller.present(alertController, animated: true)
} else {
completion()
}
}
private static func alert(coordinator: SceneCoordinator,
confirmTitle: String,
cancelCompletion: (() -> Void)?,
completion: @escaping (UIAlertAction) -> Void) -> UIAlertController {
let title = NSLocalizedString("Mark As Read", comment: "Mark As Read")
let message = NSLocalizedString("You can turn this confirmation off in settings.",
comment: "You can turn this confirmation off in settings.")
let cancelTitle = NSLocalizedString("Cancel", comment: "Cancel")
let settingsTitle = NSLocalizedString("Open Settings", comment: "Open Settings")
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
let cancelAction = UIAlertAction(title: cancelTitle, style: .cancel) { _ in
cancelCompletion?()
}
let settingsAction = UIAlertAction(title: settingsTitle, style: .default) { _ in
coordinator.showSettings(scrollToArticlesSection: true)
}
let markAction = UIAlertAction(title: confirmTitle, style: .default, handler: completion)
alertController.addAction(markAction)
alertController.addAction(settingsAction)
alertController.addAction(cancelAction)
return alertController
}
}

View File

@ -121,15 +121,9 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner
}
@IBAction func markAllAsRead(_ sender: Any) {
if coordinator.displayUndoAvailableTip {
let alertController = UndoAvailableAlertController.alert { [weak self] _ in
self?.coordinator.displayUndoAvailableTip = false
self?.coordinator.markAllAsReadInTimeline()
}
present(alertController, animated: true)
} else {
coordinator.markAllAsReadInTimeline()
let title = NSLocalizedString("Mark All as Read", comment: "Mark All as Read")
MarkAsReadAlertController.confirm(self, coordinator: coordinator, confirmTitle: title) { [weak self] in
self?.coordinator.markAllAsReadInTimeline()
}
}
@ -710,7 +704,9 @@ private extension MasterTimelineViewController {
let title = NSLocalizedString("Mark Above as Read", comment: "Mark Above as Read")
let image = AppAssets.markAboveAsReadImage
let action = UIAction(title: title, image: image) { [weak self] action in
self?.coordinator.markAboveAsRead(article)
MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title) { [weak self] in
self?.coordinator.markAboveAsRead(article)
}
}
return action
}
@ -723,7 +719,9 @@ private extension MasterTimelineViewController {
let title = NSLocalizedString("Mark Below as Read", comment: "Mark Below as Read")
let image = AppAssets.markBelowAsReadImage
let action = UIAction(title: title, image: image) { [weak self] action in
self?.coordinator.markBelowAsRead(article)
MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title) { [weak self] in
self?.coordinator.markBelowAsRead(article)
}
}
return action
}
@ -734,10 +732,16 @@ private extension MasterTimelineViewController {
}
let title = NSLocalizedString("Mark Above as Read", comment: "Mark Above as Read")
let action = UIAlertAction(title: title, style: .default) { [weak self] action in
self?.coordinator.markAboveAsRead(article)
let cancel = {
completion(true)
}
let action = UIAlertAction(title: title, style: .default) { [weak self] action in
MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title, cancelCompletion: cancel) { [weak self] in
self?.coordinator.markAboveAsRead(article)
completion(true)
}
}
return action
}
@ -747,10 +751,16 @@ private extension MasterTimelineViewController {
}
let title = NSLocalizedString("Mark Below as Read", comment: "Mark Below as Read")
let action = UIAlertAction(title: title, style: .default) { [weak self] action in
self?.coordinator.markBelowAsRead(article)
let cancel = {
completion(true)
}
let action = UIAlertAction(title: title, style: .default) { [weak self] action in
MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title, cancelCompletion: cancel) { [weak self] in
self?.coordinator.markBelowAsRead(article)
completion(true)
}
}
return action
}
@ -790,7 +800,9 @@ private extension MasterTimelineViewController {
let title = NSString.localizedStringWithFormat(localizedMenuText as NSString, webFeed.nameForDisplay) as String
let action = UIAction(title: title, image: AppAssets.markAllAsReadImage) { [weak self] action in
self?.coordinator.markAllAsRead(articles)
MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title) { [weak self] in
self?.coordinator.markAllAsRead(articles)
}
}
return action
}
@ -808,10 +820,15 @@ private extension MasterTimelineViewController {
let localizedMenuText = NSLocalizedString("Mark All as Read in “%@”", comment: "Mark All as Read in Feed")
let title = NSString.localizedStringWithFormat(localizedMenuText as NSString, webFeed.nameForDisplay) as String
let cancel = {
completion(true)
}
let action = UIAlertAction(title: title, style: .default) { [weak self] action in
self?.coordinator.markAllAsRead(articles)
completion(true)
MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title, cancelCompletion: cancel) { [weak self] in
self?.coordinator.markAllAsRead(articles)
completion(true)
}
}
return action
}

View File

@ -1,31 +0,0 @@
//
// UndoAvailableAlertController.swift
// NetNewsWire
//
// Created by Phil Viso on 9/29/19.
// Copyright © 2019 Ranchero Software. All rights reserved.
//
import Foundation
import UIKit
struct UndoAvailableAlertController {
static func alert(handler: @escaping (UIAlertAction) -> Void) -> UIAlertController {
let title = NSLocalizedString("Undo Available", comment: "Undo Available")
let message = NSLocalizedString("You can undo this and other actions with a three finger swipe to the left.",
comment: "Mark all articles")
let cancelTitle = NSLocalizedString("Cancel", comment: "Cancel")
let confirmTitle = NSLocalizedString("Got It", comment: "Got It")
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
let cancelAction = UIAlertAction(title: cancelTitle, style: .cancel)
let markAction = UIAlertAction(title: confirmTitle, style: .default, handler: handler)
alertController.addAction(cancelAction)
alertController.addAction(markAction)
return alertController
}
}

View File

@ -92,11 +92,6 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
var prefersStatusBarHidden = false
var displayUndoAvailableTip: Bool {
get { AppDefaults.displayUndoAvailableTip }
set { AppDefaults.displayUndoAvailableTip = newValue }
}
private let treeControllerDelegate = WebFeedTreeControllerDelegate()
private let treeController: TreeController
@ -964,9 +959,10 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
}
}
func showSettings() {
func showSettings(scrollToArticlesSection: Bool = false) {
let settingsNavController = UIStoryboard.settings.instantiateInitialViewController() as! UINavigationController
let settingsViewController = settingsNavController.topViewController as! SettingsViewController
settingsViewController.scrollToArticlesSection = scrollToArticlesSection
settingsNavController.modalPresentationStyle = .formSheet
settingsViewController.presentingParentController = rootSplitViewController
rootSplitViewController.present(settingsNavController, animated: true)

View File

@ -207,14 +207,14 @@
</constraints>
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" id="SXs-NQ-y3U" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" id="8Gj-qz-NMY" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="575.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="SXs-NQ-y3U" id="BpI-Hz-KH2">
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="8Gj-qz-NMY" id="OTe-tG-sb4">
<rect key="frame" x="0.0" y="0.0" width="343" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Timeline Layout" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5tY-5k-v2g">
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Timeline Layout" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="YHt-eS-KrX">
<rect key="frame" x="20" y="11.5" width="120.5" height="21"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
@ -222,8 +222,8 @@
</label>
</subviews>
<constraints>
<constraint firstItem="5tY-5k-v2g" firstAttribute="centerY" secondItem="BpI-Hz-KH2" secondAttribute="centerY" id="Pna-0P-cno"/>
<constraint firstItem="5tY-5k-v2g" firstAttribute="leading" secondItem="BpI-Hz-KH2" secondAttribute="leadingMargin" id="v4X-Nd-cpC"/>
<constraint firstItem="YHt-eS-KrX" firstAttribute="centerY" secondItem="OTe-tG-sb4" secondAttribute="centerY" id="HpK-qo-s57"/>
<constraint firstItem="YHt-eS-KrX" firstAttribute="leading" secondItem="OTe-tG-sb4" secondAttribute="leadingMargin" id="STg-aB-F7n"/>
</constraints>
</tableViewCellContentView>
</tableViewCell>
@ -231,9 +231,39 @@
</tableViewSection>
<tableViewSection headerTitle="Articles" id="TRr-Ew-IvU">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="WR6-xo-ty2" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="SXs-NQ-y3U" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="675.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="SXs-NQ-y3U" id="BpI-Hz-KH2">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Confirm Mark All as Read" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5tY-5k-v2g">
<rect key="frame" x="20" y="11.5" width="193" height="21"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="UOo-9z-IuL">
<rect key="frame" x="305" y="6.5" width="51" height="31"/>
<color key="onTintColor" name="primaryAccentColor"/>
<connections>
<action selector="switchConfirmMarkAllAsRead:" destination="a0p-rk-skQ" eventType="valueChanged" id="7wW-hF-2OY"/>
</connections>
</switch>
</subviews>
<constraints>
<constraint firstItem="UOo-9z-IuL" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="5tY-5k-v2g" secondAttribute="trailing" constant="8" id="KeP-ft-0GH"/>
<constraint firstItem="5tY-5k-v2g" firstAttribute="centerY" secondItem="BpI-Hz-KH2" secondAttribute="centerY" id="Pna-0P-cno"/>
<constraint firstItem="UOo-9z-IuL" firstAttribute="centerY" secondItem="BpI-Hz-KH2" secondAttribute="centerY" id="V2L-l3-s1E"/>
<constraint firstAttribute="trailing" secondItem="UOo-9z-IuL" secondAttribute="trailing" constant="20" symbolic="YES" id="mNk-x8-oJx"/>
<constraint firstItem="5tY-5k-v2g" firstAttribute="leading" secondItem="BpI-Hz-KH2" secondAttribute="leadingMargin" id="v4X-Nd-cpC"/>
</constraints>
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="WR6-xo-ty2" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="719.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="WR6-xo-ty2" id="zX8-l2-bVH">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
@ -266,7 +296,7 @@
<tableViewSection headerTitle="Help" 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="775.5" width="374" height="44"/>
<rect key="frame" x="20" y="819.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="Om7-lH-RUh" id="vrJ-nE-HMP">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
@ -283,7 +313,7 @@
</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="819.5" width="374" height="44"/>
<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"/>
@ -300,7 +330,7 @@
</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="863.5" width="374" height="44"/>
<rect key="frame" x="0.0" 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"/>
@ -317,14 +347,14 @@
</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="0.0" y="907.5" width="374" height="44"/>
<rect key="frame" x="0.0" 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"/>
<rect key="frame" x="15" y="0.0" width="351" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
@ -334,7 +364,7 @@
</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="0.0" y="951.5" width="374" height="44"/>
<rect key="frame" x="0.0" 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"/>
@ -351,7 +381,7 @@
</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="0.0" y="995.5" width="374" height="44"/>
<rect key="frame" x="0.0" 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"/>
@ -368,7 +398,7 @@
</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="0.0" y="1039.5" width="374" height="44"/>
<rect key="frame" x="0.0" 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"/>
@ -385,7 +415,7 @@
</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="0.0" y="1083.5" width="374" height="44"/>
<rect key="frame" x="0.0" y="1127.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="355" height="44"/>
@ -417,6 +447,7 @@
</barButtonItem>
</navigationItem>
<connections>
<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"/>
<outlet property="showFullscreenArticlesSwitch" destination="2Md-2E-7Z4" id="lEN-VP-wEO"/>

View File

@ -18,8 +18,10 @@ class SettingsViewController: UITableViewController {
@IBOutlet weak var timelineSortOrderSwitch: UISwitch!
@IBOutlet weak var groupByFeedSwitch: UISwitch!
@IBOutlet weak var refreshClearsReadArticlesSwitch: UISwitch!
@IBOutlet weak var confirmMarkAllAsReadSwitch: UISwitch!
@IBOutlet weak var showFullscreenArticlesSwitch: UISwitch!
var scrollToArticlesSection = false
weak var presentingParentController: UIViewController?
override func viewDidLoad() {
@ -34,7 +36,7 @@ class SettingsViewController: UITableViewController {
tableView.register(UINib(nibName: "SettingsAccountTableViewCell", bundle: nil), forCellReuseIdentifier: "SettingsAccountTableViewCell")
tableView.register(UINib(nibName: "SettingsTableViewCell", bundle: nil), forCellReuseIdentifier: "SettingsTableViewCell")
}
override func viewWillAppear(_ animated: Bool) {
@ -58,6 +60,12 @@ class SettingsViewController: UITableViewController {
refreshClearsReadArticlesSwitch.isOn = false
}
if AppDefaults.confirmMarkAllAsRead {
confirmMarkAllAsReadSwitch.isOn = true
} else {
confirmMarkAllAsReadSwitch.isOn = false
}
if AppDefaults.articleFullscreenEnabled {
showFullscreenArticlesSwitch.isOn = true
} else {
@ -81,6 +89,12 @@ class SettingsViewController: UITableViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
if scrollToArticlesSection {
tableView.scrollToRow(at: IndexPath(row: 0, section: 4), at: .top, animated: true)
scrollToArticlesSection = false
}
}
// MARK: UITableView
@ -195,7 +209,7 @@ class SettingsViewController: UITableViewController {
}
case 3:
switch indexPath.row {
case 3:
case 4:
let timeline = UIStoryboard.settings.instantiateController(ofType: TimelineCustomizerViewController.self)
self.navigationController?.pushViewController(timeline, animated: true)
default:
@ -285,6 +299,14 @@ class SettingsViewController: UITableViewController {
}
}
@IBAction func switchConfirmMarkAllAsRead(_ sender: Any) {
if confirmMarkAllAsReadSwitch.isOn {
AppDefaults.confirmMarkAllAsRead = true
} else {
AppDefaults.confirmMarkAllAsRead = false
}
}
@IBAction func switchFullscreenArticles(_ sender: Any) {
if showFullscreenArticlesSwitch.isOn {
AppDefaults.articleFullscreenEnabled = true