mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
move LinkItemDetailViewModel into binders package
This commit is contained in:
parent
2bbe0e22d1
commit
5e4502719e
7 changed files with 110 additions and 104 deletions
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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<AnyCancellable>()
|
||||
public let performActionSubject = PassthroughSubject<Action, Never>()
|
||||
var subscriptions = Set<AnyCancellable>()
|
||||
let performActionSubject = PassthroughSubject<Action, Never>()
|
||||
|
||||
public init(item: FeedItem) {
|
||||
init(item: FeedItem) {
|
||||
self.item = item
|
||||
}
|
||||
}
|
||||
|
||||
public struct LinkItemDetailView: View {
|
||||
struct LinkItemDetailView: View {
|
||||
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
|
||||
|
||||
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
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import SwiftUI
|
||||
|
||||
#if os(iOS)
|
||||
extension View {
|
||||
public extension View {
|
||||
func fittedPopover<Content>(
|
||||
isPresented: Binding<Bool>,
|
||||
onDismiss: (() -> Void)? = nil,
|
||||
|
|
|
|||
Loading…
Reference in a new issue