mirror of
https://github.com/Ranchero-Software/NetNewsWire
synced 2025-08-12 06:26:36 +00:00
Rename MainFeed and MainTimeline folders to Sidebar and Timeline.
This commit is contained in:
243
iOS/MainWindow/Sidebar/Cell/MainFeedTableViewCell.swift
Normal file
243
iOS/MainWindow/Sidebar/Cell/MainFeedTableViewCell.swift
Normal file
@@ -0,0 +1,243 @@
|
||||
//
|
||||
// MainFeedTableViewCell.swift
|
||||
// NetNewsWire
|
||||
//
|
||||
// Created by Brent Simmons on 8/1/15.
|
||||
// Copyright © 2015 Ranchero Software, LLC. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import RSCore
|
||||
import Account
|
||||
import RSTree
|
||||
|
||||
protocol MainFeedTableViewCellDelegate: AnyObject {
|
||||
func mainFeedTableViewCellDisclosureDidToggle(_ sender: MainFeedTableViewCell, expanding: Bool)
|
||||
}
|
||||
|
||||
final class MainFeedTableViewCell: VibrantTableViewCell {
|
||||
|
||||
weak var delegate: MainFeedTableViewCellDelegate?
|
||||
|
||||
override var accessibilityLabel: String? {
|
||||
get {
|
||||
if unreadCount > 0 {
|
||||
let unreadLabel = NSLocalizedString("unread", comment: "Unread label for accessibility")
|
||||
return "\(name) \(unreadCount) \(unreadLabel)"
|
||||
} else {
|
||||
return name
|
||||
}
|
||||
}
|
||||
set {
|
||||
}
|
||||
}
|
||||
|
||||
var iconImage: IconImage? {
|
||||
didSet {
|
||||
iconView.iconImage = iconImage
|
||||
}
|
||||
}
|
||||
|
||||
var isDisclosureAvailable = false {
|
||||
didSet {
|
||||
if isDisclosureAvailable != oldValue {
|
||||
setNeedsLayout()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var isSeparatorShown = true {
|
||||
didSet {
|
||||
if isSeparatorShown != oldValue {
|
||||
if isSeparatorShown {
|
||||
showView(bottomSeparatorView)
|
||||
} else {
|
||||
hideView(bottomSeparatorView)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var unreadCount: Int {
|
||||
get {
|
||||
return unreadCountView.unreadCount
|
||||
}
|
||||
set {
|
||||
if unreadCountView.unreadCount != newValue {
|
||||
unreadCountView.unreadCount = newValue
|
||||
unreadCountView.isHidden = (newValue < 1)
|
||||
setNeedsLayout()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var name: String {
|
||||
get {
|
||||
return titleView.text ?? ""
|
||||
}
|
||||
set {
|
||||
if titleView.text != newValue {
|
||||
titleView.text = newValue
|
||||
setNeedsLayout()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private let titleView: UILabel = {
|
||||
let label = NonIntrinsicLabel()
|
||||
label.numberOfLines = 0
|
||||
label.allowsDefaultTighteningForTruncation = false
|
||||
label.adjustsFontForContentSizeCategory = true
|
||||
label.lineBreakMode = .byTruncatingTail
|
||||
label.font = .preferredFont(forTextStyle: .body)
|
||||
return label
|
||||
}()
|
||||
|
||||
private let iconView = IconView()
|
||||
|
||||
private let bottomSeparatorView: UIView = {
|
||||
let view = UIView()
|
||||
view.backgroundColor = UIColor.separator
|
||||
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
|
||||
|
||||
UIView.animate(withDuration: duration) {
|
||||
if self.isDisclosureExpanded {
|
||||
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?.imageView?.transform = CGAffineTransform(rotationAngle: 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 = AppColor.vibrantText
|
||||
} else {
|
||||
if let preferredColor = iconImage?.preferredColor {
|
||||
iconTintColor = UIColor(cgColor: preferredColor)
|
||||
} else {
|
||||
iconTintColor = AppColor.secondaryAccent
|
||||
}
|
||||
}
|
||||
|
||||
if animated {
|
||||
UIView.animate(withDuration: Self.duration) {
|
||||
self.iconView.tintColor = iconTintColor
|
||||
}
|
||||
} else {
|
||||
self.iconView.tintColor = iconTintColor
|
||||
}
|
||||
|
||||
updateLabelVibrancy(titleView, color: labelColor, animated: animated)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private extension MainFeedTableViewCell {
|
||||
|
||||
func commonInit() {
|
||||
addSubviewAtInit(unreadCountView)
|
||||
addSubviewAtInit(iconView)
|
||||
addSubviewAtInit(titleView)
|
||||
addDisclosureView()
|
||||
addSubviewAtInit(bottomSeparatorView)
|
||||
}
|
||||
|
||||
func addDisclosureView() {
|
||||
disclosureButton = NonIntrinsicButton(type: .roundedRect)
|
||||
disclosureButton!.addTarget(self, action: #selector(buttonPressed(_:)), for: UIControl.Event.touchUpInside)
|
||||
disclosureButton?.setImage(AppImage.disclosure, for: .normal)
|
||||
disclosureButton?.tintColor = AppColor.controlBackground
|
||||
disclosureButton?.imageView?.contentMode = .center
|
||||
disclosureButton?.imageView?.clipsToBounds = false
|
||||
disclosureButton?.addInteraction(UIPointerInteraction())
|
||||
addSubviewAtInit(disclosureButton!)
|
||||
}
|
||||
|
||||
func addSubviewAtInit(_ view: UIView) {
|
||||
addSubview(view)
|
||||
view.translatesAutoresizingMaskIntoConstraints = false
|
||||
}
|
||||
|
||||
func layoutWith(_ layout: MainFeedTableViewCellLayout) {
|
||||
iconView.setFrameIfNotEqual(layout.faviconRect)
|
||||
titleView.setFrameIfNotEqual(layout.titleRect)
|
||||
unreadCountView.setFrameIfNotEqual(layout.unreadCountRect)
|
||||
disclosureButton?.setFrameIfNotEqual(layout.disclosureButtonRect)
|
||||
disclosureButton?.isHidden = !isDisclosureAvailable
|
||||
bottomSeparatorView.setFrameIfNotEqual(layout.separatorRect)
|
||||
}
|
||||
|
||||
func hideView(_ view: UIView) {
|
||||
if !view.isHidden {
|
||||
view.isHidden = true
|
||||
}
|
||||
}
|
||||
|
||||
func showView(_ view: UIView) {
|
||||
if view.isHidden {
|
||||
view.isHidden = false
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user