Merge branch 'extension-point'

This commit is contained in:
Maurice Parker
2020-04-24 13:34:13 -05:00
163 changed files with 6165 additions and 480 deletions

View File

@@ -2,7 +2,7 @@
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16086"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>

View File

@@ -9,6 +9,7 @@
import UIKit
import Account
import RSWeb
import Secrets
class FeedWranglerAccountViewController: UITableViewController {

View File

@@ -8,6 +8,7 @@
import UIKit
import Account
import Secrets
import RSWeb
class FeedbinAccountViewController: UITableViewController {

View File

@@ -8,6 +8,7 @@
import UIKit
import Account
import Secrets
import RSWeb
class NewsBlurAccountViewController: UITableViewController {

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15505" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="bqE-WD-JXz">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="bqE-WD-JXz">
<device id="retina5_9" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15509"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
@@ -26,16 +26,25 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="URL" textAlignment="natural" adjustsFontForContentSizeCategory="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="eRp-AP-WFq">
<rect key="frame" x="20" y="4" width="303" height="36"/>
<rect key="frame" x="20" y="4" width="269.66666666666669" height="36"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<textInputTraits key="textInputTraits" keyboardType="URL"/>
</textField>
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" horizontalCompressionResistancePriority="751" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="f0N-Iy-ZFD">
<rect key="frame" x="297.66666666666669" y="10.666666666666666" width="25.333333333333314" height="22.666666666666671"/>
<state key="normal" image="hammer" catalog="system"/>
<connections>
<action selector="showURLBuilder:" destination="7aE-6a-iP7" eventType="touchUpInside" id="wVv-BU-ND8"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="eRp-AP-WFq" firstAttribute="top" secondItem="eNS-Rp-w0A" secondAttribute="top" constant="4" id="80p-a2-3NC"/>
<constraint firstItem="f0N-Iy-ZFD" firstAttribute="centerY" secondItem="eRp-AP-WFq" secondAttribute="centerY" id="Ci9-Fe-KrJ"/>
<constraint firstItem="f0N-Iy-ZFD" firstAttribute="leading" secondItem="eRp-AP-WFq" secondAttribute="trailing" constant="8" id="ZNi-6o-A6w"/>
<constraint firstAttribute="trailing" secondItem="f0N-Iy-ZFD" secondAttribute="trailing" constant="20" symbolic="YES" id="aHH-ef-7dH"/>
<constraint firstItem="eRp-AP-WFq" firstAttribute="leading" secondItem="eNS-Rp-w0A" secondAttribute="leading" constant="20" symbolic="YES" id="bHJ-7l-Pl3"/>
<constraint firstAttribute="bottom" secondItem="eRp-AP-WFq" secondAttribute="bottom" constant="4" id="fs0-iw-zTo"/>
<constraint firstAttribute="trailing" secondItem="eRp-AP-WFq" secondAttribute="trailing" constant="20" symbolic="YES" id="xWD-54-Kdm"/>
</constraints>
</tableViewCellContentView>
</tableViewCell>
@@ -140,7 +149,7 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="812"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="AccountCell" id="bp5-2u-4S4" customClass="AddWebFeedFolderTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="AccountCell" id="bp5-2u-4S4" customClass="AddComboTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="0.0" y="28" width="375" height="43.666667938232422"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="bp5-2u-4S4" id="9HE-eR-YIp">
@@ -175,7 +184,7 @@
<outlet property="label" destination="ZQp-94-vJz" id="Jm5-oU-BZR"/>
</connections>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="FolderCell" id="S24-c1-0Ir" customClass="AddWebFeedFolderTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="FolderCell" id="S24-c1-0Ir" customClass="AddComboTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="0.0" y="71.666667938232422" width="375" height="43.666667938232422"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="S24-c1-0Ir" id="bA3-AB-H1n">
@@ -436,8 +445,90 @@
</objects>
<point key="canvasLocation" x="-961" y="89"/>
</scene>
<!--Modal Navigation Controller-->
<scene sceneID="cdQ-dD-r6b">
<objects>
<navigationController storyboardIdentifier="SelectURLBuilderNavViewController" id="iBn-vt-JuI" customClass="ModalNavigationController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="5ft-mx-bH1">
<rect key="frame" x="0.0" y="44" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<connections>
<segue destination="Wls-o6-7V8" kind="relationship" relationship="rootViewController" id="jlb-J3-50h"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="tmd-jJ-oxP" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-2452" y="1416"/>
</scene>
<!--Select URL Builder-->
<scene sceneID="uAc-pe-d1U">
<objects>
<tableViewController storyboardIdentifier="SelectURLBuilderViewController" title="Select URL Builder" id="Wls-o6-7V8" customClass="SelectURLBuilderTableViewController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="insetGrouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="SBu-NT-kQA">
<rect key="frame" x="0.0" y="0.0" width="375" height="812"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="URLBuilderCell" rowHeight="55" id="7Qf-cp-hyD" customClass="SelectComboTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="16" y="55.333332061767578" width="343" height="55"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="7Qf-cp-hyD" id="Rsw-xP-7HT">
<rect key="frame" x="0.0" y="0.0" width="317" height="55"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="Jka-S1-56k">
<rect key="frame" x="20" y="15.666666666666664" width="130" height="24"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="hammer" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="lQk-5J-fON">
<rect key="frame" x="0.0" y="-0.66666666666666785" width="24" height="26.333333333333336"/>
<color key="tintColor" systemColor="labelColor" cocoaTouchSystemColor="darkTextColor"/>
<constraints>
<constraint firstAttribute="width" constant="24" id="u9L-D0-kgu"/>
<constraint firstAttribute="height" constant="24" id="wDw-bL-u3p"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="URL Builder" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ys7-kv-kLW">
<rect key="frame" x="40" y="0.0" width="90" height="24"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
</subviews>
<constraints>
<constraint firstItem="Jka-S1-56k" firstAttribute="leading" secondItem="Rsw-xP-7HT" secondAttribute="leading" constant="20" symbolic="YES" id="2Sh-PL-a9u"/>
<constraint firstItem="Jka-S1-56k" firstAttribute="centerY" secondItem="Rsw-xP-7HT" secondAttribute="centerY" id="k1d-3l-LGF"/>
</constraints>
</tableViewCellContentView>
<inset key="separatorInset" minX="45" minY="0.0" maxX="0.0" maxY="0.0"/>
<connections>
<outlet property="icon" destination="lQk-5J-fON" id="uCm-OV-S80"/>
<outlet property="label" destination="Ys7-kv-kLW" id="v99-KU-U8q"/>
</connections>
</tableViewCell>
</prototypes>
<connections>
<outlet property="dataSource" destination="Wls-o6-7V8" id="3V5-PC-jlM"/>
<outlet property="delegate" destination="Wls-o6-7V8" id="kWB-zE-rh5"/>
</connections>
</tableView>
<navigationItem key="navigationItem" title="Select URL Builder" id="02z-m5-leN">
<barButtonItem key="leftBarButtonItem" systemItem="cancel" id="xeT-hn-DyW">
<connections>
<action selector="cancel:" destination="Wls-o6-7V8" id="9rX-tp-GwL"/>
</connections>
</barButtonItem>
</navigationItem>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="qFt-gM-HqV" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-1687" y="1416"/>
</scene>
</scenes>
<resources>
<image name="hammer" catalog="system" width="128" height="115"/>
<namedColor name="secondaryAccentColor">
<color red="0.031372549019607843" green="0.41568627450980394" blue="0.93333333333333335" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>

View File

@@ -1,5 +1,5 @@
//
// AddWebFeedFolderTableViewCell.swift
// AddComboTableViewCell.swift
// NetNewsWire
//
// Created by Maurice Parker on 11/16/19.
@@ -8,7 +8,7 @@
import UIKit
class AddWebFeedFolderTableViewCell: VibrantTableViewCell {
class AddComboTableViewCell: VibrantTableViewCell {
@IBOutlet weak var icon: UIImageView!
@IBOutlet weak var label: UILabel!

View File

@@ -1,5 +1,5 @@
//
// AddWebFeedLocationViewController.swift
// AddWebFeedFolderViewController.swift
// NetNewsWire-iOS
//
// Created by Maurice Parker on 11/16/19.
@@ -44,11 +44,11 @@ class AddWebFeedFolderViewController: UITableViewController {
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let container = containers[indexPath.row]
let cell: AddWebFeedFolderTableViewCell = {
let cell: AddComboTableViewCell = {
if container is Account {
return tableView.dequeueReusableCell(withIdentifier: "AccountCell", for: indexPath) as! AddWebFeedFolderTableViewCell
return tableView.dequeueReusableCell(withIdentifier: "AccountCell", for: indexPath) as! AddComboTableViewCell
} else {
return tableView.dequeueReusableCell(withIdentifier: "FolderCell", for: indexPath) as! AddWebFeedFolderTableViewCell
return tableView.dequeueReusableCell(withIdentifier: "FolderCell", for: indexPath) as! AddComboTableViewCell
}
}()

View File

@@ -65,6 +65,14 @@ class AddWebFeedViewController: UITableViewController, AddContainerViewControlle
}
@IBAction func showURLBuilder(_ sender: Any) {
let navController = UIStoryboard.add.instantiateViewController(withIdentifier: "SelectURLBuilderNavViewController") as! UINavigationController
navController.modalPresentationStyle = .currentContext
let selectURLBuilder = navController.topViewController as! SelectURLBuilderTableViewController
selectURLBuilder.delegate = self
present(navController, animated: true)
}
func cancel() {
userCancelled = true
delegate?.processingDidCancel()
@@ -118,7 +126,7 @@ class AddWebFeedViewController: UITableViewController, AddContainerViewControlle
}
@objc func textDidChange(_ note: Notification) {
delegate?.readyToAdd(state: urlTextField.text?.mayBeURL ?? false)
updateUI()
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
@@ -154,6 +162,17 @@ extension AddWebFeedViewController: AddWebFeedFolderViewControllerDelegate {
}
}
// MARK: AddWebFeedFolderViewControllerDelegate
extension AddWebFeedViewController: SelectURLBuilderDelegate {
func selectURLBuilderDidBuildURL(_ url: URL) {
urlTextField.text = url.absoluteString
updateUI()
}
}
// MARK: UITextFieldDelegate
extension AddWebFeedViewController: UITextFieldDelegate {
@@ -168,6 +187,11 @@ extension AddWebFeedViewController: UITextFieldDelegate {
// MARK: Private
private extension AddWebFeedViewController {
func updateUI() {
delegate?.readyToAdd(state: urlTextField.text?.mayBeURL ?? false)
}
func updateFolderLabel() {
if let containerName = (container as? DisplayNameProvider)?.nameForDisplay {
if container is Folder {

View File

@@ -0,0 +1,26 @@
//
// SelectComboTableViewCell.swift
// NetNewsWire-iOS
//
// Created by Maurice Parker on 4/23/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import UIKit
class SelectComboTableViewCell: VibrantTableViewCell {
@IBOutlet weak var icon: UIImageView!
@IBOutlet weak var label: UILabel!
override func updateVibrancy(animated: Bool) {
super.updateVibrancy(animated: animated)
let iconTintColor = isHighlighted || isSelected ? AppAssets.vibrantTextColor : UIColor.label
UIView.animate(withDuration: duration(animated: animated)) {
self.icon.tintColor = iconTintColor
}
updateLabelVibrancy(label, color: labelColor, animated: animated)
}
}

View File

@@ -0,0 +1,17 @@
//
// SelectURLBuilder.swift
// NetNewsWire-iOS
//
// Created by Maurice Parker on 4/23/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import UIKit
protocol SelectURLBuilderDelegate: class {
func selectURLBuilderDidBuildURL(_ url: URL)
}
protocol SelectURLBuilder {
var delegate: SelectURLBuilderDelegate? { get set }
}

View File

@@ -0,0 +1,48 @@
//
// SelectURLBuilderTableViewController.swift
// NetNewsWire-iOS
//
// Created by Maurice Parker on 4/23/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import UIKit
class SelectURLBuilderTableViewController: UITableViewController, SelectURLBuilder {
weak var delegate: SelectURLBuilderDelegate?
override func viewDidLoad() {
super.viewDidLoad()
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "URLBuilderCell", for: indexPath) as! SelectComboTableViewCell
cell.icon?.image = AppAssets.extensionPointTwitter
cell.label?.text = NSLocalizedString("Twitter", comment: "Twitter")
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let twitterURLBuilder = UIStoryboard.twitterAdd.instantiateInitialViewController() as! TwitterSelectTypeTableViewController
twitterURLBuilder.delegate = delegate
navigationController?.pushViewController(twitterURLBuilder, animated: true)
}
// MARK: Actions
@IBAction func cancel(_ sender: Any) {
dismiss(animated: true)
}
}

View File

@@ -0,0 +1,217 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="q78-0w-suH">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Select Type-->
<scene sceneID="Fmm-TL-h7h">
<objects>
<tableViewController storyboardIdentifier="TwitterSelectTypeTableViewController" title="Select Type" id="q78-0w-suH" customClass="TwitterSelectTypeTableViewController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="insetGrouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="SFq-R0-gSo">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<sections>
<tableViewSection id="Dp6-La-NeL">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" misplaced="YES" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="WAs-zr-8RJ" detailTextLabel="f8o-SY-a2H" style="IBUITableViewCellStyleSubtitle" id="VbH-aQ-M4H" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="18" width="374" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="VbH-aQ-M4H" id="Qud-m5-1ZQ">
<rect key="frame" x="0.0" y="0.0" width="374" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Home Timeline" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="WAs-zr-8RJ">
<rect key="frame" x="20" y="4" width="114.5" height="20.5"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Tweets from everyone you follow" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="f8o-SY-a2H">
<rect key="frame" x="20" y="24.5" width="198.5" height="16"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleFootnote"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" misplaced="YES" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="K0b-HX-8dR" detailTextLabel="uaZ-4Q-FBS" style="IBUITableViewCellStyleSubtitle" id="jft-wJ-OVX" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="61.5" width="374" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="jft-wJ-OVX" id="dXF-Bc-NkR">
<rect key="frame" x="0.0" y="0.0" width="374" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Mentions" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="K0b-HX-8dR">
<rect key="frame" x="20" y="4" width="71" height="20.5"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Tweets mentioning you" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="uaZ-4Q-FBS">
<rect key="frame" x="20" y="24.5" width="140" height="16"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleFootnote"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" misplaced="YES" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="Oqx-Ox-oyD" detailTextLabel="lqE-9F-jud" style="IBUITableViewCellStyleSubtitle" id="8qx-8E-cJo" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="105" width="374" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="8qx-8E-cJo" id="bk5-cB-EOT">
<rect key="frame" x="0.0" y="0.0" width="343" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Screen Name" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="Oqx-Ox-oyD">
<rect key="frame" x="20" y="4" width="103" height="20.5"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Tweets from another Twitter user" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="lqE-9F-jud">
<rect key="frame" x="20" y="24.5" width="201" height="16"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleFootnote"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" misplaced="YES" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="Xj8-CU-C7D" detailTextLabel="SJg-RF-48S" style="IBUITableViewCellStyleSubtitle" id="vrw-y9-yJd" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="148.5" width="374" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="vrw-y9-yJd" id="bOx-t8-zfi">
<rect key="frame" x="0.0" y="0.0" width="343" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Search" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="Xj8-CU-C7D">
<rect key="frame" x="20" y="5" width="53.5" height="20.5"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Tweets containing a #hastag or search term" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="SJg-RF-48S">
<rect key="frame" x="20" y="25.5" width="248" height="14.5"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
</tableViewCell>
</cells>
</tableViewSection>
</sections>
<connections>
<outlet property="dataSource" destination="q78-0w-suH" id="fIb-JL-htF"/>
<outlet property="delegate" destination="q78-0w-suH" id="j69-O6-ths"/>
</connections>
</tableView>
<simulatedNavigationBarMetrics key="simulatedTopBarMetrics"/>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="yI5-IG-7Sl" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-538" y="174"/>
</scene>
<!--Select Account-->
<scene sceneID="rKM-ZF-73N">
<objects>
<tableViewController storyboardIdentifier="TwitterSelectAccountTableViewController" title="Select Account" id="2vd-nT-5dg" customClass="TwitterSelectAccountTableViewController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="insetGrouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="T93-wO-GIE">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="Cell" textLabel="j8c-JM-nzm" style="IBUITableViewCellStyleDefault" id="vEE-Gx-Zgc" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="55.5" width="374" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="vEE-Gx-Zgc" id="pa0-mR-hgR">
<rect key="frame" x="0.0" y="0.0" width="374" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="j8c-JM-nzm">
<rect key="frame" x="20" y="0.0" width="334" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
</tableViewCell>
</prototypes>
<connections>
<outlet property="dataSource" destination="2vd-nT-5dg" id="GvE-oh-4gy"/>
<outlet property="delegate" destination="2vd-nT-5dg" id="hdE-2N-0X0"/>
</connections>
</tableView>
<simulatedNavigationBarMetrics key="simulatedTopBarMetrics"/>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="LMf-ZZ-Z1s" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="155" y="173"/>
</scene>
<!--Enter Detail-->
<scene sceneID="lmR-Pm-7vI">
<objects>
<tableViewController storyboardIdentifier="TwitterEnterDetailTableViewController" title="Enter Detail" id="Eh0-p4-hVX" customClass="TwitterEnterDetailTableViewController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="insetGrouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="76O-el-2DO">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<sections>
<tableViewSection id="ZkR-cP-Kvy">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" id="bWA-Rs-IL9">
<rect key="frame" x="20" y="18" width="374" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="bWA-Rs-IL9" id="azg-eE-bd4">
<rect key="frame" x="0.0" y="0.0" width="374" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" textAlignment="natural" adjustsFontForContentSizeCategory="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="IVd-Bz-j7J">
<rect key="frame" x="20" y="11" width="334" height="22"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<textInputTraits key="textInputTraits" autocorrectionType="no"/>
</textField>
</subviews>
<constraints>
<constraint firstItem="IVd-Bz-j7J" firstAttribute="centerY" secondItem="azg-eE-bd4" secondAttribute="centerY" id="ItM-Jv-j2G"/>
<constraint firstItem="IVd-Bz-j7J" firstAttribute="leading" secondItem="azg-eE-bd4" secondAttribute="leading" constant="20" symbolic="YES" id="ldz-j4-8kY"/>
<constraint firstAttribute="trailing" secondItem="IVd-Bz-j7J" secondAttribute="trailing" constant="20" symbolic="YES" id="un0-pU-AHV"/>
</constraints>
</tableViewCellContentView>
</tableViewCell>
</cells>
</tableViewSection>
</sections>
<connections>
<outlet property="dataSource" destination="Eh0-p4-hVX" id="eKE-xW-f3D"/>
<outlet property="delegate" destination="Eh0-p4-hVX" id="e07-6Q-SQc"/>
</connections>
</tableView>
<simulatedNavigationBarMetrics key="simulatedTopBarMetrics"/>
<connections>
<outlet property="detailTextField" destination="IVd-Bz-j7J" id="p1f-3d-6MR"/>
</connections>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="cp9-xU-RGq" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="836" y="173"/>
</scene>
</scenes>
</document>

View File

@@ -0,0 +1,83 @@
//
// TwitterEnterDetailTableViewController.swift
// NetNewsWire-iOS
//
// Created by Maurice Parker on 4/23/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import UIKit
import Account
class TwitterEnterDetailTableViewController: UITableViewController, SelectURLBuilder {
@IBOutlet weak var detailTextField: UITextField!
var doneBarButtonItem = UIBarButtonItem()
var twitterFeedType: TwitterFeedType?
weak var delegate: SelectURLBuilderDelegate?
override func viewDidLoad() {
super.viewDidLoad()
doneBarButtonItem.title = NSLocalizedString("Done", comment: "Done")
doneBarButtonItem.style = .done
doneBarButtonItem.target = self
doneBarButtonItem.action = #selector(done)
navigationItem.rightBarButtonItem = doneBarButtonItem
if case .screenName = twitterFeedType {
navigationItem.title = NSLocalizedString("Enter Name", comment: "Enter Name")
detailTextField.placeholder = NSLocalizedString("Screen Name", comment: "Screen Name")
} else {
navigationItem.title = NSLocalizedString("Enter Search", comment: "Enter Search")
detailTextField.placeholder = NSLocalizedString("Search Term", comment: "Search Term")
}
detailTextField.delegate = self
NotificationCenter.default.addObserver(self, selector: #selector(textDidChange(_:)), name: UITextField.textDidChangeNotification, object: detailTextField)
updateUI()
}
@objc func done() {
guard let twitterFeedType = twitterFeedType, var text = detailTextField.text?.collapsingWhitespace else { return }
if twitterFeedType == .screenName {
if text.starts(with: "@") {
text = String(text[text.index(text.startIndex, offsetBy: 1)..<text.endIndex])
}
if let url = TwitterFeedProvider.buildURL(twitterFeedType, username: nil, screenName: text, searchField: nil) {
delegate?.selectURLBuilderDidBuildURL(url)
}
} else {
if let url = TwitterFeedProvider.buildURL(twitterFeedType, username: nil, screenName: nil, searchField: text) {
delegate?.selectURLBuilderDidBuildURL(url)
}
}
dismiss(animated: true)
}
@objc func textDidChange(_ note: Notification) {
updateUI()
}
}
extension TwitterEnterDetailTableViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}
private extension TwitterEnterDetailTableViewController {
func updateUI() {
doneBarButtonItem.isEnabled = !(detailTextField.text?.isEmpty ?? false)
}
}

View File

@@ -0,0 +1,43 @@
//
// TwitterSelectAccountTableViewController.swift
// NetNewsWire-iOS
//
// Created by Maurice Parker on 4/23/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import UIKit
import Account
class TwitterSelectAccountTableViewController: UITableViewController, SelectURLBuilder {
private var twitterFeedProviders = [TwitterFeedProvider]()
var twitterFeedType: TwitterFeedType?
weak var delegate: SelectURLBuilderDelegate?
override func viewDidLoad() {
super.viewDidLoad()
twitterFeedProviders = ExtensionPointManager.shared.activeExtensionPoints.values.compactMap { $0 as? TwitterFeedProvider }
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return twitterFeedProviders.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = "@\(twitterFeedProviders[indexPath.row].screenName)"
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard let twitterFeedType = twitterFeedType else { return }
let username = twitterFeedProviders[indexPath.row].screenName
if let url = TwitterFeedProvider.buildURL(twitterFeedType, username: username, screenName: nil, searchField: nil) {
delegate?.selectURLBuilderDidBuildURL(url)
}
dismiss(animated: true)
}
}

View File

@@ -0,0 +1,76 @@
//
// TwitterSelectTypeTableViewController.swift
// NetNewsWire-iOS
//
// Created by Maurice Parker on 4/23/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import UIKit
import Account
class TwitterSelectTypeTableViewController: UITableViewController, SelectURLBuilder {
private var twitterFeedProviders = [TwitterFeedProvider]()
weak var delegate: SelectURLBuilderDelegate?
override func viewDidLoad() {
super.viewDidLoad()
twitterFeedProviders = ExtensionPointManager.shared.activeExtensionPoints.values.compactMap { $0 as? TwitterFeedProvider }
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = super.tableView(tableView, cellForRowAt: indexPath)
if indexPath.row < 2 {
if twitterFeedProviders.count > 1 {
cell.accessoryType = .disclosureIndicator
}
}
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch indexPath.row {
case 0:
if twitterFeedProviders.count == 1 {
let username = twitterFeedProviders.first!.screenName
if let url = TwitterFeedProvider.buildURL(.homeTimeline, username: username, screenName: nil, searchField: nil) {
delegate?.selectURLBuilderDidBuildURL(url)
}
dismiss(animated: true)
} else {
let selectAccount = UIStoryboard.twitterAdd.instantiateController(ofType: TwitterSelectAccountTableViewController.self)
selectAccount.twitterFeedType = .homeTimeline
selectAccount.delegate = delegate
navigationController?.pushViewController(selectAccount, animated: true)
}
case 1:
if twitterFeedProviders.count == 1 {
let username = twitterFeedProviders.first!.screenName
if let url = TwitterFeedProvider.buildURL(.mentions, username: username, screenName: nil, searchField: nil) {
delegate?.selectURLBuilderDidBuildURL(url)
}
dismiss(animated: true)
} else {
let selectAccount = UIStoryboard.twitterAdd.instantiateController(ofType: TwitterSelectAccountTableViewController.self)
selectAccount.twitterFeedType = .mentions
selectAccount.delegate = delegate
navigationController?.pushViewController(selectAccount, animated: true)
}
case 2:
let enterDetail = UIStoryboard.twitterAdd.instantiateController(ofType: TwitterEnterDetailTableViewController.self)
enterDetail.twitterFeedType = .screenName
enterDetail.delegate = delegate
navigationController?.pushViewController(enterDetail, animated: true)
case 3:
let enterDetail = UIStoryboard.twitterAdd.instantiateController(ofType: TwitterEnterDetailTableViewController.self)
enterDetail.twitterFeedType = .search
enterDetail.delegate = delegate
navigationController?.pushViewController(enterDetail, animated: true)
default:
fatalError()
}
}
}

View File

@@ -101,6 +101,10 @@ struct AppAssets {
UIImage(systemName: "square.and.pencil")!
}()
static var extensionPointTwitter: UIImage = {
return UIImage(named: "extensionPointTwitter")!
}()
static var faviconTemplateImage: RSImage = {
return RSImage(named: "faviconTemplateImage")!
}()

View File

@@ -36,6 +36,7 @@ struct AppDefaults {
struct Key {
static let userInterfaceColorPalette = "userInterfaceColorPalette"
static let activeExtensionPointIDs = "activeExtensionPointIDs"
static let lastImageCacheFlushDate = "lastImageCacheFlushDate"
static let firstRunDate = "firstRunDate"
static let timelineGroupByFeed = "timelineGroupByFeed"
@@ -106,6 +107,15 @@ struct AppDefaults {
}
}
static var activeExtensionPointIDs: [[AnyHashable : AnyHashable]]? {
get {
return UserDefaults.standard.object(forKey: Key.activeExtensionPointIDs) as? [[AnyHashable : AnyHashable]]
}
set {
UserDefaults.standard.set(newValue, forKey: Key.activeExtensionPointIDs)
}
}
static var lastImageCacheFlushDate: Date? {
get {
return date(for: Key.lastImageCacheFlushDate)

View File

@@ -64,6 +64,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
let documentAccountsFolder = documentAccountURL.appendingPathComponent("Accounts").absoluteString
let documentAccountsFolderPath = String(documentAccountsFolder.suffix(from: documentAccountsFolder.index(documentAccountsFolder.startIndex, offsetBy: 7)))
AccountManager.shared = AccountManager(accountsFolder: documentAccountsFolderPath)
FeedProviderManager.shared.delegate = ExtensionPointManager.shared
NotificationCenter.default.addObserver(self, selector: #selector(unreadCountDidChange(_:)), name: .UnreadCountDidChange, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(accountRefreshDidFinish(_:)), name: .AccountRefreshDidFinish, object: nil)

View File

@@ -0,0 +1,63 @@
//
// ExtensionPointInspectorViewController.swift
// NetNewsWire-iOS
//
// Created by Maurice Parker on 4/16/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import UIKit
class ExtensionPointInspectorViewController: UITableViewController {
@IBOutlet weak var extensionDescription: UILabel!
var extensionPoint: ExtensionPoint?
override func viewDidLoad() {
super.viewDidLoad()
guard let extensionPoint = extensionPoint else { return }
navigationItem.title = extensionPoint.title
extensionDescription.attributedText = extensionPoint.description
tableView.register(ImageHeaderView.self, forHeaderFooterViewReuseIdentifier: "SectionHeader")
}
@IBAction func disable(_ sender: Any) {
guard let extensionPoint = extensionPoint else { return }
ExtensionPointManager.shared.deactivateExtensionPoint(extensionPoint.extensionPointID)
self.navigationController?.popViewController(animated: true)
}
}
// MARK: Table View
extension ExtensionPointInspectorViewController {
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return section == 0 ? ImageHeaderView.rowHeight : super.tableView(tableView, heightForHeaderInSection: section)
}
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
guard let extensionPoint = extensionPoint else { return nil }
if section == 0 {
let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "SectionHeader") as! ImageHeaderView
headerView.imageView.image = extensionPoint.templateImage
return headerView
} else {
return super.tableView(tableView, viewForHeaderInSection: section)
}
}
override func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
if indexPath.section > 0 {
return true
}
return false
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
}
}

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
@@ -25,10 +25,10 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" spacing="19" translatesAutoresizingMaskIntoConstraints="NO" id="mQa-0W-eVS">
<rect key="frame" x="20" y="11.5" width="334" height="21"/>
<rect key="frame" x="20" y="11" width="334" height="22"/>
<subviews>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Name (Optional)" adjustsFontForContentSizeCategory="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="LUW-uv-piz">
<rect key="frame" x="0.0" y="0.0" width="334" height="21"/>
<rect key="frame" x="0.0" y="0.0" width="334" height="22"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<textInputTraits key="textInputTraits" autocapitalizationType="words"/>
</textField>
@@ -176,7 +176,7 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Name" textAlignment="natural" adjustsFontForContentSizeCategory="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="ZdA-rl-9eP">
<rect key="frame" x="20" y="11.5" width="334" height="21"/>
<rect key="frame" x="20" y="11" width="334" height="22"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<textInputTraits key="textInputTraits" autocapitalizationType="words"/>
</textField>
@@ -377,10 +377,99 @@
</objects>
<point key="canvasLocation" x="157" y="-591"/>
</scene>
<!--Extension Point Inspector View Controller-->
<scene sceneID="OYN-w4-caJ">
<objects>
<tableViewController storyboardIdentifier="ExtensionPointInspectorViewController" id="1B7-3Y-VYf" customClass="ExtensionPointInspectorViewController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="insetGrouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="sMo-hq-Gps">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<sections>
<tableViewSection id="hGI-fH-ovr">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" id="hx7-HU-HV2" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="18" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="hx7-HU-HV2" id="fEV-cR-i6h">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="YJL-5w-N2S">
<rect key="frame" x="20" y="11" width="334" height="22"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstItem="YJL-5w-N2S" firstAttribute="leading" secondItem="fEV-cR-i6h" secondAttribute="leadingMargin" id="kx6-6v-VNw"/>
<constraint firstItem="YJL-5w-N2S" firstAttribute="top" secondItem="fEV-cR-i6h" secondAttribute="topMargin" id="l6Y-A0-BFs"/>
<constraint firstAttribute="bottomMargin" secondItem="YJL-5w-N2S" secondAttribute="bottom" id="nKi-1U-g6E"/>
<constraint firstAttribute="trailingMargin" secondItem="YJL-5w-N2S" secondAttribute="trailing" id="o5n-Co-7RG"/>
</constraints>
</tableViewCellContentView>
</tableViewCell>
</cells>
</tableViewSection>
<tableViewSection id="OcC-FF-jGv">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" id="k4j-va-uaO" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="98" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="k4j-va-uaO" id="bQ8-mc-QAj">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="IhW-3B-PM7" customClass="VibrantButton" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
<constraints>
<constraint firstAttribute="height" constant="44" id="qwy-Nb-VrG"/>
</constraints>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<state key="normal" title="Disable Extension">
<color key="titleColor" systemColor="systemRedColor" red="1" green="0.23137254900000001" blue="0.18823529410000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted">
<color key="titleColor" systemColor="systemRedColor" red="1" green="0.23137254900000001" blue="0.18823529410000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="color" keyPath="backgroundHighlightColor">
<color key="value" name="deleteBackgroundColor"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
<connections>
<action selector="disable:" destination="1B7-3Y-VYf" eventType="touchUpInside" id="hVd-LH-FhC"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="IhW-3B-PM7" firstAttribute="centerY" secondItem="bQ8-mc-QAj" secondAttribute="centerY" id="DLY-b7-amc"/>
<constraint firstItem="IhW-3B-PM7" firstAttribute="leading" secondItem="bQ8-mc-QAj" secondAttribute="leading" id="LlY-8t-XJf"/>
<constraint firstAttribute="trailing" secondItem="IhW-3B-PM7" secondAttribute="trailing" id="Ua9-qY-YaN"/>
</constraints>
</tableViewCellContentView>
</tableViewCell>
</cells>
</tableViewSection>
</sections>
<connections>
<outlet property="dataSource" destination="1B7-3Y-VYf" id="Ro3-xz-VDK"/>
<outlet property="delegate" destination="1B7-3Y-VYf" id="X3w-Zg-zKw"/>
</connections>
</tableView>
<navigationItem key="navigationItem" id="bBU-mK-vL1"/>
<connections>
<outlet property="extensionDescription" destination="YJL-5w-N2S" id="zam-r3-KIC"/>
</connections>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="cc3-yd-zmS" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1549" y="-591"/>
</scene>
</scenes>
<resources>
<image name="safari" catalog="system" width="64" height="60"/>
<image name="safari.fill" catalog="system" width="64" height="60"/>
<image name="safari" catalog="system" width="128" height="121"/>
<image name="safari.fill" catalog="system" width="128" height="121"/>
<namedColor name="deleteBackgroundColor">
<color red="1" green="0.23100000619888306" blue="0.18799999356269836" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>

View File

@@ -55,7 +55,7 @@ struct MasterTimelineAccessibilityCellLayout: MasterTimelineCellLayout {
currentPoint.y = [self.titleRect, self.summaryRect].maxY()
if cellData.showFeedName {
if cellData.showFeedName != .none {
self.feedNameRect = MasterTimelineAccessibilityCellLayout.rectForFeedName(cellData, currentPoint, textAreaWidth)
currentPoint.y = self.feedNameRect.maxY
} else {

View File

@@ -15,7 +15,8 @@ struct MasterTimelineCellData {
let summary: String
let dateString: String
let feedName: String
let showFeedName: Bool
let byline: String
let showFeedName: ShowFeedName
let iconImage: IconImage? // feed icon, user avatar, or favicon
let showIcon: Bool // Make space even when icon is nil
let featuredImage: UIImage? // image from within the article
@@ -24,7 +25,7 @@ struct MasterTimelineCellData {
let numberOfLines: Int
let iconSize: IconSize
init(article: Article, showFeedName: Bool, feedName: String?, iconImage: IconImage?, showIcon: Bool, featuredImage: UIImage?, numberOfLines: Int, iconSize: IconSize) {
init(article: Article, showFeedName: ShowFeedName, feedName: String?, byline: String?, iconImage: IconImage?, showIcon: Bool, featuredImage: UIImage?, numberOfLines: Int, iconSize: IconSize) {
self.title = ArticleStringFormatter.truncatedTitle(article)
self.summary = ArticleStringFormatter.truncatedSummary(article)
@@ -37,6 +38,12 @@ struct MasterTimelineCellData {
else {
self.feedName = ""
}
if let byline = byline {
self.byline = byline
} else {
self.byline = ""
}
self.showFeedName = showFeedName
@@ -56,7 +63,8 @@ struct MasterTimelineCellData {
self.summary = ""
self.dateString = ""
self.feedName = ""
self.showFeedName = false
self.byline = ""
self.showFeedName = .none
self.showIcon = false
self.iconImage = nil
self.featuredImage = nil

View File

@@ -98,7 +98,8 @@ extension MasterTimelineCellLayout {
var r = CGRect.zero
r.origin = point
let size = SingleLineUILabelSizer.size(for: cellData.feedName, font: MasterTimelineDefaultCellLayout.feedNameFont)
let feedName = cellData.showFeedName == .feed ? cellData.feedName : cellData.byline
let size = SingleLineUILabelSizer.size(for: feedName, font: MasterTimelineDefaultCellLayout.feedNameFont)
r.size = size
if r.size.width > textAreaWidth {

View File

@@ -172,12 +172,18 @@ private extension MasterTimelineTableViewCell {
}
func updateFeedNameView() {
if cellData.showFeedName {
switch cellData.showFeedName {
case .feed:
showView(feedNameView)
feedNameView.font = MasterTimelineDefaultCellLayout.feedNameFont
feedNameView.textColor = secondaryLabelColor
updateTextFieldText(feedNameView, cellData.feedName)
} else {
case .byline:
showView(feedNameView)
feedNameView.font = MasterTimelineDefaultCellLayout.feedNameFont
feedNameView.textColor = secondaryLabelColor
updateTextFieldText(feedNameView, cellData.byline)
case .none:
hideView(feedNameView)
}
}

View File

@@ -489,7 +489,7 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner
let status = ArticleStatus(articleID: prototypeID, read: false, starred: false, dateArrived: Date())
let prototypeArticle = Article(accountID: prototypeID, articleID: prototypeID, webFeedID: prototypeID, uniqueID: prototypeID, title: longTitle, contentHTML: nil, contentText: nil, url: nil, externalURL: nil, summary: nil, imageURL: nil, datePublished: nil, dateModified: nil, authors: nil, status: status)
let prototypeCellData = MasterTimelineCellData(article: prototypeArticle, showFeedName: true, feedName: "Prototype Feed Name", iconImage: nil, showIcon: false, featuredImage: nil, numberOfLines: numberOfTextLines, iconSize: iconSize)
let prototypeCellData = MasterTimelineCellData(article: prototypeArticle, showFeedName: .feed, feedName: "Prototype Feed Name", byline: nil, iconImage: nil, showIcon: false, featuredImage: nil, numberOfLines: numberOfTextLines, iconSize: iconSize)
if UIApplication.shared.preferredContentSizeCategory.isAccessibilityCategory {
let layout = MasterTimelineAccessibilityCellLayout(width: tableView.bounds.width, insets: tableView.safeAreaInsets, cellData: prototypeCellData)
@@ -649,7 +649,7 @@ private extension MasterTimelineViewController {
let showFeedNames = coordinator.showFeedNames
let showIcon = coordinator.showIcons && iconImage != nil
cell.cellData = MasterTimelineCellData(article: article, showFeedName: showFeedNames, feedName: article.webFeed?.nameForDisplay, iconImage: iconImage, showIcon: showIcon, featuredImage: featuredImage, numberOfLines: numberOfTextLines, iconSize: iconSize)
cell.cellData = MasterTimelineCellData(article: article, showFeedName: showFeedNames, feedName: article.webFeed?.nameForDisplay, byline: article.byline(), iconImage: iconImage, showIcon: showIcon, featuredImage: featuredImage, numberOfLines: numberOfTextLines, iconSize: iconSize)
}

View File

@@ -0,0 +1,15 @@
{
"images" : [
{
"filename" : "twitter.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}

View File

@@ -23,6 +23,12 @@ enum SearchScope: Int {
case global = 1
}
enum ShowFeedName {
case none
case byline
case feed
}
class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
var undoableCommands = [UndoableCommand]()
@@ -159,7 +165,7 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
var timelineMiddleIndexPath: IndexPath?
private(set) var showFeedNames = false
private(set) var showFeedNames = ShowFeedName.none
private(set) var showIcons = false
var prevFeedIndexPath: IndexPath? {
@@ -1454,16 +1460,28 @@ private extension SceneCoordinator {
func updateShowNamesAndIcons() {
if timelineFeed is WebFeed {
showFeedNames = false
showFeedNames = {
for article in articles {
if !article.byline().isEmpty {
return .byline
}
}
return .none
}()
} else {
showFeedNames = true
showFeedNames = .feed
}
if showFeedNames {
if showFeedNames == .feed {
self.showIcons = true
return
}
if showFeedNames == .none {
self.showIcons = false
return
}
for article in articles {
if let authors = article.authors {
for author in authors {

View File

@@ -40,27 +40,27 @@ class AddAccountViewController: UITableViewController, AddAccountDismissDelegate
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SettingsAccountTableViewCell", for: indexPath) as! SettingsAccountTableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "SettingsAccountTableViewCell", for: indexPath) as! SettingsComboTableViewCell
switch addableAccountTypes[indexPath.row] {
case .onMyMac:
cell.accountNameLabel?.text = Account.defaultLocalAccountName
cell.accountImage?.image = AppAssets.image(for: .onMyMac)
cell.comboNameLabel?.text = Account.defaultLocalAccountName
cell.comboImage?.image = AppAssets.image(for: .onMyMac)
case .cloudKit:
cell.accountNameLabel?.text = NSLocalizedString("iCloud", comment: "iCloud")
cell.accountImage?.image = AppAssets.accountCloudKitImage
cell.comboNameLabel?.text = NSLocalizedString("iCloud", comment: "iCloud")
cell.comboImage?.image = AppAssets.accountCloudKitImage
case .feedbin:
cell.accountNameLabel?.text = NSLocalizedString("Feedbin", comment: "Feedbin")
cell.accountImage?.image = AppAssets.accountFeedbinImage
cell.comboNameLabel?.text = NSLocalizedString("Feedbin", comment: "Feedbin")
cell.comboImage?.image = AppAssets.accountFeedbinImage
case .feedWrangler:
cell.accountNameLabel?.text = NSLocalizedString("Feed Wrangler", comment: "Feed Wrangler")
cell.accountImage?.image = AppAssets.accountFeedWranglerImage
cell.comboNameLabel?.text = NSLocalizedString("Feed Wrangler", comment: "Feed Wrangler")
cell.comboImage?.image = AppAssets.accountFeedWranglerImage
case .feedly:
cell.accountNameLabel?.text = NSLocalizedString("Feedly", comment: "Feedly")
cell.accountImage?.image = AppAssets.accountFeedlyImage
cell.comboNameLabel?.text = NSLocalizedString("Feedly", comment: "Feedly")
cell.comboImage?.image = AppAssets.accountFeedlyImage
case .newsBlur:
cell.accountNameLabel?.text = NSLocalizedString("NewsBlur", comment: "NewsBlur")
cell.accountImage?.image = AppAssets.accountNewsBlurImage
cell.comboNameLabel?.text = NSLocalizedString("NewsBlur", comment: "NewsBlur")
cell.comboImage?.image = AppAssets.accountNewsBlurImage
default:
break
}

View File

@@ -0,0 +1,59 @@
//
// AddExtensionPointViewController.swift
// NetNewsWire-iOS
//
// Created by Maurice Parker on 4/16/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import UIKit
protocol AddExtensionPointDismissDelegate: UIViewController {
func dismiss()
}
class AddExtensionPointViewController: UITableViewController, AddExtensionPointDismissDelegate {
private var availableExtensionPointTypes = [ExtensionPoint.Type]()
override func viewDidLoad() {
super.viewDidLoad()
availableExtensionPointTypes = ExtensionPointManager.shared.availableExtensionPointTypes
}
override func numberOfSections(in tableView: UITableView) -> Int {
1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return availableExtensionPointTypes.count
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 52.0
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SettingsExtensionTableViewCell", for: indexPath) as! SettingsComboTableViewCell
let extensionPointType = availableExtensionPointTypes[indexPath.row]
cell.comboNameLabel?.text = extensionPointType.title
cell.comboImage?.image = extensionPointType.templateImage
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let navController = UIStoryboard.settings.instantiateViewController(withIdentifier: "EnableExtensionPointNavigationViewController") as! UINavigationController
navController.modalPresentationStyle = .currentContext
let enableViewController = navController.topViewController as! EnableExtensionPointViewController
enableViewController.delegate = self
enableViewController.extensionPointType = availableExtensionPointTypes[indexPath.row]
present(navController, animated: true)
}
func dismiss() {
navigationController?.popViewController(animated: false)
}
}

View File

@@ -0,0 +1,59 @@
//
// AddExtensionViewContrller.swift
// NetNewsWire-iOS
//
// Created by Maurice Parker on 4/16/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import UIKit
protocol AddExtensionDismissDelegate: UIViewController {
func dismiss()
}
class AddExtensionViewController: UITableViewController, AddExtensionDismissDelegate {
private var availableExtensionPointTypes = [ExtensionPoint.Type]()
override func viewDidLoad() {
super.viewDidLoad()
availableExtensionPointTypes = ExtensionPointManager.shared.availableExtensionPointTypes
}
override func numberOfSections(in tableView: UITableView) -> Int {
1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return availableExtensionPointTypes.count
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 52.0
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SettingsExtensionTableViewCell", for: indexPath) as! SettingsComboTableViewCell
let extensionPointType = availableExtensionPointTypes[indexPath.row]
cell.comboNameLabel?.text = extensionPointType.title
cell.comboImage?.image = extensionPointType.templateImage
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let navController = UIStoryboard.settings.instantiateViewController(withIdentifier: "EnableExtensiontNavigationViewController") as! UINavigationController
navController.modalPresentationStyle = .currentContext
let enableViewController = navController.topViewController as! EnableExtensionViewController
enableViewController.delegate = self
enableViewController.extensionPointType = availableExtensionPointTypes[indexPath.row]
present(navController, animated: true)
}
func dismiss() {
navigationController?.popViewController(animated: false)
}
}

View File

@@ -0,0 +1,132 @@
//
// EnableExtensionPointViewController.swift
// NetNewsWire-iOS
//
// Created by Maurice Parker on 4/16/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import UIKit
import AuthenticationServices
import Account
import OAuthSwift
import Secrets
class EnableExtensionPointViewController: UITableViewController {
@IBOutlet weak var extensionDescription: UILabel!
private let callbackURL = URL(string: "netnewswire://")!
private var oauth: OAuthSwift?
weak var delegate: AddExtensionPointDismissDelegate?
var extensionPointType: ExtensionPoint.Type?
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = extensionPointType?.title
extensionDescription.attributedText = extensionPointType?.description
tableView.register(ImageHeaderView.self, forHeaderFooterViewReuseIdentifier: "SectionHeader")
}
@IBAction func cancel(_ sender: Any) {
dismiss(animated: true, completion: nil)
delegate?.dismiss()
}
@IBAction func enable(_ sender: Any) {
guard let extensionPointType = extensionPointType else { return }
if let oauth1 = extensionPointType as? OAuth1SwiftProvider.Type {
enableOauth1(oauth1)
} else {
ExtensionPointManager.shared.activateExtensionPoint(extensionPointType)
dismiss(animated: true, completion: nil)
delegate?.dismiss()
}
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return section == 0 ? ImageHeaderView.rowHeight : super.tableView(tableView, heightForHeaderInSection: section)
}
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if section == 0 {
let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "SectionHeader") as! ImageHeaderView
headerView.imageView.image = extensionPointType?.templateImage
return headerView
} else {
return super.tableView(tableView, viewForHeaderInSection: section)
}
}
}
extension EnableExtensionPointViewController: OAuthSwiftURLHandlerType {
public func handle(_ url: URL) {
let session = ASWebAuthenticationSession(url: url, callbackURLScheme: callbackURL.scheme, completionHandler: { (url, error) in
if let callbackedURL = url {
OAuth1Swift.handle(url: callbackedURL)
}
guard let error = error else { return }
self.oauth?.cancel()
self.oauth = nil
DispatchQueue.main.async {
self.dismiss(animated: true, completion: nil)
self.delegate?.dismiss()
}
if case ASWebAuthenticationSessionError.canceledLogin = error {
print("Login cancelled.")
} else {
self.presentError(error)
}
})
session.presentationContextProvider = self
if !session.start() {
print("Session failed to start!!!")
}
}
}
extension EnableExtensionPointViewController: ASWebAuthenticationPresentationContextProviding {
public func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
return view.window!
}
}
private extension EnableExtensionPointViewController {
func enableOauth1(_ provider: OAuth1SwiftProvider.Type) {
let oauth1 = provider.oauth1Swift
self.oauth = oauth1
oauth1.authorizeURLHandler = self
oauth1.authorize(withCallbackURL: callbackURL) { [weak self] result in
guard let self = self, let extensionPointType = self.extensionPointType else { return }
switch result {
case .success(let tokenSuccess):
ExtensionPointManager.shared.activateExtensionPoint(extensionPointType, tokenSuccess: tokenSuccess)
self.dismiss(animated: true, completion: nil)
self.delegate?.dismiss()
case .failure(let oauthSwiftError):
self.presentError(oauthSwiftError)
}
self.oauth?.cancel()
self.oauth = nil
}
}
}

View File

@@ -0,0 +1,132 @@
//
// EnableExtensionViewController.swift
// NetNewsWire-iOS
//
// Created by Maurice Parker on 4/16/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import UIKit
import AuthenticationServices
import Account
import OAuthSwift
import Secrets
class EnableExtensionPointViewController: UITableViewController {
@IBOutlet weak var extensionDescription: UILabel!
private let callbackURL = URL(string: "vincodennw://")!
private var oauth: OAuthSwift?
weak var delegate: AddExtensionPointDismissDelegate?
var extensionPointType: ExtensionPoint.Type?
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = extensionPointType?.title ?? ""
extensionDescription = extensionPointType?.extensionDescription ?? ""
tableView.register(ImageHeaderView.self, forHeaderFooterViewReuseIdentifier: "SectionHeader")
}
@IBAction func cancel(_ sender: Any) {
dismiss(animated: true, completion: nil)
delegate?.dismiss()
}
@IBAction func enable(_ sender: Any) {
guard let extensionPointType = extensionPointType else { return }
if let oauth1 = extensionPointType as? OAuth1SwiftProvider.Type {
enableOauth1(oauth1)
} else {
ExtensionPointManager.shared.activateExtensionPoint(extensionPointType)
dismiss(animated: true, completion: nil)
delegate?.dismiss()
}
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return section == 0 ? ImageHeaderView.rowHeight : super.tableView(tableView, heightForHeaderInSection: section)
}
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if section == 0 {
let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "SectionHeader") as! ImageHeaderView
headerView.imageView.image = extensionPointType?.templateImage
return headerView
} else {
return super.tableView(tableView, viewForHeaderInSection: section)
}
}
}
extension EnableExtensionPointViewController: OAuthSwiftURLHandlerType {
public func handle(_ url: URL) {
let session = ASWebAuthenticationSession(url: url, callbackURLScheme: callbackURL.scheme, completionHandler: { (url, error) in
if let callbackedURL = url {
OAuth1Swift.handle(url: callbackedURL)
}
guard let error = error else { return }
self.oauth?.cancel()
self.oauth = nil
DispatchQueue.main.async {
self.dismiss(animated: true, completion: nil)
self.delegate?.dismiss()
}
if case ASWebAuthenticationSessionError.canceledLogin = error {
print("Login cancelled.")
} else {
self.presentError(error)
}
})
session.presentationContextProvider = self
if !session.start() {
print("Session failed to start!!!")
}
}
}
extension EnableExtensionPointViewController: ASWebAuthenticationPresentationContextProviding {
public func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
return view.window!
}
}
private extension EnableExtensionPointViewController {
func enableOauth1(_ provider: OAuth1SwiftProvider.Type) {
let oauth1 = provider.oauth1Swift
self.oauth = oauth1
oauth1.authorizeURLHandler = self
oauth1.authorize(withCallbackURL: callbackURL) { [weak self] result in
guard let self = self, let extensionPointType = self.extensionPointType else { return }
switch result {
case .success(let tokenSuccess):
ExtensionPointManager.shared.activateExtensionPoint(extensionPointType, tokenSuccess: tokenSuccess)
self.dismiss(animated: true, completion: nil)
self.delegate?.dismiss()
case .failure(let oauthSwiftError):
self.presentError(oauthSwiftError)
}
self.oauth?.cancel()
self.oauth = nil
}
}
}

View File

@@ -58,10 +58,31 @@
</tableViewCell>
</cells>
</tableViewSection>
<tableViewSection headerTitle="Extensions" id="oRB-NZ-WpG">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="QFr-Rs-eW2" style="IBUITableViewCellStyleDefault" id="6QJ-fX-278" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="255.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="6QJ-fX-278" id="PDs-8c-XUa">
<rect key="frame" x="0.0" y="0.0" width="343" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Add Extension" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="QFr-Rs-eW2">
<rect key="frame" x="20" y="0.0" width="315" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
</tableViewCell>
</cells>
</tableViewSection>
<tableViewSection headerTitle="Feeds" id="hAC-uA-RbS">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="4Hg-B3-zAE" style="IBUITableViewCellStyleDefault" id="glf-Pg-s3P" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="255.5" width="374" height="44"/>
<rect key="frame" x="20" y="355.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="glf-Pg-s3P" id="bPA-43-Oqh">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
@@ -78,7 +99,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="25J-iX-3at" style="IBUITableViewCellStyleDefault" id="qke-Ha-PXl" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="299.5" width="374" height="44"/>
<rect key="frame" x="20" y="399.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="qke-Ha-PXl" id="pZi-ck-RV5">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
@@ -95,7 +116,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="dXN-Mw-yf2" style="IBUITableViewCellStyleDefault" id="F0L-Ut-reX" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="343.5" width="374" height="44"/>
<rect key="frame" x="20" y="443.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="F0L-Ut-reX" id="5SX-M2-2jR">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
@@ -116,7 +137,7 @@
<tableViewSection headerTitle="Timeline" id="9Pk-Y8-JVJ">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="MpA-w1-Wwh" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="443.5" width="374" height="44"/>
<rect key="frame" x="20" y="543.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="MpA-w1-Wwh" id="GhU-ib-Mz8">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
@@ -149,7 +170,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="f7r-AZ-aDn" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="487.5" width="374" height="44"/>
<rect key="frame" x="20" y="587.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="f7r-AZ-aDn" id="KHC-cc-tOC">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
@@ -182,7 +203,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="5wo-fM-0l6" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="531.5" width="374" height="44"/>
<rect key="frame" x="20" y="631.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="5wo-fM-0l6" id="XAn-lK-LoN">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
@@ -215,7 +236,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" id="8Gj-qz-NMY" customClass="VibrantBasicTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="575.5" width="374" height="44"/>
<rect key="frame" x="20" y="675.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="8Gj-qz-NMY" id="OTe-tG-sb4">
<rect key="frame" x="0.0" y="0.0" width="343" height="44"/>
@@ -242,7 +263,7 @@
<tableViewSection headerTitle="Articles" id="TRr-Ew-IvU">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="SXs-NQ-y3U" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="675.5" width="374" height="44"/>
<rect key="frame" x="20" y="775.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="SXs-NQ-y3U" id="BpI-Hz-KH2">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
@@ -275,7 +296,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="WR6-xo-ty2" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="719.5" width="374" height="44"/>
<rect key="frame" x="20" y="819.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="WR6-xo-ty2" id="zX8-l2-bVH">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
@@ -320,7 +341,7 @@
<tableViewSection headerTitle="Appearance" id="TkH-4v-yhk">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" id="EvG-yE-gDF" customClass="VibrantBasicTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="819.5" width="374" height="44"/>
<rect key="frame" x="20" y="919.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="EvG-yE-gDF" id="wBN-zJ-6pN">
<rect key="frame" x="0.0" y="0.0" width="343" height="44"/>
@@ -356,14 +377,14 @@
<tableViewSection headerTitle="Help" id="CS8-fJ-ghn">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="uGk-2d-oFc" style="IBUITableViewCellStyleDefault" id="Tle-IV-D40" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="919.5" width="374" height="44"/>
<rect key="frame" x="20" y="1019.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="Tle-IV-D40" id="IJD-ZB-8Wm">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="NetNewsWire Help" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="uGk-2d-oFc">
<rect key="frame" x="20" y="0.0" width="334" height="44"/>
<rect key="frame" x="15" y="0.0" width="351" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
@@ -373,14 +394,14 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="6G3-yV-Eyh" style="IBUITableViewCellStyleDefault" id="Tbf-fE-nfx" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="963.5" width="374" height="44"/>
<rect key="frame" x="20" y="1063.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="Tbf-fE-nfx" id="beV-vI-g3r">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Website" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" id="6G3-yV-Eyh">
<rect key="frame" x="20" y="0.0" width="334" height="44"/>
<rect key="frame" x="15" y="0.0" width="351" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
@@ -390,7 +411,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="lfL-bQ-sOp" style="IBUITableViewCellStyleDefault" id="mFn-fE-zqa" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="1007.5" width="374" height="44"/>
<rect key="frame" x="20" y="1107.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="mFn-fE-zqa" id="jTe-mf-MRj">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
@@ -407,7 +428,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="DDJ-8P-3YY" style="IBUITableViewCellStyleDefault" id="iGs-ze-4gQ" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="1051.5" width="374" height="44"/>
<rect key="frame" x="20" y="1151.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="iGs-ze-4gQ" id="EqZ-rF-N0l">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
@@ -424,7 +445,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="DsV-Qv-X4K" style="IBUITableViewCellStyleDefault" id="taJ-sg-wnU" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="1095.5" width="374" height="44"/>
<rect key="frame" x="20" y="1195.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="taJ-sg-wnU" id="axB-si-1KM">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
@@ -441,7 +462,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="zMz-hU-UYU" style="IBUITableViewCellStyleDefault" id="OXi-cg-ab9" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="1139.5" width="374" height="44"/>
<rect key="frame" x="20" y="1239.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="OXi-cg-ab9" id="npR-a0-9wv">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
@@ -458,7 +479,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="T7x-zl-6Yf" style="IBUITableViewCellStyleDefault" id="VpI-0o-3Px" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="1183.5" width="374" height="44"/>
<rect key="frame" x="20" y="1283.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="VpI-0o-3Px" id="xRH-i4-vne">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
@@ -475,7 +496,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="NeD-y8-KrM" style="IBUITableViewCellStyleDefault" id="TIX-yK-rC6" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="1227.5" width="374" height="44"/>
<rect key="frame" x="20" y="1327.5" width="374" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="TIX-yK-rC6" id="qr8-EN-Ofg">
<rect key="frame" x="0.0" y="0.0" width="355" height="44"/>
@@ -527,7 +548,7 @@
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="SettingsAccountTableViewCell" rowHeight="55" id="UFl-6I-ucw" customClass="SettingsAccountTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="SettingsAccountTableViewCell" rowHeight="55" id="UFl-6I-ucw" customClass="SettingsComboTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="55.5" width="374" height="55"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="UFl-6I-ucw" id="99i-Ge-guB">
@@ -560,8 +581,8 @@
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="accountImage" destination="tb2-dO-AhR" id="Ucm-F4-aev"/>
<outlet property="accountNameLabel" destination="116-rt-msI" id="nn5-2i-HqG"/>
<outlet property="comboImage" destination="tb2-dO-AhR" id="2L5-ha-jdX"/>
<outlet property="comboNameLabel" destination="116-rt-msI" id="EJb-1l-k4u"/>
</connections>
</tableViewCell>
</prototypes>
@@ -726,7 +747,7 @@
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="kRt-nH-nOf" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1680" y="151"/>
<point key="canvasLocation" x="2388" y="151"/>
</scene>
<!--Timeline Layout-->
<scene sceneID="XRu-Jc-bbU">
@@ -829,7 +850,7 @@
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iNo-Vj-YZx" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="2346" y="151"/>
<point key="canvasLocation" x="3072" y="151"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="Ezn-Ny-zye">
@@ -885,7 +906,7 @@
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Oq6-5f-Oa7" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="3096" y="151"/>
<point key="canvasLocation" x="3826" y="158"/>
</scene>
<!--Color Palette-->
<scene sceneID="1mT-fg-ezs">
@@ -926,9 +947,170 @@
</objects>
<point key="canvasLocation" x="3743" y="151"/>
</scene>
<!--Add Extension Point View Controller-->
<scene sceneID="e22-Tk-eWN">
<objects>
<tableViewController storyboardIdentifier="AddExtensionPointViewController" id="x52-Ls-0dI" customClass="AddExtensionPointViewController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="insetGrouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="X7z-0u-RKM">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="SettingsExtensionTableViewCell" rowHeight="55" id="SPQ-gc-wuP" customClass="SettingsComboTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="55.5" width="374" height="55"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="SPQ-gc-wuP" id="38G-tD-Eks">
<rect key="frame" x="0.0" y="0.0" width="374" height="55"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="gMc-YX-gQa">
<rect key="frame" x="20" y="11.5" width="165.5" height="32"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="gear" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="fQm-sU-5TF">
<rect key="frame" x="0.0" y="0.0" width="32" height="32.5"/>
<color key="tintColor" systemColor="labelColor" cocoaTouchSystemColor="darkTextColor"/>
<constraints>
<constraint firstAttribute="height" constant="32" id="QJW-VY-n7f"/>
<constraint firstAttribute="width" constant="32" id="T3S-8F-Clj"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Extension" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="zuQ-ty-Tf1">
<rect key="frame" x="48" y="0.0" width="117.5" height="32"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleTitle1"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
</subviews>
<constraints>
<constraint firstItem="gMc-YX-gQa" firstAttribute="leading" secondItem="38G-tD-Eks" secondAttribute="leading" constant="20" symbolic="YES" id="DAz-fZ-LFa"/>
<constraint firstItem="gMc-YX-gQa" firstAttribute="centerY" secondItem="38G-tD-Eks" secondAttribute="centerY" id="Qpo-pr-TGF"/>
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="comboImage" destination="fQm-sU-5TF" id="aFs-Li-lHU"/>
<outlet property="comboNameLabel" destination="zuQ-ty-Tf1" id="uty-Eq-1oX"/>
</connections>
</tableViewCell>
</prototypes>
<sections/>
<connections>
<outlet property="dataSource" destination="x52-Ls-0dI" id="vsT-sk-4aY"/>
<outlet property="delegate" destination="x52-Ls-0dI" id="4Vo-yb-5Mf"/>
</connections>
</tableView>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="A3X-mp-vlt" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1691" y="151"/>
</scene>
<!--Modal Navigation Controller-->
<scene sceneID="t9A-uP-4Dk">
<objects>
<navigationController storyboardIdentifier="EnableExtensionPointNavigationViewController" id="mA0-Yf-esc" customClass="ModalNavigationController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="iXJ-DA-pQC">
<rect key="frame" x="0.0" y="44" width="414" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<connections>
<segue destination="8Eu-UD-eCa" kind="relationship" relationship="rootViewController" id="zE1-0Q-l09"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="g07-xO-ryv" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1690" y="815"/>
</scene>
<!--Extension-->
<scene sceneID="sHq-4g-bAA">
<objects>
<tableViewController id="8Eu-UD-eCa" customClass="EnableExtensionPointViewController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="insetGrouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="hqD-G5-jzC">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<sections>
<tableViewSection id="rqj-gU-4He">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="ALK-Z6-aOR" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="18" width="374" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="ALK-Z6-aOR" id="Rqf-t4-F8q">
<rect key="frame" x="0.0" y="0.0" width="374" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VCu-Yi-0ts">
<rect key="frame" x="20" y="11" width="334" height="22"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstItem="VCu-Yi-0ts" firstAttribute="top" secondItem="Rqf-t4-F8q" secondAttribute="topMargin" id="CiI-mf-hfd"/>
<constraint firstAttribute="bottomMargin" secondItem="VCu-Yi-0ts" secondAttribute="bottom" id="QW3-Ty-Hnz"/>
<constraint firstItem="VCu-Yi-0ts" firstAttribute="leading" secondItem="Rqf-t4-F8q" secondAttribute="leadingMargin" id="R3c-n2-gAq"/>
<constraint firstAttribute="trailingMargin" secondItem="VCu-Yi-0ts" secondAttribute="trailing" id="kS4-Gc-Eaf"/>
</constraints>
</tableViewCellContentView>
</tableViewCell>
</cells>
</tableViewSection>
<tableViewSection id="7Nq-pj-Wqz">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="eZ5-P9-opw" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="97.5" width="374" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="eZ5-P9-opw" id="RlA-Zq-tRl">
<rect key="frame" x="0.0" y="0.0" width="374" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="cY9-Uk-Vlx" customClass="VibrantButton" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
<constraints>
<constraint firstAttribute="height" constant="44" id="KfT-5A-V6M"/>
</constraints>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<state key="normal" title="Enable">
<color key="titleColor" name="secondaryAccentColor"/>
</state>
<connections>
<action selector="enable:" destination="8Eu-UD-eCa" eventType="touchUpInside" id="ce5-pt-YN7"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="cY9-Uk-Vlx" secondAttribute="trailing" id="KpS-U0-BBK"/>
<constraint firstItem="cY9-Uk-Vlx" firstAttribute="leading" secondItem="RlA-Zq-tRl" secondAttribute="leading" id="eEr-9i-9OF"/>
<constraint firstItem="cY9-Uk-Vlx" firstAttribute="centerY" secondItem="RlA-Zq-tRl" secondAttribute="centerY" id="gCV-Df-MUK"/>
</constraints>
</tableViewCellContentView>
</tableViewCell>
</cells>
</tableViewSection>
</sections>
<connections>
<outlet property="dataSource" destination="8Eu-UD-eCa" id="cue-E2-LrE"/>
<outlet property="delegate" destination="8Eu-UD-eCa" id="Nai-Ve-JDb"/>
</connections>
</tableView>
<navigationItem key="navigationItem" title="Extension" id="xuT-vz-veD">
<barButtonItem key="leftBarButtonItem" systemItem="cancel" id="FjO-N8-twm">
<connections>
<action selector="cancel:" destination="8Eu-UD-eCa" id="3rh-fd-LDm"/>
</connections>
</barButtonItem>
</navigationItem>
<connections>
<outlet property="extensionDescription" destination="VCu-Yi-0ts" id="grq-97-i1H"/>
</connections>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="5G7-cc-L54" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1690" y="1512"/>
</scene>
</scenes>
<resources>
<image name="accountLocal" width="99" height="77"/>
<image name="gear" catalog="system" width="128" height="119"/>
<namedColor name="primaryAccentColor">
<color red="0.031372549019607843" green="0.41568627450980394" blue="0.93333333333333335" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>

View File

@@ -8,18 +8,18 @@
import UIKit
class SettingsAccountTableViewCell: VibrantTableViewCell {
class SettingsComboTableViewCell: VibrantTableViewCell {
@IBOutlet weak var accountImage: UIImageView!
@IBOutlet weak var accountNameLabel: UILabel!
@IBOutlet weak var comboImage: UIImageView!
@IBOutlet weak var comboNameLabel: UILabel!
override func updateVibrancy(animated: Bool) {
super.updateVibrancy(animated: animated)
updateLabelVibrancy(accountNameLabel, color: labelColor, animated: animated)
updateLabelVibrancy(comboNameLabel, color: labelColor, animated: animated)
let tintColor = isHighlighted || isSelected ? AppAssets.vibrantTextColor : UIColor.label
UIView.animate(withDuration: duration(animated: animated)) {
self.accountImage?.tintColor = tintColor
self.comboImage?.tintColor = tintColor
}
}

View File

@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15505" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15509"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" id="JCb-QB-CrO" customClass="SettingsAccountTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" id="JCb-QB-CrO" customClass="SettingsComboTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="414" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="JCb-QB-CrO" id="FzD-t2-JGy">
@@ -39,8 +39,8 @@
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="accountImage" destination="yiw-9t-gil" id="E8w-FW-Jc9"/>
<outlet property="accountNameLabel" destination="TRx-RV-za8" id="BOl-hK-2mT"/>
<outlet property="comboImage" destination="yiw-9t-gil" id="WqT-gf-Pwq"/>
<outlet property="comboNameLabel" destination="TRx-RV-za8" id="CX9-Cp-qZP"/>
</connections>
<point key="canvasLocation" x="7" y="-9"/>
</tableViewCell>

View File

@@ -34,8 +34,9 @@ class SettingsViewController: UITableViewController {
NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange), name: .UserDidAddAccount, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange), name: .UserDidDeleteAccount, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(displayNameDidChange), name: .DisplayNameDidChange, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(activeExtensionPointsDidChange), name: .ActiveExtensionPointsDidChange, object: nil)
tableView.register(UINib(nibName: "SettingsAccountTableViewCell", bundle: nil), forCellReuseIdentifier: "SettingsAccountTableViewCell")
tableView.register(UINib(nibName: "SettingsComboTableViewCell", bundle: nil), forCellReuseIdentifier: "SettingsComboTableViewCell")
tableView.register(UINib(nibName: "SettingsTableViewCell", bundle: nil), forCellReuseIdentifier: "SettingsTableViewCell")
tableView.rowHeight = UITableView.automaticDimension
@@ -110,12 +111,14 @@ class SettingsViewController: UITableViewController {
case 1:
return AccountManager.shared.accounts.count + 1
case 2:
return ExtensionPointManager.shared.activeExtensionPoints.count + 1
case 3:
let defaultNumberOfRows = super.tableView(tableView, numberOfRowsInSection: section)
if AccountManager.shared.activeAccounts.isEmpty || AccountManager.shared.anyAccountHasFeedWithURL(appNewsURLString) {
return defaultNumberOfRows - 1
}
return defaultNumberOfRows
case 4:
case 5:
return traitCollection.userInterfaceIdiom == .phone ? 2 : 1
default:
return super.tableView(tableView, numberOfRowsInSection: section)
@@ -133,11 +136,26 @@ class SettingsViewController: UITableViewController {
cell = tableView.dequeueReusableCell(withIdentifier: "SettingsTableViewCell", for: indexPath)
cell.textLabel?.text = NSLocalizedString("Add Account", comment: "Accounts")
} else {
let acctCell = tableView.dequeueReusableCell(withIdentifier: "SettingsAccountTableViewCell", for: indexPath) as! SettingsAccountTableViewCell
let acctCell = tableView.dequeueReusableCell(withIdentifier: "SettingsComboTableViewCell", for: indexPath) as! SettingsComboTableViewCell
acctCell.applyThemeProperties()
let account = sortedAccounts[indexPath.row]
acctCell.accountImage?.image = AppAssets.image(for: account.type)
acctCell.accountNameLabel?.text = account.nameForDisplay
acctCell.comboImage?.image = AppAssets.image(for: account.type)
acctCell.comboNameLabel?.text = account.nameForDisplay
cell = acctCell
}
case 2:
let extensionPoints = Array(ExtensionPointManager.shared.activeExtensionPoints.values)
if indexPath.row == extensionPoints.count {
cell = tableView.dequeueReusableCell(withIdentifier: "SettingsTableViewCell", for: indexPath)
cell.textLabel?.text = NSLocalizedString("Add Extension", comment: "Extensions")
} else {
let acctCell = tableView.dequeueReusableCell(withIdentifier: "SettingsComboTableViewCell", for: indexPath) as! SettingsComboTableViewCell
acctCell.applyThemeProperties()
let extensionPoint = extensionPoints[indexPath.row]
acctCell.comboImage?.image = extensionPoint.templateImage
acctCell.comboNameLabel?.text = extensionPoint.title
cell = acctCell
}
@@ -166,6 +184,16 @@ class SettingsViewController: UITableViewController {
self.navigationController?.pushViewController(controller, animated: true)
}
case 2:
let extensionPoints = Array(ExtensionPointManager.shared.activeExtensionPoints.values)
if indexPath.row == extensionPoints.count {
let controller = UIStoryboard.settings.instantiateController(ofType: AddExtensionPointViewController.self)
self.navigationController?.pushViewController(controller, animated: true)
} else {
let controller = UIStoryboard.inspector.instantiateController(ofType: ExtensionPointInspectorViewController.self)
controller.extensionPoint = extensionPoints[indexPath.row]
self.navigationController?.pushViewController(controller, animated: true)
}
case 3:
switch indexPath.row {
case 0:
tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
@@ -185,7 +213,7 @@ class SettingsViewController: UITableViewController {
default:
break
}
case 3:
case 4:
switch indexPath.row {
case 3:
let timeline = UIStoryboard.settings.instantiateController(ofType: TimelineCustomizerViewController.self)
@@ -193,10 +221,10 @@ class SettingsViewController: UITableViewController {
default:
break
}
case 5:
case 6:
let colorPalette = UIStoryboard.settings.instantiateController(ofType: ColorPaletteTableViewController.self)
self.navigationController?.pushViewController(colorPalette, animated: true)
case 6:
case 7:
switch indexPath.row {
case 0:
openURL("https://ranchero.com/netnewswire/help/ios/5.0/en/")
@@ -310,6 +338,10 @@ class SettingsViewController: UITableViewController {
tableView.reloadData()
}
@objc func activeExtensionPointsDidChange() {
tableView.reloadData()
}
}
// MARK: OPML Document Picker

View File

@@ -71,7 +71,7 @@ private extension TimelinePreviewTableViewController {
let iconImage = IconImage(AppAssets.faviconTemplateImage.withTintColor(AppAssets.secondaryAccentColor))
return MasterTimelineCellData(article: prototypeArticle, showFeedName: true, feedName: "Feed Name", iconImage: iconImage, showIcon: true, featuredImage: nil, numberOfLines: AppDefaults.timelineNumberOfLines, iconSize: AppDefaults.timelineIconSize)
return MasterTimelineCellData(article: prototypeArticle, showFeedName: .feed, feedName: "Feed Name", byline: nil, iconImage: iconImage, showIcon: true, featuredImage: nil, numberOfLines: AppDefaults.timelineNumberOfLines, iconSize: AppDefaults.timelineIconSize)
}
}

View File

@@ -20,6 +20,10 @@ extension UIStoryboard {
return UIStoryboard(name: "Add", bundle: nil)
}
static var twitterAdd: UIStoryboard {
return UIStoryboard(name: "TwitterAdd", bundle: nil)
}
static var settings: UIStoryboard {
return UIStoryboard(name: "Settings", bundle: nil)
}