mirror of
https://github.com/Ranchero-Software/NetNewsWire
synced 2025-08-12 06:26:36 +00:00
Fix lint issues.
This commit is contained in:
@@ -11,13 +11,13 @@ import Foundation
|
||||
class MainFeedRowIdentifier: NSObject, NSCopying {
|
||||
|
||||
var indexPath: IndexPath
|
||||
|
||||
|
||||
init(indexPath: IndexPath) {
|
||||
self.indexPath = indexPath
|
||||
}
|
||||
|
||||
|
||||
func copy(with zone: NSZone? = nil) -> Any {
|
||||
return self
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ protocol MainFeedTableViewCellDelegate: AnyObject {
|
||||
func mainFeedTableViewCellDisclosureDidToggle(_ sender: MainFeedTableViewCell, expanding: Bool)
|
||||
}
|
||||
|
||||
class MainFeedTableViewCell : VibrantTableViewCell {
|
||||
class MainFeedTableViewCell: VibrantTableViewCell {
|
||||
|
||||
weak var delegate: MainFeedTableViewCellDelegate?
|
||||
|
||||
@@ -44,7 +44,7 @@ class MainFeedTableViewCell : VibrantTableViewCell {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var isSeparatorShown = true {
|
||||
didSet {
|
||||
if isSeparatorShown != oldValue {
|
||||
@@ -56,7 +56,7 @@ class MainFeedTableViewCell : VibrantTableViewCell {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var unreadCount: Int {
|
||||
get {
|
||||
return unreadCountView.unreadCount
|
||||
@@ -100,17 +100,17 @@ class MainFeedTableViewCell : VibrantTableViewCell {
|
||||
view.alpha = 0.5
|
||||
return view
|
||||
}()
|
||||
|
||||
|
||||
private var isDisclosureExpanded = false
|
||||
private var disclosureButton: UIButton?
|
||||
private var unreadCountView = MainFeedUnreadCountView(frame: CGRect.zero)
|
||||
private var isShowingEditControl = false
|
||||
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
|
||||
func setDisclosure(isExpanded: Bool, animated: Bool) {
|
||||
isDisclosureExpanded = isExpanded
|
||||
let duration = animated ? 0.3 : 0.0
|
||||
@@ -120,42 +120,38 @@ class MainFeedTableViewCell : VibrantTableViewCell {
|
||||
self.disclosureButton?.accessibilityLabel = NSLocalizedString("Collapse Folder", comment: "Collapse Folder")
|
||||
self.disclosureButton?.imageView?.transform = CGAffineTransform(rotationAngle: 1.570796)
|
||||
} else {
|
||||
self.disclosureButton?.accessibilityLabel = NSLocalizedString("Expand Folder", comment: "Expand Folder")
|
||||
self.disclosureButton?.accessibilityLabel = NSLocalizedString("Expand Folder", comment: "Expand Folder")
|
||||
self.disclosureButton?.imageView?.transform = CGAffineTransform(rotationAngle: 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override func applyThemeProperties() {
|
||||
super.applyThemeProperties()
|
||||
}
|
||||
|
||||
override func willTransition(to state: UITableViewCell.StateMask) {
|
||||
super.willTransition(to: state)
|
||||
isShowingEditControl = state.contains(.showingEditControl)
|
||||
}
|
||||
|
||||
|
||||
override func sizeThatFits(_ size: CGSize) -> CGSize {
|
||||
let layout = MainFeedTableViewCellLayout(cellWidth: bounds.size.width, insets: safeAreaInsets, label: titleView, unreadCountView: unreadCountView, showingEditingControl: isShowingEditControl, indent: indentationLevel == 1, shouldShowDisclosure: isDisclosureAvailable)
|
||||
return CGSize(width: bounds.width, height: layout.height)
|
||||
}
|
||||
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
let layout = MainFeedTableViewCellLayout(cellWidth: bounds.size.width, insets: safeAreaInsets, label: titleView, unreadCountView: unreadCountView, showingEditingControl: isShowingEditControl, indent: indentationLevel == 1, shouldShowDisclosure: isDisclosureAvailable)
|
||||
layoutWith(layout)
|
||||
}
|
||||
|
||||
|
||||
@objc func buttonPressed(_ sender: UIButton) {
|
||||
if isDisclosureAvailable {
|
||||
setDisclosure(isExpanded: !isDisclosureExpanded, animated: true)
|
||||
delegate?.mainFeedTableViewCellDisclosureDidToggle(self, expanding: isDisclosureExpanded)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override func updateVibrancy(animated: Bool) {
|
||||
super.updateVibrancy(animated: animated)
|
||||
|
||||
|
||||
let iconTintColor: UIColor
|
||||
if isHighlighted || isSelected {
|
||||
iconTintColor = AppAssets.vibrantTextColor
|
||||
@@ -166,7 +162,7 @@ class MainFeedTableViewCell : VibrantTableViewCell {
|
||||
iconTintColor = AppAssets.secondaryAccentColor
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if animated {
|
||||
UIView.animate(withDuration: Self.duration) {
|
||||
self.iconView.tintColor = iconTintColor
|
||||
@@ -174,10 +170,10 @@ class MainFeedTableViewCell : VibrantTableViewCell {
|
||||
} else {
|
||||
self.iconView.tintColor = iconTintColor
|
||||
}
|
||||
|
||||
|
||||
updateLabelVibrancy(titleView, color: labelColor, animated: animated)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private extension MainFeedTableViewCell {
|
||||
@@ -200,7 +196,7 @@ private extension MainFeedTableViewCell {
|
||||
disclosureButton?.addInteraction(UIPointerInteraction())
|
||||
addSubviewAtInit(disclosureButton!)
|
||||
}
|
||||
|
||||
|
||||
func addSubviewAtInit(_ view: UIView) {
|
||||
addSubview(view)
|
||||
view.translatesAutoresizingMaskIntoConstraints = false
|
||||
@@ -220,11 +216,11 @@ private extension MainFeedTableViewCell {
|
||||
view.isHidden = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func showView(_ view: UIView) {
|
||||
if view.isHidden {
|
||||
view.isHidden = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ struct MainFeedTableViewCellLayout {
|
||||
private static let verticalPadding = CGFloat(integerLiteral: 11)
|
||||
|
||||
private static let minRowHeight = CGFloat(integerLiteral: 44)
|
||||
|
||||
|
||||
static let faviconCornerRadius = CGFloat(integerLiteral: 2)
|
||||
|
||||
let faviconRect: CGRect
|
||||
@@ -29,9 +29,9 @@ struct MainFeedTableViewCellLayout {
|
||||
let unreadCountRect: CGRect
|
||||
let disclosureButtonRect: CGRect
|
||||
let separatorRect: CGRect
|
||||
|
||||
|
||||
let height: CGFloat
|
||||
|
||||
|
||||
init(cellWidth: CGFloat, insets: UIEdgeInsets, label: UILabel, unreadCountView: MainFeedUnreadCountView, showingEditingControl: Bool, indent: Bool, shouldShowDisclosure: Bool) {
|
||||
|
||||
var initialIndent = insets.left
|
||||
@@ -39,7 +39,7 @@ struct MainFeedTableViewCellLayout {
|
||||
initialIndent += MainFeedTableViewCellLayout.indentWidth
|
||||
}
|
||||
let bounds = CGRect(x: initialIndent, y: 0.0, width: floor(cellWidth - initialIndent - insets.right), height: 0.0)
|
||||
|
||||
|
||||
// Disclosure Button
|
||||
var rDisclosure = CGRect.zero
|
||||
if shouldShowDisclosure {
|
||||
@@ -66,7 +66,7 @@ struct MainFeedTableViewCellLayout {
|
||||
rUnread.size = unreadCountSize
|
||||
rUnread.origin.x = bounds.maxX - (MainFeedTableViewCellLayout.unreadCountMarginRight + unreadCountSize.width)
|
||||
}
|
||||
|
||||
|
||||
// Title
|
||||
var rLabelx = insets.left + MainFeedTableViewCellLayout.disclosureButtonSize.width
|
||||
if !shouldShowDisclosure {
|
||||
@@ -80,7 +80,7 @@ struct MainFeedTableViewCellLayout {
|
||||
} else {
|
||||
labelWidth = cellWidth - (rLabelx + MainFeedTableViewCellLayout.labelMarginRight)
|
||||
}
|
||||
|
||||
|
||||
let labelSizeInfo = MultilineUILabelSizer.size(for: label.text ?? "", font: label.font, numberOfLines: 0, width: Int(floor(labelWidth)))
|
||||
|
||||
// Now that we've got everything (especially the label) computed without the editing controls, update for them.
|
||||
@@ -99,7 +99,7 @@ struct MainFeedTableViewCellLayout {
|
||||
}
|
||||
|
||||
var rLabel = CGRect(x: rLabelx, y: rLabely, width: labelWidth, height: labelSizeInfo.size.height)
|
||||
|
||||
|
||||
// Determine cell height
|
||||
let paddedLabelHeight = rLabel.maxY + UIFontMetrics.default.scaledValue(for: MainFeedTableViewCellLayout.verticalPadding)
|
||||
let maxGraphicsHeight = [rFavicon, rUnread, rDisclosure].maxY()
|
||||
@@ -107,7 +107,7 @@ struct MainFeedTableViewCellLayout {
|
||||
if cellHeight < MainFeedTableViewCellLayout.minRowHeight {
|
||||
cellHeight = MainFeedTableViewCellLayout.minRowHeight
|
||||
}
|
||||
|
||||
|
||||
// Center in Cell
|
||||
let newBounds = CGRect(x: bounds.origin.x, y: bounds.origin.y, width: bounds.width, height: cellHeight)
|
||||
if !unreadCountIsHidden {
|
||||
@@ -126,16 +126,16 @@ struct MainFeedTableViewCellLayout {
|
||||
// Separator Insets
|
||||
let separatorInset = MainFeedTableViewCellLayout.disclosureButtonSize.width
|
||||
separatorRect = CGRect(x: separatorInset, y: cellHeight - 0.5, width: cellWidth - separatorInset, height: 0.5)
|
||||
|
||||
|
||||
// Assign the properties
|
||||
self.height = cellHeight
|
||||
self.faviconRect = rFavicon
|
||||
self.unreadCountRect = rUnread
|
||||
self.disclosureButtonRect = rDisclosure
|
||||
self.titleRect = rLabel
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Ideally this will be implemented in RSCore (see RSGeometry)
|
||||
static func centerVertically(_ originalRect: CGRect, _ containerRect: CGRect) -> CGRect {
|
||||
var result = originalRect
|
||||
@@ -144,5 +144,5 @@ struct MainFeedTableViewCellLayout {
|
||||
result.size = originalRect.size
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ protocol MainFeedTableViewSectionHeaderDelegate {
|
||||
class MainFeedTableViewSectionHeader: UITableViewHeaderFooterView {
|
||||
|
||||
var delegate: MainFeedTableViewSectionHeaderDelegate?
|
||||
|
||||
|
||||
override var accessibilityLabel: String? {
|
||||
set {}
|
||||
get {
|
||||
@@ -37,7 +37,7 @@ class MainFeedTableViewSectionHeader: UITableViewHeaderFooterView {
|
||||
return NSLocalizedString("Collapsed", comment: "Disclosure button collapsed state for accessibility")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var unreadCount: Int {
|
||||
get {
|
||||
return unreadCountView.unreadCount
|
||||
@@ -50,7 +50,7 @@ class MainFeedTableViewSectionHeader: UITableViewHeaderFooterView {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var name: String {
|
||||
get {
|
||||
return titleView.text ?? ""
|
||||
@@ -62,16 +62,16 @@ class MainFeedTableViewSectionHeader: UITableViewHeaderFooterView {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var disclosureExpanded = false {
|
||||
didSet {
|
||||
updateExpandedState(animate: true)
|
||||
updateUnreadCountView()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var isLastSection = false
|
||||
|
||||
|
||||
private let titleView: UILabel = {
|
||||
let label = NonIntrinsicLabel()
|
||||
label.numberOfLines = 0
|
||||
@@ -80,7 +80,7 @@ class MainFeedTableViewSectionHeader: UITableViewHeaderFooterView {
|
||||
label.font = .preferredFont(forTextStyle: .body)
|
||||
return label
|
||||
}()
|
||||
|
||||
|
||||
private let unreadCountView = MainFeedUnreadCountView(frame: CGRect.zero)
|
||||
|
||||
private lazy var disclosureButton: UIButton = {
|
||||
@@ -98,27 +98,27 @@ class MainFeedTableViewSectionHeader: UITableViewHeaderFooterView {
|
||||
view.backgroundColor = UIColor.separator
|
||||
return view
|
||||
}()
|
||||
|
||||
|
||||
private let bottomSeparatorView: UIView = {
|
||||
let view = UIView()
|
||||
view.backgroundColor = UIColor.separator
|
||||
return view
|
||||
}()
|
||||
|
||||
|
||||
override init(reuseIdentifier: String?) {
|
||||
super.init(reuseIdentifier: reuseIdentifier)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
|
||||
override func sizeThatFits(_ size: CGSize) -> CGSize {
|
||||
let layout = MainFeedTableViewSectionHeaderLayout(cellWidth: size.width, insets: safeAreaInsets, label: titleView, unreadCountView: unreadCountView)
|
||||
return CGSize(width: bounds.width, height: layout.height)
|
||||
|
||||
|
||||
}
|
||||
|
||||
override func layoutSubviews() {
|
||||
@@ -137,7 +137,7 @@ private extension MainFeedTableViewSectionHeader {
|
||||
@objc func toggleDisclosure() {
|
||||
delegate?.mainFeedTableViewSectionHeaderDisclosureDidToggle(self)
|
||||
}
|
||||
|
||||
|
||||
func commonInit() {
|
||||
addSubviewAtInit(unreadCountView)
|
||||
addSubviewAtInit(titleView)
|
||||
@@ -147,14 +147,14 @@ private extension MainFeedTableViewSectionHeader {
|
||||
addSubviewAtInit(topSeparatorView)
|
||||
addSubviewAtInit(bottomSeparatorView)
|
||||
}
|
||||
|
||||
|
||||
func updateExpandedState(animate: Bool) {
|
||||
if !isLastSection && self.disclosureExpanded {
|
||||
self.bottomSeparatorView.isHidden = false
|
||||
}
|
||||
|
||||
|
||||
let duration = animate ? 0.3 : 0.0
|
||||
|
||||
|
||||
UIView.animate(
|
||||
withDuration: duration,
|
||||
animations: {
|
||||
@@ -169,7 +169,7 @@ private extension MainFeedTableViewSectionHeader {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
func updateUnreadCountView() {
|
||||
if !disclosureExpanded && unreadCount > 0 {
|
||||
UIView.animate(withDuration: 0.3) {
|
||||
@@ -186,7 +186,7 @@ private extension MainFeedTableViewSectionHeader {
|
||||
contentView.addSubview(view)
|
||||
view.translatesAutoresizingMaskIntoConstraints = false
|
||||
}
|
||||
|
||||
|
||||
func layoutWith(_ layout: MainFeedTableViewSectionHeaderLayout) {
|
||||
titleView.setFrameIfNotEqual(layout.titleRect)
|
||||
unreadCountView.setFrameIfNotEqual(layout.unreadCountRect)
|
||||
@@ -198,14 +198,14 @@ private extension MainFeedTableViewSectionHeader {
|
||||
|
||||
let top = CGRect(x: x, y: 0, width: width, height: height)
|
||||
topSeparatorView.setFrameIfNotEqual(top)
|
||||
|
||||
|
||||
let bottom = CGRect(x: x, y: frame.height - height, width: width, height: height)
|
||||
bottomSeparatorView.setFrameIfNotEqual(bottom)
|
||||
}
|
||||
|
||||
|
||||
func addBackgroundView() {
|
||||
self.backgroundView = UIView(frame: self.bounds)
|
||||
self.backgroundView?.backgroundColor = AppAssets.sectionHeaderColor
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -17,17 +17,17 @@ struct MainFeedTableViewSectionHeaderLayout {
|
||||
private static let verticalPadding = CGFloat(integerLiteral: 11)
|
||||
|
||||
private static let minRowHeight = CGFloat(integerLiteral: 44)
|
||||
|
||||
|
||||
let titleRect: CGRect
|
||||
let unreadCountRect: CGRect
|
||||
let disclosureButtonRect: CGRect
|
||||
|
||||
|
||||
let height: CGFloat
|
||||
|
||||
|
||||
init(cellWidth: CGFloat, insets: UIEdgeInsets, label: UILabel, unreadCountView: MainFeedUnreadCountView) {
|
||||
|
||||
let bounds = CGRect(x: insets.left, y: 0.0, width: floor(cellWidth - insets.right), height: 0.0)
|
||||
|
||||
|
||||
// Disclosure Button
|
||||
var rDisclosure = CGRect.zero
|
||||
rDisclosure.size = MainFeedTableViewSectionHeaderLayout.disclosureButtonSize
|
||||
@@ -42,7 +42,7 @@ struct MainFeedTableViewSectionHeaderLayout {
|
||||
rUnread.size = unreadCountSize
|
||||
rUnread.origin.x = bounds.maxX - (MainFeedTableViewSectionHeaderLayout.unreadCountMarginRight + unreadCountSize.width)
|
||||
}
|
||||
|
||||
|
||||
// Max Unread Count
|
||||
// We can't reload Section Headers so we don't let the title extend into the (probably) worse case Unread Count area.
|
||||
let maxUnreadCountView = MainFeedUnreadCountView(frame: CGRect.zero)
|
||||
@@ -58,7 +58,7 @@ struct MainFeedTableViewSectionHeaderLayout {
|
||||
|
||||
let labelSizeInfo = MultilineUILabelSizer.size(for: label.text ?? "", font: label.font, numberOfLines: 0, width: Int(floor(labelWidth)))
|
||||
var rLabel = CGRect(x: rLabelx, y: rLabely, width: labelWidth, height: labelSizeInfo.size.height)
|
||||
|
||||
|
||||
// Determine cell height
|
||||
let paddedLabelHeight = rLabel.maxY + UIFontMetrics.default.scaledValue(for: MainFeedTableViewSectionHeaderLayout.verticalPadding)
|
||||
let maxGraphicsHeight = [rUnread, rDisclosure].maxY()
|
||||
@@ -66,7 +66,7 @@ struct MainFeedTableViewSectionHeaderLayout {
|
||||
if cellHeight < MainFeedTableViewSectionHeaderLayout.minRowHeight {
|
||||
cellHeight = MainFeedTableViewSectionHeaderLayout.minRowHeight
|
||||
}
|
||||
|
||||
|
||||
// Center in Cell
|
||||
let newBounds = CGRect(x: bounds.origin.x, y: bounds.origin.y, width: bounds.width, height: cellHeight)
|
||||
if !unreadCountIsHidden {
|
||||
@@ -78,13 +78,13 @@ struct MainFeedTableViewSectionHeaderLayout {
|
||||
if cellHeight == MainFeedTableViewSectionHeaderLayout.minRowHeight {
|
||||
rLabel = MainFeedTableViewCellLayout.centerVertically(rLabel, newBounds)
|
||||
}
|
||||
|
||||
|
||||
// Assign the properties
|
||||
self.height = cellHeight
|
||||
self.unreadCountRect = rUnread
|
||||
self.disclosureButtonRect = rDisclosure
|
||||
self.titleRect = rLabel
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -8,18 +8,18 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
class MainFeedUnreadCountView : UIView {
|
||||
class MainFeedUnreadCountView: UIView {
|
||||
|
||||
var padding: UIEdgeInsets {
|
||||
return UIEdgeInsets(top: 1.0, left: 9.0, bottom: 1.0, right: 9.0)
|
||||
}
|
||||
|
||||
|
||||
let cornerRadius = 8.0
|
||||
let bgColor = AppAssets.controlBackgroundColor
|
||||
var textColor: UIColor {
|
||||
return UIColor.white
|
||||
}
|
||||
|
||||
|
||||
var textAttributes: [NSAttributedString.Key: AnyObject] {
|
||||
let textFont = UIFont.preferredFont(forTextStyle: .caption1).bold()
|
||||
return [NSAttributedString.Key.foregroundColor: textColor, NSAttributedString.Key.font: textFont, NSAttributedString.Key.kern: NSNull()]
|
||||
@@ -33,7 +33,7 @@ class MainFeedUnreadCountView : UIView {
|
||||
setNeedsDisplay()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var unreadCountString: String {
|
||||
return unreadCount < 1 ? "" : "\(unreadCount)"
|
||||
}
|
||||
@@ -45,18 +45,18 @@ class MainFeedUnreadCountView : UIView {
|
||||
super.init(frame: frame)
|
||||
self.isOpaque = false
|
||||
}
|
||||
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
self.isOpaque = false
|
||||
}
|
||||
|
||||
|
||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||
textSizeCache = [Int: CGSize]()
|
||||
contentSizeIsValid = false
|
||||
setNeedsDisplay()
|
||||
}
|
||||
|
||||
|
||||
var contentSize: CGSize {
|
||||
if !contentSizeIsValid {
|
||||
var size = CGSize.zero
|
||||
@@ -70,7 +70,7 @@ class MainFeedUnreadCountView : UIView {
|
||||
}
|
||||
return _contentSize
|
||||
}
|
||||
|
||||
|
||||
// Prevent autolayout from messing around with our frame settings
|
||||
override var intrinsicContentSize: CGSize {
|
||||
return CGSize(width: UIView.noIntrinsicMetric, height: UIView.noIntrinsicMetric)
|
||||
@@ -92,7 +92,7 @@ class MainFeedUnreadCountView : UIView {
|
||||
|
||||
textSizeCache[unreadCount] = size
|
||||
return size
|
||||
|
||||
|
||||
}
|
||||
|
||||
func textRect() -> CGRect {
|
||||
@@ -103,7 +103,7 @@ class MainFeedUnreadCountView : UIView {
|
||||
r.origin.x = (bounds.maxX - padding.right) - r.size.width
|
||||
r.origin.y = padding.top
|
||||
return r
|
||||
|
||||
|
||||
}
|
||||
|
||||
override func draw(_ dirtyRect: CGRect) {
|
||||
@@ -116,8 +116,7 @@ class MainFeedUnreadCountView : UIView {
|
||||
if unreadCount > 0 {
|
||||
unreadCountString.draw(at: textRect().origin, withAttributes: textAttributes)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,25 +12,25 @@ import Account
|
||||
import UniformTypeIdentifiers
|
||||
|
||||
extension MainFeedViewController: UITableViewDragDelegate {
|
||||
|
||||
|
||||
func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
|
||||
guard let node = coordinator.nodeFor(indexPath), let feed = node.representedObject as? Feed else {
|
||||
return [UIDragItem]()
|
||||
}
|
||||
|
||||
|
||||
let data = feed.url.data(using: .utf8)
|
||||
let itemProvider = NSItemProvider()
|
||||
|
||||
|
||||
itemProvider.registerDataRepresentation(forTypeIdentifier: UTType.url.identifier, visibility: .ownProcess) { completion in
|
||||
Task { @MainActor in
|
||||
completion(data, nil)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
let dragItem = UIDragItem(itemProvider: itemProvider)
|
||||
dragItem.localObject = node
|
||||
return [dragItem]
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -12,16 +12,16 @@ import Account
|
||||
import RSTree
|
||||
|
||||
extension MainFeedViewController: UITableViewDropDelegate {
|
||||
|
||||
|
||||
func tableView(_ tableView: UITableView, canHandle session: UIDropSession) -> Bool {
|
||||
return session.localDragSession != nil
|
||||
}
|
||||
|
||||
|
||||
func tableView(_ tableView: UITableView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UITableViewDropProposal {
|
||||
guard let destIndexPath = destinationIndexPath, destIndexPath.section > 0, tableView.hasActiveDrag else {
|
||||
guard let destIndexPath = destinationIndexPath, destIndexPath.section > 0, tableView.hasActiveDrag else {
|
||||
return UITableViewDropProposal(operation: .forbidden)
|
||||
}
|
||||
|
||||
|
||||
guard let destFeed = coordinator.nodeFor(destIndexPath)?.representedObject as? SidebarItem,
|
||||
let destAccount = destFeed.account,
|
||||
let destCell = tableView.cellForRow(at: destIndexPath) else {
|
||||
@@ -48,7 +48,7 @@ extension MainFeedViewController: UITableViewDropDelegate {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
func tableView(_ tableView: UITableView, performDropWith dropCoordinator: UITableViewDropCoordinator) {
|
||||
guard let dragItem = dropCoordinator.items.first?.dragItem,
|
||||
let dragNode = dragItem.localObject as? Node,
|
||||
@@ -56,17 +56,17 @@ extension MainFeedViewController: UITableViewDropDelegate {
|
||||
let destIndexPath = dropCoordinator.destinationIndexPath else {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
let isFolderDrop: Bool = {
|
||||
if coordinator.nodeFor(destIndexPath)?.representedObject is Folder, let propCell = tableView.cellForRow(at: destIndexPath) {
|
||||
return dropCoordinator.session.location(in: propCell).y >= 0
|
||||
}
|
||||
return false
|
||||
}()
|
||||
|
||||
|
||||
// Based on the drop we have to determine a node to start looking for a parent container.
|
||||
let destNode: Node? = {
|
||||
|
||||
|
||||
if isFolderDrop {
|
||||
return coordinator.nodeFor(destIndexPath)
|
||||
} else {
|
||||
@@ -78,7 +78,7 @@ extension MainFeedViewController: UITableViewDropDelegate {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}()
|
||||
|
||||
// Now we start looking for the parent container
|
||||
@@ -90,9 +90,9 @@ extension MainFeedViewController: UITableViewDropDelegate {
|
||||
return coordinator.rootNode.childAtIndex(destIndexPath.section)?.representedObject as? Account
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
guard let destination = destinationContainer, let feed = dragNode.representedObject as? Feed else { return }
|
||||
|
||||
|
||||
if source.account == destination.account {
|
||||
moveFeedInAccount(feed: feed, sourceContainer: source, destinationContainer: destination)
|
||||
} else {
|
||||
@@ -102,7 +102,7 @@ extension MainFeedViewController: UITableViewDropDelegate {
|
||||
|
||||
func moveFeedInAccount(feed: Feed, sourceContainer: Container, destinationContainer: Container) {
|
||||
guard sourceContainer !== destinationContainer else { return }
|
||||
|
||||
|
||||
BatchUpdate.shared.start()
|
||||
sourceContainer.account?.moveFeed(feed, from: sourceContainer, to: destinationContainer) { result in
|
||||
BatchUpdate.shared.end()
|
||||
@@ -114,11 +114,11 @@ extension MainFeedViewController: UITableViewDropDelegate {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func moveFeedBetweenAccounts(feed: Feed, sourceContainer: Container, destinationContainer: Container) {
|
||||
|
||||
|
||||
if let existingFeed = destinationContainer.account?.existingFeed(withURL: feed.url) {
|
||||
|
||||
|
||||
BatchUpdate.shared.start()
|
||||
destinationContainer.account?.addFeed(existingFeed, to: destinationContainer) { result in
|
||||
switch result {
|
||||
@@ -137,9 +137,9 @@ extension MainFeedViewController: UITableViewDropDelegate {
|
||||
self.presentError(error)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
BatchUpdate.shared.start()
|
||||
destinationContainer.account?.createFeed(url: feed.url, name: feed.editedName, container: destinationContainer, validateFeed: false) { result in
|
||||
switch result {
|
||||
@@ -158,9 +158,8 @@ extension MainFeedViewController: UITableViewDropDelegate {
|
||||
self.presentError(error)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ class MainFeedViewController: UITableViewController, UndoableCommandRunner {
|
||||
return
|
||||
}
|
||||
|
||||
var node: Node? = nil
|
||||
var node: Node?
|
||||
if let coordinator = unreadCountProvider as? SceneCoordinator, let feed = coordinator.timelineFeed {
|
||||
node = coordinator.rootNode.descendantNodeRepresentingObject(feed as AnyObject)
|
||||
} else {
|
||||
@@ -249,7 +249,7 @@ class MainFeedViewController: UITableViewController, UndoableCommandRunner {
|
||||
}
|
||||
|
||||
headerView.gestureRecognizers?.removeAll()
|
||||
let tap = UITapGestureRecognizer(target: self, action:#selector(self.toggleSectionHeader(_:)))
|
||||
let tap = UITapGestureRecognizer(target: self, action: #selector(self.toggleSectionHeader(_:)))
|
||||
headerView.addGestureRecognizer(tap)
|
||||
|
||||
// Without this the swipe gesture registers on the cell below
|
||||
@@ -279,7 +279,7 @@ class MainFeedViewController: UITableViewController, UndoableCommandRunner {
|
||||
|
||||
// Set up the delete action
|
||||
let deleteTitle = NSLocalizedString("Delete", comment: "Delete")
|
||||
let deleteAction = UIContextualAction(style: .normal, title: deleteTitle) { [weak self] (action, view, completion) in
|
||||
let deleteAction = UIContextualAction(style: .normal, title: deleteTitle) { [weak self] (_, _, completion) in
|
||||
self?.delete(indexPath: indexPath)
|
||||
completion(true)
|
||||
}
|
||||
@@ -288,7 +288,7 @@ class MainFeedViewController: UITableViewController, UndoableCommandRunner {
|
||||
|
||||
// Set up the rename action
|
||||
let renameTitle = NSLocalizedString("Rename", comment: "Rename")
|
||||
let renameAction = UIContextualAction(style: .normal, title: renameTitle) { [weak self] (action, view, completion) in
|
||||
let renameAction = UIContextualAction(style: .normal, title: renameTitle) { [weak self] (_, _, completion) in
|
||||
self?.rename(indexPath: indexPath)
|
||||
completion(true)
|
||||
}
|
||||
@@ -354,7 +354,7 @@ class MainFeedViewController: UITableViewController, UndoableCommandRunner {
|
||||
return makeFeedContextMenu(indexPath: indexPath, includeDeleteRename: true)
|
||||
} else if feed is Folder {
|
||||
return makeFolderContextMenu(indexPath: indexPath)
|
||||
} else if feed is PseudoFeed {
|
||||
} else if feed is PseudoFeed {
|
||||
return makePseudoFeedContextMenu(indexPath: indexPath)
|
||||
} else {
|
||||
return nil
|
||||
@@ -686,7 +686,7 @@ extension MainFeedViewController: UIContextMenuInteractionDelegate {
|
||||
return nil
|
||||
}
|
||||
|
||||
return UIContextMenuConfiguration(identifier: sectionIndex as NSCopying, previewProvider: nil) { suggestedActions in
|
||||
return UIContextMenuConfiguration(identifier: sectionIndex as NSCopying, previewProvider: nil) { _ in
|
||||
|
||||
var menuElements = [UIMenuElement]()
|
||||
menuElements.append(UIMenu(title: "", options: .displayInline, children: [self.getAccountInfoAction(account: account)]))
|
||||
@@ -890,7 +890,7 @@ private extension MainFeedViewController {
|
||||
}
|
||||
|
||||
func makeFeedContextMenu(indexPath: IndexPath, includeDeleteRename: Bool) -> UIContextMenuConfiguration {
|
||||
return UIContextMenuConfiguration(identifier: MainFeedRowIdentifier(indexPath: indexPath), previewProvider: nil, actionProvider: { [ weak self] suggestedActions in
|
||||
return UIContextMenuConfiguration(identifier: MainFeedRowIdentifier(indexPath: indexPath), previewProvider: nil, actionProvider: { [ weak self] _ in
|
||||
|
||||
guard let self = self else { return nil }
|
||||
|
||||
@@ -935,7 +935,7 @@ private extension MainFeedViewController {
|
||||
}
|
||||
|
||||
func makeFolderContextMenu(indexPath: IndexPath) -> UIContextMenuConfiguration {
|
||||
return UIContextMenuConfiguration(identifier: MainFeedRowIdentifier(indexPath: indexPath), previewProvider: nil, actionProvider: { [weak self] suggestedActions in
|
||||
return UIContextMenuConfiguration(identifier: MainFeedRowIdentifier(indexPath: indexPath), previewProvider: nil, actionProvider: { [weak self] _ in
|
||||
|
||||
guard let self = self else { return nil }
|
||||
|
||||
@@ -962,7 +962,7 @@ private extension MainFeedViewController {
|
||||
return nil
|
||||
}
|
||||
|
||||
return UIContextMenuConfiguration(identifier: MainFeedRowIdentifier(indexPath: indexPath), previewProvider: nil, actionProvider: { suggestedActions in
|
||||
return UIContextMenuConfiguration(identifier: MainFeedRowIdentifier(indexPath: indexPath), previewProvider: nil, actionProvider: { _ in
|
||||
return UIMenu(title: "", children: [markAllAction])
|
||||
})
|
||||
}
|
||||
@@ -973,7 +973,7 @@ private extension MainFeedViewController {
|
||||
}
|
||||
|
||||
let title = NSLocalizedString("Open Home Page", comment: "Open Home Page")
|
||||
let action = UIAction(title: title, image: AppAssets.safariImage) { [weak self] action in
|
||||
let action = UIAction(title: title, image: AppAssets.safariImage) { [weak self] _ in
|
||||
self?.coordinator.showBrowserForFeed(indexPath)
|
||||
}
|
||||
return action
|
||||
@@ -985,7 +985,7 @@ private extension MainFeedViewController {
|
||||
}
|
||||
|
||||
let title = NSLocalizedString("Open Home Page", comment: "Open Home Page")
|
||||
let action = UIAlertAction(title: title, style: .default) { [weak self] action in
|
||||
let action = UIAlertAction(title: title, style: .default) { [weak self] _ in
|
||||
self?.coordinator.showBrowserForFeed(indexPath)
|
||||
completion(true)
|
||||
}
|
||||
@@ -999,7 +999,7 @@ private extension MainFeedViewController {
|
||||
}
|
||||
|
||||
let title = NSLocalizedString("Copy Feed URL", comment: "Copy Feed URL")
|
||||
let action = UIAction(title: title, image: AppAssets.copyImage) { action in
|
||||
let action = UIAction(title: title, image: AppAssets.copyImage) { _ in
|
||||
UIPasteboard.general.url = url
|
||||
}
|
||||
return action
|
||||
@@ -1012,7 +1012,7 @@ private extension MainFeedViewController {
|
||||
}
|
||||
|
||||
let title = NSLocalizedString("Copy Feed URL", comment: "Copy Feed URL")
|
||||
let action = UIAlertAction(title: title, style: .default) { action in
|
||||
let action = UIAlertAction(title: title, style: .default) { _ in
|
||||
UIPasteboard.general.url = url
|
||||
completion(true)
|
||||
}
|
||||
@@ -1027,7 +1027,7 @@ private extension MainFeedViewController {
|
||||
}
|
||||
|
||||
let title = NSLocalizedString("Copy Home Page URL", comment: "Copy Home Page URL")
|
||||
let action = UIAction(title: title, image: AppAssets.copyImage) { action in
|
||||
let action = UIAction(title: title, image: AppAssets.copyImage) { _ in
|
||||
UIPasteboard.general.url = url
|
||||
}
|
||||
return action
|
||||
@@ -1041,7 +1041,7 @@ private extension MainFeedViewController {
|
||||
}
|
||||
|
||||
let title = NSLocalizedString("Copy Home Page URL", comment: "Copy Home Page URL")
|
||||
let action = UIAlertAction(title: title, style: .default) { action in
|
||||
let action = UIAlertAction(title: title, style: .default) { _ in
|
||||
UIPasteboard.general.url = url
|
||||
completion(true)
|
||||
}
|
||||
@@ -1061,8 +1061,7 @@ private extension MainFeedViewController {
|
||||
completion(true)
|
||||
}
|
||||
|
||||
|
||||
let action = UIAlertAction(title: title, style: .default) { [weak self] action in
|
||||
let action = UIAlertAction(title: title, style: .default) { [weak self] _ in
|
||||
MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title, sourceType: contentView, cancelCompletion: cancel) { [weak self] in
|
||||
self?.coordinator.markAllAsRead(Array(articles))
|
||||
completion(true)
|
||||
@@ -1074,7 +1073,7 @@ private extension MainFeedViewController {
|
||||
func deleteAction(indexPath: IndexPath) -> UIAction {
|
||||
let title = NSLocalizedString("Delete", comment: "Delete")
|
||||
|
||||
let action = UIAction(title: title, image: AppAssets.trashImage, attributes: .destructive) { [weak self] action in
|
||||
let action = UIAction(title: title, image: AppAssets.trashImage, attributes: .destructive) { [weak self] _ in
|
||||
self?.delete(indexPath: indexPath)
|
||||
}
|
||||
return action
|
||||
@@ -1082,7 +1081,7 @@ private extension MainFeedViewController {
|
||||
|
||||
func renameAction(indexPath: IndexPath) -> UIAction {
|
||||
let title = NSLocalizedString("Rename", comment: "Rename")
|
||||
let action = UIAction(title: title, image: AppAssets.editImage) { [weak self] action in
|
||||
let action = UIAction(title: title, image: AppAssets.editImage) { [weak self] _ in
|
||||
self?.rename(indexPath: indexPath)
|
||||
}
|
||||
return action
|
||||
@@ -1094,7 +1093,7 @@ private extension MainFeedViewController {
|
||||
}
|
||||
|
||||
let title = NSLocalizedString("Get Info", comment: "Get Info")
|
||||
let action = UIAction(title: title, image: AppAssets.infoImage) { [weak self] action in
|
||||
let action = UIAction(title: title, image: AppAssets.infoImage) { [weak self] _ in
|
||||
self?.coordinator.showFeedInspector(for: feed)
|
||||
}
|
||||
return action
|
||||
@@ -1102,7 +1101,7 @@ private extension MainFeedViewController {
|
||||
|
||||
func getAccountInfoAction(account: Account) -> UIAction {
|
||||
let title = NSLocalizedString("Get Info", comment: "Get Info")
|
||||
let action = UIAction(title: title, image: AppAssets.infoImage) { [weak self] action in
|
||||
let action = UIAction(title: title, image: AppAssets.infoImage) { [weak self] _ in
|
||||
self?.coordinator.showAccountInspector(for: account)
|
||||
}
|
||||
return action
|
||||
@@ -1110,7 +1109,7 @@ private extension MainFeedViewController {
|
||||
|
||||
func deactivateAccountAction(account: Account) -> UIAction {
|
||||
let title = NSLocalizedString("Deactivate", comment: "Deactivate")
|
||||
let action = UIAction(title: title, image: AppAssets.deactivateImage) { action in
|
||||
let action = UIAction(title: title, image: AppAssets.deactivateImage) { _ in
|
||||
account.isActive = false
|
||||
}
|
||||
return action
|
||||
@@ -1122,7 +1121,7 @@ private extension MainFeedViewController {
|
||||
}
|
||||
|
||||
let title = NSLocalizedString("Get Info", comment: "Get Info")
|
||||
let action = UIAlertAction(title: title, style: .default) { [weak self] action in
|
||||
let action = UIAlertAction(title: title, style: .default) { [weak self] _ in
|
||||
self?.coordinator.showFeedInspector(for: feed)
|
||||
completion(true)
|
||||
}
|
||||
@@ -1138,7 +1137,7 @@ private extension MainFeedViewController {
|
||||
|
||||
let localizedMenuText = NSLocalizedString("Mark All as Read in “%@”", comment: "Command")
|
||||
let title = NSString.localizedStringWithFormat(localizedMenuText as NSString, feed.nameForDisplay) as String
|
||||
let action = UIAction(title: title, image: AppAssets.markAllAsReadImage) { [weak self] action in
|
||||
let action = UIAction(title: title, image: AppAssets.markAllAsReadImage) { [weak self] _ in
|
||||
MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title, sourceType: contentView) { [weak self] in
|
||||
if let articles = try? feed.fetchUnreadArticles() {
|
||||
self?.coordinator.markAllAsRead(Array(articles))
|
||||
@@ -1156,7 +1155,7 @@ private extension MainFeedViewController {
|
||||
|
||||
let localizedMenuText = NSLocalizedString("Mark All as Read in “%@”", comment: "Command")
|
||||
let title = NSString.localizedStringWithFormat(localizedMenuText as NSString, account.nameForDisplay) as String
|
||||
let action = UIAction(title: title, image: AppAssets.markAllAsReadImage) { [weak self] action in
|
||||
let action = UIAction(title: title, image: AppAssets.markAllAsReadImage) { [weak self] _ in
|
||||
MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title, sourceType: contentView) { [weak self] in
|
||||
// If you don't have this delay the screen flashes when it executes this code
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
@@ -1170,7 +1169,6 @@ private extension MainFeedViewController {
|
||||
return action
|
||||
}
|
||||
|
||||
|
||||
func rename(indexPath: IndexPath) {
|
||||
guard let feed = coordinator.nodeFor(indexPath)?.representedObject as? SidebarItem else { return }
|
||||
|
||||
@@ -1183,7 +1181,7 @@ private extension MainFeedViewController {
|
||||
alertController.addAction(UIAlertAction(title: cancelTitle, style: .cancel))
|
||||
|
||||
let renameTitle = NSLocalizedString("Rename", comment: "Rename")
|
||||
let renameAction = UIAlertAction(title: renameTitle, style: .default) { [weak self] action in
|
||||
let renameAction = UIAlertAction(title: renameTitle, style: .default) { [weak self] _ in
|
||||
|
||||
guard let name = alertController.textFields?[0].text, !name.isEmpty else {
|
||||
return
|
||||
@@ -1214,7 +1212,7 @@ private extension MainFeedViewController {
|
||||
alertController.addAction(renameAction)
|
||||
alertController.preferredAction = renameAction
|
||||
|
||||
alertController.addTextField() { textField in
|
||||
alertController.addTextField { textField in
|
||||
textField.text = feed.nameForDisplay
|
||||
textField.placeholder = NSLocalizedString("Name", comment: "Name")
|
||||
}
|
||||
@@ -1234,7 +1232,7 @@ private extension MainFeedViewController {
|
||||
title = NSLocalizedString("Delete Folder", comment: "Delete folder")
|
||||
let localizedInformativeText = NSLocalizedString("Are you sure you want to delete the “%@” folder?", comment: "Folder delete text")
|
||||
message = NSString.localizedStringWithFormat(localizedInformativeText as NSString, feed.nameForDisplay) as String
|
||||
} else {
|
||||
} else {
|
||||
title = NSLocalizedString("Delete Feed", comment: "Delete feed")
|
||||
let localizedInformativeText = NSLocalizedString("Are you sure you want to delete the “%@” feed?", comment: "Feed delete text")
|
||||
message = NSString.localizedStringWithFormat(localizedInformativeText as NSString, feed.nameForDisplay) as String
|
||||
@@ -1246,7 +1244,7 @@ private extension MainFeedViewController {
|
||||
alertController.addAction(UIAlertAction(title: cancelTitle, style: .cancel))
|
||||
|
||||
let deleteTitle = NSLocalizedString("Delete", comment: "Delete")
|
||||
let deleteAction = UIAlertAction(title: deleteTitle, style: .destructive) { [weak self] action in
|
||||
let deleteAction = UIAlertAction(title: deleteTitle, style: .destructive) { [weak self] _ in
|
||||
self?.performDelete(indexPath: indexPath)
|
||||
}
|
||||
alertController.addAction(deleteAction)
|
||||
@@ -1284,6 +1282,6 @@ extension MainFeedViewController: UIGestureRecognizerDelegate {
|
||||
return false
|
||||
}
|
||||
let velocity = gestureRecognizer.velocity(in: self.view)
|
||||
return abs(velocity.x) > abs(velocity.y);
|
||||
return abs(velocity.x) > abs(velocity.y)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,10 +10,10 @@ import UIKit
|
||||
import Account
|
||||
|
||||
class RefreshProgressView: UIView {
|
||||
|
||||
|
||||
@IBOutlet weak var progressView: UIProgressView!
|
||||
@IBOutlet weak var label: UILabel!
|
||||
|
||||
|
||||
override func awakeFromNib() {
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(progressDidChange(_:)), name: .combinedRefreshProgressDidChange, object: nil)
|
||||
@@ -24,7 +24,7 @@ class RefreshProgressView: UIView {
|
||||
isAccessibilityElement = true
|
||||
accessibilityTraits = [.updatesFrequently, .notEnabled]
|
||||
}
|
||||
|
||||
|
||||
func update() {
|
||||
if !AccountManager.shared.combinedRefreshProgress.isComplete {
|
||||
progressChanged(animated: false)
|
||||
@@ -50,7 +50,7 @@ class RefreshProgressView: UIView {
|
||||
deinit {
|
||||
NotificationCenter.default.removeObserver(self)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// MARK: Private
|
||||
@@ -68,7 +68,7 @@ private extension RefreshProgressView {
|
||||
if isInViewHierarchy {
|
||||
progressView.setProgress(1, animated: animated)
|
||||
}
|
||||
|
||||
|
||||
func completeLabel() {
|
||||
// Check that there are no pending downloads.
|
||||
if AccountManager.shared.combinedRefreshProgress.isComplete {
|
||||
@@ -101,7 +101,7 @@ private extension RefreshProgressView {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func updateRefreshLabel() {
|
||||
if let accountLastArticleFetchEndTime = AccountManager.shared.lastArticleFetchEndTime {
|
||||
|
||||
@@ -131,5 +131,5 @@ private extension RefreshProgressView {
|
||||
self?.scheduleUpdateRefreshLabel()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user