Merge branch 'mac-candidate' into main

This commit is contained in:
Maurice Parker 2020-08-19 21:03:55 -05:00
commit b0e7ae0324
21 changed files with 125 additions and 136 deletions

View File

@ -237,14 +237,12 @@ struct AppAssets {
}
}()
static var timelineStar: RSImage! = {
if #available(macOS 11.0, *) {
let image = NSImage(systemSymbolName: "star.fill", accessibilityDescription: nil)!
let coloredImage = image.tinted(with: NSColor(named: "StarColor")!)
return coloredImage
} else {
return RSImage(named: "timelineStar")
}
static var timelineStarSelected: RSImage! = {
return RSImage(named: "timelineStar")?.tinted(with: .white)
}()
static var timelineStarUnselected: RSImage! = {
return RSImage(named: "timelineStar")?.tinted(with: starColor)
}()
static var todayFeedImage: IconImage = {
@ -285,8 +283,8 @@ struct AppAssets {
return RSImage(named: "swipeMarkUnstarred")!
}()
static var swipeMarkUnstarredColor: NSColor = {
return NSColor(named: NSColor.Name("swipeMarkUnstarredColor"))!
static var starColor: NSColor = {
return NSColor(named: NSColor.Name("StarColor"))!
}()
static func image(for accountType: AccountType) -> NSImage? {

View File

@ -16,7 +16,7 @@
<windowCollectionBehavior key="collectionBehavior" fullScreenPrimary="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="480" height="270"/>
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
<toolbar key="toolbar" implicitIdentifier="3C53153F-2D4C-441B-B551-D28ADBB5869C" explicitIdentifier="MainWindowToolbar" displayMode="iconOnly" sizeMode="regular" id="463-wM-1ZF">
<allowedToolbarItems>
<toolbarItem implicitItemIdentifier="NSToolbarSpaceItem" id="d4b-Sp-qek"/>
@ -298,39 +298,18 @@
<scene sceneID="Yae-mu-VsH">
<objects>
<viewController id="XML-A3-pDn" userLabel="Sidebar View Controller" customClass="SidebarViewController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" wantsLayer="YES" id="bJZ-bH-vgc">
<rect key="frame" x="0.0" y="0.0" width="206" height="468"/>
<view key="view" wantsLayer="YES" misplaced="YES" id="bJZ-bH-vgc">
<rect key="frame" x="0.0" y="0.0" width="206" height="531"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<visualEffectView blendingMode="behindWindow" material="appearanceBased" state="followsWindowActiveState" translatesAutoresizingMaskIntoConstraints="NO" id="977-L4-4ey">
<rect key="frame" x="0.0" y="393" width="206" height="23"/>
<subviews>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="eZS-8K-qiN">
<rect key="frame" x="181" y="5" width="13" height="13"/>
<buttonCell key="cell" type="bevel" bezelStyle="rounded" image="filterInactive" imagePosition="overlaps" alignment="center" imageScaling="proportionallyDown" inset="2" id="5QJ-Ja-Gng">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<color key="contentTintColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
<connections>
<action selector="toggleReadFeedsFilter:" target="Jih-JO-hIE" id="hbr-xR-smq"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="23" id="Ax2-oO-NTV"/>
<constraint firstAttribute="trailing" secondItem="eZS-8K-qiN" secondAttribute="trailing" constant="12" id="CFy-rz-Otf"/>
<constraint firstItem="eZS-8K-qiN" firstAttribute="top" secondItem="977-L4-4ey" secondAttribute="top" constant="5" id="M0q-C7-z10"/>
</constraints>
</visualEffectView>
<scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="28" horizontalPageScroll="10" verticalLineScroll="28" verticalPageScroll="10" hasHorizontalScroller="NO" horizontalScrollElasticity="none" translatesAutoresizingMaskIntoConstraints="NO" id="cJj-Wv-9ep">
<rect key="frame" x="0.0" y="0.0" width="206" height="393"/>
<rect key="frame" x="0.0" y="0.0" width="206" height="1098"/>
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="2eU-Wz-F9g">
<rect key="frame" x="0.0" y="0.0" width="206" height="393"/>
<rect key="frame" x="0.0" y="0.0" width="206" height="1098"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<outlineView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="firstColumnOnly" tableStyle="sourceList" selectionHighlightStyle="sourceList" columnReordering="NO" columnResizing="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="28" rowSizeStyle="systemDefault" viewBased="YES" floatsGroupRows="NO" indentationPerLevel="13" outlineTableColumn="ih9-mJ-EA7" id="cnV-kg-Dn2" customClass="SidebarOutlineView" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="206" height="393"/>
<outlineView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="firstColumnOnly" selectionHighlightStyle="sourceList" columnReordering="NO" columnResizing="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="28" rowSizeStyle="systemDefault" viewBased="YES" floatsGroupRows="NO" indentationPerLevel="13" outlineTableColumn="ih9-mJ-EA7" id="cnV-kg-Dn2" customClass="SidebarOutlineView" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="206" height="1098"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="3" height="0.0"/>
<color key="backgroundColor" name="_sourceListBackgroundColor" catalog="System" colorSpace="catalog"/>
@ -408,7 +387,7 @@
</constraints>
</progressIndicator>
<textField hidden="YES" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="iyL-pW-cT6">
<rect key="frame" x="62" y="6" width="106" height="16"/>
<rect key="frame" x="62" y="6" width="126" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Label" id="dVE-XG-mlU">
<font key="font" metaFont="system"/>
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
@ -437,22 +416,19 @@
<constraints>
<constraint firstItem="HZs-Zf-G8s" firstAttribute="top" secondItem="cJj-Wv-9ep" secondAttribute="bottom" id="0Zg-oW-o7U"/>
<constraint firstItem="cJj-Wv-9ep" firstAttribute="leading" secondItem="bJZ-bH-vgc" secondAttribute="leading" id="5Rs-9M-TKq"/>
<constraint firstItem="977-L4-4ey" firstAttribute="leading" secondItem="j0H-G3-rg2" secondAttribute="leading" id="8Oc-5V-xgb"/>
<constraint firstItem="cJj-Wv-9ep" firstAttribute="top" secondItem="977-L4-4ey" secondAttribute="bottom" id="FPj-rG-6Lw"/>
<constraint firstItem="mQg-Jg-Bfh" firstAttribute="trailing" secondItem="iyL-pW-cT6" secondAttribute="trailing" constant="20" id="Mnm-9S-Qpm"/>
<constraint firstItem="cJj-Wv-9ep" firstAttribute="top" secondItem="bJZ-bH-vgc" secondAttribute="top" id="A7C-VI-drt"/>
<constraint firstAttribute="trailing" secondItem="iyL-pW-cT6" secondAttribute="trailing" constant="20" id="Mnm-9S-Qpm"/>
<constraint firstAttribute="bottom" secondItem="HZs-Zf-G8s" secondAttribute="bottom" constant="-28" id="UN9-Wa-uxb"/>
<constraint firstItem="977-L4-4ey" firstAttribute="top" secondItem="j0H-G3-rg2" secondAttribute="top" id="eBr-dj-I25"/>
<constraint firstAttribute="trailing" secondItem="HZs-Zf-G8s" secondAttribute="trailing" id="iNE-nb-QEB"/>
<constraint firstItem="HZs-Zf-G8s" firstAttribute="leading" secondItem="bJZ-bH-vgc" secondAttribute="leading" id="tPp-xB-CgB"/>
<constraint firstAttribute="trailing" secondItem="cJj-Wv-9ep" secondAttribute="trailing" id="vo7-3F-Fd3"/>
<constraint firstItem="977-L4-4ey" firstAttribute="trailing" secondItem="j0H-G3-rg2" secondAttribute="trailing" id="wWv-I7-qKm"/>
<constraint firstAttribute="trailing" secondItem="j0H-G3-rg2" secondAttribute="trailing" id="wWv-I7-qKm"/>
</constraints>
<viewLayoutGuide key="safeArea" id="j0H-G3-rg2"/>
<viewLayoutGuide key="layoutMargins" id="mQg-Jg-Bfh"/>
</view>
<connections>
<outlet property="outlineView" destination="cnV-kg-Dn2" id="FVf-OT-E3h"/>
<outlet property="readFilteredButton" destination="eZS-8K-qiN" id="DDa-Hl-TSh"/>
</connections>
</viewController>
<customObject id="Jih-JO-hIE" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
@ -495,24 +471,25 @@
</constraints>
</visualEffectView>
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="lSU-OC-sEC">
<rect key="frame" x="4" y="123" width="49" height="19"/>
<rect key="frame" x="8" y="123" width="51" height="19"/>
<constraints>
<constraint firstAttribute="height" constant="18" id="DoO-KI-ena"/>
</constraints>
<popUpButtonCell key="cell" type="recessed" title="Sort" bezelStyle="recessed" alignment="center" lineBreakMode="truncatingTail" borderStyle="border" tag="1" imageScaling="proportionallyDown" inset="2" pullsDown="YES" id="bl0-6I-cH2">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="controlContent" size="11"/>
<font key="font" metaFont="smallSystemBold"/>
<menu key="menu" id="dN0-S2-uqU">
<items>
<menuItem title="Sort" tag="1" hidden="YES" id="4BZ-ya-evy">
<attributedString key="attributedTitle"/>
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="Newest To Oldest" state="on" tag="2" id="40c-kt-vhO">
<menuItem title="Newest Article on Top" state="on" tag="2" id="40c-kt-vhO">
<connections>
<action selector="sortByNewestArticleOnTop:" target="Ebq-4s-EwK" id="vYg-MZ-zve"/>
</connections>
</menuItem>
<menuItem title="Oldest To Newest" tag="3" id="sOF-Ez-vIL">
<menuItem title="Oldest Article on Top" tag="3" id="sOF-Ez-vIL">
<connections>
<action selector="sortByOldestArticleOnTop:" target="Ebq-4s-EwK" id="KFG-M7-blB"/>
</connections>
@ -528,7 +505,7 @@
</popUpButtonCell>
</popUpButton>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="iA5-go-AO0">
<rect key="frame" x="425" y="128" width="13" height="13"/>
<rect key="frame" x="425" y="127" width="13" height="13"/>
<buttonCell key="cell" type="bevel" bezelStyle="rounded" image="filterInactive" imagePosition="overlaps" alignment="center" imageScaling="proportionallyDown" inset="2" id="j7d-36-DO5">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@ -543,16 +520,17 @@
</customView>
</subviews>
<constraints>
<constraint firstItem="Zpk-pq-9nW" firstAttribute="top" secondItem="PdS-jL-yH1" secondAttribute="bottom" id="2dy-bB-DI2"/>
<constraint firstAttribute="trailing" secondItem="Zpk-pq-9nW" secondAttribute="trailing" id="67d-pI-I9C"/>
<constraint firstAttribute="trailing" secondItem="iA5-go-AO0" secondAttribute="trailing" constant="12" id="9Dl-n9-vRI"/>
<constraint firstItem="lSU-OC-sEC" firstAttribute="leading" secondItem="Dnl-L5-xFP" secondAttribute="leading" constant="4" id="Ceb-sA-ECJ"/>
<constraint firstItem="PdS-jL-yH1" firstAttribute="leading" secondItem="M3G-7s-D6y" secondAttribute="leading" id="KW1-4o-qoz"/>
<constraint firstItem="PdS-jL-yH1" firstAttribute="trailing" secondItem="M3G-7s-D6y" secondAttribute="trailing" id="WHL-h4-cLZ"/>
<constraint firstItem="lSU-OC-sEC" firstAttribute="leading" secondItem="Dnl-L5-xFP" secondAttribute="leading" constant="8" id="Ceb-sA-ECJ"/>
<constraint firstItem="PdS-jL-yH1" firstAttribute="trailing" secondItem="M3G-7s-D6y" secondAttribute="trailing" id="Eln-Tf-W9k"/>
<constraint firstItem="lSU-OC-sEC" firstAttribute="centerY" secondItem="iA5-go-AO0" secondAttribute="centerY" id="OeL-Zp-iRT"/>
<constraint firstItem="Zpk-pq-9nW" firstAttribute="leading" secondItem="Dnl-L5-xFP" secondAttribute="leading" id="XF2-31-E1x"/>
<constraint firstItem="PdS-jL-yH1" firstAttribute="top" secondItem="M3G-7s-D6y" secondAttribute="top" id="aB8-Pt-Szt"/>
<constraint firstAttribute="bottom" secondItem="Zpk-pq-9nW" secondAttribute="bottom" id="fyv-EG-PC8"/>
<constraint firstItem="Zpk-pq-9nW" firstAttribute="top" secondItem="lSU-OC-sEC" secondAttribute="bottom" constant="4" id="gFm-Ix-hBf"/>
<constraint firstItem="iA5-go-AO0" firstAttribute="top" secondItem="M3G-7s-D6y" secondAttribute="top" constant="5" id="nM9-iA-OzY"/>
<constraint firstItem="PdS-jL-yH1" firstAttribute="leading" secondItem="M3G-7s-D6y" secondAttribute="leading" id="lSy-HN-fWB"/>
<constraint firstAttribute="leading" secondItem="Dnl-L5-xFP" secondAttribute="leading" id="pZU-jW-B1h"/>
<constraint firstItem="iA5-go-AO0" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="lSU-OC-sEC" secondAttribute="trailing" constant="8" id="yCg-gc-exN"/>
<constraint firstItem="lSU-OC-sEC" firstAttribute="top" secondItem="M3G-7s-D6y" secondAttribute="top" constant="4" id="zay-ZJ-od3"/>
</constraints>

View File

@ -157,7 +157,7 @@
<rect key="frame" x="145" y="32" width="197" height="28"/>
<textFieldCell key="cell" controlSize="small" title="Hold the Shift key to invert this preference." id="EMq-9M-zTJ">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
@ -735,7 +735,7 @@
</scenes>
<resources>
<image name="NSActionTemplate" width="15" height="15"/>
<image name="NSAddTemplate" width="15" height="13"/>
<image name="NSRemoveTemplate" width="15" height="4"/>
<image name="NSAddTemplate" width="14" height="13"/>
<image name="NSRemoveTemplate" width="14" height="4"/>
</resources>
</document>

View File

@ -1,8 +1,8 @@
body {
margin-top: 20px;
margin-bottom: 64px;
padding-left: 32px;
padding-right: 32px;
padding-left: 64px;
padding-right: 64px;
font-family: -apple-system;
font-size: 18px;
}
@ -10,16 +10,16 @@ body {
:root {
--body-color: #444;
--body-background-color: -apple-system-text-background;
--accent-color: rgba([[accent-r]], [[accent-g]], [[accent-b]], .75);
--block-quote-border-color: rgba([[accent-r]], [[accent-g]], [[accent-b]], .50);
--accent-color: rgb(8, 106, 238, 1);
--block-quote-border-color: rgb(8, 106, 238, .50);
}
@media(prefers-color-scheme: dark) {
:root {
--body-color: #d2d2d2;
--body-background-color: #2d2d2d;
--accent-color: rgba([[accent-r]], [[accent-g]], [[accent-b]], .75);
--block-quote-border-color: rgba([[accent-r]], [[accent-g]], [[accent-b]], .50);
--accent-color: rgba(45, 128, 241, 1);
--block-quote-border-color: rgba(45, 128, 241, .50);
--header-table-border-color: rgba(255, 255, 255, 0.1);
}
}
@ -27,9 +27,6 @@ body {
body a, body a:visited {
color: var(--accent-color);
}
body .header a:link, body .header a:visited {
color: var(--accent-color);
}
pre {
border: 1px solid var(--accent-color);

View File

@ -1149,9 +1149,7 @@ private extension MainWindowController {
}
func validateCleanUp(_ item: NSValidatedUserInterfaceItem) -> Bool {
let isSidebarFiltered = sidebarViewController?.isReadFiltered ?? false
let isTimelineFiltered = timelineContainerViewController?.isReadFiltered ?? false
return isSidebarFiltered || isTimelineFiltered
return timelineContainerViewController?.isCleanUpAvailable ?? false
}
func validateToggleReadFeeds(_ item: NSValidatedUserInterfaceItem) -> Bool {

View File

@ -24,7 +24,6 @@ protocol SidebarDelegate: class {
@objc class SidebarViewController: NSViewController, NSOutlineViewDelegate, NSMenuDelegate, UndoableCommandRunner {
@IBOutlet weak var readFilteredButton: NSButton!
@IBOutlet var outlineView: SidebarOutlineView!
weak var delegate: SidebarDelegate?
@ -134,8 +133,6 @@ protocol SidebarDelegate: class {
if let readFeedsFilterState = state[UserInfoKey.readFeedsFilterState] as? Bool {
isReadFiltered = readFeedsFilterState
}
updateReadFilterButton()
}
// MARK: - Notifications
@ -475,7 +472,6 @@ protocol SidebarDelegate: class {
}
delegate?.sidebarInvalidatedRestorationState(self)
rebuildTreeAndRestoreSelection()
updateReadFilterButton()
}
}
@ -845,13 +841,6 @@ private extension SidebarViewController {
return outlineView.revealAndSelectRepresentedObject(representedObject, treeController)
}
func updateReadFilterButton() {
if isReadFiltered {
readFilteredButton.image = AppAssets.filterActive
} else {
readFilteredButton.image = AppAssets.filterInactive
}
}
}
private extension Node {

View File

@ -49,7 +49,7 @@ struct TimelineCellAppearance: Equatable {
let largeItemFontSize = actualFontSize
self.feedNameFont = NSFont.systemFont(ofSize: smallItemFontSize)
self.dateFont = NSFont.systemFont(ofSize: smallItemFontSize)
self.dateFont = NSFont.systemFont(ofSize: smallItemFontSize, weight: NSFont.Weight.bold)
self.titleFont = NSFont.systemFont(ofSize: largeItemFontSize, weight: NSFont.Weight.semibold)
self.textFont = NSFont.systemFont(ofSize: largeItemFontSize, weight: NSFont.Weight.light)
self.textOnlyFont = NSFont.systemFont(ofSize: largeItemFontSize)

View File

@ -20,7 +20,7 @@ class TimelineTableCellView: NSTableCellView {
private lazy var iconView = IconView()
private let starView = TimelineTableCellView.imageView(with: AppAssets.timelineStar, scaling: .scaleProportionallyUpOrDown)
private var starView = TimelineTableCellView.imageView(with: AppAssets.timelineStarUnselected, scaling: .scaleNone)
private let separatorView = TimelineTableCellView.separatorView()
private lazy var textFields = {
@ -52,12 +52,14 @@ class TimelineTableCellView: NSTableCellView {
var isEmphasized: Bool = false {
didSet {
unreadIndicatorView.isEmphasized = isEmphasized
updateStarView()
}
}
var isSelected: Bool = false {
didSet {
unreadIndicatorView.isSelected = isSelected
updateStarView()
}
}
@ -180,7 +182,7 @@ private extension TimelineTableCellView {
titleView.textColor = NSColor.labelColor
feedNameView.textColor = NSColor.secondaryLabelColor
dateView.textColor = NSColor.secondaryLabelColor
summaryView.textColor = NSColor.labelColor
summaryView.textColor = NSColor.secondaryLabelColor
textView.textColor = NSColor.labelColor
}
@ -279,6 +281,11 @@ private extension TimelineTableCellView {
}
func updateStarView() {
if isSelected && isEmphasized {
starView.image = AppAssets.timelineStarSelected
} else {
starView.image = AppAssets.timelineStarUnselected
}
showOrHideView(starView, !cellData.starred)
}

View File

@ -45,6 +45,11 @@ final class TimelineContainerViewController: NSViewController {
return regularTimelineViewController.isReadFiltered
}
var isCleanUpAvailable: Bool {
guard let currentTimelineViewController = currentTimelineViewController, mode(for: currentTimelineViewController) == .regular else { return false }
return regularTimelineViewController.isCleanUpAvailable
}
lazy var regularTimelineViewController = {
return TimelineViewController(delegate: self)
}()
@ -58,6 +63,10 @@ final class TimelineContainerViewController: NSViewController {
super.viewDidLoad()
setRepresentedObjects(nil, mode: .regular)
showTimeline(for: .regular)
makeMenuItemTitleLarger(newestToOldestMenuItem)
makeMenuItemTitleLarger(oldestToNewestMenuItem)
makeMenuItemTitleLarger(groupByFeedMenuItem)
updateViewOptionsPopUpButton()
NotificationCenter.default.addObserver(self, selector: #selector(userDefaultsDidChange(_:)), name: UserDefaults.didChangeNotification, object: nil)
@ -144,6 +153,11 @@ extension TimelineContainerViewController: TimelineDelegate {
private extension TimelineContainerViewController {
func makeMenuItemTitleLarger(_ menuItem: NSMenuItem) {
menuItem.attributedTitle = NSAttributedString(string: menuItem.title,
attributes: [NSAttributedString.Key.font: NSFont.controlContentFont(ofSize: NSFont.systemFontSize)])
}
func timelineViewController(for mode: TimelineSourceMode) -> TimelineViewController {
switch mode {
case .regular:
@ -165,18 +179,14 @@ private extension TimelineContainerViewController {
}
func updateViewOptionsPopUpButton() {
let localizedTitle = NSLocalizedString("Sort %@", comment: "Sort")
if AppDefaults.shared.timelineSortDirection == .orderedAscending {
newestToOldestMenuItem.state = .off
oldestToNewestMenuItem.state = .on
let title = NSString.localizedStringWithFormat(localizedTitle as NSString, oldestToNewestMenuItem.title) as String
viewOptionsPopUpButton.setTitle(title)
viewOptionsPopUpButton.setTitle(oldestToNewestMenuItem.title)
} else {
newestToOldestMenuItem.state = .on
oldestToNewestMenuItem.state = .off
let title = NSString.localizedStringWithFormat(localizedTitle as NSString, newestToOldestMenuItem.title) as String
viewOptionsPopUpButton.setTitle(title)
viewOptionsPopUpButton.setTitle(newestToOldestMenuItem.title)
}
if AppDefaults.shared.timelineGroupByFeed == true {

View File

@ -43,6 +43,15 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner, Unr
}
}
var isCleanUpAvailable: Bool {
guard isReadFiltered ?? false else { return false }
let readSelectedCount = selectedArticles.filter({ $0.status.read }).count
let readArticleCount = articles.count - unreadCount
let availableToCleanCount = readArticleCount - readSelectedCount
return availableToCleanCount > 0
}
var representedObjects: [AnyObject]? {
didSet {
if !representedObjectArraysAreEqual(oldValue, representedObjects) {
@ -901,7 +910,7 @@ extension TimelineViewController: NSTableViewDelegate {
self.toggleArticleStarred(article);
tableView.rowActionsVisible = false
}
action.backgroundColor = AppAssets.swipeMarkUnstarredColor
action.backgroundColor = AppAssets.starColor
action.image = article.status.starred ? AppAssets.swipeMarkUnstarredImage : AppAssets.swipeMarkStarredImage
return [action]

View File

@ -114,6 +114,7 @@ extension AccountsPreferencesViewController: NSTableViewDelegate {
let selectedRow = tableView.selectedRow
if tableView.selectedRow == -1 {
deleteButton.isEnabled = false
showController(AccountsAddViewController())
return
} else {
deleteButton.isEnabled = true

View File

@ -1,13 +1,13 @@
{
"images" : [
{
"filename" : "star.pdf",
"idiom" : "universal",
"filename" : "timelineStar.png",
"scale" : "1x"
},
{
"filename" : "star@2x.pdf",
"idiom" : "universal",
"filename" : "timelineStar@2x.png",
"scale" : "2x"
},
{
@ -16,7 +16,11 @@
}
],
"info" : {
"version" : 1,
"author" : "xcode"
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "template"
}
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 875 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -164,6 +164,12 @@ private extension ArticleRenderer {
else {
d["avatars"] = ""
}
if self.title.isEmpty {
d["dateline_style"] = "articleDatelineTitle"
} else {
d["dateline_style"] = "articleDateline"
}
var feedLink = ""
if let feedTitle = article.webFeed?.nameForDisplay {
@ -218,19 +224,24 @@ private extension ArticleRenderer {
}
isFirstAuthor = false
if let emailAddress = author.emailAddress, emailAddress.contains(" ") {
var authorEmailAddress: String? = nil
if let emailAddress = author.emailAddress, !(emailAddress.contains("noreply@") || emailAddress.contains("no-reply@")) {
authorEmailAddress = emailAddress
}
if let emailAddress = authorEmailAddress, emailAddress.contains(" ") {
byline += emailAddress // probably name plus email address
}
else if let name = author.name, let url = author.url {
byline += name.htmlByAddingLink(url)
}
else if let name = author.name, let emailAddress = author.emailAddress {
else if let name = author.name, let emailAddress = authorEmailAddress {
byline += "\(name) &lt;\(emailAddress)&gt;"
}
else if let name = author.name {
byline += name
}
else if let emailAddress = author.emailAddress {
else if let emailAddress = authorEmailAddress {
byline += "&lt;\(emailAddress)&gt;" // TODO: mailto link
}
else if let url = author.url {
@ -271,32 +282,6 @@ private extension ArticleRenderer {
d["font-size"] = String(describing: Int(round(bodyFont.pointSize * 1.33)))
}
guard let linkColor = NSColor.controlAccentColor.usingColorSpace(.deviceRGB) else {
return d
}
let red: Int
let green: Int
let blue: Int
if NSApplication.shared.effectiveAppearance.isDarkMode {
let brighten = CGFloat(0.50)
let baseRed = linkColor.redComponent * 0xFF
red = Int(round(((255 - baseRed) * brighten)) + round(baseRed))
let baseGreen = linkColor.greenComponent * 0xFF
green = Int(round(((255 - baseGreen) * brighten)) + round(baseGreen))
let baseBlue = linkColor.blueComponent * 0xFF
blue = Int(round(((255 - baseBlue) * brighten)) + round(baseBlue))
} else {
let darken = CGFloat(0.75)
red = Int(round(linkColor.redComponent * 0xFF * darken))
green = Int(round(linkColor.greenComponent * 0xFF * darken))
blue = Int(round(linkColor.blueComponent * 0xFF * darken))
}
d["accent-r"] = String(red)
d["accent-g"] = String(green)
d["accent-b"] = String(blue)
return d
}
#endif

View File

@ -32,17 +32,20 @@ a:hover {
--header-color: rgba(0, 0, 0, 0.3);
--body-code-color: #666;
--system-message-color: #cbcbcb;
--feedlink-color: rgba(0, 0, 0, 0.6);
--feedlink-color: rgba(0, 0, 0, 0.3);
--article-title-color: #333;
--article-date-color: rgba(0, 0, 0, 0.5);
--table-cell-border-color: lightgray;
}
@media(prefers-color-scheme: dark) {
:root {
--header-color: #d2d2d2;
--header-color: #d2d2d2;
--body-code-color: #b2b2b2;
--system-message-color: #5f5f5f;
--feedlink-color: rgba(255, 255, 255, 0.7);
--article-title-color: #e0e0e0;
--article-date-color: rgba(255, 255, 255, 0.5);
--table-cell-border-color: dimgray;
}
}
@ -59,10 +62,6 @@ body .header {
color: var(--header-color);
}
body .articleDateline, body .articleDateLine.a:link, body .articleDateline a:visited {
color: var(--header-color);
}
body code, body pre {
color: var(--body-code-color);
}
@ -72,7 +71,7 @@ body > .systemMessage {
}
.feedlink a:link, .feedlink a:visited {
color: var(--feed-link-color);
color: var(--feedlink-color);
}
.avatar img {
@ -100,6 +99,15 @@ body > .systemMessage {
}
.articleDateline a:link, .articleDateline a:visited {
color: var(--article-date-color);
}
.articleDatelineTitle {
margin-bottom: 25px;
font-weight: bold;
}
.articleDatelineTitle a:link, .articleDatelineTitle a:visited {
color: var(--article-title-color);
}

View File

@ -9,6 +9,6 @@
<article>
<div class="articleTitle"><h1>[[title]]</h1></div>
<div class="articleDateline">[[date_medium]]</div>
<div class="[[dateline_style]]">[[date_medium]]</div>
<div class="articleBody">[[body]]</div>
</article>

View File

@ -134,17 +134,22 @@ extension Article {
byline += ", "
}
isFirstAuthor = false
var authorEmailAddress: String? = nil
if let emailAddress = author.emailAddress, !(emailAddress.contains("noreply@") || emailAddress.contains("no-reply@")) {
authorEmailAddress = emailAddress
}
if let emailAddress = author.emailAddress, emailAddress.contains(" ") {
if let emailAddress = authorEmailAddress, emailAddress.contains(" ") {
byline += emailAddress // probably name plus email address
}
else if let name = author.name, let emailAddress = author.emailAddress {
else if let name = author.name, let emailAddress = authorEmailAddress {
byline += "\(name) <\(emailAddress)>"
}
else if let name = author.name {
byline += name
}
else if let emailAddress = author.emailAddress {
else if let emailAddress = authorEmailAddress {
byline += "<\(emailAddress)>"
}
else if let url = author.url {