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 */; };
|
||||
51FA73B72332D5F70090D516 /* ArticleExtractorButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51FA73B62332D5F70090D516 /* ArticleExtractorButton.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 */; };
|
||||
55E15BCC229D65A900D6602A /* AccountsReaderAPIWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55E15BCA229D65A900D6602A /* AccountsReaderAPIWindowController.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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
@ -1369,6 +1371,7 @@
|
||||
51D6A5BB23199C85001C27D8 /* MasterTimelineDataSource.swift */,
|
||||
5148F4542336DB7000F8CD8B /* MasterTimelineTitleView.swift */,
|
||||
5148F44A2336DB4700F8CD8B /* MasterTimelineTitleView.xib */,
|
||||
51FD413A2342BD0500880194 /* MasterTimelineUnreadCountView.swift */,
|
||||
51C4526F2265091600C03939 /* Cell */,
|
||||
);
|
||||
path = MasterTimeline;
|
||||
@ -2791,6 +2794,7 @@
|
||||
517630232336657E00E15FFF /* ArticleViewControllerWebViewProvider.swift in Sources */,
|
||||
51C4528F226509BD00C03939 /* UnreadFeed.swift in Sources */,
|
||||
51AF460E232488C6001742EF /* Account-Extensions.swift in Sources */,
|
||||
51FD413B2342BD0500880194 /* MasterTimelineUnreadCountView.swift in Sources */,
|
||||
5183CCDD226F1F5C0010922C /* NavigationProgressView.swift in Sources */,
|
||||
51AF45E123246731001742EF /* SettingsAccountLabelView.swift in Sources */,
|
||||
51D87EE12311D34700E63F03 /* ActivityType.swift in Sources */,
|
||||
|
@ -10,19 +10,26 @@ import UIKit
|
||||
|
||||
class MasterFeedUnreadCountView : UIView {
|
||||
|
||||
private let padding = UIEdgeInsets(top: 1.0, left: 7.0, bottom: 1.0, right: 7.0)
|
||||
private let cornerRadius = 8.0
|
||||
private let bgColor = UIColor.darkGray
|
||||
private let textColor = UIColor.white
|
||||
private var textAttributes: [NSAttributedString.Key: AnyObject] {
|
||||
var padding: UIEdgeInsets {
|
||||
return UIEdgeInsets(top: 1.0, left: 7.0, bottom: 1.0, right: 7.0)
|
||||
}
|
||||
|
||||
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)
|
||||
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 {
|
||||
didSet {
|
||||
contentSizeIsValid = false
|
||||
invalidateIntrinsicContentSize()
|
||||
setNeedsDisplay()
|
||||
}
|
||||
}
|
||||
@ -69,7 +76,7 @@ class MasterFeedUnreadCountView : UIView {
|
||||
return CGSize(width: UIView.noIntrinsicMetric, height: UIView.noIntrinsicMetric)
|
||||
}
|
||||
|
||||
private func textSize() -> CGSize {
|
||||
func textSize() -> CGSize {
|
||||
|
||||
if unreadCount < 1 {
|
||||
return CGSize.zero
|
||||
@ -88,7 +95,7 @@ class MasterFeedUnreadCountView : UIView {
|
||||
|
||||
}
|
||||
|
||||
private func textRect() -> CGRect {
|
||||
func textRect() -> CGRect {
|
||||
|
||||
let size = textSize()
|
||||
var r = CGRect.zero
|
||||
|
@ -20,5 +20,6 @@ class MasterTimelineTitleView: UIView {
|
||||
}
|
||||
|
||||
@IBOutlet weak var label: UILabel!
|
||||
@IBOutlet weak var unreadCountView: MasterTimelineUnreadCountView!
|
||||
|
||||
}
|
||||
|
@ -20,20 +20,26 @@
|
||||
<constraint firstAttribute="width" constant="20" id="jOK-1W-SEO"/>
|
||||
</constraints>
|
||||
</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">
|
||||
<rect key="frame" x="28" y="9" width="162" height="20"/>
|
||||
<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="43.5" height="20"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</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>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<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 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="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>
|
||||
<nil key="simulatedTopBarMetrics"/>
|
||||
<nil key="simulatedBottomBarMetrics"/>
|
||||
@ -42,6 +48,7 @@
|
||||
<connections>
|
||||
<outlet property="imageView" destination="Rne-3c-G6E" id="sHA-Vh-kck"/>
|
||||
<outlet property="label" destination="5F6-2v-qSS" id="ec7-8Y-PRv"/>
|
||||
<outlet property="unreadCountView" destination="z9o-XA-3t4" id="JBy-aa-feL"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="14.492753623188406" y="-224.33035714285714"/>
|
||||
</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
|
||||
|
||||
updateTitleUnreadCount()
|
||||
|
||||
if coordinator.timelineFetcher is Feed {
|
||||
titleView.heightAnchor.constraint(equalToConstant: 44.0).isActive = true
|
||||
let tap = UITapGestureRecognizer(target: self, action:#selector(showFeedInspector(_:)))
|
||||
@ -500,10 +501,17 @@ private extension MasterTimelineViewController {
|
||||
}
|
||||
|
||||
func updateUI() {
|
||||
updateTitleUnreadCount()
|
||||
markAllAsReadButton.isEnabled = coordinator.isTimelineUnreadAvailable
|
||||
firstUnreadButton.isEnabled = coordinator.isTimelineUnreadAvailable
|
||||
}
|
||||
|
||||
func updateTitleUnreadCount() {
|
||||
if let unreadCountProvider = coordinator.timelineFetcher as? UnreadCountProvider {
|
||||
titleView?.unreadCountView.unreadCount = unreadCountProvider.unreadCount
|
||||
}
|
||||
}
|
||||
|
||||
func updateProgressIndicatorIfNeeded() {
|
||||
if !coordinator.isThreePanelMode {
|
||||
navigationController?.updateAccountRefreshProgressIndicator()
|
||||
|
Loading…
x
Reference in New Issue
Block a user