Add unread count to the timeline
This commit is contained in:
parent
ed2257a4f4
commit
77ba42f102
@ -217,6 +217,7 @@
|
|||||||
51FA73AB2332C2FD0090D516 /* ArticleExtractorConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51FA73A92332C2FD0090D516 /* ArticleExtractorConfig.swift */; };
|
51FA73AB2332C2FD0090D516 /* ArticleExtractorConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51FA73A92332C2FD0090D516 /* ArticleExtractorConfig.swift */; };
|
||||||
51FA73B72332D5F70090D516 /* ArticleExtractorButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51FA73B62332D5F70090D516 /* ArticleExtractorButton.swift */; };
|
51FA73B72332D5F70090D516 /* ArticleExtractorButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51FA73B62332D5F70090D516 /* ArticleExtractorButton.swift */; };
|
||||||
51FD40C72341555A00880194 /* UIImage-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51FD40BD2341555600880194 /* UIImage-Extensions.swift */; };
|
51FD40C72341555A00880194 /* UIImage-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51FD40BD2341555600880194 /* UIImage-Extensions.swift */; };
|
||||||
|
51FD413B2342BD0500880194 /* MasterTimelineUnreadCountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51FD413A2342BD0500880194 /* MasterTimelineUnreadCountView.swift */; };
|
||||||
55E15BCB229D65A900D6602A /* AccountsReaderAPI.xib in Resources */ = {isa = PBXBuildFile; fileRef = 55E15BC1229D65A900D6602A /* AccountsReaderAPI.xib */; };
|
55E15BCB229D65A900D6602A /* AccountsReaderAPI.xib in Resources */ = {isa = PBXBuildFile; fileRef = 55E15BC1229D65A900D6602A /* AccountsReaderAPI.xib */; };
|
||||||
55E15BCC229D65A900D6602A /* AccountsReaderAPIWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55E15BCA229D65A900D6602A /* AccountsReaderAPIWindowController.swift */; };
|
55E15BCC229D65A900D6602A /* AccountsReaderAPIWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55E15BCA229D65A900D6602A /* AccountsReaderAPIWindowController.swift */; };
|
||||||
5F323809231DF9F000706F6B /* NNWTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F323808231DF9F000706F6B /* NNWTableViewCell.swift */; };
|
5F323809231DF9F000706F6B /* NNWTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F323808231DF9F000706F6B /* NNWTableViewCell.swift */; };
|
||||||
@ -897,6 +898,7 @@
|
|||||||
51FA73A92332C2FD0090D516 /* ArticleExtractorConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleExtractorConfig.swift; sourceTree = "<group>"; };
|
51FA73A92332C2FD0090D516 /* ArticleExtractorConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleExtractorConfig.swift; sourceTree = "<group>"; };
|
||||||
51FA73B62332D5F70090D516 /* ArticleExtractorButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleExtractorButton.swift; sourceTree = "<group>"; };
|
51FA73B62332D5F70090D516 /* ArticleExtractorButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleExtractorButton.swift; sourceTree = "<group>"; };
|
||||||
51FD40BD2341555600880194 /* UIImage-Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage-Extensions.swift"; sourceTree = "<group>"; };
|
51FD40BD2341555600880194 /* UIImage-Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage-Extensions.swift"; sourceTree = "<group>"; };
|
||||||
|
51FD413A2342BD0500880194 /* MasterTimelineUnreadCountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MasterTimelineUnreadCountView.swift; sourceTree = "<group>"; };
|
||||||
557EE1A522B6F4E1004206FA /* SettingsReaderAPIAccountView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsReaderAPIAccountView.swift; sourceTree = "<group>"; };
|
557EE1A522B6F4E1004206FA /* SettingsReaderAPIAccountView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsReaderAPIAccountView.swift; sourceTree = "<group>"; };
|
||||||
55E15BC1229D65A900D6602A /* AccountsReaderAPI.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AccountsReaderAPI.xib; sourceTree = "<group>"; };
|
55E15BC1229D65A900D6602A /* AccountsReaderAPI.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AccountsReaderAPI.xib; sourceTree = "<group>"; };
|
||||||
55E15BCA229D65A900D6602A /* AccountsReaderAPIWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountsReaderAPIWindowController.swift; sourceTree = "<group>"; };
|
55E15BCA229D65A900D6602A /* AccountsReaderAPIWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountsReaderAPIWindowController.swift; sourceTree = "<group>"; };
|
||||||
@ -1369,6 +1371,7 @@
|
|||||||
51D6A5BB23199C85001C27D8 /* MasterTimelineDataSource.swift */,
|
51D6A5BB23199C85001C27D8 /* MasterTimelineDataSource.swift */,
|
||||||
5148F4542336DB7000F8CD8B /* MasterTimelineTitleView.swift */,
|
5148F4542336DB7000F8CD8B /* MasterTimelineTitleView.swift */,
|
||||||
5148F44A2336DB4700F8CD8B /* MasterTimelineTitleView.xib */,
|
5148F44A2336DB4700F8CD8B /* MasterTimelineTitleView.xib */,
|
||||||
|
51FD413A2342BD0500880194 /* MasterTimelineUnreadCountView.swift */,
|
||||||
51C4526F2265091600C03939 /* Cell */,
|
51C4526F2265091600C03939 /* Cell */,
|
||||||
);
|
);
|
||||||
path = MasterTimeline;
|
path = MasterTimeline;
|
||||||
@ -2791,6 +2794,7 @@
|
|||||||
517630232336657E00E15FFF /* ArticleViewControllerWebViewProvider.swift in Sources */,
|
517630232336657E00E15FFF /* ArticleViewControllerWebViewProvider.swift in Sources */,
|
||||||
51C4528F226509BD00C03939 /* UnreadFeed.swift in Sources */,
|
51C4528F226509BD00C03939 /* UnreadFeed.swift in Sources */,
|
||||||
51AF460E232488C6001742EF /* Account-Extensions.swift in Sources */,
|
51AF460E232488C6001742EF /* Account-Extensions.swift in Sources */,
|
||||||
|
51FD413B2342BD0500880194 /* MasterTimelineUnreadCountView.swift in Sources */,
|
||||||
5183CCDD226F1F5C0010922C /* NavigationProgressView.swift in Sources */,
|
5183CCDD226F1F5C0010922C /* NavigationProgressView.swift in Sources */,
|
||||||
51AF45E123246731001742EF /* SettingsAccountLabelView.swift in Sources */,
|
51AF45E123246731001742EF /* SettingsAccountLabelView.swift in Sources */,
|
||||||
51D87EE12311D34700E63F03 /* ActivityType.swift in Sources */,
|
51D87EE12311D34700E63F03 /* ActivityType.swift in Sources */,
|
||||||
|
@ -10,19 +10,26 @@ import UIKit
|
|||||||
|
|
||||||
class MasterFeedUnreadCountView : UIView {
|
class MasterFeedUnreadCountView : UIView {
|
||||||
|
|
||||||
private let padding = UIEdgeInsets(top: 1.0, left: 7.0, bottom: 1.0, right: 7.0)
|
var padding: UIEdgeInsets {
|
||||||
private let cornerRadius = 8.0
|
return UIEdgeInsets(top: 1.0, left: 7.0, bottom: 1.0, right: 7.0)
|
||||||
private let bgColor = UIColor.darkGray
|
}
|
||||||
private let textColor = UIColor.white
|
|
||||||
private var textAttributes: [NSAttributedString.Key: AnyObject] {
|
let cornerRadius = 8.0
|
||||||
|
let bgColor = UIColor.darkGray
|
||||||
|
var textColor: UIColor {
|
||||||
|
return UIColor.white
|
||||||
|
}
|
||||||
|
|
||||||
|
var textAttributes: [NSAttributedString.Key: AnyObject] {
|
||||||
let textFont = UIFont.preferredFont(forTextStyle: .caption1)
|
let textFont = UIFont.preferredFont(forTextStyle: .caption1)
|
||||||
return [NSAttributedString.Key.foregroundColor: textColor, NSAttributedString.Key.font: textFont, NSAttributedString.Key.kern: NSNull()]
|
return [NSAttributedString.Key.foregroundColor: textColor, NSAttributedString.Key.font: textFont, NSAttributedString.Key.kern: NSNull()]
|
||||||
}
|
}
|
||||||
private var textSizeCache = [Int: CGSize]()
|
var textSizeCache = [Int: CGSize]()
|
||||||
|
|
||||||
var unreadCount = 0 {
|
var unreadCount = 0 {
|
||||||
didSet {
|
didSet {
|
||||||
contentSizeIsValid = false
|
contentSizeIsValid = false
|
||||||
|
invalidateIntrinsicContentSize()
|
||||||
setNeedsDisplay()
|
setNeedsDisplay()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -69,7 +76,7 @@ class MasterFeedUnreadCountView : UIView {
|
|||||||
return CGSize(width: UIView.noIntrinsicMetric, height: UIView.noIntrinsicMetric)
|
return CGSize(width: UIView.noIntrinsicMetric, height: UIView.noIntrinsicMetric)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func textSize() -> CGSize {
|
func textSize() -> CGSize {
|
||||||
|
|
||||||
if unreadCount < 1 {
|
if unreadCount < 1 {
|
||||||
return CGSize.zero
|
return CGSize.zero
|
||||||
@ -88,7 +95,7 @@ class MasterFeedUnreadCountView : UIView {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func textRect() -> CGRect {
|
func textRect() -> CGRect {
|
||||||
|
|
||||||
let size = textSize()
|
let size = textSize()
|
||||||
var r = CGRect.zero
|
var r = CGRect.zero
|
||||||
|
@ -20,5 +20,6 @@ class MasterTimelineTitleView: UIView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@IBOutlet weak var label: UILabel!
|
@IBOutlet weak var label: UILabel!
|
||||||
|
@IBOutlet weak var unreadCountView: MasterTimelineUnreadCountView!
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,20 +20,26 @@
|
|||||||
<constraint firstAttribute="width" constant="20" id="jOK-1W-SEO"/>
|
<constraint firstAttribute="width" constant="20" id="jOK-1W-SEO"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</imageView>
|
</imageView>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5F6-2v-qSS">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="250" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5F6-2v-qSS">
|
||||||
<rect key="frame" x="28" y="9" width="162" height="20"/>
|
<rect key="frame" x="28" y="9" width="43.5" height="20"/>
|
||||||
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
|
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
|
||||||
<nil key="textColor"/>
|
<nil key="textColor"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
|
<view verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="z9o-XA-3t4" customClass="MasterTimelineUnreadCountView" customModule="NetNewsWire" customModuleProvider="target">
|
||||||
|
<rect key="frame" x="79.5" y="9" width="110.5" height="20"/>
|
||||||
|
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
|
</view>
|
||||||
</subviews>
|
</subviews>
|
||||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstItem="5F6-2v-qSS" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="CeZ-D5-NOV"/>
|
<constraint firstItem="5F6-2v-qSS" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="CeZ-D5-NOV"/>
|
||||||
|
<constraint firstItem="z9o-XA-3t4" firstAttribute="leading" secondItem="5F6-2v-qSS" secondAttribute="trailing" constant="8" symbolic="YES" id="CiV-5P-T1S"/>
|
||||||
<constraint firstItem="5F6-2v-qSS" firstAttribute="leading" secondItem="Rne-3c-G6E" secondAttribute="trailing" constant="8" id="OUK-1k-4Gc"/>
|
<constraint firstItem="5F6-2v-qSS" firstAttribute="leading" secondItem="Rne-3c-G6E" secondAttribute="trailing" constant="8" id="OUK-1k-4Gc"/>
|
||||||
|
<constraint firstAttribute="trailing" secondItem="z9o-XA-3t4" secondAttribute="trailing" id="OVL-Ac-Rtt"/>
|
||||||
|
<constraint firstItem="z9o-XA-3t4" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="ZkY-jG-eZO"/>
|
||||||
<constraint firstItem="Rne-3c-G6E" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="e1Z-hg-3Cc"/>
|
<constraint firstItem="Rne-3c-G6E" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="e1Z-hg-3Cc"/>
|
||||||
<constraint firstItem="Rne-3c-G6E" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="h3i-G1-ays"/>
|
<constraint firstItem="Rne-3c-G6E" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="h3i-G1-ays"/>
|
||||||
<constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="5F6-2v-qSS" secondAttribute="trailing" id="w9X-65-lnV"/>
|
|
||||||
</constraints>
|
</constraints>
|
||||||
<nil key="simulatedTopBarMetrics"/>
|
<nil key="simulatedTopBarMetrics"/>
|
||||||
<nil key="simulatedBottomBarMetrics"/>
|
<nil key="simulatedBottomBarMetrics"/>
|
||||||
@ -42,6 +48,7 @@
|
|||||||
<connections>
|
<connections>
|
||||||
<outlet property="imageView" destination="Rne-3c-G6E" id="sHA-Vh-kck"/>
|
<outlet property="imageView" destination="Rne-3c-G6E" id="sHA-Vh-kck"/>
|
||||||
<outlet property="label" destination="5F6-2v-qSS" id="ec7-8Y-PRv"/>
|
<outlet property="label" destination="5F6-2v-qSS" id="ec7-8Y-PRv"/>
|
||||||
|
<outlet property="unreadCountView" destination="z9o-XA-3t4" id="JBy-aa-feL"/>
|
||||||
</connections>
|
</connections>
|
||||||
<point key="canvasLocation" x="14.492753623188406" y="-224.33035714285714"/>
|
<point key="canvasLocation" x="14.492753623188406" y="-224.33035714285714"/>
|
||||||
</view>
|
</view>
|
||||||
|
35
iOS/MasterTimeline/MasterTimelineUnreadCountView.swift
Normal file
35
iOS/MasterTimeline/MasterTimelineUnreadCountView.swift
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
//
|
||||||
|
// MasterTimelineUnreadCountView.swift
|
||||||
|
// NetNewsWire-iOS
|
||||||
|
//
|
||||||
|
// Created by Maurice Parker on 9/30/19.
|
||||||
|
// Copyright © 2019 Ranchero Software. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class MasterTimelineUnreadCountView: MasterFeedUnreadCountView {
|
||||||
|
|
||||||
|
override var textColor: UIColor {
|
||||||
|
return UIColor.systemBackground
|
||||||
|
}
|
||||||
|
|
||||||
|
override var intrinsicContentSize: CGSize {
|
||||||
|
return contentSize
|
||||||
|
}
|
||||||
|
|
||||||
|
override func draw(_ dirtyRect: CGRect) {
|
||||||
|
|
||||||
|
let cornerRadii = CGSize(width: cornerRadius, height: cornerRadius)
|
||||||
|
let rect = CGRect(x: 1, y: 1, width: bounds.width - 2, height: bounds.height - 2)
|
||||||
|
let path = UIBezierPath(roundedRect: rect, byRoundingCorners: .allCorners, cornerRadii: cornerRadii)
|
||||||
|
AppAssets.primaryAccentColor.setFill()
|
||||||
|
path.fill()
|
||||||
|
|
||||||
|
if unreadCount > 0 {
|
||||||
|
unreadCountString.draw(at: textRect().origin, withAttributes: textAttributes)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -479,7 +479,8 @@ private extension MasterTimelineViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
titleView.label.text = coordinator.timelineName
|
titleView.label.text = coordinator.timelineName
|
||||||
|
updateTitleUnreadCount()
|
||||||
|
|
||||||
if coordinator.timelineFetcher is Feed {
|
if coordinator.timelineFetcher is Feed {
|
||||||
titleView.heightAnchor.constraint(equalToConstant: 44.0).isActive = true
|
titleView.heightAnchor.constraint(equalToConstant: 44.0).isActive = true
|
||||||
let tap = UITapGestureRecognizer(target: self, action:#selector(showFeedInspector(_:)))
|
let tap = UITapGestureRecognizer(target: self, action:#selector(showFeedInspector(_:)))
|
||||||
@ -500,10 +501,17 @@ private extension MasterTimelineViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func updateUI() {
|
func updateUI() {
|
||||||
|
updateTitleUnreadCount()
|
||||||
markAllAsReadButton.isEnabled = coordinator.isTimelineUnreadAvailable
|
markAllAsReadButton.isEnabled = coordinator.isTimelineUnreadAvailable
|
||||||
firstUnreadButton.isEnabled = coordinator.isTimelineUnreadAvailable
|
firstUnreadButton.isEnabled = coordinator.isTimelineUnreadAvailable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func updateTitleUnreadCount() {
|
||||||
|
if let unreadCountProvider = coordinator.timelineFetcher as? UnreadCountProvider {
|
||||||
|
titleView?.unreadCountView.unreadCount = unreadCountProvider.unreadCount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func updateProgressIndicatorIfNeeded() {
|
func updateProgressIndicatorIfNeeded() {
|
||||||
if !coordinator.isThreePanelMode {
|
if !coordinator.isThreePanelMode {
|
||||||
navigationController?.updateAccountRefreshProgressIndicator()
|
navigationController?.updateAccountRefreshProgressIndicator()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user