Bridge response values from highlight mutations back to JS in the format it expects

This commit is contained in:
Jackson Harper
2022-03-24 10:49:31 -07:00
parent f3edb9ca7a
commit 5392265a5e
9 changed files with 61 additions and 42 deletions

View File

@ -9,6 +9,14 @@ struct SafariWebLink: Identifiable {
let url: URL
}
func encodeHighlightResult(_ highlight: Highlight) -> [String: Any]? {
let data = try? JSONEncoder().encode(highlight)
if let data = data, let dictionary = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any] {
return dictionary
}
return nil
}
final class WebReaderViewModel: ObservableObject {
@Published var isLoading = false
@Published var articleContent: ArticleContent?
@ -46,9 +54,13 @@ final class WebReaderViewModel: ObservableObject {
)
.sink { completion in
guard case .failure = completion else { return }
replyHandler(["result": false], nil)
} receiveValue: { _ in
replyHandler(["result": true], nil)
replyHandler([], "createHighlight: Error encoding response")
} receiveValue: { highlight in
if let highlight = encodeHighlightResult(highlight) {
replyHandler(["result": highlight], nil)
} else {
replyHandler([], "createHighlight: Error encoding response")
}
}
.store(in: &subscriptions)
}
@ -85,9 +97,13 @@ final class WebReaderViewModel: ObservableObject {
)
.sink { completion in
guard case .failure = completion else { return }
replyHandler(["result": false], nil)
} receiveValue: { _ in
replyHandler(["result": true], nil)
replyHandler([], "mergeHighlight: Error encoding response")
} receiveValue: { highlight in
if let highlight = encodeHighlightResult(highlight) {
replyHandler(["result": highlight], nil)
} else {
replyHandler([], "mergeHighlight: Error encoding response")
}
}
.store(in: &subscriptions)
}
@ -104,9 +120,10 @@ final class WebReaderViewModel: ObservableObject {
)
.sink { completion in
guard case .failure = completion else { return }
replyHandler(["result": false], nil)
} receiveValue: { _ in
replyHandler(["result": true], nil)
replyHandler([], "updateHighlight: Error encoding response")
} receiveValue: { highlight in
// Update highlight JS code just expects the highlight ID back
replyHandler(["result": highlight.id], nil)
}
.store(in: &subscriptions)
}

View File

