Add unread count to the timeline

This commit is contained in:
Maurice Parker
2019-09-30 20:01:02 -05:00
parent ed2257a4f4
commit 77ba42f102
6 changed files with 74 additions and 12 deletions

View File

@@ -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

View File

@@ -20,5 +20,6 @@ class MasterTimelineTitleView: UIView {
}
@IBOutlet weak var label: UILabel!
@IBOutlet weak var unreadCountView: MasterTimelineUnreadCountView!
}

View File

@@ -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>

View 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)
}
}
}

View File

@@ -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()