diff --git a/iOS/AppAssets.swift b/iOS/AppAssets.swift index 2a5ed0659..160e5bf2e 100644 --- a/iOS/AppAssets.swift +++ b/iOS/AppAssets.swift @@ -98,9 +98,13 @@ struct AppAssets { }() static var disclosureImage: UIImage = { - return UIImage(named: "disclosure")! + return UIImage(systemName: "chevron.right")! }() + static func disclosureImage(size: CGFloat, weight: UIImage.SymbolWeight) -> UIImage { + return UIImage(systemName: "chevron.right", withConfiguration: UIImage.SymbolConfiguration(pointSize: size, weight: weight))! + } + static var contextMenuReddit: UIImage = { return UIImage(named: "contextMenuReddit")! }() diff --git a/iOS/Base.lproj/Main.storyboard b/iOS/Base.lproj/Main.storyboard index 44386a8f9..4ccb0e39a 100644 --- a/iOS/Base.lproj/Main.storyboard +++ b/iOS/Base.lproj/Main.storyboard @@ -1,9 +1,8 @@ - + - - + @@ -13,13 +12,13 @@ - + @@ -113,14 +112,14 @@ - - - + + + - + @@ -166,7 +165,7 @@ - + @@ -316,26 +315,26 @@ - - + diff --git a/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift b/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift index bf9c5a8da..ac55c60dc 100644 --- a/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift +++ b/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift @@ -45,6 +45,14 @@ class MasterFeedTableViewCell : VibrantTableViewCell { } } + var itemIsInFolder = false { + didSet { + if itemIsInFolder != oldValue { + setNeedsLayout() + } + } + } + var isSeparatorShown = true { didSet { if isSeparatorShown != oldValue { @@ -136,14 +144,19 @@ class MasterFeedTableViewCell : VibrantTableViewCell { } override func sizeThatFits(_ size: CGSize) -> CGSize { - let layout = MasterFeedTableViewCellLayout(cellWidth: bounds.size.width, insets: safeAreaInsets, label: titleView, unreadCountView: unreadCountView, showingEditingControl: isShowingEditControl, indent: indentationLevel == 1, shouldShowDisclosure: isDisclosureAvailable) + let layout = MasterFeedTableViewCellLayout(cellWidth: bounds.size.width, insets: safeAreaInsets, label: titleView, unreadCountView: unreadCountView, showingEditingControl: isShowingEditControl, indent: indentationLevel == 1, shouldShowDisclosure: isDisclosureAvailable, itemIsInFolder: itemIsInFolder) return CGSize(width: bounds.width, height: layout.height) } override func layoutSubviews() { super.layoutSubviews() - let layout = MasterFeedTableViewCellLayout(cellWidth: bounds.size.width, insets: safeAreaInsets, label: titleView, unreadCountView: unreadCountView, showingEditingControl: isShowingEditControl, indent: indentationLevel == 1, shouldShowDisclosure: isDisclosureAvailable) + let layout = MasterFeedTableViewCellLayout(cellWidth: bounds.size.width, insets: safeAreaInsets, label: titleView, unreadCountView: unreadCountView, showingEditingControl: isShowingEditControl, indent: indentationLevel == 1, shouldShowDisclosure: isDisclosureAvailable, itemIsInFolder: itemIsInFolder) layoutWith(layout) + if isDisclosureAvailable { + titleView.font = .preferredFont(forTextStyle: .body).bold() + } else { + titleView.font = .preferredFont(forTextStyle: .body) + } } @objc func buttonPressed(_ sender: UIButton) { @@ -193,8 +206,8 @@ private extension MasterFeedTableViewCell { func addDisclosureView() { disclosureButton = NonIntrinsicButton(type: .roundedRect) disclosureButton!.addTarget(self, action: #selector(buttonPressed(_:)), for: UIControl.Event.touchUpInside) - disclosureButton?.setImage(AppAssets.disclosureImage, for: .normal) - disclosureButton?.tintColor = AppAssets.controlBackgroundColor + disclosureButton?.setImage(AppAssets.disclosureImage(size: 16, weight: .regular), for: .normal) + disclosureButton?.tintColor = AppAssets.secondaryAccentColor disclosureButton?.imageView?.contentMode = .center disclosureButton?.imageView?.clipsToBounds = false disclosureButton?.addInteraction(UIPointerInteraction()) diff --git a/iOS/MasterFeed/Cell/MasterFeedTableViewCellLayout.swift b/iOS/MasterFeed/Cell/MasterFeedTableViewCellLayout.swift index 4ff894978..2c8b9d6a4 100644 --- a/iOS/MasterFeed/Cell/MasterFeedTableViewCellLayout.swift +++ b/iOS/MasterFeed/Cell/MasterFeedTableViewCellLayout.swift @@ -11,13 +11,13 @@ import RSCore struct MasterFeedTableViewCellLayout { - private static let indentWidth = CGFloat(integerLiteral: 42) + private static let indentWidth = CGFloat(integerLiteral: 15) private static let editingControlIndent = CGFloat(integerLiteral: 40) private static let imageSize = CGSize(width: 24, height: 24) private static let imageMarginRight = CGFloat(integerLiteral: 11) private static let labelMarginRight = CGFloat(integerLiteral: 8) private static let unreadCountMarginRight = CGFloat(integerLiteral: 16) - private static let disclosureButtonSize = CGSize(width: 44, height: 44) + private static let disclosureButtonSize = CGSize(width: 55, height: 44) private static let verticalPadding = CGFloat(integerLiteral: 11) private static let minRowHeight = CGFloat(integerLiteral: 44) @@ -32,7 +32,7 @@ struct MasterFeedTableViewCellLayout { let height: CGFloat - init(cellWidth: CGFloat, insets: UIEdgeInsets, label: UILabel, unreadCountView: MasterFeedUnreadCountView, showingEditingControl: Bool, indent: Bool, shouldShowDisclosure: Bool) { + init(cellWidth: CGFloat, insets: UIEdgeInsets, label: UILabel, unreadCountView: MasterFeedUnreadCountView, showingEditingControl: Bool, indent: Bool, shouldShowDisclosure: Bool, itemIsInFolder: Bool) { var initialIndent = insets.left if indent { @@ -54,7 +54,12 @@ struct MasterFeedTableViewCellLayout { let y = UIFontMetrics.default.scaledValue(for: MasterFeedTableViewCellLayout.verticalPadding) + label.font.lineHeight / 2.0 - MasterFeedTableViewCellLayout.imageSize.height / 2.0 - rFavicon = CGRect(x: x, y: y, width: MasterFeedTableViewCellLayout.imageSize.width, height: MasterFeedTableViewCellLayout.imageSize.height) + if itemIsInFolder { + rFavicon = CGRect(x: x + MasterFeedTableViewCellLayout.disclosureButtonSize.width - (MasterFeedTableViewCellLayout.imageSize.width / 2), y: y, width: MasterFeedTableViewCellLayout.imageSize.width, height: MasterFeedTableViewCellLayout.imageSize.height) + } else { + rFavicon = CGRect(x: x, y: y, width: MasterFeedTableViewCellLayout.imageSize.width, height: MasterFeedTableViewCellLayout.imageSize.height) + } + } // Unread Count @@ -68,9 +73,9 @@ struct MasterFeedTableViewCellLayout { } // Title - var rLabelx = insets.left + MasterFeedTableViewCellLayout.disclosureButtonSize.width - if !shouldShowDisclosure { - rLabelx = rLabelx + MasterFeedTableViewCellLayout.imageSize.width + MasterFeedTableViewCellLayout.imageMarginRight + var rLabelx = MasterFeedTableViewCellLayout.disclosureButtonSize.width + if itemIsInFolder { + rLabelx += MasterFeedTableViewCellLayout.disclosureButtonSize.width - (rFavicon.width / 2) } let rLabely = UIFontMetrics.default.scaledValue(for: MasterFeedTableViewCellLayout.verticalPadding) @@ -127,6 +132,7 @@ struct MasterFeedTableViewCellLayout { let separatorInset = MasterFeedTableViewCellLayout.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 diff --git a/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeader.swift b/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeader.swift index ee9cc296b..a2aff10d4 100644 --- a/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeader.swift +++ b/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeader.swift @@ -19,12 +19,7 @@ class MasterFeedTableViewSectionHeader: UITableViewHeaderFooterView { override var accessibilityLabel: String? { set {} get { - if unreadCount > 0 { - let unreadLabel = NSLocalizedString("unread", comment: "Unread label for accessiblity") - return "\(name) \(unreadCount) \(unreadLabel) \(expandedStateMessage) " - } else { - return "\(name) \(expandedStateMessage) " - } + return "\(name) \(expandedStateMessage)" } } @@ -38,19 +33,6 @@ class MasterFeedTableViewSectionHeader: UITableViewHeaderFooterView { } } - var unreadCount: Int { - get { - return unreadCountView.unreadCount - } - set { - if unreadCountView.unreadCount != newValue { - unreadCountView.unreadCount = newValue - updateUnreadCountView() - setNeedsLayout() - } - } - } - var name: String { get { return titleView.text ?? "" @@ -66,7 +48,6 @@ class MasterFeedTableViewSectionHeader: UITableViewHeaderFooterView { var disclosureExpanded = false { didSet { updateExpandedState(animate: true) - updateUnreadCountView() } } @@ -77,7 +58,7 @@ class MasterFeedTableViewSectionHeader: UITableViewHeaderFooterView { label.numberOfLines = 0 label.allowsDefaultTighteningForTruncation = false label.adjustsFontForContentSizeCategory = true - label.font = .preferredFont(forTextStyle: .body) + label.font = UIFont.systemFont(ofSize: UIFont.preferredFont(forTextStyle: .title2).pointSize, weight: .bold) return label }() @@ -85,8 +66,8 @@ class MasterFeedTableViewSectionHeader: UITableViewHeaderFooterView { private lazy var disclosureButton: UIButton = { let button = NonIntrinsicButton() - button.tintColor = UIColor.tertiaryLabel - button.setImage(AppAssets.disclosureImage, for: .normal) + button.tintColor = AppAssets.secondaryAccentColor + button.setImage(AppAssets.disclosureImage(size: 14, weight: .bold), for: .normal) button.contentMode = .center button.addInteraction(UIPointerInteraction()) button.addTarget(self, action: #selector(toggleDisclosure), for: .touchUpInside) @@ -95,13 +76,13 @@ class MasterFeedTableViewSectionHeader: UITableViewHeaderFooterView { private let topSeparatorView: UIView = { let view = UIView() - view.backgroundColor = UIColor.separator + view.backgroundColor = UIColor.clear return view }() private let bottomSeparatorView: UIView = { let view = UIView() - view.backgroundColor = UIColor.separator + view.backgroundColor = UIColor.clear return view }() @@ -139,7 +120,6 @@ private extension MasterFeedTableViewSectionHeader { } func commonInit() { - addSubviewAtInit(unreadCountView) addSubviewAtInit(titleView) addSubviewAtInit(disclosureButton) updateExpandedState(animate: false) @@ -169,18 +149,6 @@ private extension MasterFeedTableViewSectionHeader { } }) } - - func updateUnreadCountView() { - if !disclosureExpanded && unreadCount > 0 { - UIView.animate(withDuration: 0.3) { - self.unreadCountView.alpha = 1 - } - } else { - UIView.animate(withDuration: 0.3) { - self.unreadCountView.alpha = 0 - } - } - } func addSubviewAtInit(_ view: UIView) { contentView.addSubview(view) @@ -200,7 +168,7 @@ private extension MasterFeedTableViewSectionHeader { func addBackgroundView() { self.backgroundView = UIView(frame: self.bounds) - self.backgroundView?.backgroundColor = AppAssets.sectionHeaderColor + self.backgroundView?.backgroundColor = .clear } } diff --git a/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeaderLayout.swift b/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeaderLayout.swift index 1421e16f0..60748bb82 100644 --- a/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeaderLayout.swift +++ b/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeaderLayout.swift @@ -12,7 +12,7 @@ import RSCore struct MasterFeedTableViewSectionHeaderLayout { private static let labelMarginRight = CGFloat(integerLiteral: 8) - private static let unreadCountMarginRight = CGFloat(integerLiteral: 16) + private static let unreadCountMarginRight = CGFloat(integerLiteral: 0) private static let disclosureButtonSize = CGSize(width: 44, height: 44) private static let verticalPadding = CGFloat(integerLiteral: 11) @@ -31,7 +31,7 @@ struct MasterFeedTableViewSectionHeaderLayout { // Disclosure Button var rDisclosure = CGRect.zero rDisclosure.size = MasterFeedTableViewSectionHeaderLayout.disclosureButtonSize - rDisclosure.origin.x = bounds.origin.x + rDisclosure.origin.x = bounds.maxX - rDisclosure.size.width // Unread Count let unreadCountSize = unreadCountView.contentSize @@ -40,7 +40,7 @@ struct MasterFeedTableViewSectionHeaderLayout { var rUnread = CGRect.zero if !unreadCountIsHidden { rUnread.size = unreadCountSize - rUnread.origin.x = bounds.maxX - (MasterFeedTableViewSectionHeaderLayout.unreadCountMarginRight + unreadCountSize.width) + rUnread.origin.x = bounds.maxX - (MasterFeedTableViewSectionHeaderLayout.unreadCountMarginRight + unreadCountSize.width + rDisclosure.size.width) } // Max Unread Count @@ -50,7 +50,7 @@ struct MasterFeedTableViewSectionHeaderLayout { let maxUnreadCountSize = maxUnreadCountView.contentSize // Title - let rLabelx = insets.left + MasterFeedTableViewSectionHeaderLayout.disclosureButtonSize.width + let rLabelx = 15.0 let rLabely = UIFontMetrics.default.scaledValue(for: MasterFeedTableViewSectionHeaderLayout.verticalPadding) var labelWidth = CGFloat.zero diff --git a/iOS/MasterFeed/MasterFeedViewController.swift b/iOS/MasterFeed/MasterFeedViewController.swift index c61d6d329..ea5893150 100644 --- a/iOS/MasterFeed/MasterFeedViewController.swift +++ b/iOS/MasterFeed/MasterFeedViewController.swift @@ -99,13 +99,7 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner { return } - if let account = unreadCountProvider as? Account { - if let node = coordinator.rootNode.childNodeRepresentingObject(account) { - let sectionIndex = coordinator.rootNode.indexOfChild(node)! - if let headerView = tableView.headerView(forSection: sectionIndex) as? MasterFeedTableViewSectionHeader { - headerView.unreadCount = account.unreadCount - } - } + if let _ = unreadCountProvider as? Account { return } @@ -203,11 +197,7 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner { return headerView } - if let account = sectionNode.representedObject as? Account { - headerView.unreadCount = account.unreadCount - } else { - headerView.unreadCount = 0 - } + headerView.tag = section headerView.disclosureExpanded = coordinator.isExpanded(sectionNode) @@ -739,7 +729,7 @@ private extension MasterFeedViewController { let unreadCountView = MasterFeedUnreadCountView() unreadCountView.unreadCount = 10 - let layout = MasterFeedTableViewCellLayout(cellWidth: tableView.bounds.size.width, insets: tableView.safeAreaInsets, label: titleLabel, unreadCountView: unreadCountView, showingEditingControl: false, indent: false, shouldShowDisclosure: false) + let layout = MasterFeedTableViewCellLayout(cellWidth: tableView.bounds.size.width, insets: tableView.safeAreaInsets, label: titleLabel, unreadCountView: unreadCountView, showingEditingControl: false, indent: false, shouldShowDisclosure: false, itemIsInFolder: false) tableView.estimatedRowHeight = layout.height } @@ -763,6 +753,16 @@ private extension MasterFeedViewController { if let feed = node.representedObject as? Feed { cell.name = feed.nameForDisplay cell.unreadCount = feed.unreadCount + cell.itemIsInFolder = false + if let account = feed.account, let folders = account.folders { + for folder in folders { + if folder.objectIsChild(node.representedObject) { + cell.itemIsInFolder = true + break + } + } + } + } configureIcon(cell, indexPath) diff --git a/iOS/UIKit Extensions/InteractiveNavigationController.swift b/iOS/UIKit Extensions/InteractiveNavigationController.swift index eb939fc3d..2737cf5d1 100644 --- a/iOS/UIKit Extensions/InteractiveNavigationController.swift +++ b/iOS/UIKit Extensions/InteractiveNavigationController.swift @@ -46,20 +46,26 @@ private extension InteractiveNavigationController { func configure() { isToolbarHidden = false - let navigationStandardAppearance = UINavigationBarAppearance() - navigationStandardAppearance.titleTextAttributes = [.foregroundColor: UIColor.label] - navigationStandardAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.label] - navigationBar.standardAppearance = navigationStandardAppearance + // Standard appearance with system background + let standardAppearance = UINavigationBarAppearance() + standardAppearance.backgroundColor = .clear + standardAppearance.shadowColor = nil - let scrollEdgeStandardAppearance = UINavigationBarAppearance() - scrollEdgeStandardAppearance.backgroundColor = .systemBackground - navigationBar.scrollEdgeAppearance = scrollEdgeStandardAppearance + let scrollEdgeAppearance = UINavigationBarAppearance() + scrollEdgeAppearance.backgroundColor = .systemBackground + scrollEdgeAppearance.shadowColor = nil + + navigationBar.standardAppearance = standardAppearance + navigationBar.scrollEdgeAppearance = scrollEdgeAppearance + navigationBar.compactAppearance = standardAppearance + navigationBar.compactScrollEdgeAppearance = scrollEdgeAppearance - navigationBar.tintColor = AppAssets.primaryAccentColor let toolbarAppearance = UIToolbarAppearance() + toolbarAppearance.shadowColor = nil toolbar.standardAppearance = toolbarAppearance - toolbar.compactAppearance = toolbarAppearance + toolbar.compactAppearance = nil + toolbar.scrollEdgeAppearance = nil toolbar.tintColor = AppAssets.primaryAccentColor }