@ -11,16 +11,16 @@ public extension DataService {
patch: String,
articleId: String,
annotation: String? = nil
) -> AnyPublisher<String, BasicError> {
) -> AnyPublisher<Highlight, BasicError> {
enum MutationResult {
case saved(id: String)
case saved(highlight: Highlight)
case error(errorCode: Enums.CreateHighlightErrorCode)
}
let selection = Selection<MutationResult, Unions.CreateHighlightResult> {
try $0.on(
createHighlightSuccess: .init {
.saved(id: try $0.highlight(selection: Selection.Highlight { try $0.id() }))
.saved(highlight: try $0.highlight(selection: highlightSelection))
},
createHighlightError: .init { .error(errorCode: try $0.errorCodes().first ?? .badData) }
)
@ -53,8 +53,8 @@ public extension DataService {
}
switch payload.data {
case let .saved(id: id):
promise(.success(id))
case let .saved(highlight: highlight):
promise(.success(highlight))
case let .error(errorCode: errorCode):
promise(.failure(.message(messageText: errorCode.rawValue)))
}

View File

@ -12,16 +12,16 @@ public extension DataService {
patch: String,
articleId: String,
overlapHighlightIdList: [String]
) -> AnyPublisher<String, BasicError> {
) -> AnyPublisher<Highlight, BasicError> {
enum MutationResult {
case saved(id: String)
case saved(highlight: Highlight)
case error(errorCode: Enums.MergeHighlightErrorCode)
}
let selection = Selection<MutationResult, Unions.MergeHighlightResult> {
try $0.on(
mergeHighlightSuccess: .init {
.saved(id: try $0.highlight(selection: Selection.Highlight { try $0.id() }))
.saved(highlight: try $0.highlight(selection: highlightSelection))
},
mergeHighlightError: .init { .error(errorCode: try $0.errorCodes().first ?? .badData) }
)
@ -57,8 +57,8 @@ public extension DataService {
}
switch payload.data {
case let .saved(id: id):
promise(.success(id))
case let .saved(highlight: highlight):
promise(.success(highlight))
case let .error(errorCode: errorCode):
promise(.failure(.message(messageText: errorCode.rawValue)))
}

View File

@ -8,16 +8,16 @@ public extension DataService {
highlightID: String,
annotation: String?,
sharedAt: Date?
) -> AnyPublisher<String, BasicError> {
) -> AnyPublisher<Highlight, BasicError> {
enum MutationResult {
case saved(id: String)
case saved(highlight: Highlight)
case error(errorCode: Enums.UpdateHighlightErrorCode)
}
let selection = Selection<MutationResult, Unions.UpdateHighlightResult> {
try $0.on(
updateHighlightSuccess: .init {
.saved(id: try $0.highlight(selection: Selection.Highlight { try $0.id() }))
.saved(highlight: try $0.highlight(selection: highlightSelection))
},
updateHighlightError: .init { .error(errorCode: try $0.errorCodes().first ?? .badData) }
)
@ -47,8 +47,8 @@ public extension DataService {
}
switch payload.data {
case let .saved(id: id):
promise(.success(id))
case let .saved(highlight: highlight):
promise(.success(highlight))
case let .error(errorCode: errorCode):
promise(.failure(.message(messageText: errorCode.rawValue)))
}

View File

@ -11,19 +11,6 @@ public extension DataService {
case error(error: String)
}
let highlightSelection = Selection.Highlight {
Highlight(
id: try $0.id(),
shortId: try $0.shortId(),
quote: try $0.quote(),
prefix: try $0.prefix(),
suffix: try $0.suffix(),
patch: try $0.patch(),
annotation: try $0.annotation(),
createdByMe: try $0.createdByMe()
)
}
let articleSelection = Selection.Article {
ArticleContent(
htmlContent: try $0.content(),

View File

@ -0,0 +1,15 @@
import Models
import SwiftGraphQL
let highlightSelection = Selection.Highlight {
Highlight(
id: try $0.id(),
shortId: try $0.shortId(),
quote: try $0.quote(),
prefix: try $0.prefix(),
suffix: try $0.suffix(),
patch: try $0.patch(),
annotation: try $0.annotation(),
createdByMe: try $0.createdByMe()
)
}

File diff suppressed because one or more lines are too long

View File

@ -89,12 +89,11 @@ export async function createHighlight(
let keptHighlights = input.existingHighlights
if (shouldMerge) {
const result = await articleMutations.mergeHighlightMutation({
highlight = await articleMutations.mergeHighlightMutation({
...newHighlightAttributes,
overlapHighlightIdList: input.selection.overlapHighlights,
})
highlight = result?.mergeHighlight.highlight
keptHighlights = input.existingHighlights.filter(
($0) => !input.selection.overlapHighlights.includes($0.id)
)

View File

@ -25,7 +25,7 @@ type InnerMergeHighlightOutput = {
export async function mergeHighlightMutation(
input: MergeHighlightInput
): Promise<MergeHighlightOutput | undefined> {
): Promise<Highlight | undefined> {
const mutation = gql`
mutation MergeHighlight($input: MergeHighlightInput!) {
mergeHighlight(input: $input) {
@ -54,7 +54,8 @@ export async function mergeHighlightMutation(
try {
const data = await gqlFetcher(mutation, { input })
return data as MergeHighlightOutput | undefined
const output = data as MergeHighlightOutput | undefined
return output?.mergeHighlight.highlight
} catch {
return undefined
}