Files
omnivore/apple/OmnivoreKit/Sources/Services/DataService/Queries/ArticleContentQuery.swift
2022-12-05 21:14:12 +08:00

90 lines
3.0 KiB
Swift

import CoreData
import Foundation
import Models
import SwiftGraphQL
import Utils
struct ArticleProps {
let item: InternalLinkedItem
let htmlContent: String
let highlights: [InternalHighlight]
}
extension DataService {
// swiftlint:disable:next function_body_length
func articleContentFetch(username: String, itemID: String) async throws -> ArticleProps {
enum QueryResult {
case success(result: ArticleProps)
case error(error: String)
}
let articleContentSelection = Selection.Article {
ArticleProps(
item: InternalLinkedItem(
id: try $0.id(),
title: try $0.title(),
createdAt: try $0.createdAt().value ?? Date(),
savedAt: try $0.savedAt().value ?? Date(),
readAt: try $0.readAt()?.value,
updatedAt: try $0.updatedAt().value ?? Date(),
state: try $0.state()?.rawValue.asArticleContentStatus ?? .succeeded,
readingProgress: try $0.readingProgressPercent(),
readingProgressAnchor: try $0.readingProgressAnchorIndex(),
imageURLString: try $0.image(),
onDeviceImageURLString: nil,
documentDirectoryPath: nil,
pageURLString: try $0.url(),
descriptionText: try $0.description(),
publisherURLString: try $0.originalArticleUrl(),
siteName: try $0.siteName(),
author: try $0.author(),
publishDate: try $0.publishedAt()?.value,
slug: try $0.slug(),
isArchived: try $0.isArchived(),
contentReader: try $0.contentReader().rawValue,
originalHtml: nil,
language: try $0.language(),
recommendedBy: try $0.recommendedBy(selection: recommendationSelection.list.nullable) ?? [],
labels: try $0.labels(selection: feedItemLabelSelection.list.nullable) ?? []
),
htmlContent: try $0.content(),
highlights: try $0.highlights(selection: highlightSelection.list)
)
}
let selection = Selection<QueryResult, Unions.ArticleResult> {
try $0.on(
articleError: .init {
QueryResult.error(error: try $0.errorCodes().description)
},
articleSuccess: .init {
QueryResult.success(result: try $0.article(selection: articleContentSelection))
}
)
}
let query = Selection.Query {
try $0.article(slug: itemID, username: username, selection: selection)
}
let path = appEnvironment.graphqlPath
let headers = networker.defaultHeaders
return try await withCheckedThrowingContinuation { continuation in
send(query, to: path, headers: headers) { queryResult in
guard let payload = try? queryResult.get() else {
continuation.resume(throwing: ContentFetchError.network)
return
}
switch payload.data {
case let .success(result: result):
continuation.resume(returning: result)
case .error:
continuation.resume(throwing: ContentFetchError.badData)
}
}
}
}
}