This commit is contained in:
Andrew Brehaut 2019-09-24 19:40:01 +12:00
commit 10633f31a9
28 changed files with 116 additions and 191 deletions

View File

@ -174,13 +174,17 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
private lazy var opmlFile = OPMLFile(filename: (dataFolder as NSString).appendingPathComponent("Subscriptions.opml"), account: self)
private lazy var metadataFile = AccountMetadataFile(filename: (dataFolder as NSString).appendingPathComponent("Settings.plist"), account: self)
var metadata = AccountMetadata()
var metadata = AccountMetadata() {
didSet {
delegate.accountMetadata = metadata
}
}
private lazy var feedMetadataFile = FeedMetadataFile(filename: (dataFolder as NSString).appendingPathComponent("FeedMetadata.plist"), account: self)
typealias FeedMetadataDictionary = [String: FeedMetadata]
var feedMetadata = FeedMetadataDictionary()
private var startingUp = true
var startingUp = true
public var unreadCount = 0 {
didSet {
@ -202,7 +206,7 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
}
else {
NotificationCenter.default.post(name: .AccountRefreshDidFinish, object: self)
opmlFile.queueSaveToDiskIfNeeded()
opmlFile.markAsDirty()
}
}
}
@ -364,6 +368,12 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
}
public func saveIfNecessary() {
metadataFile.saveIfNecessary()
feedMetadataFile.saveIfNecessary()
opmlFile.saveIfNecessary()
}
func loadOPMLItems(_ items: [RSOPMLItem], parentFolder: Folder?) {
var feedsToAdd = Set<Feed>()
@ -402,10 +412,11 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
}
public func resetAllFeedMetadata() {
public func resetFeedMetadataAndUnreadCounts() {
for feed in flattenedFeeds() {
feed.metadata = feedMetadata(feedURL: feed.url, feedID: feed.feedID)
}
fetchAllUnreadCounts()
NotificationCenter.default.post(name: .FeedMetadataDidChange, object: self, userInfo: nil)
}

View File

@ -27,14 +27,14 @@ final class AccountMetadataFile {
managedFile.markAsDirty()
}
func queueSaveToDiskIfNeeded() {
managedFile.queueSaveToDiskIfNeeded()
}
func load() {
managedFile.load()
}
func saveIfNecessary() {
managedFile.saveIfNecessary()
}
}
private extension AccountMetadataFile {

View File

@ -65,18 +65,7 @@ public final class Feed: DisplayNameProvider, Renamable, UnreadCountProvider, Ha
}
}
public var name: String? {
get {
return metadata.name
}
set {
let oldNameForDisplay = nameForDisplay
metadata.name = newValue
if oldNameForDisplay != newValue {
postDisplayNameDidChangeNotification()
}
}
}
public var name: String?
public var authors: Set<Author>? {
get {

View File

@ -21,7 +21,6 @@ final class FeedMetadata: Codable {
case homePageURL
case iconURL
case faviconURL
case name
case editedName
case authors
case contentHash
@ -63,14 +62,6 @@ final class FeedMetadata: Codable {
}
}
var name: String? {
didSet {
if name != oldValue {
valueDidChange(.name)
}
}
}
var editedName: String? {
didSet {
if editedName != oldValue {

View File

@ -27,14 +27,14 @@ final class FeedMetadataFile {
managedFile.markAsDirty()
}
func queueSaveToDiskIfNeeded() {
managedFile.queueSaveToDiskIfNeeded()
}
func load() {
managedFile.load()
}
func saveIfNecessary() {
managedFile.saveIfNecessary()
}
}
private extension FeedMetadataFile {
@ -49,7 +49,9 @@ private extension FeedMetadataFile {
let decoder = PropertyListDecoder()
account.feedMetadata = (try? decoder.decode(Account.FeedMetadataDictionary.self, from: fileData)) ?? Account.FeedMetadataDictionary()
account.feedMetadata.values.forEach { $0.delegate = account }
account.resetAllFeedMetadata()
if !account.startingUp {
account.resetFeedMetadataAndUnreadCounts()
}
}
})

View File

@ -524,7 +524,6 @@ final class FeedbinAccountDelegate: AccountDelegate {
func accountDidInitialize(_ account: Account) {
credentials = try? account.retrieveCredentials(type: .basic)
accountMetadata = account.metadata
}
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL? = nil, completion: @escaping (Result<Credentials?, Error>) -> Void) {

View File

@ -170,7 +170,6 @@ final class FeedlyAccountDelegate: AccountDelegate {
}
func accountDidInitialize(_ account: Account) {
// accountMetadata = account.metadata
credentials = try? account.retrieveCredentials(type: .oauthAccessToken)
syncStrategy = FeedlySyncStrategy(account: account, caller: caller, log: log)

View File

@ -52,7 +52,12 @@ final class FeedlyCreateFeedsForCollectionFoldersOperation: FeedlySyncOperation
let url = collectionFeed.id
let metadata = FeedMetadata(feedID: url)
// TODO: More metadata
metadata.name = collectionFeed.title
// Kiel, I'm commenting this out as we shouldn't be storing the name
// in the feed metadata. It should be stored in the OPML file.
// You can just set the name directly on the feed itself.
// metadata.name = collectionFeed.title
let feed = Feed(account: account, url: url, metadata: metadata)
// So the same feed isn't created more than once.

View File

@ -28,14 +28,14 @@ final class OPMLFile {
managedFile.markAsDirty()
}
func queueSaveToDiskIfNeeded() {
managedFile.queueSaveToDiskIfNeeded()
}
func load() {
managedFile.load()
}
func saveIfNecessary() {
managedFile.saveIfNecessary()
}
}
private extension OPMLFile {

View File

@ -411,7 +411,6 @@ final class ReaderAPIAccountDelegate: AccountDelegate {
}
func accountDidInitialize(_ account: Account) {
accountMetadata = account.metadata
credentials = try? account.retrieveCredentials(type: .readerAPIKey)
}

View File

@ -11,4 +11,4 @@ INFOPLIST_FILE = Info.plist
PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.Account
PRODUCT_NAME = $(TARGET_NAME:c99extidentifier)
CLANG_ENABLE_MODULES = YES
APPLICATION_EXTENSION_API_ONLY = YES

View File

@ -345,6 +345,7 @@
844BEE701F0AB3C9004AB7CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = "$(SRCROOT)/Info.plist";
MACOSX_DEPLOYMENT_TARGET = 10.13;
@ -357,6 +358,7 @@
844BEE711F0AB3C9004AB7CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = "$(SRCROOT)/Info.plist";
MACOSX_DEPLOYMENT_TARGET = 10.13;

View File

@ -11,4 +11,4 @@ INFOPLIST_FILE = Info.plist
PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.Articles
PRODUCT_NAME = $(TARGET_NAME)
CLANG_ENABLE_MODULES = YES
APPLICATION_EXTENSION_API_ONLY = YES

View File

@ -13,4 +13,4 @@ INFOPLIST_FILE = Info.plist
PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.ArticlesDatabase
PRODUCT_NAME = $(TARGET_NAME)
CLANG_ENABLE_MODULES = YES
APPLICATION_EXTENSION_API_ONLY = YES

View File

@ -13,4 +13,4 @@ INFOPLIST_FILE = Info.plist
PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.SyncDatabase
PRODUCT_NAME = $(TARGET_NAME)
CLANG_ENABLE_MODULES = YES
APPLICATION_EXTENSION_API_ONLY = YES

View File

@ -74,7 +74,6 @@
51554C25228B71910055115A /* SyncDatabase.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 51554C01228B6EB50055115A /* SyncDatabase.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
51554C30228B71A10055115A /* SyncDatabase.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51554C01228B6EB50055115A /* SyncDatabase.framework */; };
51554C31228B71A10055115A /* SyncDatabase.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 51554C01228B6EB50055115A /* SyncDatabase.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
515ADE4022E11FAE006B2460 /* SystemMessageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515ADE3F22E11FAE006B2460 /* SystemMessageViewController.swift */; };
515D4FC123257A3200EE1167 /* FolderTreeControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849A97A11ED9F180007D329B /* FolderTreeControllerDelegate.swift */; };
515D4FCA23257CB500EE1167 /* Node-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849A97971ED9EFAA007D329B /* Node-Extensions.swift */; };
515D4FCC2325815A00EE1167 /* SafariExt.js in Resources */ = {isa = PBXBuildFile; fileRef = 515D4FCB2325815A00EE1167 /* SafariExt.js */; };
@ -815,7 +814,6 @@
514B7C8223205EFB00BAC947 /* RootSplitViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootSplitViewController.swift; sourceTree = "<group>"; };
514B7D1E23219F3C00BAC947 /* AddControllerType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddControllerType.swift; sourceTree = "<group>"; };
51554BFC228B6EB50055115A /* SyncDatabase.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SyncDatabase.xcodeproj; path = Frameworks/SyncDatabase/SyncDatabase.xcodeproj; sourceTree = SOURCE_ROOT; };
515ADE3F22E11FAE006B2460 /* SystemMessageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemMessageViewController.swift; sourceTree = "<group>"; };
515D4FCB2325815A00EE1167 /* SafariExt.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = SafariExt.js; sourceTree = "<group>"; };
515D4FCD2325909200EE1167 /* NetNewsWire_iOS_ShareExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NetNewsWire_iOS_ShareExtension.entitlements; sourceTree = "<group>"; };
515D4FCE2325B3D000EE1167 /* NetNewsWire_iOSshareextension_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = NetNewsWire_iOSshareextension_target.xcconfig; sourceTree = "<group>"; };
@ -1382,7 +1380,6 @@
children = (
51C4527E2265092C00C03939 /* DetailViewController.swift */,
517630222336657E00E15FFF /* DetailViewControllerWebViewProvider.swift */,
515ADE3F22E11FAE006B2460 /* SystemMessageViewController.swift */,
);
path = Detail;
sourceTree = "<group>";
@ -2710,7 +2707,6 @@
51EAED96231363EF00A9EEE3 /* NonIntrinsicButton.swift in Sources */,
51C4527B2265091600C03939 /* MasterUnreadIndicatorView.swift in Sources */,
5152E1022324900D00E5C7AD /* SettingsAddAccountView.swift in Sources */,
515ADE4022E11FAE006B2460 /* SystemMessageViewController.swift in Sources */,
51F85BF92274AA7B00C787DC /* UIBarButtonItem-Extensions.swift in Sources */,
51B62E68233186730085F949 /* MasterTimelineAvatarView.swift in Sources */,
51C45296226509D300C03939 /* OPMLExporter.swift in Sources */,

