omnivore/packages/web/lib/networking/queries/useGetArticleQuery.tsx

174 lines
4.2 KiB
TypeScript
Raw Normal View History

2022-02-11 17:24:33 +00:00
import { gql } from 'graphql-request'
import useSWRImmutable, { Cache } from 'swr'
2022-02-11 17:24:33 +00:00
import { makeGqlFetcher, RequestContext, ssrFetcher } from '../networkHelpers'
Remove article saving request (#493) * Add state and taskName in elastic page mappings * Add state and taskName in elastic page interface * Create page with PROCESSING state before scrapping * Update createArticleRequest API * Fix tests * Add default state for pages * Update createArticle API * Update save page * Update save file * Update saving item description * Show unable to parse content for failed page * Fix date parsing * Search for not failed pages * Fix tests * Add test for saveUrl * Update get article saving request api * Update get article test * Add test for articleSavingRequest API * Add test for failure * Return new page id if clientRequestId empty * Update clientRequestId in savePage * Update clientRequestId in saveFile * Replace article with slug in articleSavingRequest * Add slug in articleSavingRequest response * Depreciate article * Use slug in web * Remove article and highlight fragments * Query article.slug on Prod * Show unable to parse description for failed page * Fix a bug having duplicate pages when saving the same url multiple times * Add state in response * Rename variables in removeArticle API * Rename state * Add state in response in web * Make state an enum * Open temporary page by link id * Use an empty reader view as the background for loading pages * Progressively load the article page as content is loaded * Add includePending flag in getArticles API * Set includePending = true in web * Add elastic update mappings in migration script * Add elastic mappings in docker image * Move index_settings.json to migrate package * Remove elastic index creation in api * Move elastic migrations to a separate directory * Remove index_settings from api docker image Co-authored-by: Jackson Harper <jacksonh@gmail.com>
2022-04-29 05:41:06 +00:00
import {
articleFragment,
ContentReader,
State,
} from '../fragments/articleFragment'
2022-02-24 04:35:42 +00:00
import { Highlight, highlightFragment } from '../fragments/highlightFragment'
import { ScopedMutator } from 'swr/dist/types'
2022-02-24 04:35:42 +00:00
import { Label, labelFragment } from '../fragments/labelFragment'
import { LibraryItems } from './useGetLibraryItemsQuery'
2022-02-11 17:24:33 +00:00
type ArticleQueryInput = {
username?: string
slug?: string
includeFriendsHighlights?: boolean
}
type ArticleQueryOutput = {
articleData?: ArticleData
articleFetchError: unknown
isLoading: boolean
}
type ArticleData = {
article: NestedArticleData
}
type NestedArticleData = {
article: ArticleAttributes
errorCodes?: string[]
}
export type ArticleAttributes = {
id: string
title: string
url: string
originalArticleUrl: string
author?: string
image?: string
savedAt: string
createdAt: string
publishedAt?: string
description?: string
contentReader: ContentReader
readingProgressPercent: number
readingProgressAnchorIndex: number
slug: string
savedByViewer?: boolean
content: string
highlights: Highlight[]
2022-02-24 04:35:42 +00:00
linkId: string
labels?: Label[]
Remove article saving request (#493) * Add state and taskName in elastic page mappings * Add state and taskName in elastic page interface * Create page with PROCESSING state before scrapping * Update createArticleRequest API * Fix tests * Add default state for pages * Update createArticle API * Update save page * Update save file * Update saving item description * Show unable to parse content for failed page * Fix date parsing * Search for not failed pages * Fix tests * Add test for saveUrl * Update get article saving request api * Update get article test * Add test for articleSavingRequest API * Add test for failure * Return new page id if clientRequestId empty * Update clientRequestId in savePage * Update clientRequestId in saveFile * Replace article with slug in articleSavingRequest * Add slug in articleSavingRequest response * Depreciate article * Use slug in web * Remove article and highlight fragments * Query article.slug on Prod * Show unable to parse description for failed page * Fix a bug having duplicate pages when saving the same url multiple times * Add state in response * Rename variables in removeArticle API * Rename state * Add state in response in web * Make state an enum * Open temporary page by link id * Use an empty reader view as the background for loading pages * Progressively load the article page as content is loaded * Add includePending flag in getArticles API * Set includePending = true in web * Add elastic update mappings in migration script * Add elastic mappings in docker image * Move index_settings.json to migrate package * Remove elastic index creation in api * Move elastic migrations to a separate directory * Remove index_settings from api docker image Co-authored-by: Jackson Harper <jacksonh@gmail.com>
2022-04-29 05:41:06 +00:00
state?: State
2022-02-11 17:24:33 +00:00
}
const query = gql`
query GetArticle(
$username: String!
$slug: String!
$includeFriendsHighlights: Boolean
) {
article(username: $username, slug: $slug) {
... on ArticleSuccess {
article {
...ArticleFields
content
highlights(input: { includeFriends: $includeFriendsHighlights }) {
...HighlightFields
}
labels {
...LabelFields
}
2022-02-11 17:24:33 +00:00
}
}
... on ArticleError {
errorCodes
}
}
}
${articleFragment}
${highlightFragment}
${labelFragment}
2022-02-11 17:24:33 +00:00
`
2022-02-11 17:24:33 +00:00
export function useGetArticleQuery({
username,
slug,
includeFriendsHighlights,
}: ArticleQueryInput): ArticleQueryOutput {
const variables = {
username,
slug,
includeFriendsHighlights,
}
const { data, error, mutate } = useSWRImmutable(
2022-02-11 17:24:33 +00:00
slug ? [query, username, slug, includeFriendsHighlights] : null,
makeGqlFetcher(variables)
)
let resultData: ArticleData | undefined = data as ArticleData
let resultError = error
// We need to check the response errors here and return the error
// it will be nested in the data pages, if there is one error,
// we invalidate the data and return the error. We also zero out
// the response in the case of an error.
if (!error && resultData && resultData.article.errorCodes) {
resultError = resultData.article.errorCodes
resultData = undefined
}
return {
articleData: resultData,
articleFetchError: resultError as unknown,
isLoading: !error && !data,
}
}
export async function articleQuery(
context: RequestContext,
input: ArticleQueryInput
): Promise<ArticleAttributes> {
const result = (await ssrFetcher(context, query, input)) as ArticleData
if (result.article) {
return result.article.article
}
return Promise.reject()
}
export const cacheArticle = (
mutate: ScopedMutator,
username: string,
article: ArticleAttributes,
includeFriendsHighlights = false
) => {
mutate([query, username, article.slug, includeFriendsHighlights], {
article: { article: { ...article, cached: true } },
})
}
export const removeItemFromCache = (
cache: Cache<unknown>,
mutate: ScopedMutator,
Remove article saving request (#493) * Add state and taskName in elastic page mappings * Add state and taskName in elastic page interface * Create page with PROCESSING state before scrapping * Update createArticleRequest API * Fix tests * Add default state for pages * Update createArticle API * Update save page * Update save file * Update saving item description * Show unable to parse content for failed page * Fix date parsing * Search for not failed pages * Fix tests * Add test for saveUrl * Update get article saving request api * Update get article test * Add test for articleSavingRequest API * Add test for failure * Return new page id if clientRequestId empty * Update clientRequestId in savePage * Update clientRequestId in saveFile * Replace article with slug in articleSavingRequest * Add slug in articleSavingRequest response * Depreciate article * Use slug in web * Remove article and highlight fragments * Query article.slug on Prod * Show unable to parse description for failed page * Fix a bug having duplicate pages when saving the same url multiple times * Add state in response * Rename variables in removeArticle API * Rename state * Add state in response in web * Make state an enum * Open temporary page by link id * Use an empty reader view as the background for loading pages * Progressively load the article page as content is loaded * Add includePending flag in getArticles API * Set includePending = true in web * Add elastic update mappings in migration script * Add elastic mappings in docker image * Move index_settings.json to migrate package * Remove elastic index creation in api * Move elastic migrations to a separate directory * Remove index_settings from api docker image Co-authored-by: Jackson Harper <jacksonh@gmail.com>
2022-04-29 05:41:06 +00:00
itemId: string
) => {
try {
const mappedCache = cache as Map<string, unknown>
mappedCache.forEach((value: any, key) => {
if (typeof value == 'object' && 'articles' in value) {
const articles = value.articles as LibraryItems
const idx = articles.edges.findIndex((edge) => edge.node.id == itemId)
if (idx > -1) {
value.articles.edges.splice(idx, 1)
mutate(key, value, false)
}
}
})
mappedCache.forEach((value: any, key) => {
if (Array.isArray(value)) {
const idx = value.findIndex((item) => 'articles' in item)
if (idx > -1) {
mutate(key, value, false)
}
}
})
} catch (error) {
console.log('error removing item from cache', error)
}
}