Skip to content

Commit

Permalink
Merge pull request #3820 from thematters/feat/me-drafts-cache
Browse files Browse the repository at this point in the history
feat(draft): revise local cache updating on /me/drafts
  • Loading branch information
robertu7 authored Sep 18, 2023
2 parents f08e5d5 + 5ddf633 commit 6d9bdde
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 75 deletions.
14 changes: 7 additions & 7 deletions src/components/DraftDigest/Feed/DeleteButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import {
useDialogSwitch,
useMutation,
} from '~/components'
import { updateUserDrafts } from '~/components/GQL'
import { DeleteButtonDraftFragment, DeleteDraftMutation } from '~/gql/graphql'

import { DraftsContext } from '../../../views/Me/Drafts/context'
import styles from './styles.module.css'

interface DeleteButtonProps {
Expand All @@ -36,17 +36,17 @@ const fragments = {

const DeleteButton = ({ draft }: DeleteButtonProps) => {
const { show, openDialog, closeDialog } = useDialogSwitch(false)
const [edges, setEdges] = useContext(DraftsContext)

const { lang } = useContext(LanguageContext)

const [deleteDraft] = useMutation<DeleteDraftMutation>(DELETE_DRAFT, {
variables: { id: draft.id },
update: () => {
const filteredEdges = (edges ?? []).filter(
({ node }) => node.id !== draft.id
)
setEdges(filteredEdges)
update: (cache) => {
updateUserDrafts({
cache,
targetId: draft.id,
type: 'remove',
})
},
})

Expand Down
1 change: 1 addition & 0 deletions src/components/GQL/updates/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export * from './userArticles'
export * from './userCollectionDetail'
export * from './userCollections'
export * from './userCollectionsArticles'
export * from './userDrafts'
export * from './userFollowerCount'
export * from './userProfile'
export * from './viewerFolloweeCount'
Expand Down
47 changes: 47 additions & 0 deletions src/components/GQL/updates/userDrafts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { DataProxy } from 'apollo-cache'

import { MeDraftFeedQuery } from '~/gql/graphql'

export const updateUserDrafts = ({
cache,
targetId,
type,
}: {
cache: DataProxy
targetId?: string
type: 'remove' | 'add'
}) => {
// FIXME: circular dependencies
const { ME_DRAFTS_FEED } = require('~/views/Me/Drafts/gql')

let draftsData: MeDraftFeedQuery | null = null
try {
draftsData = cache.readQuery<MeDraftFeedQuery>({ query: ME_DRAFTS_FEED })
} catch (e) {
//
}

let draftEdges = draftsData?.viewer?.drafts.edges || []

switch (type) {
case 'remove':
draftEdges = draftEdges.filter((edge) => edge.node.id !== targetId)
break
}

if (draftsData) {
cache.writeQuery({
query: ME_DRAFTS_FEED,
data: {
...draftsData,
viewer: {
...draftsData?.viewer,
drafts: {
...draftsData?.viewer?.drafts,
edges: draftEdges,
},
},
},
})
}
}
6 changes: 5 additions & 1 deletion src/components/Hook/useCreateDraft.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@ import { useRoute } from '~/components'
import { useMutation } from '~/components/GQL'
import CREATE_DRAFT from '~/components/GQL/mutations/createDraft'
import { CreateDraftMutation } from '~/gql/graphql'
import { ME_DRAFTS_FEED } from '~/views/Me/Drafts/gql'

export const useCreateDraft = () => {
const { router } = useRoute()

const [create] = useMutation<CreateDraftMutation>(CREATE_DRAFT)
// refetch /me/drafts after creating a new draft
const [create] = useMutation<CreateDraftMutation>(CREATE_DRAFT, {
refetchQueries: [{ query: ME_DRAFTS_FEED }],
})

// create draft and redirect to draft detail page
// NOTE: shallow replace if it's already on it
Expand Down
19 changes: 17 additions & 2 deletions src/views/Me/DraftDetail/PublishState/PublishedState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@ import { useRouter } from 'next/router'
import { useEffect } from 'react'

import { toPath } from '~/common/utils'
import { Dialog, ShareDialog, Translate } from '~/components'
import { PublishStateDraftFragment } from '~/gql/graphql'
import {
Dialog,
ShareDialog,
Translate,
useImperativeQuery,
} from '~/components'
import { MeDraftFeedQuery, PublishStateDraftFragment } from '~/gql/graphql'

import { ME_DRAFTS_FEED } from '../../Drafts/gql'

const BasePublishedState = ({
openShareDialog,
Expand All @@ -20,6 +27,14 @@ const BasePublishedState = ({
const PublishedState = ({ draft }: { draft: PublishStateDraftFragment }) => {
const router = useRouter()

// refetch /me/drafts on published
const refetch = useImperativeQuery<MeDraftFeedQuery>(ME_DRAFTS_FEED, {
variables: { id: draft.id },
})
useEffect(() => {
refetch()
}, [])

if (!draft.article) {
return null
}
Expand Down
8 changes: 0 additions & 8 deletions src/views/Me/Drafts/context.ts

This file was deleted.

26 changes: 26 additions & 0 deletions src/views/Me/Drafts/gql.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import gql from 'graphql-tag'

import { DraftDigest } from '~/components/DraftDigest'

export const ME_DRAFTS_FEED = gql`
query MeDraftFeed($after: String) {
viewer {
id
drafts(input: { first: 20, after: $after })
@connection(key: "viewerDrafts") {
pageInfo {
startCursor
endCursor
hasNextPage
}
edges {
cursor
node {
...DraftDigestFeedDraft
}
}
}
}
}
${DraftDigest.Feed.fragments.draft}
`
69 changes: 12 additions & 57 deletions src/views/Me/Drafts/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { useQuery } from '@apollo/react-hooks'
import gql from 'graphql-tag'
import { useEffect } from 'react'

import { mergeConnections } from '~/common/utils'
import {
Expand All @@ -12,52 +10,15 @@ import {
List,
QueryError,
Spinner,
useCache,
} from '~/components'
import { MeDraftFeedQuery } from '~/gql/graphql'

import { DraftsContext } from './context'

const ME_DRAFTS_FEED = gql`
query MeDraftFeed($after: String) {
viewer {
id
drafts(input: { first: 20, after: $after })
@connection(key: "viewerDrafts") {
pageInfo {
startCursor
endCursor
hasNextPage
}
edges {
cursor
node {
...DraftDigestFeedDraft
}
}
}
}
}
${DraftDigest.Feed.fragments.draft}
`

type Edge = NonNullable<
NonNullable<MeDraftFeedQuery['viewer']>['drafts']['edges']
>
import { ME_DRAFTS_FEED } from './gql'

export const BaseMeDrafts = () => {
const [edges, setEdges, DraftsContextProvider] = useCache<Edge>(
[],
DraftsContext
)

const { data, loading, error, fetchMore } =
useQuery<MeDraftFeedQuery>(ME_DRAFTS_FEED)

useEffect(() => {
setEdges(data?.viewer?.drafts.edges ?? [])
}, [data?.viewer?.drafts.edges?.length])

if (loading) {
return <Spinner />
}
Expand All @@ -67,9 +28,9 @@ export const BaseMeDrafts = () => {
}

const connectionPath = 'viewer.drafts'
const { pageInfo } = data?.viewer?.drafts || {}
const { edges, pageInfo } = data?.viewer?.drafts || {}

if (edges.length <= 0 || !pageInfo) {
if (!edges || edges.length <= 0 || !pageInfo) {
return <EmptyDraft />
}

Expand All @@ -85,21 +46,15 @@ export const BaseMeDrafts = () => {
})

return (
<DraftsContextProvider>
<InfiniteScroll
hasNextPage={pageInfo.hasNextPage}
loadMore={loadMore}
eof
>
<List>
{edges.map(({ node, cursor }) => (
<List.Item key={cursor}>
<DraftDigest.Feed draft={node} />
</List.Item>
))}
</List>
</InfiniteScroll>
</DraftsContextProvider>
<InfiniteScroll hasNextPage={pageInfo.hasNextPage} loadMore={loadMore} eof>
<List>
{edges.map(({ node, cursor }) => (
<List.Item key={cursor}>
<DraftDigest.Feed draft={node} />
</List.Item>
))}
</List>
</InfiniteScroll>
)
}

Expand Down

1 comment on commit 6d9bdde

@vercel
Copy link

@vercel vercel bot commented on 6d9bdde Sep 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.