diff --git a/apple/OmnivoreKit/Sources/Binders/Scenes/LinkItemDetailScene.swift b/apple/OmnivoreKit/Sources/Binders/Scenes/LinkItemDetailScene.swift deleted file mode 100644 index 3955b7e3f..000000000 --- a/apple/OmnivoreKit/Sources/Binders/Scenes/LinkItemDetailScene.swift +++ /dev/null @@ -1,86 +0,0 @@ -import Models -import Services -import SwiftUI -import Utils -import Views - -extension LinkItemDetailViewModel { - static func make(feedItem: FeedItem, services: Services) -> LinkItemDetailViewModel { - let viewModel = LinkItemDetailViewModel(item: feedItem) - viewModel.bind(services: services) - return viewModel - } - - func bind(services: Services) { - performActionSubject.sink { [weak self] action in - switch action { - case .load: - self?.loadWebAppWrapper(services: services) - case let .updateReadStatus(markAsRead: markAsRead): - self?.updateItemReadStatus(markAsRead: markAsRead, dataService: services.dataService) - } - } - .store(in: &subscriptions) - } - - private func updateItemReadStatus(markAsRead: Bool, dataService: DataService) { - dataService - .updateArticleReadingProgressPublisher( - itemID: item.id, - readingProgress: markAsRead ? 100 : 0, - anchorIndex: 0 - ) - .sink { completion in - guard case let .failure(error) = completion else { return } - print(error) - } receiveValue: { [weak self] feedItem in - self?.item.readingProgress = feedItem.readingProgress - } - .store(in: &subscriptions) - } - - private func loadWebAppWrapper(services: Services) { - // Attempt to get `Viewer` from DataService - if let currentViewer = services.dataService.currentViewer { - createWebAppWrapperViewModel(username: currentViewer.username, services: services) - return - } - - services.dataService.viewerPublisher().sink( - receiveCompletion: { completion in - guard case let .failure(error) = completion else { return } - print(error) - }, - receiveValue: { [weak self] viewer in - self?.createWebAppWrapperViewModel(username: viewer.username, services: services) - } - ) - .store(in: &subscriptions) - } - - private func createWebAppWrapperViewModel(username: String, services: Services) { - let baseURL = services.dataService.appEnvironment.webAppBaseURL - - let urlRequest = URLRequest.webRequest( - baseURL: services.dataService.appEnvironment.webAppBaseURL, - urlPath: "/app/\(username)/\(item.slug)", - queryParams: ["isAppEmbedView": "true", "highlightBarDisabled": isMacApp ? "false" : "true"] - ) - - let newWebAppWrapperViewModel = WebAppWrapperViewModel( - webViewURLRequest: urlRequest, - baseURL: baseURL, - rawAuthCookie: services.authenticator.omnivoreAuthCookieString - ) - - newWebAppWrapperViewModel.performActionSubject.sink { action in - switch action { - case let .shareHighlight(highlightID): - print("show share modal for highlight with id: \(highlightID)") - } - } - .store(in: &newWebAppWrapperViewModel.subscriptions) - - webAppWrapperViewModel = newWebAppWrapperViewModel - } -} diff --git a/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift b/apple/OmnivoreKit/Sources/Binders/Views/LinkItemDetailView.swift similarity index 61% rename from apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift rename to apple/OmnivoreKit/Sources/Binders/Views/LinkItemDetailView.swift index 3250a37e8..ac491a6cb 100644 --- a/apple/OmnivoreKit/Sources/Views/LinkedItemDetail/LinkItemDetailView.swift +++ b/apple/OmnivoreKit/Sources/Binders/Views/LinkItemDetailView.swift @@ -1,30 +1,114 @@ import Combine import Models +import Services import SwiftUI import Utils +import Views -public enum PDFProvider { - public static var pdfViewerProvider: ((URL, FeedItem) -> AnyView)? +// TODO: remove this view model +extension LinkItemDetailViewModel { + static func make(feedItem: FeedItem, services: Services) -> LinkItemDetailViewModel { + let viewModel = LinkItemDetailViewModel(item: feedItem) + viewModel.bind(services: services) + return viewModel + } + + func bind(services: Services) { + performActionSubject.sink { [weak self] action in + switch action { + case .load: + self?.loadWebAppWrapper(services: services) + case let .updateReadStatus(markAsRead: markAsRead): + self?.updateItemReadStatus(markAsRead: markAsRead, dataService: services.dataService) + } + } + .store(in: &subscriptions) + } + + private func updateItemReadStatus(markAsRead: Bool, dataService: DataService) { + dataService + .updateArticleReadingProgressPublisher( + itemID: item.id, + readingProgress: markAsRead ? 100 : 0, + anchorIndex: 0 + ) + .sink { completion in + guard case let .failure(error) = completion else { return } + print(error) + } receiveValue: { [weak self] feedItem in + self?.item.readingProgress = feedItem.readingProgress + } + .store(in: &subscriptions) + } + + private func loadWebAppWrapper(services: Services) { + // Attempt to get `Viewer` from DataService + if let currentViewer = services.dataService.currentViewer { + createWebAppWrapperViewModel(username: currentViewer.username, services: services) + return + } + + services.dataService.viewerPublisher().sink( + receiveCompletion: { completion in + guard case let .failure(error) = completion else { return } + print(error) + }, + receiveValue: { [weak self] viewer in + self?.createWebAppWrapperViewModel(username: viewer.username, services: services) + } + ) + .store(in: &subscriptions) + } + + private func createWebAppWrapperViewModel(username: String, services: Services) { + let baseURL = services.dataService.appEnvironment.webAppBaseURL + + let urlRequest = URLRequest.webRequest( + baseURL: services.dataService.appEnvironment.webAppBaseURL, + urlPath: "/app/\(username)/\(item.slug)", + queryParams: ["isAppEmbedView": "true", "highlightBarDisabled": isMacApp ? "false" : "true"] + ) + + let newWebAppWrapperViewModel = WebAppWrapperViewModel( + webViewURLRequest: urlRequest, + baseURL: baseURL, + rawAuthCookie: services.authenticator.omnivoreAuthCookieString + ) + + newWebAppWrapperViewModel.performActionSubject.sink { action in + switch action { + case let .shareHighlight(highlightID): + print("show share modal for highlight with id: \(highlightID)") + } + } + .store(in: &newWebAppWrapperViewModel.subscriptions) + + webAppWrapperViewModel = newWebAppWrapperViewModel + } } -public final class LinkItemDetailViewModel: ObservableObject { - @Published public var item: FeedItem - @Published public var webAppWrapperViewModel: WebAppWrapperViewModel? +enum PDFProvider { + static var pdfViewerProvider: ((URL, FeedItem) -> AnyView)? +} - public enum Action { +final class LinkItemDetailViewModel: ObservableObject { + @Published var item: FeedItem + @Published var webAppWrapperViewModel: WebAppWrapperViewModel? + + enum Action { case load case updateReadStatus(markAsRead: Bool) } - public var subscriptions = Set() - public let performActionSubject = PassthroughSubject() + var subscriptions = Set() + let performActionSubject = PassthroughSubject() - public init(item: FeedItem) { + init(item: FeedItem) { self.item = item } } -public struct LinkItemDetailView: View { +struct LinkItemDetailView: View { @Environment(\.presentationMode) var presentationMode: Binding static let navBarHeight = 50.0 @@ -32,7 +116,7 @@ public struct LinkItemDetailView: View { @State private var showFontSizePopover = false @State private var navBarVisibilityRatio = 1.0 - public init(viewModel: LinkItemDetailViewModel) { + init(viewModel: LinkItemDetailViewModel) { self.viewModel = viewModel } @@ -61,7 +145,7 @@ public struct LinkItemDetailView: View { ) } - public var body: some View { + var body: some View { #if os(iOS) if UIDevice.isIPhone, !viewModel.item.isPDF { compactInnerBody diff --git a/apple/OmnivoreKit/Sources/Views/Article/WebAppView.swift b/apple/OmnivoreKit/Sources/Views/Article/WebAppView.swift index e725392f9..bc131ad93 100644 --- a/apple/OmnivoreKit/Sources/Views/Article/WebAppView.swift +++ b/apple/OmnivoreKit/Sources/Views/Article/WebAppView.swift @@ -34,8 +34,8 @@ import WebKit webView.backgroundColor = UIColor.clear webView.configuration.userContentController = contentController webView.scrollView.delegate = context.coordinator - webView.scrollView.contentInset.top = LinkItemDetailView.navBarHeight - webView.scrollView.verticalScrollIndicatorInsets.top = LinkItemDetailView.navBarHeight + webView.scrollView.contentInset.top = 50.0 // TODO: LinkItemDetailView.navBarHeight + webView.scrollView.verticalScrollIndicatorInsets.top = 50.0 // TODO: LinkItemDetailView.navBarHeight for action in WebViewAction.allCases { webView.configuration.userContentController.add(context.coordinator, name: action.rawValue) diff --git a/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift b/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift index 1f54a5fdd..a14acfb53 100644 --- a/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift +++ b/apple/OmnivoreKit/Sources/Views/Article/WebAppViewCoordinator.swift @@ -2,7 +2,7 @@ import SwiftUI import WebKit final class WebAppViewCoordinator: NSObject { - let navBarHeight = LinkItemDetailView.navBarHeight + let navBarHeight = 50.0 // TODO: LinkItemDetailView.navBarHeight var webViewActionHandler: (WKScriptMessage) -> Void = { _ in } var linkHandler: (URL) -> Void = { _ in } var needsReload = true diff --git a/apple/OmnivoreKit/Sources/Views/Article/WebAppWrapperView.swift b/apple/OmnivoreKit/Sources/Views/Article/WebAppWrapperView.swift index f87b67573..6f704e6b1 100644 --- a/apple/OmnivoreKit/Sources/Views/Article/WebAppWrapperView.swift +++ b/apple/OmnivoreKit/Sources/Views/Article/WebAppWrapperView.swift @@ -14,8 +14,8 @@ public final class WebAppWrapperViewModel: ObservableObject { let baseURL: URL let rawAuthCookie: String? - @Published var sendIncreaseFontSignal: Bool = false - @Published var sendDecreaseFontSignal: Bool = false + @Published public var sendIncreaseFontSignal: Bool = false + @Published public var sendDecreaseFontSignal: Bool = false public init(webViewURLRequest: URLRequest, baseURL: URL, rawAuthCookie: String?) { self.webViewURLRequest = webViewURLRequest diff --git a/apple/OmnivoreKit/Sources/Views/FontSizeAdjustmentPopoverView.swift b/apple/OmnivoreKit/Sources/Views/FontSizeAdjustmentPopoverView.swift index deff8c4f8..76ec5520e 100644 --- a/apple/OmnivoreKit/Sources/Views/FontSizeAdjustmentPopoverView.swift +++ b/apple/OmnivoreKit/Sources/Views/FontSizeAdjustmentPopoverView.swift @@ -5,6 +5,14 @@ public struct FontSizeAdjustmentPopoverView: View { let increaseFontAction: () -> Void let decreaseFontAction: () -> Void + public init( + increaseFontAction: @escaping () -> Void, + decreaseFontAction: @escaping () -> Void + ) { + self.increaseFontAction = increaseFontAction + self.decreaseFontAction = decreaseFontAction + } + static let preferredWebFontSizeKey = UserDefaultKey.preferredWebFontSize.rawValue #if os(macOS) @AppStorage(preferredWebFontSizeKey) var storedFontSize = Int(NSFont.userFont(ofSize: 16)?.pointSize ?? 16) diff --git a/apple/OmnivoreKit/Sources/Views/Popover.swift b/apple/OmnivoreKit/Sources/Views/Popover.swift index 91d9dfd2f..5cba95786 100644 --- a/apple/OmnivoreKit/Sources/Views/Popover.swift +++ b/apple/OmnivoreKit/Sources/Views/Popover.swift @@ -1,7 +1,7 @@ import SwiftUI #if os(iOS) - extension View { + public extension View { func fittedPopover( isPresented: Binding, onDismiss: (() -> Void)? = nil,