View File

@ -113,39 +113,7 @@
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="FJe-Yq-33r" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1619" y="-87"/>
</scene>
<!--System Message-->
<scene sceneID="tbo-yR-QVH">
<objects>
<viewController storyboardIdentifier="SystemMessageViewController" title="System Message" id="Xld-e9-xoL" customClass="SystemMessageViewController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="5hz-HK-J2Q">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="System Message" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6C9-Jb-ZZR">
<rect key="frame" x="141.5" y="437.5" width="131" height="21"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<constraints>
<constraint firstItem="6C9-Jb-ZZR" firstAttribute="centerX" secondItem="5hz-HK-J2Q" secondAttribute="centerX" id="9iO-I1-FtK"/>
<constraint firstItem="6C9-Jb-ZZR" firstAttribute="centerY" secondItem="5hz-HK-J2Q" secondAttribute="centerY" id="jXm-OI-Igs"/>
</constraints>
<viewLayoutGuide key="safeArea" id="zOb-OV-HXy"/>
</view>
<navigationItem key="navigationItem" id="2kf-IY-WDY"/>
<simulatedToolbarMetrics key="simulatedBottomBarMetrics"/>
<connections>
<outlet property="messageLabel" destination="6C9-Jb-ZZR" id="HeR-Qv-yfz"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="rgH-br-nLG" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="872" y="-87"/>
<point key="canvasLocation" x="2320" y="-759"/>
</scene>
<!--Timeline-->
<scene sceneID="fag-XH-avP">

