Update picker for Share Extension to be hierarchical and use icons. Issue #1269

This commit is contained in:
Maurice Parker 2019-11-16 19:44:01 -06:00
parent e74e6cb875
commit 397d8e8ffa
17 changed files with 236 additions and 131 deletions

View File

@ -13,7 +13,6 @@
5108F6B72375E612001ABC45 /* CacheCleaner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5108F6B52375E612001ABC45 /* CacheCleaner.swift */; };
5108F6D22375EED2001ABC45 /* TimelineCustomizerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5108F6D12375EED2001ABC45 /* TimelineCustomizerViewController.swift */; };
5108F6D42375EEEF001ABC45 /* TimelinePreviewTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5108F6D32375EEEF001ABC45 /* TimelinePreviewTableViewController.swift */; };
5108F6D623762309001ABC45 /* MasterTimelineIconSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5108F6D523762309001ABC45 /* MasterTimelineIconSize.swift */; };
5108F6D823763094001ABC45 /* TickMarkSlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5108F6D723763094001ABC45 /* TickMarkSlider.swift */; };
51102165233A7D6C0007A5F7 /* ArticleExtractorButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51102164233A7D6C0007A5F7 /* ArticleExtractorButton.swift */; };
5110C37D2373A8D100A9C04F /* InspectorIconHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5110C37C2373A8D100A9C04F /* InspectorIconHeaderView.swift */; };
@ -129,6 +128,14 @@
51A1699F235E10D700EB091F /* AboutViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A16995235E10D600EB091F /* AboutViewController.swift */; };
51A169A0235E10D700EB091F /* FeedbinAccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A16996235E10D700EB091F /* FeedbinAccountViewController.swift */; };
51A66685238075AE00CB272D /* AddWebFeedDefaultContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A66684238075AE00CB272D /* AddWebFeedDefaultContainer.swift */; };
51A9A5E02380C3F10033AADF /* AddWebFeedDefaultContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A66684238075AE00CB272D /* AddWebFeedDefaultContainer.swift */; };
51A9A5E12380C4FE0033AADF /* AppDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C45255226507D200C03939 /* AppDefaults.swift */; };
51A9A5E42380C8880033AADF /* ShareFolderPickerAccountCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 51A9A5E32380C8870033AADF /* ShareFolderPickerAccountCell.xib */; };
51A9A5E62380C8B20033AADF /* ShareFolderPickerFolderCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 51A9A5E52380C8B20033AADF /* ShareFolderPickerFolderCell.xib */; };
51A9A5E82380CA130033AADF /* ShareFolderPickerCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A9A5E72380CA130033AADF /* ShareFolderPickerCell.swift */; };
51A9A5ED2380D6000033AADF /* AppAssets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C45254226507D200C03939 /* AppAssets.swift */; };
51A9A5EE2380D6080033AADF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 84C9FC9B2262A1A900D921D6 /* Assets.xcassets */; };
51A9A5EF2380D63B0033AADF /* IconImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 516AE9DE2372269A007DEEAA /* IconImage.swift */; };
51B62E68233186730085F949 /* IconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51B62E67233186730085F949 /* IconView.swift */; };
51BB7C272335A8E5008E8144 /* ArticleActivityItemSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51BB7C262335A8E5008E8144 /* ArticleActivityItemSource.swift */; };
51BB7C312335ACDE008E8144 /* page.html in Resources */ = {isa = PBXBuildFile; fileRef = 51BB7C302335ACDE008E8144 /* page.html */; };
@ -212,8 +219,6 @@
51E3EB33229AB02C00645299 /* ErrorHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51E3EB32229AB02C00645299 /* ErrorHandler.swift */; };
51E3EB3D229AB08300645299 /* ErrorHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51E3EB3C229AB08300645299 /* ErrorHandler.swift */; };
51E43962238037C400015C31 /* AddWebFeedFolderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51E43961238037C400015C31 /* AddWebFeedFolderViewController.swift */; };
51E4397D23805A6D00015C31 /* FlattenedAccountFolderPickerData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51E4397C23805A6C00015C31 /* FlattenedAccountFolderPickerData.swift */; };
51E4397E23805A6D00015C31 /* FlattenedAccountFolderPickerData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51E4397C23805A6C00015C31 /* FlattenedAccountFolderPickerData.swift */; };
51E4398023805EBC00015C31 /* AddWebFeedFolderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51E4397F23805EBC00015C31 /* AddWebFeedFolderTableViewCell.swift */; };
51E595A5228CC36500FCC42B /* ArticleStatusSyncTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51E595A4228CC36500FCC42B /* ArticleStatusSyncTimer.swift */; };
51E595A6228CC36500FCC42B /* ArticleStatusSyncTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51E595A4228CC36500FCC42B /* ArticleStatusSyncTimer.swift */; };
@ -1208,7 +1213,6 @@
5108F6B52375E612001ABC45 /* CacheCleaner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CacheCleaner.swift; sourceTree = "<group>"; };
5108F6D12375EED2001ABC45 /* TimelineCustomizerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineCustomizerViewController.swift; sourceTree = "<group>"; };
5108F6D32375EEEF001ABC45 /* TimelinePreviewTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelinePreviewTableViewController.swift; sourceTree = "<group>"; };
5108F6D523762309001ABC45 /* MasterTimelineIconSize.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MasterTimelineIconSize.swift; sourceTree = "<group>"; };
5108F6D723763094001ABC45 /* TickMarkSlider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TickMarkSlider.swift; sourceTree = "<group>"; };
51102164233A7D6C0007A5F7 /* ArticleExtractorButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleExtractorButton.swift; sourceTree = "<group>"; };
5110C37C2373A8D100A9C04F /* InspectorIconHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InspectorIconHeaderView.swift; sourceTree = "<group>"; };
@ -1292,6 +1296,9 @@
51A16995235E10D600EB091F /* AboutViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AboutViewController.swift; sourceTree = "<group>"; };
51A16996235E10D700EB091F /* FeedbinAccountViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedbinAccountViewController.swift; sourceTree = "<group>"; };
51A66684238075AE00CB272D /* AddWebFeedDefaultContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddWebFeedDefaultContainer.swift; sourceTree = "<group>"; };
51A9A5E32380C8870033AADF /* ShareFolderPickerAccountCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ShareFolderPickerAccountCell.xib; sourceTree = "<group>"; };
51A9A5E52380C8B20033AADF /* ShareFolderPickerFolderCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ShareFolderPickerFolderCell.xib; sourceTree = "<group>"; };
51A9A5E72380CA130033AADF /* ShareFolderPickerCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareFolderPickerCell.swift; sourceTree = "<group>"; };
51B62E67233186730085F949 /* IconView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconView.swift; sourceTree = "<group>"; };
51BB7C262335A8E5008E8144 /* ArticleActivityItemSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleActivityItemSource.swift; sourceTree = "<group>"; };
51BB7C302335ACDE008E8144 /* page.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = page.html; sourceTree = "<group>"; };
@ -1323,7 +1330,6 @@
51E3EB32229AB02C00645299 /* ErrorHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorHandler.swift; sourceTree = "<group>"; };
51E3EB3C229AB08300645299 /* ErrorHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorHandler.swift; sourceTree = "<group>"; };
51E43961238037C400015C31 /* AddWebFeedFolderViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddWebFeedFolderViewController.swift; sourceTree = "<group>"; };
51E4397C23805A6C00015C31 /* FlattenedAccountFolderPickerData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlattenedAccountFolderPickerData.swift; sourceTree = "<group>"; };
51E4397F23805EBC00015C31 /* AddWebFeedFolderTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddWebFeedFolderTableViewCell.swift; sourceTree = "<group>"; };
51E595A4228CC36500FCC42B /* ArticleStatusSyncTimer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleStatusSyncTimer.swift; sourceTree = "<group>"; };
51EAED95231363EF00A9EEE3 /* NonIntrinsicButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NonIntrinsicButton.swift; sourceTree = "<group>"; };
@ -1711,7 +1717,6 @@
512E08DD22687FA000BDCFDD /* Tree */ = {
isa = PBXGroup;
children = (
51E4397C23805A6C00015C31 /* FlattenedAccountFolderPickerData.swift */,
849A97611ED9EB96007D329B /* WebFeedTreeControllerDelegate.swift */,
849A97A11ED9F180007D329B /* FolderTreeControllerDelegate.swift */,
);
@ -1750,6 +1755,9 @@
children = (
513C5CE8232571C2003D4054 /* ShareViewController.swift */,
51707438232AA97100A461A3 /* ShareFolderPickerController.swift */,
51A9A5E72380CA130033AADF /* ShareFolderPickerCell.swift */,
51A9A5E32380C8870033AADF /* ShareFolderPickerAccountCell.xib */,
51A9A5E52380C8B20033AADF /* ShareFolderPickerFolderCell.xib */,
513C5CEA232571C2003D4054 /* MainInterface.storyboard */,
513C5CED232571C2003D4054 /* Info.plist */,
515D4FCB2325815A00EE1167 /* SafariExt.js */,
@ -1892,7 +1900,6 @@
51FD413A2342BD0500880194 /* MasterTimelineUnreadCountView.swift */,
FFD43E372340F320009E5CA3 /* UndoAvailableAlertController.swift */,
51C4526F2265091600C03939 /* Cell */,
5108F6D523762309001ABC45 /* MasterTimelineIconSize.swift */,
);
path = MasterTimeline;
sourceTree = "<group>";
@ -1935,7 +1942,6 @@
51C452842265093600C03939 /* AddWebFeedViewController.swift */,
51E43961238037C400015C31 /* AddWebFeedFolderViewController.swift */,
51E4397F23805EBC00015C31 /* AddWebFeedFolderTableViewCell.swift */,
51A66684238075AE00CB272D /* AddWebFeedDefaultContainer.swift */,
);
path = Add;
sourceTree = "<group>";
@ -2203,6 +2209,7 @@
849A97561ED9EB0D007D329B /* Data */ = {
isa = PBXGroup;
children = (
51A66684238075AE00CB272D /* AddWebFeedDefaultContainer.swift */,
849A97731ED9EC04007D329B /* ArticleStringFormatter.swift */,
849A97581ED9EB0D007D329B /* ArticleUtilities.swift */,
5108F6B52375E612001ABC45 /* CacheCleaner.swift */,
@ -3317,7 +3324,10 @@
buildActionMask = 2147483647;
files = (
515D4FCC2325815A00EE1167 /* SafariExt.js in Resources */,
51A9A5E62380C8B20033AADF /* ShareFolderPickerFolderCell.xib in Resources */,
51A9A5E42380C8880033AADF /* ShareFolderPickerAccountCell.xib in Resources */,
513C5CEC232571C2003D4054 /* MainInterface.storyboard in Resources */,
51A9A5EE2380D6080033AADF /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3702,7 +3712,11 @@
515D4FCA23257CB500EE1167 /* Node-Extensions.swift in Sources */,
513C5CE9232571C2003D4054 /* ShareViewController.swift in Sources */,
51707439232AA97100A461A3 /* ShareFolderPickerController.swift in Sources */,
51E4397E23805A6D00015C31 /* FlattenedAccountFolderPickerData.swift in Sources */,
51A9A5E02380C3F10033AADF /* AddWebFeedDefaultContainer.swift in Sources */,
51A9A5E82380CA130033AADF /* ShareFolderPickerCell.swift in Sources */,
51A9A5EF2380D63B0033AADF /* IconImage.swift in Sources */,
51A9A5ED2380D6000033AADF /* AppAssets.swift in Sources */,
51A9A5E12380C4FE0033AADF /* AppDefaults.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3885,7 +3899,6 @@
512E08E72268801200BDCFDD /* WebFeedTreeControllerDelegate.swift in Sources */,
51C452A422650A2D00C03939 /* ArticleUtilities.swift in Sources */,
51EF0F79227716380050506E /* ColorHash.swift in Sources */,
51E4397D23805A6D00015C31 /* FlattenedAccountFolderPickerData.swift in Sources */,
5183CCDA226E31A50010922C /* NonIntrinsicImageView.swift in Sources */,
51EAED96231363EF00A9EEE3 /* NonIntrinsicButton.swift in Sources */,
51C4527B2265091600C03939 /* MasterUnreadIndicatorView.swift in Sources */,
@ -4004,7 +4017,6 @@
51CE1C0B23622007005548FC /* RefreshProgressView.swift in Sources */,
511D4419231FC02D00FB1562 /* KeyboardManager.swift in Sources */,
51A1699D235E10D700EB091F /* SettingsViewController.swift in Sources */,
5108F6D623762309001ABC45 /* MasterTimelineIconSize.swift in Sources */,
51C45293226509C800C03939 /* StarredFeedDelegate.swift in Sources */,
51D6A5BC23199C85001C27D8 /* MasterTimelineDataSource.swift in Sources */,
51934CCB230F599B006127BE /* ThemedNavigationController.swift in Sources */,

View File

@ -27,7 +27,7 @@ struct AddWebFeedDefaultContainer {
}
static func storeDefaultContainer(_ container: Container) {
static func saveDefaultContainer(_ container: Container) {
AppDefaults.addWebFeedAccountID = container.account?.accountID
if let folder = container as? Folder {
AppDefaults.addWebFeedFolderName = folder.nameForDisplay

View File

@ -64,3 +64,26 @@ extension CGImage {
}
}
enum IconSize: Int, CaseIterable {
case small = 1
case medium = 2
case large = 3
private static let smallDimension = CGFloat(integerLiteral: 24)
private static let mediumDimension = CGFloat(integerLiteral: 36)
private static let largeDimension = CGFloat(integerLiteral: 48)
var size: CGSize {
switch self {
case .small:
return CGSize(width: IconSize.smallDimension, height: IconSize.smallDimension)
case .medium:
return CGSize(width: IconSize.mediumDimension, height: IconSize.mediumDimension)
case .large:
return CGSize(width: IconSize.largeDimension, height: IconSize.largeDimension)
}
}
}

View File

@ -1,50 +0,0 @@
//
// FlattenedAccountFolderPickerData.swift
// NetNewsWire
//
// Created by Maurice Parker on 4/16/19.
// Copyright © 2019 Ranchero Software, LLC. All rights reserved.
//
import Foundation
import Account
import RSCore
import RSTree
struct FlattenedAccountFolderPickerData {
var containerNames = [String]()
var containers = [Container]()
init() {
let treeControllerDelegate = FolderTreeControllerDelegate()
let treeController = TreeController(delegate: treeControllerDelegate)
treeController.rootNode.childNodes.forEach { node in
guard let acctNameProvider = node.representedObject as? DisplayNameProvider else {
return
}
let acctName = acctNameProvider.nameForDisplay
containerNames.append(acctName)
containers.append(node.representedObject as! Container)
for child in node.childNodes {
guard let childContainer = child.representedObject as? Container else {
return
}
let childName = (childContainer as! DisplayNameProvider).nameForDisplay
containerNames.append("\(acctName) / \(childName)")
containers.append(childContainer)
}
}
}
}

View File

@ -62,6 +62,8 @@ class AddWebFeedFolderViewController: UITableViewController {
if let compContainer = initialContainer, container === compContainer {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
return cell

View File

@ -138,7 +138,7 @@ extension AddWebFeedViewController: AddWebFeedFolderViewControllerDelegate {
func didSelect(container: Container) {
self.container = container
updateFolderLabel()
AddWebFeedDefaultContainer.storeDefaultContainer(container)
AddWebFeedDefaultContainer.saveDefaultContainer(container)
}
}

View File

@ -119,10 +119,10 @@ struct AppDefaults {
}
}
static var timelineIconSize: MasterTimelineIconSize {
static var timelineIconSize: IconSize {
get {
let rawValue = AppDefaults.shared.integer(forKey: Key.timelineIconSize)
return MasterTimelineIconSize(rawValue: rawValue) ?? MasterTimelineIconSize.medium
return IconSize(rawValue: rawValue) ?? IconSize.medium
}
set {
AppDefaults.shared.set(newValue.rawValue, forKey: Key.timelineIconSize)
@ -133,7 +133,7 @@ struct AppDefaults {
let defaults: [String : Any] = [Key.lastImageCacheFlushDate: Date(),
Key.timelineGroupByFeed: false,
Key.timelineNumberOfLines: 2,
Key.timelineIconSize: MasterTimelineIconSize.medium.rawValue,
Key.timelineIconSize: IconSize.medium.rawValue,
Key.timelineSortDirection: ComparisonResult.orderedDescending.rawValue,
Key.displayUndoAvailableTip: true]
AppDefaults.shared.register(defaults: defaults)
@ -202,5 +202,3 @@ private extension AppDefaults {
}
}

View File

@ -22,9 +22,9 @@ struct MasterTimelineCellData {
let read: Bool
let starred: Bool
let numberOfLines: Int
let iconSize: MasterTimelineIconSize
let iconSize: IconSize
init(article: Article, showFeedName: Bool, feedName: String?, iconImage: IconImage?, showIcon: Bool, featuredImage: UIImage?, numberOfLines: Int, iconSize: MasterTimelineIconSize) {
init(article: Article, showFeedName: Bool, feedName: String?, iconImage: IconImage?, showIcon: Bool, featuredImage: UIImage?, numberOfLines: Int, iconSize: IconSize) {
self.title = ArticleStringFormatter.truncatedTitle(article)
self.summary = ArticleStringFormatter.truncatedSummary(article)

View File

@ -42,7 +42,7 @@ extension MasterTimelineCellLayout {
return r
}
static func rectForIconView(_ point: CGPoint, iconSize: MasterTimelineIconSize) -> CGRect {
static func rectForIconView(_ point: CGPoint, iconSize: IconSize) -> CGRect {
var r = CGRect.zero
r.size = iconSize.size
r.origin.x = point.x

View File

@ -1,32 +0,0 @@
//
// MasterTimelineIconSize.swift
// NetNewsWire-iOS
//
// Created by Maurice Parker on 11/8/19.
// Copyright © 2019 Ranchero Software. All rights reserved.
//
import Foundation
import CoreGraphics
enum MasterTimelineIconSize: Int, CaseIterable {
case small = 1
case medium = 2
case large = 3
private static let smallDimension = CGFloat(integerLiteral: 24)
private static let mediumDimension = CGFloat(integerLiteral: 36)
private static let largeDimension = CGFloat(integerLiteral: 48)
var size: CGSize {
switch self {
case .small:
return CGSize(width: MasterTimelineIconSize.smallDimension, height: MasterTimelineIconSize.smallDimension)
case .medium:
return CGSize(width: MasterTimelineIconSize.mediumDimension, height: MasterTimelineIconSize.mediumDimension)
case .large:
return CGSize(width: MasterTimelineIconSize.largeDimension, height: MasterTimelineIconSize.largeDimension)
}
}
}

View File

@ -15,7 +15,7 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner
private var titleView: MasterTimelineTitleView?
private var numberOfTextLines = 0
private var iconSize = MasterTimelineIconSize.medium
private var iconSize = IconSize.medium
@IBOutlet weak var markAllAsReadButton: UIBarButtonItem!
@IBOutlet weak var firstUnreadButton: UIBarButtonItem!

View File

@ -47,7 +47,7 @@ class TimelineCustomizerViewController: UIViewController {
}
@IBAction func iconSizeChanged(_ sender: Any) {
guard let iconSize = MasterTimelineIconSize(rawValue: Int(iconSizeSlider.value.rounded())) else { return }
guard let iconSize = IconSize(rawValue: Int(iconSizeSlider.value.rounded())) else { return }
AppDefaults.timelineIconSize = iconSize
updatePreview()
}

View File

@ -0,0 +1,49 @@
<?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">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15509"/>
<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="ShareFolderPickerCell" customModule="NetNewsWire_iOS_Share_Extension" 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">
<rect key="frame" x="0.0" y="0.0" width="383" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="yiw-9t-gil" userLabel="Account Icon">
<rect key="frame" x="20" y="11" width="22" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="22" id="43E-Em-Z6O"/>
<constraint firstAttribute="height" constant="22" id="mTY-cQ-1R1"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="TRx-RV-za8" userLabel="Account Label">
<rect key="frame" x="50" y="14" width="42" height="16"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstItem="TRx-RV-za8" firstAttribute="leading" secondItem="yiw-9t-gil" secondAttribute="trailing" constant="8" symbolic="YES" id="RUN-Ol-xSl"/>
<constraint firstItem="TRx-RV-za8" firstAttribute="top" secondItem="FzD-t2-JGy" secondAttribute="top" constant="14" id="cze-hi-8Uh"/>
<constraint firstItem="yiw-9t-gil" firstAttribute="leading" secondItem="FzD-t2-JGy" secondAttribute="leading" constant="20" symbolic="YES" id="oU9-E3-lEt"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="TRx-RV-za8" secondAttribute="trailing" constant="8" id="sJ6-wr-JIw"/>
<constraint firstItem="yiw-9t-gil" firstAttribute="centerY" secondItem="FzD-t2-JGy" secondAttribute="centerY" id="tUD-tI-dgr"/>
<constraint firstAttribute="bottom" secondItem="TRx-RV-za8" secondAttribute="bottom" constant="14" id="zls-MW-Ffp"/>
</constraints>
</tableViewCellContentView>
<inset key="separatorInset" minX="50" minY="0.0" maxX="0.0" maxY="0.0"/>
<connections>
<outlet property="icon" destination="yiw-9t-gil" id="uXC-nW-WFl"/>
<outlet property="label" destination="TRx-RV-za8" id="ABN-lc-R1A"/>
</connections>
<point key="canvasLocation" x="7" y="-9"/>
</tableViewCell>
</objects>
</document>

View File

@ -0,0 +1,15 @@
//
// ShareFolderPickerCell.swift
// NetNewsWire iOS Share Extension
//
// Created by Maurice Parker on 11/16/19.
// Copyright © 2019 Ranchero Software. All rights reserved.
//
import UIKit
class ShareFolderPickerCell: UITableViewCell {
@IBOutlet weak var icon: UIImageView!
@IBOutlet weak var label: UILabel!
}

View File

@ -7,21 +7,30 @@
//
import UIKit
import RSCore
import Account
protocol ShareFolderPickerControllerDelegate: class {
func shareFolderPickerDidSelect(_ container: Container, _ selectionName: String)
func shareFolderPickerDidSelect(_ container: Container)
}
class ShareFolderPickerController: UITableViewController {
var pickerData: FlattenedAccountFolderPickerData?
var selectedContainer: Container?
var containers = [Container]()
weak var delegate: ShareFolderPickerControllerDelegate?
override func viewDidLoad() {
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
for account in AccountManager.shared.sortedActiveAccounts {
containers.append(account)
if let sortedFolders = account.sortedFolders {
containers.append(contentsOf: sortedFolders)
}
}
tableView.register(UINib(nibName: "ShareFolderPickerAccountCell", bundle: Bundle.main), forCellReuseIdentifier: "AccountCell")
tableView.register(UINib(nibName: "ShareFolderPickerFolderCell", bundle: Bundle.main), forCellReuseIdentifier: "FolderCell")
}
override func numberOfSections(in tableView: UITableView) -> Int {
@ -29,23 +38,48 @@ class ShareFolderPickerController: UITableViewController {
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return pickerData?.containerNames.count ?? 0
return containers.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = pickerData?.containerNames[indexPath.row] ?? ""
if pickerData?.containers[indexPath.row] === selectedContainer {
let container = containers[indexPath.row]
let cell: ShareFolderPickerCell = {
if container is Account {
return tableView.dequeueReusableCell(withIdentifier: "AccountCell", for: indexPath) as! ShareFolderPickerCell
} else {
return tableView.dequeueReusableCell(withIdentifier: "FolderCell", for: indexPath) as! ShareFolderPickerCell
}
}()
if let account = container as? Account {
cell.icon.image = AppAssets.image(for: account.type)
} else {
cell.icon.image = AppAssets.masterFolderImage.image
}
if let displayNameProvider = container as? DisplayNameProvider {
cell.label?.text = displayNameProvider.nameForDisplay
}
if let compContainer = selectedContainer, container === compContainer {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard let pickerData = pickerData else { return }
delegate?.shareFolderPickerDidSelect(pickerData.containers[indexPath.row], pickerData.containerNames[indexPath.row])
let container = containers[indexPath.row]
if let account = container as? Account, account.behaviors.contains(.disallowFeedInRootFolder) {
tableView.selectRow(at: nil, animated: false, scrollPosition: .none)
} else {
let cell = tableView.cellForRow(at: indexPath)
cell?.accessoryType = .checkmark
delegate?.shareFolderPickerDidSelect(container)
}
}
}

View File

@ -0,0 +1,49 @@
<?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">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15509"/>
<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="ShareFolderPickerCell" customModule="NetNewsWire_iOS_Share_Extension" 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">
<rect key="frame" x="0.0" y="0.0" width="383" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="yiw-9t-gil" userLabel="Folder Icon">
<rect key="frame" x="50" y="11" width="22" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="22" id="43E-Em-Z6O"/>
<constraint firstAttribute="height" constant="22" id="mTY-cQ-1R1"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="TRx-RV-za8" userLabel="Folder Label">
<rect key="frame" x="80" y="14" width="42" height="16"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstItem="TRx-RV-za8" firstAttribute="leading" secondItem="yiw-9t-gil" secondAttribute="trailing" constant="8" symbolic="YES" id="RUN-Ol-xSl"/>
<constraint firstItem="TRx-RV-za8" firstAttribute="top" secondItem="FzD-t2-JGy" secondAttribute="top" constant="14" id="cze-hi-8Uh"/>
<constraint firstItem="yiw-9t-gil" firstAttribute="leading" secondItem="FzD-t2-JGy" secondAttribute="leading" constant="50" id="oU9-E3-lEt"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="TRx-RV-za8" secondAttribute="trailing" constant="8" id="sJ6-wr-JIw"/>
<constraint firstItem="yiw-9t-gil" firstAttribute="centerY" secondItem="FzD-t2-JGy" secondAttribute="centerY" id="tUD-tI-dgr"/>
<constraint firstAttribute="bottom" secondItem="TRx-RV-za8" secondAttribute="bottom" constant="14" id="zls-MW-Ffp"/>
</constraints>
</tableViewCellContentView>
<inset key="separatorInset" minX="80" minY="0.0" maxX="0.0" maxY="0.0"/>
<connections>
<outlet property="icon" destination="yiw-9t-gil" id="adY-cS-RuD"/>
<outlet property="label" destination="TRx-RV-za8" id="lIo-uF-Cle"/>
</connections>
<point key="canvasLocation" x="7" y="-9"/>
</tableViewCell>
</objects>
</document>

View File

@ -16,8 +16,6 @@ import RSTree
class ShareViewController: SLComposeServiceViewController, ShareFolderPickerControllerDelegate {
private var pickerData: FlattenedAccountFolderPickerData?
private var url: URL?
private var container: Container?
private var folderItem: SLComposeSheetConfigurationItem!
@ -26,11 +24,7 @@ class ShareViewController: SLComposeServiceViewController, ShareFolderPickerCont
AccountManager.shared = AccountManager()
pickerData = FlattenedAccountFolderPickerData()
if pickerData?.containers.count ?? 0 > 0 {
container = pickerData?.containers[0]
}
container = AddWebFeedDefaultContainer.defaultContainer
title = "NetNewsWire"
placeholder = "Feed Name (Optional)"
@ -130,9 +124,10 @@ class ShareViewController: SLComposeServiceViewController, ShareFolderPickerCont
}
}
func shareFolderPickerDidSelect(_ container: Container, _ selectionName: String) {
func shareFolderPickerDidSelect(_ container: Container) {
AddWebFeedDefaultContainer.saveDefaultContainer(container)
self.container = container
self.folderItem.value = selectionName
updateFolderItemValue()
self.popConfigurationViewController()
}
@ -145,10 +140,7 @@ class ShareViewController: SLComposeServiceViewController, ShareFolderPickerCont
folderItem = SLComposeSheetConfigurationItem()
folderItem.title = "Folder"
if let nameProvider = container as? DisplayNameProvider {
folderItem.value = nameProvider.nameForDisplay
}
updateFolderItemValue()
folderItem.tapHandler = {
@ -156,7 +148,6 @@ class ShareViewController: SLComposeServiceViewController, ShareFolderPickerCont
folderPickerController.navigationController?.title = NSLocalizedString("Folder", comment: "Folder")
folderPickerController.delegate = self
folderPickerController.pickerData = self.pickerData
folderPickerController.selectedContainer = self.container
self.pushConfigurationViewController(folderPickerController)
@ -168,3 +159,17 @@ class ShareViewController: SLComposeServiceViewController, ShareFolderPickerCont
}
}
private extension ShareViewController {
func updateFolderItemValue() {
if let containerName = (container as? DisplayNameProvider)?.nameForDisplay {
if container is Folder {
self.folderItem.value = "\(container?.account?.nameForDisplay ?? "") / \(containerName)"
} else {
self.folderItem.value = containerName
}
}
}
}