From 184ef5757699ab8eb08f7be6c458ed33de6258f3 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Sat, 11 Jul 2020 18:22:47 -0500 Subject: [PATCH] Implement Timeline multiselect --- .../Shared/Article/ArticleContainerView.swift | 4 +- .../Shared/Article/ArticleManager.swift | 14 --- .../Article/ArticleToolbarModifier.swift | 4 +- Multiplatform/Shared/SceneModel.swift | 98 +++++-------------- .../Shared/SceneNavigationView.swift | 6 +- .../Shared/Sidebar/SidebarContainerView.swift | 9 +- .../Shared/Sidebar/SidebarModel.swift | 6 +- .../Shared/Sidebar/SidebarView.swift | 3 +- .../Timeline/TimelineContainerView.swift | 11 +-- .../Shared/Timeline/TimelineModel.swift | 45 +++++---- .../Shared/Timeline/TimelineView.swift | 48 ++++++--- Multiplatform/iOS/Article/ArticleView.swift | 12 +-- .../iOS/Article/ArticleViewController.swift | 11 ++- Multiplatform/macOS/Article/ArticleView.swift | 10 +- .../macOS/Article/WebViewController.swift | 22 ++--- NetNewsWire.xcodeproj/project.pbxproj | 6 -- ...sWire_multiplatform_widget_target.xcconfig | 10 -- 17 files changed, 126 insertions(+), 193 deletions(-) delete mode 100644 Multiplatform/Shared/Article/ArticleManager.swift delete mode 100644 xcconfig/NetNewsWire_multiplatform_widget_target.xcconfig diff --git a/Multiplatform/Shared/Article/ArticleContainerView.swift b/Multiplatform/Shared/Article/ArticleContainerView.swift index 3d1a8d225..2fa4838bd 100644 --- a/Multiplatform/Shared/Article/ArticleContainerView.swift +++ b/Multiplatform/Shared/Article/ArticleContainerView.swift @@ -12,10 +12,10 @@ import Articles struct ArticleContainerView: View { @EnvironmentObject private var sceneModel: SceneModel - var article: Article + var articles: [Article] @ViewBuilder var body: some View { - ArticleView(sceneModel: sceneModel, article: article) + ArticleView(sceneModel: sceneModel, articles: articles) .modifier(ArticleToolbarModifier()) } diff --git a/Multiplatform/Shared/Article/ArticleManager.swift b/Multiplatform/Shared/Article/ArticleManager.swift deleted file mode 100644 index adcc9e10e..000000000 --- a/Multiplatform/Shared/Article/ArticleManager.swift +++ /dev/null @@ -1,14 +0,0 @@ -// -// ArticleManager.swift -// NetNewsWire -// -// Created by Maurice Parker on 7/9/20. -// Copyright © 2020 Ranchero Software. All rights reserved. -// - -import Foundation -import Articles - -protocol ArticleManager: class { - var currentArticle: Article? { get } -} diff --git a/Multiplatform/Shared/Article/ArticleToolbarModifier.swift b/Multiplatform/Shared/Article/ArticleToolbarModifier.swift index 8fddef334..e1ff6eb6f 100644 --- a/Multiplatform/Shared/Article/ArticleToolbarModifier.swift +++ b/Multiplatform/Shared/Article/ArticleToolbarModifier.swift @@ -33,7 +33,7 @@ struct ArticleToolbarModifier: ViewModifier { } ToolbarItem(placement: .bottomBar) { - Button(action: { sceneModel.toggleReadForCurrentArticle() }, label: { + Button(action: { }, label: { if sceneModel.readButtonState == .on { AppAssets.readClosedImage } else { @@ -49,7 +49,7 @@ struct ArticleToolbarModifier: ViewModifier { } ToolbarItem(placement: .bottomBar) { - Button(action: { sceneModel.toggleStarForCurrentArticle() }, label: { + Button(action: { }, label: { if sceneModel.starButtonState == .on { AppAssets.starClosedImage } else { diff --git a/Multiplatform/Shared/SceneModel.swift b/Multiplatform/Shared/SceneModel.swift index b81c23d57..0c92e80a5 100644 --- a/Multiplatform/Shared/SceneModel.swift +++ b/Multiplatform/Shared/SceneModel.swift @@ -21,23 +21,17 @@ final class SceneModel: ObservableObject { private var refreshProgressModel: RefreshProgressModel? = nil private var articleIconSchemeHandler: ArticleIconSchemeHandler? = nil - var webViewProvider: WebViewProvider? = nil - - var undoManager: UndoManager? - var undoableCommands = [UndoableCommand]() - - var sidebarModel: SidebarModel? - var timelineModel: TimelineModel? - var articleManager: ArticleManager? - - var currentArticle: Article? { - return articleManager?.currentArticle - } + private(set) var webViewProvider: WebViewProvider? = nil + private(set) var sidebarModel = SidebarModel() + private(set) var timelineModel = TimelineModel() // MARK: Initialization API /// Prepares the SceneModel to be used in the views func startup() { + sidebarModel.delegate = self + timelineModel.delegate = self + self.refreshProgressModel = RefreshProgressModel() self.refreshProgressModel!.$state.assign(to: self.$refreshProgressState) @@ -48,58 +42,20 @@ final class SceneModel: ObservableObject { } // MARK: Article Management API - - /// Toggles the read indicator for the currently viewable article - func toggleReadForCurrentArticle() { - if let article = articleManager?.currentArticle { - toggleRead(article) - } - } - - /// Toggles the read indicator for the given article - func toggleRead(_ article: Article) { - guard !article.status.read || article.isAvailableToMarkUnread else { return } - markArticles([article], statusKey: .read, flag: !article.status.read) - } - - /// Toggles the star indicator for the currently viewable article - func toggleStarForCurrentArticle() { - if let article = articleManager?.currentArticle { - toggleStar(article) - } - } - - /// Toggles the star indicator for the given article - func toggleStar(_ article: Article) { - markArticles([article], statusKey: .starred, flag: !article.status.starred) - } /// Retrieves the article before the given article in the Timeline func findPrevArticle(_ article: Article) -> Article? { - return timelineModel?.findPrevArticle(article) + return timelineModel.findPrevArticle(article) } /// Retrieves the article after the given article in the Timeline func findNextArticle(_ article: Article) -> Article? { - return timelineModel?.findNextArticle(article) - } - - /// Marks the article as read and selects it in the Timeline. Don't call until after the ArticleManager article has been set. - func updateArticleSelection() { - guard let article = currentArticle else { return } - - timelineModel?.selectArticle(article) - - if article.status.read { - updateArticleState() - } else { - markArticles([article], statusKey: .read, flag: true) - } + return timelineModel.findNextArticle(article) } /// Returns the article with the given articleID func articleFor(_ articleID: String) -> Article? { - return timelineModel?.articleFor(articleID) + return timelineModel.articleFor(articleID) } } @@ -124,19 +80,6 @@ extension SceneModel: TimelineModelDelegate { } -// MARK: UndoableCommandRunner - -extension SceneModel: UndoableCommandRunner { - - func markArticlesWithUndo(_ articles: [Article], statusKey: ArticleStatus.Key, flag: Bool) { - guard let undoManager = undoManager, let markReadCommand = MarkStatusCommand(initialArticles: articles, statusKey: statusKey, flag: flag, undoManager: undoManager) else { - return - } - runCommand(markReadCommand) - } - -} - // MARK: Private private extension SceneModel { @@ -144,30 +87,39 @@ private extension SceneModel { // MARK: Notifications @objc func statusesDidChange(_ note: Notification) { - guard let article = currentArticle, let articleIDs = note.userInfo?[Account.UserInfoKey.articleIDs] as? Set else { + guard let articleIDs = note.userInfo?[Account.UserInfoKey.articleIDs] as? Set else { return } - if articleIDs.contains(article.articleID) { + let selectedArticleIDs = timelineModel.selectedArticles.map { $0.articleID } + if !articleIDs.intersection(selectedArticleIDs).isEmpty { updateArticleState() } } - // MARK: State Updates + // MARK: Button State Updates func updateArticleState() { - guard let article = currentArticle else { + let articles = timelineModel.selectedArticles + + guard !articles.isEmpty else { readButtonState = nil starButtonState = nil return } - if article.isAvailableToMarkUnread { - readButtonState = article.status.read ? .off : .on + if articles.anyArticleIsUnread() { + readButtonState = .on + } else if articles.anyArticleIsReadAndCanMarkUnread() { + readButtonState = .off } else { readButtonState = nil } - starButtonState = article.status.starred ? .on : .off + if articles.anyArticleIsUnstarred() { + starButtonState = .on + } else { + starButtonState = .off + } } } diff --git a/Multiplatform/Shared/SceneNavigationView.swift b/Multiplatform/Shared/SceneNavigationView.swift index 02c6de558..346ad2564 100644 --- a/Multiplatform/Shared/SceneNavigationView.swift +++ b/Multiplatform/Shared/SceneNavigationView.swift @@ -10,7 +10,6 @@ import SwiftUI struct SceneNavigationView: View { - @Environment(\.undoManager) var undoManager @StateObject private var sceneModel = SceneModel() @State private var showSheet: Bool = false @State private var sheetToShow: ToolbarSheets = .none @@ -49,7 +48,6 @@ struct SceneNavigationView: View { } .environmentObject(sceneModel) .onAppear { - sceneModel.undoManager = undoManager sceneModel.startup() } .sheet(isPresented: $showSheet, onDismiss: { sheetToShow = .none }) { @@ -100,7 +98,7 @@ struct SceneNavigationView: View { }).help("Go to Next Unread").padding(.trailing, 40) } ToolbarItem { - Button(action: { sceneModel.toggleReadForCurrentArticle() }, label: { + Button(action: { }, label: { if sceneModel.readButtonState == .on { AppAssets.readClosedImage } else { @@ -111,7 +109,7 @@ struct SceneNavigationView: View { .help(sceneModel.readButtonState == .on ? "Mark as Unread" : "Mark as Read") } ToolbarItem { - Button(action: { sceneModel.toggleStarForCurrentArticle() }, label: { + Button(action: { }, label: { if sceneModel.starButtonState == .on { AppAssets.starClosedImage } else { diff --git a/Multiplatform/Shared/Sidebar/SidebarContainerView.swift b/Multiplatform/Shared/Sidebar/SidebarContainerView.swift index e9352afc2..59861364f 100644 --- a/Multiplatform/Shared/Sidebar/SidebarContainerView.swift +++ b/Multiplatform/Shared/Sidebar/SidebarContainerView.swift @@ -10,8 +10,8 @@ import SwiftUI struct SidebarContainerView: View { + @Environment(\.undoManager) var undoManager @EnvironmentObject private var sceneModel: SceneModel - @StateObject private var sidebarModel = SidebarModel() @State private var showSettings: Bool = false @@ -19,12 +19,11 @@ struct SidebarContainerView: View { SidebarView() .modifier(SidebarToolbarModifier()) .modifier(SidebarListStyleModifier()) - .environmentObject(sidebarModel) + .environmentObject(sceneModel.sidebarModel) .navigationTitle(Text("Feeds")) .onAppear { - sceneModel.sidebarModel = sidebarModel - sidebarModel.delegate = sceneModel - sidebarModel.rebuildSidebarItems() + sceneModel.sidebarModel.undoManager = undoManager + sceneModel.sidebarModel.rebuildSidebarItems() } } diff --git a/Multiplatform/Shared/Sidebar/SidebarModel.swift b/Multiplatform/Shared/Sidebar/SidebarModel.swift index 683ecb1e7..06ea114f6 100644 --- a/Multiplatform/Shared/Sidebar/SidebarModel.swift +++ b/Multiplatform/Shared/Sidebar/SidebarModel.swift @@ -15,7 +15,7 @@ protocol SidebarModelDelegate: class { func unreadCount(for: Feed) -> Int } -class SidebarModel: ObservableObject { +class SidebarModel: ObservableObject, UndoableCommandRunner { weak var delegate: SidebarModelDelegate? @@ -27,6 +27,9 @@ class SidebarModel: ObservableObject { private var selectedFeedIdentifiersCancellable: AnyCancellable? private var selectedFeedIdentifierCancellable: AnyCancellable? + var undoManager: UndoManager? + var undoableCommands = [UndoableCommand]() + init() { NotificationCenter.default.addObserver(self, selector: #selector(unreadCountDidInitialize(_:)), name: .UnreadCountDidInitialize, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(containerChildrenDidChange(_:)), name: .ChildrenDidChange, object: nil) @@ -49,7 +52,6 @@ class SidebarModel: ObservableObject { self.selectedFeeds = [feed] } } - } // MARK: API diff --git a/Multiplatform/Shared/Sidebar/SidebarView.swift b/Multiplatform/Shared/Sidebar/SidebarView.swift index d5eb28754..09288dff3 100644 --- a/Multiplatform/Shared/Sidebar/SidebarView.swift +++ b/Multiplatform/Shared/Sidebar/SidebarView.swift @@ -17,8 +17,7 @@ struct SidebarView: View { @EnvironmentObject private var sidebarModel: SidebarModel @State var navigate = false - @ViewBuilder - var body: some View { + @ViewBuilder var body: some View { #if os(macOS) ZStack { NavigationLink(destination: TimelineContainerView(feeds: sidebarModel.selectedFeeds), isActive: $navigate) { diff --git a/Multiplatform/Shared/Timeline/TimelineContainerView.swift b/Multiplatform/Shared/Timeline/TimelineContainerView.swift index 690d1e0fd..a1ed6ced9 100644 --- a/Multiplatform/Shared/Timeline/TimelineContainerView.swift +++ b/Multiplatform/Shared/Timeline/TimelineContainerView.swift @@ -11,20 +11,19 @@ import Account struct TimelineContainerView: View { + @Environment(\.undoManager) var undoManager @EnvironmentObject private var sceneModel: SceneModel - @StateObject private var timelineModel = TimelineModel() var feeds: [Feed]? = nil @ViewBuilder var body: some View { if let feeds = feeds { TimelineView() - .modifier(TimelineTitleModifier(title: timelineModel.nameForDisplay)) + .modifier(TimelineTitleModifier(title: sceneModel.timelineModel.nameForDisplay)) .modifier(TimelineToolbarModifier()) - .environmentObject(timelineModel) + .environmentObject(sceneModel.timelineModel) .onAppear { - sceneModel.timelineModel = timelineModel - timelineModel.delegate = sceneModel - timelineModel.rebuildTimelineItems(feeds: feeds) + sceneModel.timelineModel.undoManager = undoManager + sceneModel.timelineModel.rebuildTimelineItems(feeds: feeds) } } else { EmptyView() diff --git a/Multiplatform/Shared/Timeline/TimelineModel.swift b/Multiplatform/Shared/Timeline/TimelineModel.swift index c941b6c80..319e050d9 100644 --- a/Multiplatform/Shared/Timeline/TimelineModel.swift +++ b/Multiplatform/Shared/Timeline/TimelineModel.swift @@ -7,6 +7,7 @@ // import Foundation +import Combine import RSCore import Account import Articles @@ -15,13 +16,22 @@ protocol TimelineModelDelegate: class { func timelineRequestedWebFeedSelection(_: TimelineModel, webFeed: WebFeed) } -class TimelineModel: ObservableObject { +class TimelineModel: ObservableObject, UndoableCommandRunner { weak var delegate: TimelineModelDelegate? @Published var nameForDisplay = "" @Published var timelineItems = [TimelineItem]() + @Published var selectedArticleIDs = Set() + @Published var selectedArticleID: String? = .none + @Published var selectedArticles = [Article]() + var undoManager: UndoManager? + var undoableCommands = [UndoableCommand]() + + private var selectedArticleIDsCancellable: AnyCancellable? + private var selectedArticleIDCancellable: AnyCancellable? + private var fetchSerialNumber = 0 private let fetchRequestQueue = FetchRequestQueue() private var exceptionArticleFetcher: ArticleFetcher? @@ -60,6 +70,20 @@ class TimelineModel: ObservableObject { init() { NotificationCenter.default.addObserver(self, selector: #selector(statusesDidChange(_:)), name: .StatusesDidChange, object: nil) + + // TODO: This should be rewritten to use Combine correctly + selectedArticleIDsCancellable = $selectedArticleIDs.sink { [weak self] articleIDs in + guard let self = self else { return } + self.selectedArticles = articleIDs.compactMap { self.idToArticleDictionary[$0] } + } + + // TODO: This should be rewritten to use Combine correctly + selectedArticleIDCancellable = $selectedArticleID.sink { [weak self] articleID in + guard let self = self else { return } + if let articleID = articleID, let article = self.idToArticleDictionary[articleID] { + self.selectedArticles = [article] + } + } } // MARK: API @@ -73,14 +97,6 @@ class TimelineModel: ObservableObject { fetchAndReplaceArticlesAsync(feeds: feeds) } - // TODO: Replace this with ScrollViewReader if we have to keep it - func loadMoreTimelineItemsIfNecessary(_ timelineItem: TimelineItem) { - let thresholdIndex = timelineItems.index(timelineItems.endIndex, offsetBy: -10) - if timelineItems.firstIndex(where: { $0.id == timelineItem.id }) == thresholdIndex { - nextBatch() - } - } - func articleFor(_ articleID: String) -> Article? { return idToArticleDictionary[articleID] } @@ -182,18 +198,9 @@ private extension TimelineModel { func replaceArticles(with unsortedArticles: Set
) { articles = Array(unsortedArticles).sortedByDate(sortDirection ? .orderedDescending : .orderedAscending, groupByFeed: groupByFeed) - timelineItems = [TimelineItem]() - nextBatch() + timelineItems = articles.map { TimelineItem(article: $0) } // TODO: Update unread counts and other item done in didSet on AppKit } - - func nextBatch() { - let rangeEndIndex = timelineItems.endIndex + 50 > articles.endIndex ? articles.endIndex : timelineItems.endIndex + 50 - let range = timelineItems.endIndex.. some View { + #if os(macOS) + return TimelineItemView(timelineItem: timelineItem) //.tag(timelineItem.article.articleID) + #else + return ZStack { + TimelineItemView(timelineItem: timelineItem) + NavigationLink(destination: ArticleContainerView(articles: timelineModel.selectedArticles), + tag: timelineItem.article.articleID, + selection: $timelineModel.selectedArticleID) { + EmptyView() + }.buttonStyle(PlainButtonStyle()) + } + #endif + } } diff --git a/Multiplatform/iOS/Article/ArticleView.swift b/Multiplatform/iOS/Article/ArticleView.swift index 989659371..edf1cf31a 100644 --- a/Multiplatform/iOS/Article/ArticleView.swift +++ b/Multiplatform/iOS/Article/ArticleView.swift @@ -9,21 +9,15 @@ import SwiftUI import Articles -final class ArticleView: UIViewControllerRepresentable { +struct ArticleView: UIViewControllerRepresentable { var sceneModel: SceneModel - var article: Article - - init(sceneModel: SceneModel, article: Article) { - self.sceneModel = sceneModel - self.article = article - } + var articles: [Article] func makeUIViewController(context: Context) -> ArticleViewController { let controller = ArticleViewController() - sceneModel.articleManager = controller controller.sceneModel = sceneModel - controller.currentArticle = article + controller.articles = articles return controller } diff --git a/Multiplatform/iOS/Article/ArticleViewController.swift b/Multiplatform/iOS/Article/ArticleViewController.swift index dc51acc3d..355d1cba3 100644 --- a/Multiplatform/iOS/Article/ArticleViewController.swift +++ b/Multiplatform/iOS/Article/ArticleViewController.swift @@ -12,7 +12,7 @@ import Account import Articles import SafariServices -class ArticleViewController: UIViewController, ArticleManager { +class ArticleViewController: UIViewController { weak var sceneModel: SceneModel? @@ -22,6 +22,12 @@ class ArticleViewController: UIViewController, ArticleManager { return pageViewController?.viewControllers?.first as? WebViewController } + var articles: [Article]? { + didSet { + currentArticle = articles?.first + } + } + var currentArticle: Article? { didSet { if let controller = currentWebViewController, controller.article != currentArticle { @@ -54,8 +60,6 @@ class ArticleViewController: UIViewController, ArticleManager { let controller = createWebViewController(currentArticle, updateView: true) self.pageViewController.setViewControllers([controller], direction: .forward, animated: false, completion: nil) - - sceneModel?.updateArticleSelection() } // MARK: API @@ -123,7 +127,6 @@ extension ArticleViewController: UIPageViewControllerDelegate { guard finished, completed else { return } // guard let article = currentWebViewController?.article else { return } - sceneModel?.updateArticleSelection() // articleExtractorButton.buttonState = currentWebViewController?.articleExtractorButtonState ?? .off previousViewControllers.compactMap({ $0 as? WebViewController }).forEach({ $0.stopWebViewActivity() }) diff --git a/Multiplatform/macOS/Article/ArticleView.swift b/Multiplatform/macOS/Article/ArticleView.swift index 51b5f16ef..640d2e579 100644 --- a/Multiplatform/macOS/Article/ArticleView.swift +++ b/Multiplatform/macOS/Article/ArticleView.swift @@ -12,18 +12,12 @@ import Articles struct ArticleView: NSViewControllerRepresentable { var sceneModel: SceneModel - var article: Article - - init(sceneModel: SceneModel, article: Article) { - self.sceneModel = sceneModel - self.article = article - } + var articles: [Article] func makeNSViewController(context: Context) -> WebViewController { let controller = WebViewController() - sceneModel.articleManager = controller controller.sceneModel = sceneModel - controller.currentArticle = article + controller.articles = articles return controller } diff --git a/Multiplatform/macOS/Article/WebViewController.swift b/Multiplatform/macOS/Article/WebViewController.swift index 8150e3d4a..2901c0cb4 100644 --- a/Multiplatform/macOS/Article/WebViewController.swift +++ b/Multiplatform/macOS/Article/WebViewController.swift @@ -22,7 +22,7 @@ protocol WebViewControllerDelegate: class { func webViewController(_: WebViewController, articleExtractorButtonStateDidUpdate: ArticleExtractorButtonState) } -class WebViewController: NSViewController, ArticleManager { +class WebViewController: NSViewController { private struct MessageName { static let imageWasClicked = "imageWasClicked" @@ -49,7 +49,7 @@ class WebViewController: NSViewController, ArticleManager { var sceneModel: SceneModel? weak var delegate: WebViewControllerDelegate? - var currentArticle: Article? + var articles: [Article]? override func loadView() { view = NSView() @@ -75,8 +75,6 @@ class WebViewController: NSViewController, ArticleManager { ]) loadWebView() - - sceneModel?.updateArticleSelection() } // MARK: Notifications @@ -119,7 +117,7 @@ class WebViewController: NSViewController, ArticleManager { func toggleArticleExtractor() { - guard let article = currentArticle else { + guard let article = articles?.first else { return } @@ -247,17 +245,19 @@ private extension WebViewController { let style = ArticleStylesManager.shared.currentStyle let rendering: ArticleRenderer.Rendering - if let articleExtractor = articleExtractor, articleExtractor.state == .processing { + if articles?.count ?? 0 > 1 { + rendering = ArticleRenderer.multipleSelectionHTML(style: style) + } else if let articleExtractor = articleExtractor, articleExtractor.state == .processing { rendering = ArticleRenderer.loadingHTML(style: style) - } else if let articleExtractor = articleExtractor, articleExtractor.state == .failedToParse, let article = currentArticle { + } else if let articleExtractor = articleExtractor, articleExtractor.state == .failedToParse, let article = articles?.first { rendering = ArticleRenderer.articleHTML(article: article, style: style) - } else if let article = currentArticle, let extractedArticle = extractedArticle { + } else if let article = articles?.first, let extractedArticle = extractedArticle { if isShowingExtractedArticle { rendering = ArticleRenderer.articleHTML(article: article, extractedArticle: extractedArticle, style: style) } else { rendering = ArticleRenderer.articleHTML(article: article, style: style) } - } else if let article = currentArticle { + } else if let article = articles?.first { rendering = ArticleRenderer.articleHTML(article: article, style: style) } else { rendering = ArticleRenderer.noSelectionHTML(style: style) @@ -299,7 +299,7 @@ private extension WebViewController { } func startArticleExtractor() { - if let link = currentArticle?.preferredLink, let extractor = ArticleExtractor(link) { + if let link = articles?.first?.preferredLink, let extractor = ArticleExtractor(link) { extractor.delegate = self extractor.process() articleExtractor = extractor @@ -315,7 +315,7 @@ private extension WebViewController { } func reloadArticleImage() { - guard let article = currentArticle else { return } + guard let article = articles?.first else { return } var components = URLComponents() components.scheme = ArticleRenderer.imageIconScheme diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj index a84a81401..968be9eed 100644 --- a/NetNewsWire.xcodeproj/project.pbxproj +++ b/NetNewsWire.xcodeproj/project.pbxproj @@ -211,8 +211,6 @@ 51707439232AA97100A461A3 /* ShareFolderPickerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51707438232AA97100A461A3 /* ShareFolderPickerController.swift */; }; 5171B4D424B7BABA00FB8D3B /* MarkStatusCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84702AA31FA27AC0006B8943 /* MarkStatusCommand.swift */; }; 5171B4F624B7BABA00FB8D3B /* MarkStatusCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84702AA31FA27AC0006B8943 /* MarkStatusCommand.swift */; }; - 5171B4F824B7CB3600FB8D3B /* ArticleManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5171B4F724B7CB3600FB8D3B /* ArticleManager.swift */; }; - 5171B4F924B7CB3600FB8D3B /* ArticleManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5171B4F724B7CB3600FB8D3B /* ArticleManager.swift */; }; 517630042336215100E15FFF /* main.js in Resources */ = {isa = PBXBuildFile; fileRef = 517630032336215100E15FFF /* main.js */; }; 517630052336215100E15FFF /* main.js in Resources */ = {isa = PBXBuildFile; fileRef = 517630032336215100E15FFF /* main.js */; }; 517630232336657E00E15FFF /* WebViewProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 517630222336657E00E15FFF /* WebViewProvider.swift */; }; @@ -1906,7 +1904,6 @@ 516AE9B22371C372007DEEAA /* MasterFeedTableViewSectionHeaderLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MasterFeedTableViewSectionHeaderLayout.swift; sourceTree = ""; }; 516AE9DE2372269A007DEEAA /* IconImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconImage.swift; sourceTree = ""; }; 51707438232AA97100A461A3 /* ShareFolderPickerController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareFolderPickerController.swift; sourceTree = ""; }; - 5171B4F724B7CB3600FB8D3B /* ArticleManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleManager.swift; sourceTree = ""; }; 517630032336215100E15FFF /* main.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; path = main.js; sourceTree = ""; }; 517630222336657E00E15FFF /* WebViewProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebViewProvider.swift; sourceTree = ""; }; 5177470224B2657F00EB0F74 /* TimelineToolbarModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineToolbarModifier.swift; sourceTree = ""; }; @@ -2867,7 +2864,6 @@ 5177471324B37D4000EB0F74 /* PreloadedWebView.swift */, 5177471924B3863000EB0F74 /* WebViewProvider.swift */, 517B2EBB24B3E62A001AC46C /* WrapperScriptMessageHandler.swift */, - 5171B4F724B7CB3600FB8D3B /* ArticleManager.swift */, ); path = Article; sourceTree = ""; @@ -5095,7 +5091,6 @@ 51E4990324A808BB00B667CB /* FaviconDownloader.swift in Sources */, 172199ED24AB2E0100A31D04 /* SafariView.swift in Sources */, 65ACE48624B477C9003AE06A /* SettingsAccountLabelView.swift in Sources */, - 5171B4F824B7CB3600FB8D3B /* ArticleManager.swift in Sources */, 51E4990224A808BB00B667CB /* ColorHash.swift in Sources */, 51919FAC24AA8CCA00541E64 /* UnreadCountView.swift in Sources */, 5177476224B3BC4700EB0F74 /* SettingsAboutView.swift in Sources */, @@ -5142,7 +5137,6 @@ 51E4996C24A8762D00B667CB /* ExtractedArticle.swift in Sources */, 51E4990824A808C300B667CB /* RSHTMLMetadata+Extension.swift in Sources */, 51919FF824AB8B7700541E64 /* TimelineView.swift in Sources */, - 5171B4F924B7CB3600FB8D3B /* ArticleManager.swift in Sources */, 51E4992B24A8676300B667CB /* ArticleArray.swift in Sources */, 51B54AB324B5AC830014348B /* ArticleButtonState.swift in Sources */, 17D5F17224B0BC6700375168 /* SidebarToolbarModel.swift in Sources */, diff --git a/xcconfig/NetNewsWire_multiplatform_widget_target.xcconfig b/xcconfig/NetNewsWire_multiplatform_widget_target.xcconfig deleted file mode 100644 index 8d083938b..000000000 --- a/xcconfig/NetNewsWire_multiplatform_widget_target.xcconfig +++ /dev/null @@ -1,10 +0,0 @@ -// -// NetNewsWire_multiplatform_widget_target.xcconfig -// NetNewsWire -// -// Created by Maurice Parker on 7/11/20. -// Copyright © 2020 Ranchero Software. All rights reserved. -// - -// Configuration settings file format documentation can be found at: -// https://help.apple.com/xcode/#/dev745c5c974