View File

@ -12,6 +12,14 @@ import Account
import Articles
import SafariServices
enum DetailViewState: Equatable {
case noSelection
case multipleSelection
case loading
case article(Article)
case extracted(Article, ExtractedArticle)
}
class DetailViewController: UIViewController {
@IBOutlet private weak var nextUnreadBarButtonItem: UIBarButtonItem!
@ -26,6 +34,26 @@ class DetailViewController: UIViewController {
weak var coordinator: SceneCoordinator!
var state: DetailViewState = .noSelection {
didSet {
if state != oldValue {
updateUI()
reloadHTML()
}
}
}
var currentArticle: Article? {
switch state {
case .article(let article):
return article
case .extracted(let article, _):
return article
default:
return nil
}
}
private let keyboardManager = KeyboardManager(type: .detail)
override var keyCommands: [UIKeyCommand]? {
return keyboardManager.keyCommands
@ -66,7 +94,7 @@ class DetailViewController: UIViewController {
func updateUI() {
guard let article = coordinator.currentArticle else {
guard let article = currentArticle else {
nextUnreadBarButtonItem.isEnabled = false
prevArticleBarButtonItem.isEnabled = false
nextArticleBarButtonItem.isEnabled = false
@ -95,12 +123,22 @@ class DetailViewController: UIViewController {
}
func reloadHTML() {
guard let article = coordinator.currentArticle, let webView = webView else {
return
}
let style = ArticleStylesManager.shared.currentStyle
let rendering = ArticleRenderer.articleHTML(article: article, style: style)
let rendering: ArticleRenderer.Rendering
switch state {
case .noSelection:
rendering = ArticleRenderer.noSelectionHTML(style: style)
case .multipleSelection:
rendering = ArticleRenderer.multipleSelectionHTML(style: style)
case .loading:
rendering = ArticleRenderer.loadingHTML(style: style)
case .article(let article):
rendering = ArticleRenderer.articleHTML(article: article, style: style)
case .extracted(let article, let extractedArticle):
rendering = ArticleRenderer.articleHTML(article: article, extractedArticle: extractedArticle, style: style)
}
let templateData = TemplateData(style: rendering.style, body: rendering.html)
@ -111,7 +149,8 @@ class DetailViewController: UIViewController {
render = "render(\(json));"
}
webView.evaluateJavaScript(render)
webView?.evaluateJavaScript(render)
}
// MARK: Notifications
@ -124,7 +163,7 @@ class DetailViewController: UIViewController {
guard let articles = note.userInfo?[Account.UserInfoKey.articles] as? Set<Article> else {
return
}
if articles.count == 1 && articles.first?.articleID == coordinator.currentArticle?.articleID {
if articles.count == 1 && articles.first?.articleID == currentArticle?.articleID {
updateUI()
}
}
@ -164,11 +203,11 @@ class DetailViewController: UIViewController {
}
@IBAction func showActivityDialog(_ sender: Any) {
guard let currentArticle = coordinator.currentArticle, let preferredLink = currentArticle.preferredLink, let url = URL(string: preferredLink) else {
guard let preferredLink = currentArticle?.preferredLink, let url = URL(string: preferredLink) else {
return
}
let itemSource = ArticleActivityItemSource(url: url, subject: currentArticle.title)
let itemSource = ArticleActivityItemSource(url: url, subject: currentArticle!.title)
let activityViewController = UIActivityViewController(activityItems: [itemSource], applicationActivities: nil)
activityViewController.popoverPresentationController?.barButtonItem = actionBarButtonItem
present(activityViewController, animated: true)
@ -180,10 +219,6 @@ class DetailViewController: UIViewController {
}
// MARK: API
func updateArticleSelection() {
updateUI()
reloadHTML()
}
func focus() {
webView.becomeFirstResponder()
@ -241,7 +276,8 @@ extension DetailViewController: WKNavigationDelegate {
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
self.updateArticleSelection()
self.updateUI()
self.reloadHTML()
}
}

View File

@ -1,21 +0,0 @@
//
// SystemMessageViewController.swift
// NetNewsWire-iOS
//
// Created by Maurice Parker on 7/18/19.
// Copyright © 2019 Ranchero Software. All rights reserved.
//
import UIKit
class SystemMessageViewController: UIViewController {
@IBOutlet weak var messageLabel: UILabel!
var message: String = NSLocalizedString("No Selection", comment: "No Selection")
override func viewDidLoad() {
super.viewDidLoad()
messageLabel.text = message
}
}

View File

@ -223,7 +223,7 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
if let self = self {
let alert = UIAlertController(title: feed.name, message: nil, preferredStyle: .actionSheet)
let alert = UIAlertController(title: feed.nameForDisplay, message: nil, preferredStyle: .actionSheet)
if let popoverController = alert.popoverPresentationController {
popoverController.sourceView = view
popoverController.sourceRect = CGRect(x: view.frame.size.width/2, y: view.frame.size.height/2, width: 1, height: 1)

View File

@ -13,6 +13,7 @@ import Articles
class MasterTimelineViewController: UITableViewController, UndoableCommandRunner {
private var titleView: MasterTimelineTitleView?
private var numberOfTextLines = 0
@IBOutlet weak var markAllAsReadButton: UIBarButtonItem!
@ -342,6 +343,7 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner
}
@objc func faviconDidBecomeAvailable(_ note: Notification) {
titleView?.imageView.image = coordinator.timelineFavicon
if coordinator.showAvatars {
queueReloadAvailableCells()
}
@ -455,6 +457,7 @@ private extension MasterTimelineViewController {
title = coordinator.timelineName
if let titleView = Bundle.main.loadNibNamed("MasterTimelineTitleView", owner: self, options: nil)?[0] as? MasterTimelineTitleView {
self.titleView = titleView
titleView.imageView.image = coordinator.timelineFavicon
titleView.label.text = coordinator.timelineName
navigationItem.titleView = titleView

View File

@ -289,8 +289,10 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
masterFeedViewController.coordinator = self
masterNavigationController.pushViewController(masterFeedViewController, animated: false)
let noSelectionController = fullyWrappedSystemMesssageController(showButton: true)
rootSplitViewController.showDetailViewController(noSelectionController, sender: self)
let detailViewController = UIStoryboard.main.instantiateController(ofType: DetailViewController.self)
detailViewController.coordinator = self
let detailNavigationController = addNavControllerIfNecessary(detailViewController, showButton: false)
rootSplitViewController.showDetailViewController(detailNavigationController, sender: self)
configureThreePanelMode(for: size)
@ -560,8 +562,7 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
masterNavigationController.popViewController(animated: !automated)
}
} else {
let systemMessageViewController = UIStoryboard.main.instantiateController(ofType: SystemMessageViewController.self)
installDetailController(systemMessageViewController, automated: automated)
detailViewController?.state = .noSelection
}
masterTimelineViewController?.updateArticleSelection(animate: !automated)
return
@ -577,11 +578,12 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
masterTimelineViewController?.updateArticleSelection(animate: false)
}
detailViewController?.updateArticleSelection()
detailViewController?.state = .article(article!)
if let article = currentArticle {
markArticles(Set([article]), statusKey: .read, flag: true)
}
}
func beginSearching() {
@ -852,60 +854,7 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
extension SceneCoordinator: UISplitViewControllerDelegate {
func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController:UIViewController, onto primaryViewController:UIViewController) -> Bool {
// Check to see if the system is currently configured for three panel mode
if let subSplit = secondaryViewController as? UISplitViewController {
// Take the timeline controller out of the subsplit and throw it on the master navigation stack
if let masterTimelineNav = subSplit.viewControllers.first as? UINavigationController, let masterTimeline = masterTimelineNav.topViewController {
masterNavigationController.pushViewController(masterTimeline, animated: false)
}
// Take the detail view (ignoring system message controllers) and put it on the master navigation stack
if let detailNav = subSplit.viewControllers.last as? UINavigationController, let detail = detailNav.topViewController as? DetailViewController {
masterNavigationController.pushViewController(detail, animated: false)
}
} else {
// If the timeline controller has been initialized and only the feeds controller is on the stack, we add the timeline controller
if let timeline = masterTimelineViewController, masterNavigationController.viewControllers.count == 1 {
masterNavigationController.pushViewController(timeline, animated: false)
}
// Take the detail view (ignoring system message controllers) and put it on the master navigation stack
if let detailNav = secondaryViewController as? UINavigationController, let detail = detailNav.topViewController as? DetailViewController {
// I have no idea why, I have to wire up the left bar button item for this, but not when I am transitioning from three panel mode
detail.navigationItem.leftBarButtonItem = rootSplitViewController.displayModeButtonItem
detail.navigationItem.leftItemsSupplementBackButton = true
masterNavigationController.pushViewController(detail, animated: false)
}
}
return true
}
func splitViewController(_ splitViewController: UISplitViewController, separateSecondaryFrom primaryViewController: UIViewController) -> UIViewController? {
if isThreePanelMode {
return transitionToThreePanelMode()
}
if let detail = masterNavigationController.viewControllers.last as? DetailViewController {
// If we have a detail controller on the stack, remove it and return it.
masterNavigationController.viewControllers.removeLast()
let detailNav = addNavControllerIfNecessary(detail, showButton: true)
return detailNav
} else {
// Display a no selection controller since we don't have any detail selected
return fullyWrappedSystemMesssageController(showButton: true)
}
return currentArticle == nil
}
}
@ -1449,12 +1398,6 @@ private extension SceneCoordinator {
}
}
func fullyWrappedSystemMesssageController(showButton: Bool) -> UIViewController {
let systemMessageViewController = UIStoryboard.main.instantiateController(ofType: SystemMessageViewController.self)
let navController = addNavControllerIfNecessary(systemMessageViewController, showButton: showButton)
return navController
}
@discardableResult
func transitionToThreePanelMode() -> UIViewController {
@ -1466,7 +1409,9 @@ private extension SceneCoordinator {
if let result = detailViewController {
return result
} else {
return UIStoryboard.main.instantiateController(ofType: SystemMessageViewController.self)
let detailController = UIStoryboard.main.instantiateController(ofType: DetailViewController.self)
detailController.coordinator = self
return detailController
}
}()

View File

@ -119,6 +119,7 @@ class ShareViewController: SLComposeServiceViewController, ShareFolderPickerCont
switch result {
case .success:
account!.saveIfNecessary()
self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
case .failure(let error):
self.presentError(error) {

@ -1 +1 @@
Subproject commit ced48ad15ebc762fea50beb618eed3cf10721148
Subproject commit 388b58e2fde1a93233767f4dba61d236838b6900

@ -1 +1 @@
Subproject commit 7b44768308dc6970ee78470d0ea1e5287badc2bc
Subproject commit feb02ec73674fc572914f429e38428809c8d2281

@ -1 +1 @@
Subproject commit 9e86cf613b40b6a3389b6248be9427d90debbf9f
Subproject commit 6d0b05ccd661dac745dc4db402b5078e25c86b56

@ -1 +1 @@
Subproject commit d333739a776236aae32b3868415729499021cec3
Subproject commit 1a856651f1643abc5d52f4ef416077b9c41bf7e4

@ -1 +1 @@
Subproject commit b1230d5aae49ee6c908fe694cd4f77b98d17cc42
Subproject commit c55f96018ef1c81db35376065e1f094840162943