mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
use core data to track reading progress
This commit is contained in:
parent
9c7a0d2ee9
commit
9828846222
4 changed files with 49 additions and 75 deletions
|
|
@ -75,18 +75,11 @@ public final class PDFViewerViewModel: ObservableObject {
|
|||
}
|
||||
|
||||
public func updateItemReadProgress(percent: Double, anchorIndex: Int) {
|
||||
services.dataService
|
||||
.updateArticleReadingProgressPublisher(
|
||||
itemID: linkedItem.unwrappedID,
|
||||
readingProgress: percent,
|
||||
anchorIndex: anchorIndex
|
||||
)
|
||||
.sink { completion in
|
||||
guard case let .failure(error) = completion else { return }
|
||||
print(error)
|
||||
} receiveValue: { _ in
|
||||
}
|
||||
.store(in: &subscriptions)
|
||||
services.dataService.updateLinkReadingProgress(
|
||||
itemID: linkedItem.unwrappedID,
|
||||
readingProgress: percent,
|
||||
anchorIndex: anchorIndex
|
||||
)
|
||||
}
|
||||
|
||||
public func highlightShareURL(shortId: String) -> URL? {
|
||||
|
|
|
|||
|
|
@ -34,19 +34,11 @@ enum PDFProvider {
|
|||
}
|
||||
|
||||
func updateItemReadStatus(dataService: DataService) {
|
||||
dataService
|
||||
.updateArticleReadingProgressPublisher(
|
||||
itemID: item.unwrappedID,
|
||||
readingProgress: item.isRead ? 0 : 100,
|
||||
anchorIndex: 0
|
||||
)
|
||||
.sink { completion in
|
||||
guard case let .failure(error) = completion else { return }
|
||||
print(error)
|
||||
} receiveValue: { [weak self] readingProgress in
|
||||
self?.item.readingProgress = readingProgress
|
||||
}
|
||||
.store(in: &subscriptions)
|
||||
dataService.updateLinkReadingProgress(
|
||||
itemID: item.unwrappedID,
|
||||
readingProgress: item.isRead ? 0 : 100,
|
||||
anchorIndex: 0
|
||||
)
|
||||
}
|
||||
|
||||
func loadWebAppWrapper(dataService: DataService, rawAuthCookie: String?) async {
|
||||
|
|
|
|||
|
|
@ -141,18 +141,8 @@ final class WebReaderViewModel: ObservableObject {
|
|||
return
|
||||
}
|
||||
|
||||
dataService.updateArticleReadingProgressPublisher(
|
||||
itemID: itemID,
|
||||
readingProgress: readingProgress,
|
||||
anchorIndex: anchorIndex
|
||||
)
|
||||
.sink { completion in
|
||||
guard case .failure = completion else { return }
|
||||
replyHandler(["result": false], nil)
|
||||
} receiveValue: { _ in
|
||||
replyHandler(["result": true], nil)
|
||||
}
|
||||
.store(in: &subscriptions)
|
||||
dataService.updateLinkReadingProgress(itemID: itemID, readingProgress: readingProgress, anchorIndex: anchorIndex)
|
||||
replyHandler(["result": true], nil)
|
||||
}
|
||||
|
||||
func webViewActionWithReplyHandler(
|
||||
|
|
|
|||
|
|
@ -4,13 +4,29 @@ import Foundation
|
|||
import Models
|
||||
import SwiftGraphQL
|
||||
|
||||
public extension DataService {
|
||||
// swiftlint:disable function_body_length
|
||||
func updateArticleReadingProgressPublisher(
|
||||
itemID: String,
|
||||
readingProgress: Double,
|
||||
anchorIndex: Int
|
||||
) -> AnyPublisher<Double, SaveArticleError> {
|
||||
extension DataService {
|
||||
public func updateLinkReadingProgress(itemID: String, readingProgress: Double, anchorIndex: Int) {
|
||||
backgroundContext.perform { [weak self] in
|
||||
guard let self = self else { return }
|
||||
guard let linkedItem = LinkedItem.lookup(byID: itemID, inContext: self.backgroundContext) else { return }
|
||||
|
||||
linkedItem.update(
|
||||
inContext: self.backgroundContext,
|
||||
newReadingProgress: readingProgress,
|
||||
newAnchorIndex: anchorIndex
|
||||
)
|
||||
|
||||
// Send update to server
|
||||
self.syncLinkReadingProgress(
|
||||
itemID: linkedItem.unwrappedID,
|
||||
objectID: linkedItem.objectID,
|
||||
readingProgress: readingProgress,
|
||||
anchorIndex: anchorIndex
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func syncLinkReadingProgress(itemID: String, objectID: NSManagedObjectID, readingProgress: Double, anchorIndex: Int) {
|
||||
enum MutationResult {
|
||||
case saved(readingProgress: Double)
|
||||
case error(errorCode: Enums.SaveArticleReadingProgressErrorCode)
|
||||
|
|
@ -40,41 +56,24 @@ public extension DataService {
|
|||
|
||||
let path = appEnvironment.graphqlPath
|
||||
let headers = networker.defaultHeaders
|
||||
let context = backgroundContext
|
||||
|
||||
return Deferred {
|
||||
Future { promise in
|
||||
send(mutation, to: path, headers: headers) { result in
|
||||
switch result {
|
||||
case let .success(payload):
|
||||
if let graphqlError = payload.errors {
|
||||
promise(.failure(.unknown(description: graphqlError.first.debugDescription)))
|
||||
}
|
||||
send(mutation, to: path, headers: headers) { result in
|
||||
let data = try? result.get()
|
||||
let syncStatus: ServerSyncStatus = data == nil ? .needsUpdate : .isNSync
|
||||
|
||||
switch payload.data {
|
||||
case .saved:
|
||||
if let linkedItem = LinkedItem.lookup(byID: itemID, inContext: self.backgroundContext) {
|
||||
linkedItem.update(
|
||||
inContext: self.backgroundContext,
|
||||
newReadingProgress: readingProgress,
|
||||
newAnchorIndex: anchorIndex
|
||||
)
|
||||
}
|
||||
promise(.success(readingProgress))
|
||||
case let .error(errorCode: errorCode):
|
||||
switch errorCode {
|
||||
case .unauthorized:
|
||||
promise(.failure(.unauthorized))
|
||||
case .badData, .notFound:
|
||||
promise(.failure(.badData))
|
||||
}
|
||||
}
|
||||
case .failure:
|
||||
promise(.failure(.badData))
|
||||
}
|
||||
context.perform {
|
||||
guard let linkedItem = context.object(with: objectID) as? LinkedItem else { return }
|
||||
linkedItem.serverSyncStatus = Int64(syncStatus.rawValue)
|
||||
|
||||
do {
|
||||
try context.save()
|
||||
logger.debug("LinkedItem updated succesfully")
|
||||
} catch {
|
||||
context.rollback()
|
||||
logger.debug("Failed to update LinkedItem: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
}
|
||||
.receive(on: DispatchQueue.main)
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue