Stub out mark as read and star functionality
This commit is contained in:
parent
94f956b41f
commit
3e61c7044b
@ -8,6 +8,16 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
enum ArticleReadButtonState {
|
||||
case on
|
||||
case off
|
||||
}
|
||||
|
||||
enum ArticleStarButtonState {
|
||||
case on
|
||||
case off
|
||||
}
|
||||
|
||||
enum ArticleExtractorButtonState {
|
||||
case error
|
||||
case animated
|
@ -20,14 +20,23 @@ protocol ArticleModelDelegate: class {
|
||||
func selectArticle(_: ArticleModel, article: Article)
|
||||
}
|
||||
|
||||
protocol ArticleManager: class {
|
||||
var currentArticle: Article? { get }
|
||||
}
|
||||
|
||||
class ArticleModel: ObservableObject {
|
||||
|
||||
weak var articleManager: ArticleManager?
|
||||
weak var delegate: ArticleModelDelegate?
|
||||
|
||||
var webViewProvider: WebViewProvider? {
|
||||
return delegate?.articleModelWebViewProvider
|
||||
}
|
||||
|
||||
var currentArticle: Article? {
|
||||
return articleManager?.currentArticle
|
||||
}
|
||||
|
||||
// MARK: API
|
||||
|
||||
func findPrevArticle(_ article: Article) -> Article? {
|
||||
@ -41,6 +50,19 @@ class ArticleModel: ObservableObject {
|
||||
func selectArticle(_ article: Article) {
|
||||
delegate?.selectArticle(self, article: article)
|
||||
}
|
||||
|
||||
func toggleReadForCurrentArticle() {
|
||||
if let article = currentArticle {
|
||||
markArticles([article], statusKey: .starred, flag: !article.status.starred)
|
||||
}
|
||||
}
|
||||
|
||||
func toggleStarForCurrentArticle() {
|
||||
if let article = currentArticle {
|
||||
markArticles([article], statusKey: .starred, flag: !article.status.starred)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -9,11 +9,15 @@
|
||||
import Foundation
|
||||
import Account
|
||||
import Articles
|
||||
import RSCore
|
||||
|
||||
final class SceneModel: ObservableObject {
|
||||
|
||||
@Published var refreshProgressState = RefreshProgressModel.State.none
|
||||
|
||||
var undoManager: UndoManager?
|
||||
var undoableCommands = [UndoableCommand]()
|
||||
|
||||
var sidebarModel: SidebarModel?
|
||||
var timelineModel: TimelineModel?
|
||||
var articleModel: ArticleModel?
|
||||
@ -22,7 +26,7 @@ final class SceneModel: ObservableObject {
|
||||
private var articleIconSchemeHandler: ArticleIconSchemeHandler? = nil
|
||||
private var webViewProvider: WebViewProvider? = nil
|
||||
|
||||
// MARK: API
|
||||
// MARK: Initialization API
|
||||
|
||||
func startup() {
|
||||
self.refreshProgressModel = RefreshProgressModel()
|
||||
@ -31,7 +35,28 @@ final class SceneModel: ObservableObject {
|
||||
self.articleIconSchemeHandler = ArticleIconSchemeHandler(sceneModel: self)
|
||||
self.webViewProvider = WebViewProvider(articleIconSchemeHandler: self.articleIconSchemeHandler!)
|
||||
}
|
||||
|
||||
// MARK: Article Status Change API
|
||||
|
||||
func toggleReadForCurrentArticle() {
|
||||
articleModel?.toggleReadForCurrentArticle()
|
||||
}
|
||||
|
||||
func toggleRead(_ article: Article) {
|
||||
guard !article.status.read || article.isAvailableToMarkUnread else { return }
|
||||
markArticles([article], statusKey: .read, flag: !article.status.read)
|
||||
}
|
||||
|
||||
func toggleStarForCurrentArticle() {
|
||||
articleModel?.toggleStarForCurrentArticle()
|
||||
}
|
||||
|
||||
func toggleStar(_ article: Article) {
|
||||
markArticles([article], statusKey: .starred, flag: !article.status.starred)
|
||||
}
|
||||
|
||||
// MARK: Resource lookup API
|
||||
|
||||
func articleFor(_ articleID: String) -> Article? {
|
||||
return timelineModel?.articleFor(articleID)
|
||||
}
|
||||
@ -80,8 +105,22 @@ extension SceneModel: ArticleModelDelegate {
|
||||
|
||||
}
|
||||
|
||||
// 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 {
|
||||
|
||||
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ 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
|
||||
@ -48,6 +49,7 @@ struct SceneNavigationView: View {
|
||||
}
|
||||
.environmentObject(sceneModel)
|
||||
.onAppear {
|
||||
sceneModel.undoManager = undoManager
|
||||
sceneModel.startup()
|
||||
}
|
||||
.sheet(isPresented: $showSheet, onDismiss: { sheetToShow = .none }) {
|
||||
|
@ -12,7 +12,7 @@ import Account
|
||||
import Articles
|
||||
import SafariServices
|
||||
|
||||
class ArticleViewController: UIViewController {
|
||||
class ArticleViewController: UIViewController, ArticleManager {
|
||||
|
||||
weak var articleModel: ArticleModel?
|
||||
|
||||
@ -22,7 +22,7 @@ class ArticleViewController: UIViewController {
|
||||
return pageViewController?.viewControllers?.first as? WebViewController
|
||||
}
|
||||
|
||||
var article: Article? {
|
||||
var currentArticle: Article? {
|
||||
didSet {
|
||||
if let controller = currentWebViewController, controller.article != article {
|
||||
controller.setArticle(article)
|
||||
|
@ -26,7 +26,7 @@ struct ArticleView: NSViewControllerRepresentable {
|
||||
func makeNSViewController(context: Context) -> WebViewController {
|
||||
let controller = WebViewController()
|
||||
controller.articleModel = articleModel
|
||||
controller.article = article
|
||||
controller.currentArticle = article
|
||||
return controller
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ protocol WebViewControllerDelegate: class {
|
||||
func webViewController(_: WebViewController, articleExtractorButtonStateDidUpdate: ArticleExtractorButtonState)
|
||||
}
|
||||
|
||||
class WebViewController: NSViewController {
|
||||
class WebViewController: NSViewController, ArticleManager {
|
||||
|
||||
private struct MessageName {
|
||||
static let imageWasClicked = "imageWasClicked"
|
||||
@ -49,7 +49,7 @@ class WebViewController: NSViewController {
|
||||
var articleModel: ArticleModel?
|
||||
weak var delegate: WebViewControllerDelegate?
|
||||
|
||||
var article: Article?
|
||||
var currentArticle: Article?
|
||||
|
||||
override func loadView() {
|
||||
view = NSView()
|
||||
@ -117,7 +117,7 @@ class WebViewController: NSViewController {
|
||||
|
||||
func toggleArticleExtractor() {
|
||||
|
||||
guard let article = article else {
|
||||
guard let article = currentArticle else {
|
||||
return
|
||||
}
|
||||
|
||||
@ -247,15 +247,15 @@ private extension WebViewController {
|
||||
|
||||
if let articleExtractor = articleExtractor, articleExtractor.state == .processing {
|
||||
rendering = ArticleRenderer.loadingHTML(style: style)
|
||||
} else if let articleExtractor = articleExtractor, articleExtractor.state == .failedToParse, let article = article {
|
||||
} else if let articleExtractor = articleExtractor, articleExtractor.state == .failedToParse, let article = currentArticle {
|
||||
rendering = ArticleRenderer.articleHTML(article: article, style: style)
|
||||
} else if let article = article, let extractedArticle = extractedArticle {
|
||||
} else if let article = currentArticle, 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 = article {
|
||||
} else if let article = currentArticle {
|
||||
rendering = ArticleRenderer.articleHTML(article: article, style: style)
|
||||
} else {
|
||||
rendering = ArticleRenderer.noSelectionHTML(style: style)
|
||||
@ -297,7 +297,7 @@ private extension WebViewController {
|
||||
}
|
||||
|
||||
func startArticleExtractor() {
|
||||
if let link = article?.preferredLink, let extractor = ArticleExtractor(link) {
|
||||
if let link = currentArticle?.preferredLink, let extractor = ArticleExtractor(link) {
|
||||
extractor.delegate = self
|
||||
extractor.process()
|
||||
articleExtractor = extractor
|
||||
@ -313,7 +313,7 @@ private extension WebViewController {
|
||||
}
|
||||
|
||||
func reloadArticleImage() {
|
||||
guard let article = article else { return }
|
||||
guard let article = currentArticle else { return }
|
||||
|
||||
var components = URLComponents()
|
||||
components.scheme = ArticleRenderer.imageIconScheme
|
||||
|
@ -209,6 +209,8 @@
|
||||
516AE9DF2372269A007DEEAA /* IconImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 516AE9DE2372269A007DEEAA /* IconImage.swift */; };
|
||||
516AE9E02372269A007DEEAA /* IconImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 516AE9DE2372269A007DEEAA /* IconImage.swift */; };
|
||||
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 */; };
|
||||
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 */; };
|
||||
@ -228,7 +230,7 @@
|
||||
5177471C24B387AC00EB0F74 /* ImageScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5177471B24B387AC00EB0F74 /* ImageScrollView.swift */; };
|
||||
5177471E24B387E100EB0F74 /* ImageTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5177471D24B387E100EB0F74 /* ImageTransition.swift */; };
|
||||
5177472024B3882600EB0F74 /* ImageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5177471F24B3882600EB0F74 /* ImageViewController.swift */; };
|
||||
5177472224B38CAE00EB0F74 /* ArticleExtractorButtonState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5177472124B38CAE00EB0F74 /* ArticleExtractorButtonState.swift */; };
|
||||
5177472224B38CAE00EB0F74 /* ArticleButtonState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5177472124B38CAE00EB0F74 /* ArticleButtonState.swift */; };
|
||||
5177475C24B39AD500EB0F74 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 5177475824B39AD400EB0F74 /* Credits.rtf */; };
|
||||
5177475D24B39AD500EB0F74 /* Dedication.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 5177475924B39AD400EB0F74 /* Dedication.rtf */; };
|
||||
5177475E24B39AD500EB0F74 /* Thanks.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 5177475A24B39AD500EB0F74 /* Thanks.rtf */; };
|
||||
@ -330,7 +332,7 @@
|
||||
51B54A6624B549CB0014348B /* PreloadedWebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5177471324B37D4000EB0F74 /* PreloadedWebView.swift */; };
|
||||
51B54A6724B549FE0014348B /* ArticleIconSchemeHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5177471524B37D9700EB0F74 /* ArticleIconSchemeHandler.swift */; };
|
||||
51B54A6924B54A490014348B /* IconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51B54A6824B54A490014348B /* IconView.swift */; };
|
||||
51B54AB324B5AC830014348B /* ArticleExtractorButtonState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5177472124B38CAE00EB0F74 /* ArticleExtractorButtonState.swift */; };
|
||||
51B54AB324B5AC830014348B /* ArticleButtonState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5177472124B38CAE00EB0F74 /* ArticleButtonState.swift */; };
|
||||
51B54AB624B5B33C0014348B /* WebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51B54AB524B5B33C0014348B /* WebViewController.swift */; };
|
||||
51B54ABC24B5BEF20014348B /* ArticleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51B54ABB24B5BEF20014348B /* ArticleView.swift */; };
|
||||
51B54B6724B6A7960014348B /* WebStatusBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51B54B6624B6A7960014348B /* WebStatusBarView.swift */; };
|
||||
@ -1919,7 +1921,7 @@
|
||||
5177471B24B387AC00EB0F74 /* ImageScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageScrollView.swift; sourceTree = "<group>"; };
|
||||
5177471D24B387E100EB0F74 /* ImageTransition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageTransition.swift; sourceTree = "<group>"; };
|
||||
5177471F24B3882600EB0F74 /* ImageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageViewController.swift; sourceTree = "<group>"; };
|
||||
5177472124B38CAE00EB0F74 /* ArticleExtractorButtonState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleExtractorButtonState.swift; sourceTree = "<group>"; };
|
||||
5177472124B38CAE00EB0F74 /* ArticleButtonState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleButtonState.swift; sourceTree = "<group>"; };
|
||||
5177475824B39AD400EB0F74 /* Credits.rtf */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.rtf; path = Credits.rtf; sourceTree = "<group>"; };
|
||||
5177475924B39AD400EB0F74 /* Dedication.rtf */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.rtf; path = Dedication.rtf; sourceTree = "<group>"; };
|
||||
5177475A24B39AD500EB0F74 /* Thanks.rtf */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.rtf; path = Thanks.rtf; sourceTree = "<group>"; };
|
||||
@ -2858,8 +2860,8 @@
|
||||
517B2EDF24B3E8FE001AC46C /* blank.html */,
|
||||
517B2EDE24B3E8FE001AC46C /* page.html */,
|
||||
517B2EE124B3E8FE001AC46C /* main_multiplatform.js */,
|
||||
5177472124B38CAE00EB0F74 /* ArticleButtonState.swift */,
|
||||
51A5769524AE617200078888 /* ArticleContainerView.swift */,
|
||||
5177472124B38CAE00EB0F74 /* ArticleExtractorButtonState.swift */,
|
||||
5177471524B37D9700EB0F74 /* ArticleIconSchemeHandler.swift */,
|
||||
51A576BA24AE621800078888 /* ArticleModel.swift */,
|
||||
5177470524B2910300EB0F74 /* ArticleToolbarModifier.swift */,
|
||||
@ -5072,6 +5074,7 @@
|
||||
51E4991E24A8094300B667CB /* RSImage-AppIcons.swift in Sources */,
|
||||
51E499D824A912C200B667CB /* SceneModel.swift in Sources */,
|
||||
5177470E24B2FF6F00EB0F74 /* ArticleView.swift in Sources */,
|
||||
5171B4F624B7BABA00FB8D3B /* MarkStatusCommand.swift in Sources */,
|
||||
65422D1724B75CD1008A2FA2 /* SettingsAddAccountModel.swift in Sources */,
|
||||
5177471424B37D4000EB0F74 /* PreloadedWebView.swift in Sources */,
|
||||
517B2EBC24B3E62A001AC46C /* WrapperScriptMessageHandler.swift in Sources */,
|
||||
@ -5087,7 +5090,7 @@
|
||||
17930ED424AF10EE00A9BA52 /* AddWebFeedView.swift in Sources */,
|
||||
51E4995124A8734D00B667CB /* ExtensionPointManager.swift in Sources */,
|
||||
51E4990C24A808C500B667CB /* AuthorAvatarDownloader.swift in Sources */,
|
||||
5177472224B38CAE00EB0F74 /* ArticleExtractorButtonState.swift in Sources */,
|
||||
5177472224B38CAE00EB0F74 /* ArticleButtonState.swift in Sources */,
|
||||
5177471A24B3863000EB0F74 /* WebViewProvider.swift in Sources */,
|
||||
51E4992124A8095000B667CB /* RSImage-Extensions.swift in Sources */,
|
||||
51E4990324A808BB00B667CB /* FaviconDownloader.swift in Sources */,
|
||||
@ -5133,13 +5136,14 @@
|
||||
51919FB024AA8EFA00541E64 /* SidebarItemView.swift in Sources */,
|
||||
51919FEF24AB85E400541E64 /* TimelineContainerView.swift in Sources */,
|
||||
51E4996624A8760B00B667CB /* ArticleStyle.swift in Sources */,
|
||||
5171B4D424B7BABA00FB8D3B /* MarkStatusCommand.swift in Sources */,
|
||||
5177470724B2910300EB0F74 /* ArticleToolbarModifier.swift in Sources */,
|
||||
FA80C11824B0728000974098 /* AddFolderView.swift in Sources */,
|
||||
51E4996C24A8762D00B667CB /* ExtractedArticle.swift in Sources */,
|
||||
51E4990824A808C300B667CB /* RSHTMLMetadata+Extension.swift in Sources */,
|
||||
51919FF824AB8B7700541E64 /* TimelineView.swift in Sources */,
|
||||
51E4992B24A8676300B667CB /* ArticleArray.swift in Sources */,
|
||||
51B54AB324B5AC830014348B /* ArticleExtractorButtonState.swift in Sources */,
|
||||
51B54AB324B5AC830014348B /* ArticleButtonState.swift in Sources */,
|
||||
17D5F17224B0BC6700375168 /* SidebarToolbarModel.swift in Sources */,
|
||||
514E6C0724AD2B5F00AC6F6E /* Image-Extensions.swift in Sources */,
|
||||
51E4994D24A8734C00B667CB /* ExtensionPointIdentifer.swift in Sources */,
|
||||
|
Loading…
x
Reference in New Issue
Block a user