mirror of
https://github.com/Ranchero-Software/NetNewsWire
synced 2025-08-12 06:26:36 +00:00
This commit is contained in:
@@ -93,8 +93,6 @@
|
||||
517630232336657E00E15FFF /* ArticleViewControllerWebViewProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 517630222336657E00E15FFF /* ArticleViewControllerWebViewProvider.swift */; };
|
||||
5183CCD0226E1E880010922C /* NonIntrinsicLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5183CCCF226E1E880010922C /* NonIntrinsicLabel.swift */; };
|
||||
5183CCDA226E31A50010922C /* NonIntrinsicImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5183CCD9226E31A50010922C /* NonIntrinsicImageView.swift */; };
|
||||
5183CCDD226F1F5C0010922C /* NavigationProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5183CCDC226F1F5C0010922C /* NavigationProgressView.swift */; };
|
||||
5183CCDF226F1FCC0010922C /* UINavigationController+Progress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5183CCDE226F1FCC0010922C /* UINavigationController+Progress.swift */; };
|
||||
5183CCE5226F4DFA0010922C /* RefreshInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5183CCE4226F4DFA0010922C /* RefreshInterval.swift */; };
|
||||
5183CCE6226F4E110010922C /* RefreshInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5183CCE4226F4DFA0010922C /* RefreshInterval.swift */; };
|
||||
5183CCE8226F68D90010922C /* AccountRefreshTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5183CCE7226F68D90010922C /* AccountRefreshTimer.swift */; };
|
||||
@@ -194,6 +192,8 @@
|
||||
51C452B42265141B00C03939 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51C452B32265141B00C03939 /* WebKit.framework */; };
|
||||
51C452B82265178500C03939 /* styleSheet.css in Resources */ = {isa = PBXBuildFile; fileRef = 51C452B72265178500C03939 /* styleSheet.css */; };
|
||||
51CC9B3E231720B2000E842F /* MasterFeedDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51CC9B3D231720B2000E842F /* MasterFeedDataSource.swift */; };
|
||||
51CE1C0923621EDA005548FC /* RefreshProgressView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 51CE1C0823621EDA005548FC /* RefreshProgressView.xib */; };
|
||||
51CE1C0B23622007005548FC /* RefreshProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51CE1C0A23622006005548FC /* RefreshProgressView.swift */; };
|
||||
51D5948722668EFA00DFC836 /* MarkStatusCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84702AA31FA27AC0006B8943 /* MarkStatusCommand.swift */; };
|
||||
51D6A5BC23199C85001C27D8 /* MasterTimelineDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51D6A5BB23199C85001C27D8 /* MasterTimelineDataSource.swift */; };
|
||||
51D87EE12311D34700E63F03 /* ActivityType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51D87EE02311D34700E63F03 /* ActivityType.swift */; };
|
||||
@@ -1251,8 +1251,6 @@
|
||||
517630222336657E00E15FFF /* ArticleViewControllerWebViewProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleViewControllerWebViewProvider.swift; sourceTree = "<group>"; };
|
||||
5183CCCF226E1E880010922C /* NonIntrinsicLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NonIntrinsicLabel.swift; sourceTree = "<group>"; };
|
||||
5183CCD9226E31A50010922C /* NonIntrinsicImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NonIntrinsicImageView.swift; sourceTree = "<group>"; };
|
||||
5183CCDC226F1F5C0010922C /* NavigationProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationProgressView.swift; sourceTree = "<group>"; };
|
||||
5183CCDE226F1FCC0010922C /* UINavigationController+Progress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UINavigationController+Progress.swift"; sourceTree = "<group>"; };
|
||||
5183CCE4226F4DFA0010922C /* RefreshInterval.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RefreshInterval.swift; sourceTree = "<group>"; };
|
||||
5183CCE7226F68D90010922C /* AccountRefreshTimer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountRefreshTimer.swift; sourceTree = "<group>"; };
|
||||
518651AB23555EB20078E021 /* NNW3Document.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NNW3Document.swift; sourceTree = "<group>"; };
|
||||
@@ -1300,6 +1298,8 @@
|
||||
51C452B32265141B00C03939 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk/System/Library/Frameworks/WebKit.framework; sourceTree = DEVELOPER_DIR; };
|
||||
51C452B72265178500C03939 /* styleSheet.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = styleSheet.css; sourceTree = "<group>"; };
|
||||
51CC9B3D231720B2000E842F /* MasterFeedDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MasterFeedDataSource.swift; sourceTree = "<group>"; };
|
||||
51CE1C0823621EDA005548FC /* RefreshProgressView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = RefreshProgressView.xib; sourceTree = "<group>"; };
|
||||
51CE1C0A23622006005548FC /* RefreshProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RefreshProgressView.swift; sourceTree = "<group>"; };
|
||||
51D6A5BB23199C85001C27D8 /* MasterTimelineDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MasterTimelineDataSource.swift; sourceTree = "<group>"; };
|
||||
51D87EE02311D34700E63F03 /* ActivityType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityType.swift; sourceTree = "<group>"; };
|
||||
51E3EB32229AB02C00645299 /* ErrorHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorHandler.swift; sourceTree = "<group>"; };
|
||||
@@ -1766,15 +1766,6 @@
|
||||
path = Account;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
5183CCDB226F1EEB0010922C /* Progress */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5183CCDC226F1F5C0010922C /* NavigationProgressView.swift */,
|
||||
5183CCDE226F1FCC0010922C /* UINavigationController+Progress.swift */,
|
||||
);
|
||||
path = Progress;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
5183CCEA226F70350010922C /* Timer */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -1854,9 +1845,10 @@
|
||||
51C4525D226508F600C03939 /* MasterFeed */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FFD43E372340F320009E5CA3 /* UndoAvailableAlertController.swift */,
|
||||
51C45264226508F600C03939 /* MasterFeedViewController.swift */,
|
||||
51CC9B3D231720B2000E842F /* MasterFeedDataSource.swift */,
|
||||
51CE1C0A23622006005548FC /* RefreshProgressView.swift */,
|
||||
51CE1C0823621EDA005548FC /* RefreshProgressView.xib */,
|
||||
51C45260226508F600C03939 /* Cell */,
|
||||
);
|
||||
path = MasterFeed;
|
||||
@@ -1881,6 +1873,7 @@
|
||||
5148F4542336DB7000F8CD8B /* MasterTimelineTitleView.swift */,
|
||||
5148F44A2336DB4700F8CD8B /* MasterTimelineTitleView.xib */,
|
||||
51FD413A2342BD0500880194 /* MasterTimelineUnreadCountView.swift */,
|
||||
FFD43E372340F320009E5CA3 /* UndoAvailableAlertController.swift */,
|
||||
51C4526F2265091600C03939 /* Cell */,
|
||||
);
|
||||
path = MasterTimeline;
|
||||
@@ -2538,7 +2531,6 @@
|
||||
51C452802265093600C03939 /* Add */,
|
||||
5123DB95233EC69300282CC9 /* Inspector */,
|
||||
513145F9235A55A700387FDC /* Intents */,
|
||||
5183CCDB226F1EEB0010922C /* Progress */,
|
||||
5183CCEB227117C70010922C /* Settings */,
|
||||
519D740423243C68008BB345 /* Model Extensions */,
|
||||
51C45245226506C800C03939 /* UIKit Extensions */,
|
||||
@@ -3403,6 +3395,7 @@
|
||||
51A1699A235E10D700EB091F /* Settings.storyboard in Resources */,
|
||||
49F40DF92335B71000552BF4 /* newsfoot.js in Resources */,
|
||||
51F85BEF2272520B00C787DC /* Thanks.rtf in Resources */,
|
||||
51CE1C0923621EDA005548FC /* RefreshProgressView.xib in Resources */,
|
||||
84C9FC9D2262A1A900D921D6 /* Assets.xcassets in Resources */,
|
||||
514219582353C28900E07E2C /* main_ios.js in Resources */,
|
||||
51C452B82265178500C03939 /* styleSheet.css in Resources */,
|
||||
@@ -3889,7 +3882,6 @@
|
||||
51AF460E232488C6001742EF /* Account-Extensions.swift in Sources */,
|
||||
51FD413B2342BD0500880194 /* MasterTimelineUnreadCountView.swift in Sources */,
|
||||
513146B2235A81A400387FDC /* AddFeedIntentHandler.swift in Sources */,
|
||||
5183CCDD226F1F5C0010922C /* NavigationProgressView.swift in Sources */,
|
||||
51D87EE12311D34700E63F03 /* ActivityType.swift in Sources */,
|
||||
51C452772265091600C03939 /* MultilineUILabelSizer.swift in Sources */,
|
||||
51C452A522650A2D00C03939 /* SmallIconProvider.swift in Sources */,
|
||||
@@ -3915,7 +3907,6 @@
|
||||
51BB7C272335A8E5008E8144 /* ArticleActivityItemSource.swift in Sources */,
|
||||
51F85BF52273625800C787DC /* Bundle-Extensions.swift in Sources */,
|
||||
51C452A622650A3500C03939 /* Node-Extensions.swift in Sources */,
|
||||
5183CCDF226F1FCC0010922C /* UINavigationController+Progress.swift in Sources */,
|
||||
51C45294226509C800C03939 /* SearchFeedDelegate.swift in Sources */,
|
||||
5F323809231DF9F000706F6B /* VibrantTableViewCell.swift in Sources */,
|
||||
512E09352268B25900BDCFDD /* UISplitViewController-Extensions.swift in Sources */,
|
||||
@@ -3982,6 +3973,7 @@
|
||||
51FFF0C4235EE8E5002762AA /* VibrantButton.swift in Sources */,
|
||||
513228FC233037630033D4ED /* Reachability.swift in Sources */,
|
||||
51C45259226508D300C03939 /* AppDefaults.swift in Sources */,
|
||||
51CE1C0B23622007005548FC /* RefreshProgressView.swift in Sources */,
|
||||
511D4419231FC02D00FB1562 /* KeyboardManager.swift in Sources */,
|
||||
51A1699D235E10D700EB091F /* SettingsViewController.swift in Sources */,
|
||||
51C45293226509C800C03939 /* StarredFeedDelegate.swift in Sources */,
|
||||
|
||||
@@ -96,7 +96,6 @@ class ArticleViewController: UIViewController {
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(unreadCountDidChange(_:)), name: .UnreadCountDidChange, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(statusesDidChange(_:)), name: .StatusesDidChange, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(progressDidChange(_:)), name: .AccountRefreshProgressDidChange, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(contentSizeCategoryDidChange(_:)), name: UIContentSizeCategory.didChangeNotification, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(willEnterForeground(_:)), name: UIApplication.willEnterForegroundNotification, object: nil)
|
||||
|
||||
@@ -126,11 +125,6 @@ class ArticleViewController: UIViewController {
|
||||
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
updateProgressIndicatorIfNeeded()
|
||||
}
|
||||
|
||||
func updateUI() {
|
||||
|
||||
guard let article = currentArticle else {
|
||||
@@ -209,10 +203,6 @@ class ArticleViewController: UIViewController {
|
||||
}
|
||||
}
|
||||
|
||||
@objc func progressDidChange(_ note: Notification) {
|
||||
updateProgressIndicatorIfNeeded()
|
||||
}
|
||||
|
||||
@objc func contentSizeCategoryDidChange(_ note: Notification) {
|
||||
reloadHTML()
|
||||
}
|
||||
@@ -427,12 +417,6 @@ private struct ImageClickMessage: Codable {
|
||||
|
||||
private extension ArticleViewController {
|
||||
|
||||
func updateProgressIndicatorIfNeeded() {
|
||||
if !(UIDevice.current.userInterfaceIdiom == .pad) {
|
||||
navigationController?.updateAccountRefreshProgressIndicator()
|
||||
}
|
||||
}
|
||||
|
||||
func imageWasClicked(body: String?) {
|
||||
guard let body = body,
|
||||
let data = body.data(using: .utf8),
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14868" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Cqo-6I-B1A">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Cqo-6I-B1A">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14824"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15508"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
@@ -65,7 +65,6 @@
|
||||
</connections>
|
||||
</tableView>
|
||||
<toolbarItems>
|
||||
<barButtonItem title="Mark All as Read" id="BzW-aD-jIq"/>
|
||||
<barButtonItem style="plain" systemItem="flexibleSpace" id="Kjl-Sb-QP1"/>
|
||||
<barButtonItem systemItem="add" id="PVr-3K-nPg"/>
|
||||
</toolbarItems>
|
||||
@@ -114,6 +113,6 @@
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="gear" catalog="system" width="64" height="60"/>
|
||||
<image name="gear" catalog="system" width="64" height="58"/>
|
||||
</resources>
|
||||
</document>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14868" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Cqo-6I-B1A">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Cqo-6I-B1A">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14824"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15508"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
@@ -65,7 +65,6 @@
|
||||
</connections>
|
||||
</tableView>
|
||||
<toolbarItems>
|
||||
<barButtonItem title="Mark All as Read" id="BzW-aD-jIq"/>
|
||||
<barButtonItem style="plain" systemItem="flexibleSpace" id="Kjl-Sb-QP1"/>
|
||||
<barButtonItem systemItem="add" id="PVr-3K-nPg"/>
|
||||
</toolbarItems>
|
||||
@@ -114,6 +113,6 @@
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="gear" catalog="system" width="64" height="60"/>
|
||||
<image name="gear" catalog="system" width="64" height="58"/>
|
||||
</resources>
|
||||
</document>
|
||||
|
||||
@@ -190,22 +190,7 @@
|
||||
<outlet property="delegate" destination="7bK-jq-Zjz" id="RA6-mI-bju"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<toolbarItems>
|
||||
<barButtonItem title="Mark All as Read" id="ddj-Ya-Wol">
|
||||
<connections>
|
||||
<action selector="markAllAsRead:" destination="7bK-jq-Zjz" id="jmv-SM-7XE"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
<barButtonItem style="plain" systemItem="flexibleSpace" id="ePD-cM-h2y"/>
|
||||
<barButtonItem systemItem="add" id="yo6-w4-SfI">
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="accLabelText" value="Add Feed or Folder"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<connections>
|
||||
<action selector="add:" destination="7bK-jq-Zjz" id="k61-ub-SdZ"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</toolbarItems>
|
||||
<toolbarItems/>
|
||||
<navigationItem key="navigationItem" title="Feeds" id="Zdf-7t-Un8">
|
||||
<barButtonItem key="leftBarButtonItem" title="Settings" image="gear" catalog="system" id="TlU-Pg-ATe">
|
||||
<userDefinedRuntimeAttributes>
|
||||
@@ -218,10 +203,6 @@
|
||||
</navigationItem>
|
||||
<simulatedNavigationBarMetrics key="simulatedTopBarMetrics" prompted="NO"/>
|
||||
<simulatedToolbarMetrics key="simulatedBottomBarMetrics"/>
|
||||
<connections>
|
||||
<outlet property="addNewItemButton" destination="yo6-w4-SfI" id="NbL-RH-N4J"/>
|
||||
<outlet property="markAllAsReadButton" destination="ddj-Ya-Wol" id="jjr-OK-4zl"/>
|
||||
</connections>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="Rux-fX-hf1" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
|
||||
@@ -14,8 +14,8 @@ import RSTree
|
||||
|
||||
class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
|
||||
|
||||
@IBOutlet private weak var markAllAsReadButton: UIBarButtonItem!
|
||||
@IBOutlet private weak var addNewItemButton: UIBarButtonItem!
|
||||
private var refreshProgressView: RefreshProgressView!
|
||||
private var addNewItemButton: UIBarButtonItem!
|
||||
|
||||
private lazy var dataSource = makeDataSource()
|
||||
var undoableCommands = [UndoableCommand]()
|
||||
@@ -54,12 +54,13 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(feedSettingDidChange(_:)), name: .FeedSettingDidChange, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(feedMetadataDidChange(_:)), name: .FeedMetadataDidChange, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(userDidAddFeed(_:)), name: .UserDidAddFeed, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(progressDidChange(_:)), name: .AccountRefreshProgressDidChange, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(contentSizeCategoryDidChange), name: UIContentSizeCategory.didChangeNotification, object: nil)
|
||||
|
||||
refreshControl = UIRefreshControl()
|
||||
refreshControl!.addTarget(self, action: #selector(refreshAccounts(_:)), for: .valueChanged)
|
||||
|
||||
configureToolbar()
|
||||
|
||||
updateUI()
|
||||
becomeFirstResponder()
|
||||
|
||||
@@ -73,7 +74,6 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
navigationController?.updateAccountRefreshProgressIndicator()
|
||||
}
|
||||
|
||||
// MARK: Notifications
|
||||
@@ -133,10 +133,6 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
|
||||
discloseFeed(feed)
|
||||
}
|
||||
|
||||
@objc func progressDidChange(_ note: Notification) {
|
||||
navigationController?.updateAccountRefreshProgressIndicator()
|
||||
}
|
||||
|
||||
@objc func contentSizeCategoryDidChange(_ note: Notification) {
|
||||
applyChanges(animate: false)
|
||||
}
|
||||
@@ -344,19 +340,6 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
|
||||
@IBAction func settings(_ sender: UIBarButtonItem) {
|
||||
coordinator.showSettings()
|
||||
}
|
||||
|
||||
@IBAction func markAllAsRead(_ sender: Any) {
|
||||
if coordinator.displayUndoAvailableTip {
|
||||
let alertController = UndoAvailableAlertController.alert { [weak self] _ in
|
||||
self?.coordinator.displayUndoAvailableTip = false
|
||||
self?.coordinator.markAllAsRead()
|
||||
}
|
||||
|
||||
present(alertController, animated: true)
|
||||
} else {
|
||||
coordinator.markAllAsRead()
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func add(_ sender: UIBarButtonItem) {
|
||||
coordinator.showAdd(.feed)
|
||||
@@ -573,8 +556,21 @@ extension MasterFeedViewController: MasterFeedTableViewCellDelegate {
|
||||
|
||||
private extension MasterFeedViewController {
|
||||
|
||||
func configureToolbar() {
|
||||
guard let refreshProgressView = Bundle.main.loadNibNamed("RefreshProgressView", owner: self, options: nil)?[0] as? RefreshProgressView else {
|
||||
return
|
||||
}
|
||||
|
||||
self.refreshProgressView = refreshProgressView
|
||||
|
||||
let refreshProgressItemButton = UIBarButtonItem(customView: refreshProgressView)
|
||||
let spaceItemButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
|
||||
addNewItemButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(add(_:)))
|
||||
setToolbarItems([refreshProgressItemButton, spaceItemButton, addNewItemButton], animated: false)
|
||||
}
|
||||
|
||||
func updateUI() {
|
||||
markAllAsReadButton.isEnabled = coordinator.isAnyUnreadAvailable
|
||||
refreshProgressView.updateRefreshLabel()
|
||||
addNewItemButton.isEnabled = !AccountManager.shared.activeAccounts.isEmpty
|
||||
}
|
||||
|
||||
|
||||
70
iOS/MasterFeed/RefreshProgressView.swift
Normal file
70
iOS/MasterFeed/RefreshProgressView.swift
Normal file
@@ -0,0 +1,70 @@
|
||||
//
|
||||
// RefeshProgressView.swift
|
||||
// NetNewsWire-iOS
|
||||
//
|
||||
// Created by Maurice Parker on 10/24/19.
|
||||
// Copyright © 2019 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Account
|
||||
|
||||
class RefreshProgressView: UIView {
|
||||
|
||||
@IBOutlet weak var progressView: UIProgressView!
|
||||
@IBOutlet weak var label: UILabel!
|
||||
private lazy var progressWidth = progressView.widthAnchor.constraint(equalToConstant: 100.0)
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
func commonInit() {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(progressDidChange(_:)), name: .AccountRefreshProgressDidChange, object: nil)
|
||||
}
|
||||
|
||||
func updateRefreshLabel() {
|
||||
if let refreshDate = AppDefaults.lastRefresh {
|
||||
let relativeDateTimeFormatter = RelativeDateTimeFormatter()
|
||||
relativeDateTimeFormatter.dateTimeStyle = .named
|
||||
let refreshed = relativeDateTimeFormatter.localizedString(for: refreshDate, relativeTo: Date())
|
||||
let localizedRefreshText = NSLocalizedString("Refreshed %@", comment: "Refreshed")
|
||||
let refreshText = NSString.localizedStringWithFormat(localizedRefreshText as NSString, refreshed) as String
|
||||
label.text = refreshText
|
||||
}
|
||||
|
||||
}
|
||||
@objc func progressDidChange(_ note: Notification) {
|
||||
|
||||
let progress = AccountManager.shared.combinedRefreshProgress
|
||||
|
||||
if progress.isComplete {
|
||||
progressView.progress = 1
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
self.updateRefreshLabel()
|
||||
self.label.isHidden = false
|
||||
self.progressView.isHidden = true
|
||||
self.progressWidth.isActive = false
|
||||
}
|
||||
} else {
|
||||
label.isHidden = true
|
||||
progressView.isHidden = false
|
||||
self.progressWidth.isActive = true
|
||||
let percent = Float(progress.numberCompleted) / Float(progress.numberOfTasks)
|
||||
progressView.progress = percent
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
deinit {
|
||||
NotificationCenter.default.removeObserver(self)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
49
iOS/MasterFeed/RefreshProgressView.xib
Normal file
49
iOS/MasterFeed/RefreshProgressView.xib
Normal file
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15508"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="iN0-l3-epB" customClass="RefreshProgressView" customModule="NetNewsWire" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="60"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<progressView hidden="YES" opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" progress="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="gKH-fc-zh7">
|
||||
<rect key="frame" x="0.0" y="27.5" width="375" height="5"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="5" id="OCl-qi-owb"/>
|
||||
</constraints>
|
||||
</progressView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="07B-Zy-FCt">
|
||||
<rect key="frame" x="0.0" y="22" width="375" height="16"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleFootnote"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="07B-Zy-FCt" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="6eL-GN-NIE"/>
|
||||
<constraint firstItem="07B-Zy-FCt" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="QJ0-os-kZt"/>
|
||||
<constraint firstAttribute="trailing" secondItem="gKH-fc-zh7" secondAttribute="trailing" id="SbS-0T-bdo"/>
|
||||
<constraint firstItem="gKH-fc-zh7" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="V0P-ix-fa3"/>
|
||||
<constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="07B-Zy-FCt" secondAttribute="trailing" id="Zor-53-U98"/>
|
||||
<constraint firstItem="gKH-fc-zh7" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="mnf-7m-knt"/>
|
||||
</constraints>
|
||||
<nil key="simulatedTopBarMetrics"/>
|
||||
<nil key="simulatedBottomBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
|
||||
<connections>
|
||||
<outlet property="label" destination="07B-Zy-FCt" id="UEr-Dh-NBo"/>
|
||||
<outlet property="progressView" destination="gKH-fc-zh7" id="Una-CD-Zi8"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="-151" y="6"/>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -44,14 +44,9 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(avatarDidBecomeAvailable(_:)), name: .AvatarDidBecomeAvailable, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(faviconDidBecomeAvailable(_:)), name: .FaviconDidBecomeAvailable, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(userDefaultsDidChange(_:)), name: UserDefaults.didChangeNotification, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(progressDidChange(_:)), name: .AccountRefreshProgressDidChange, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(contentSizeCategoryDidChange), name: UIContentSizeCategory.didChangeNotification, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(displayNameDidChange), name: .DisplayNameDidChange, object: nil)
|
||||
|
||||
// Setup the Refresh Control
|
||||
refreshControl = UIRefreshControl()
|
||||
refreshControl!.addTarget(self, action: #selector(refreshAccounts(_:)), for: .valueChanged)
|
||||
|
||||
// Configure the table
|
||||
tableView.dataSource = dataSource
|
||||
numberOfTextLines = AppDefaults.timelineNumberOfLines
|
||||
@@ -66,11 +61,6 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner
|
||||
super.viewWillAppear(animated)
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
updateProgressIndicatorIfNeeded()
|
||||
}
|
||||
|
||||
override func viewWillLayoutSubviews() {
|
||||
// If you setup the Search Controller in viewWillLayoutSubviews it won't show by default on creation
|
||||
searchController.delegate = self
|
||||
@@ -368,10 +358,6 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner
|
||||
reloadAllVisibleCells()
|
||||
}
|
||||
|
||||
@objc func progressDidChange(_ note: Notification) {
|
||||
updateProgressIndicatorIfNeeded()
|
||||
}
|
||||
|
||||
@objc func displayNameDidChange(_ note: Notification) {
|
||||
titleView?.label.text = coordinator.timelineName
|
||||
}
|
||||
@@ -455,15 +441,6 @@ extension MasterTimelineViewController: UISearchBarDelegate {
|
||||
|
||||
private extension MasterTimelineViewController {
|
||||
|
||||
@objc private func refreshAccounts(_ sender: Any) {
|
||||
refreshControl?.endRefreshing()
|
||||
// This is a hack to make sure that an error dialog doesn't interfere with dismissing the refreshControl.
|
||||
// If the error dialog appears too closely to the call to endRefreshing, then the refreshControl never disappears.
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
AccountManager.shared.refreshAll(errorHandler: ErrorHandler.present(self))
|
||||
}
|
||||
}
|
||||
|
||||
func resetUI() {
|
||||
title = coordinator.timelineName
|
||||
|
||||
@@ -521,12 +498,6 @@ private extension MasterTimelineViewController {
|
||||
}
|
||||
}
|
||||
|
||||
func updateProgressIndicatorIfNeeded() {
|
||||
if !coordinator.isThreePanelMode {
|
||||
navigationController?.updateAccountRefreshProgressIndicator()
|
||||
}
|
||||
}
|
||||
|
||||
func applyChanges(animate: Bool, completion: (() -> Void)? = nil) {
|
||||
var snapshot = NSDiffableDataSourceSnapshot<Int, Article>()
|
||||
snapshot.appendSections([0])
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
//
|
||||
// NavigationProgressView.swift
|
||||
// KYNavigationProgress
|
||||
//
|
||||
// Created by kyo__hei on 2015/12/29.
|
||||
// Copyright (c) 2015 kyo__hei. All rights reserved.
|
||||
//
|
||||
// Original project: https://github.com/ykyouhei/KYNavigationProgress
|
||||
|
||||
import UIKit
|
||||
|
||||
public final class NavigationProgressView: UIView {
|
||||
|
||||
/* ====================================================================== */
|
||||
// MARK: - Properties
|
||||
/* ====================================================================== */
|
||||
|
||||
internal var progress: Float = 0 {
|
||||
didSet {
|
||||
progress = min(1, progress)
|
||||
barWidthConstraint.constant = bounds.width * CGFloat(progress)
|
||||
}
|
||||
}
|
||||
|
||||
internal let bar = UIView()
|
||||
|
||||
@objc public dynamic var progressTintColor: UIColor? = AppAssets.primaryAccentColor {
|
||||
didSet {
|
||||
bar.backgroundColor = progressTintColor
|
||||
}
|
||||
}
|
||||
|
||||
@objc public dynamic var trackTintColor: UIColor? = .clear {
|
||||
didSet {
|
||||
backgroundColor = trackTintColor
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate let barWidthConstraint: NSLayoutConstraint
|
||||
|
||||
override public var frame: CGRect {
|
||||
didSet {
|
||||
let tmpProgress = progress
|
||||
progress = tmpProgress
|
||||
}
|
||||
}
|
||||
|
||||
/* ====================================================================== */
|
||||
// MARK: - initializer
|
||||
/* ====================================================================== */
|
||||
|
||||
required public init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override init(frame: CGRect) {
|
||||
barWidthConstraint = NSLayoutConstraint(
|
||||
item: bar,
|
||||
attribute: .width,
|
||||
relatedBy: .equal,
|
||||
toItem: nil,
|
||||
attribute: .notAnAttribute,
|
||||
multiplier: 1,
|
||||
constant: frame.width * CGFloat(progress))
|
||||
|
||||
super.init(frame: frame)
|
||||
|
||||
let leftConstraint = NSLayoutConstraint(
|
||||
item: bar,
|
||||
attribute: .left,
|
||||
relatedBy: .equal,
|
||||
toItem: self,
|
||||
attribute: .left,
|
||||
multiplier: 1,
|
||||
constant: 0)
|
||||
|
||||
let bottomConstraint = NSLayoutConstraint(
|
||||
item: bar,
|
||||
attribute: .bottom,
|
||||
relatedBy: .equal,
|
||||
toItem: self,
|
||||
attribute: .bottom,
|
||||
multiplier: 1,
|
||||
constant: 0)
|
||||
|
||||
let topConstraint = NSLayoutConstraint(
|
||||
item: bar,
|
||||
attribute: .top,
|
||||
relatedBy: .equal,
|
||||
toItem: self,
|
||||
attribute: .top,
|
||||
multiplier: 1,
|
||||
constant: 0)
|
||||
|
||||
addSubview(bar)
|
||||
|
||||
backgroundColor = trackTintColor
|
||||
|
||||
bar.backgroundColor = progressTintColor
|
||||
bar.translatesAutoresizingMaskIntoConstraints = false
|
||||
addConstraints([
|
||||
barWidthConstraint,
|
||||
leftConstraint,
|
||||
topConstraint,
|
||||
bottomConstraint])
|
||||
}
|
||||
|
||||
|
||||
/* ====================================================================== */
|
||||
// MARK: - Notification
|
||||
/* ====================================================================== */
|
||||
|
||||
func deviceDidRotate(_ notification: Notification) {
|
||||
}
|
||||
|
||||
|
||||
/* ====================================================================== */
|
||||
// MARK: - Method
|
||||
/* ====================================================================== */
|
||||
|
||||
internal func setProgress(_ progress: Float, animated: Bool, completion: @escaping () -> Void) {
|
||||
let duration: TimeInterval = animated ? 0.2 : 0
|
||||
|
||||
self.progress = progress
|
||||
|
||||
UIView.animate(withDuration: duration, animations: { self.layoutIfNeeded() }) { _ in
|
||||
completion()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
//
|
||||
// UINavigationController+Progress.swift
|
||||
// KYNavigationProgress
|
||||
//
|
||||
// Created by kyo__hei on 2015/12/29.
|
||||
// Copyright (c) 2015 kyo__hei. All rights reserved.
|
||||
//
|
||||
// Original project: https://github.com/ykyouhei/KYNavigationProgress
|
||||
|
||||
import UIKit
|
||||
import Account
|
||||
|
||||
private let constraintIdentifier = "progressHeightConstraint"
|
||||
|
||||
public extension UINavigationController {
|
||||
|
||||
/* ====================================================================== */
|
||||
// MARK: - Properties
|
||||
/* ====================================================================== */
|
||||
|
||||
/**
|
||||
Default is 2.0
|
||||
*/
|
||||
var progressHeight: CGFloat {
|
||||
get { return progressView.frame.height }
|
||||
set {
|
||||
progressView.frame.origin.y = navigationBar.frame.height - newValue
|
||||
progressView.frame.size.height = newValue
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
The color shown for the portion of the progress bar that is not filled.
|
||||
default is clear color.
|
||||
*/
|
||||
var trackTintColor: UIColor? {
|
||||
get { return progressView.trackTintColor }
|
||||
set { progressView.trackTintColor = newValue }
|
||||
}
|
||||
|
||||
/**
|
||||
The color shown for the portion of the progress bar that is filled.
|
||||
default is (r: 0, g: 122, b: 225, a: 255.
|
||||
*/
|
||||
var progressTintColor: UIColor? {
|
||||
get { return progressView.progressTintColor }
|
||||
set { progressView.progressTintColor = newValue }
|
||||
}
|
||||
|
||||
/**
|
||||
The current progress is represented by a floating-point value between 0.0 and 1.0,
|
||||
inclusive, where 1.0 indicates the completion of the task. The default value is 0.0.
|
||||
*/
|
||||
var progress: Float {
|
||||
get { return progressView.progress }
|
||||
set { progressView.progress = newValue }
|
||||
}
|
||||
|
||||
|
||||
private var progressView: NavigationProgressView {
|
||||
|
||||
for subview in navigationBar.subviews {
|
||||
if let progressView = subview as? NavigationProgressView {
|
||||
return progressView
|
||||
}
|
||||
}
|
||||
|
||||
let defaultHeight = CGFloat(2)
|
||||
let frame = CGRect(
|
||||
x: 0,
|
||||
y: navigationBar.frame.height - defaultHeight,
|
||||
width: navigationBar.frame.width,
|
||||
height: defaultHeight
|
||||
)
|
||||
let progressView = NavigationProgressView(frame: frame)
|
||||
|
||||
navigationBar.addSubview(progressView)
|
||||
|
||||
progressView.autoresizingMask = [
|
||||
.flexibleWidth, .flexibleTopMargin
|
||||
]
|
||||
|
||||
|
||||
return progressView
|
||||
}
|
||||
|
||||
|
||||
/* ====================================================================== */
|
||||
// MARK: - Public Method
|
||||
/* ====================================================================== */
|
||||
|
||||
/**
|
||||
Adjusts the current progress shown by the receiver, optionally animating the change.
|
||||
|
||||
- parameter progress: The new progress value.
|
||||
- parameter animated: true if the change should be animated, false if the change should happen immediately.
|
||||
*/
|
||||
func setProgress(_ progress: Float, animated: Bool, completion: @escaping () -> Void) {
|
||||
progressView.bar.alpha = 1
|
||||
progressView.setProgress(progress, animated: animated, completion: completion)
|
||||
}
|
||||
|
||||
/**
|
||||
While progress is changed to 1.0, the bar will fade out. After that, progress will be 0.0.
|
||||
*/
|
||||
func finishProgress() {
|
||||
progressView.bar.alpha = 1
|
||||
progressView.setProgress(1, animated: true) {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
|
||||
UIView.animate(withDuration: 0.5, animations: { self.progressView.bar.alpha = 0 }) { finished in
|
||||
self.progressView.progress = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
While progress is changed to 0.0, the bar will fade out.
|
||||
*/
|
||||
func cancelProgress() {
|
||||
progressView.setProgress(0, animated: true) {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
|
||||
UIView.animate(withDuration: 0.5, animations: {
|
||||
self.progressView.bar.alpha = 0
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func updateAccountRefreshProgressIndicator() {
|
||||
|
||||
let progress = AccountManager.shared.combinedRefreshProgress
|
||||
|
||||
if progress.isComplete {
|
||||
if self.progress != 0 {
|
||||
finishProgress()
|
||||
}
|
||||
} else {
|
||||
let percent = Float(progress.numberCompleted) / Float(progress.numberOfTasks)
|
||||
setProgress(percent, animated: true) {}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -718,15 +718,6 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
|
||||
markArticlesWithUndo(articles, statusKey: .read, flag: true)
|
||||
}
|
||||
|
||||
func markAllAsRead() {
|
||||
let accounts = AccountManager.shared.activeAccounts
|
||||
var articles = Set<Article>()
|
||||
accounts.forEach { account in
|
||||
articles.formUnion(account.fetchArticles(.unread))
|
||||
}
|
||||
markAllAsRead(Array(articles))
|
||||
}
|
||||
|
||||
func markAllAsReadInTimeline() {
|
||||
markAllAsRead(articles)
|
||||
masterNavigationController.popViewController(animated: true)
|
||||
|
||||
Reference in New Issue
Block a user