Skip to content

Commit

Permalink
Mark images as submitted on client after successful mutation
Browse files Browse the repository at this point in the history
  • Loading branch information
ekzyis committed Oct 19, 2023
1 parent c299735 commit 323fae1
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 6 deletions.
8 changes: 7 additions & 1 deletion components/bounty-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { useCallback } from 'react'
import { normalizeForwards } from '../lib/form'
import { MAX_TITLE_LENGTH } from '../lib/constants'
import { useMe } from './me'
import { useImages } from './image'

export function BountyForm ({
item,
Expand All @@ -27,6 +28,7 @@ export function BountyForm ({
const router = useRouter()
const client = useApolloClient()
const me = useMe()
const { markImagesAsSubmitted } = useImages()
const schema = bountySchema({ client, me, existingBoost: item?.boost })
const [upsertBounty] = useMutation(
gql`
Expand Down Expand Up @@ -55,7 +57,11 @@ export function BountyForm ({
id
}
}
`
`, {
onCompleted ({ upsertBounty: { text } }) {
markImagesAsSubmitted(text)
}
}
)

const onSubmit = useCallback(
Expand Down
5 changes: 5 additions & 0 deletions components/comment-edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,20 @@ import { EditFeeButton } from './fee-button'
import Button from 'react-bootstrap/Button'
import Delete from './delete'
import { commentSchema } from '../lib/validate'
import { useImages } from './image'

export default function CommentEdit ({ comment, editThreshold, onSuccess, onCancel }) {
const { markImagesAsSubmitted } = useImages()
const [upsertComment] = useMutation(
gql`
mutation upsertComment($id: ID! $text: String!) {
upsertComment(id: $id, text: $text) {
text
}
}`, {
onCompleted ({ upsertComment: { text } }) {
markImagesAsSubmitted(text)
},
update (cache, { data: { upsertComment } }) {
cache.modify({
id: `Item:${comment.id}`,
Expand Down
10 changes: 9 additions & 1 deletion components/discussion-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { normalizeForwards } from '../lib/form'
import { MAX_TITLE_LENGTH } from '../lib/constants'
import { useMe } from './me'
import useCrossposter from './use-crossposter'
import { useImages } from './image'

export function DiscussionForm ({
item, sub, editThreshold, titleLabel = 'title',
Expand All @@ -30,14 +31,21 @@ export function DiscussionForm ({
// if Web Share Target API was used
const shareTitle = router.query.title
const crossposter = useCrossposter()
const { markImagesAsSubmitted } = useImages()

const [upsertDiscussion] = useMutation(
gql`
mutation upsertDiscussion($sub: String, $id: ID, $title: String!, $text: String, $boost: Int, $forward: [ItemForwardInput], $hash: String, $hmac: String) {
upsertDiscussion(sub: $sub, id: $id, title: $title, text: $text, boost: $boost, forward: $forward, hash: $hash, hmac: $hmac) {
id
text
}
}`
}`,
{
onCompleted ({ upsertDiscussion: { text } }) {
markImagesAsSubmitted(text)
}
}
)

const onSubmit = useCallback(
Expand Down
16 changes: 15 additions & 1 deletion components/image.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { UPLOAD_TYPES_ALLOW } from '../lib/constants'
import { useToast } from './toast'
import gql from 'graphql-tag'
import { useMutation, useQuery } from '@apollo/client'
import { extractUrls } from '../lib/md'

const ImageContext = createContext({ unsubmitted: [] })

Expand Down Expand Up @@ -44,6 +45,18 @@ export function ImageProvider ({ me, children }) {
})
const [unsubmittedImages, setUnsubmittedImages] = useState([])

const markImagesAsSubmitted = useCallback((text) => {
// mark images from S3 included in the text as submitted on the client
const urls = extractUrls(text)
const s3UrlPrefix = `https://${process.env.NEXT_PUBLIC_AWS_UPLOAD_BUCKET}.s3.amazonaws.com/`
urls
.filter(url => url.startsWith(s3UrlPrefix))
.forEach(url => {
const s3Key = url.split('/').pop()
setUnsubmittedImages(prev => prev.filter(img => img.id !== s3Key))
})
}, [setUnsubmittedImages])

useEffect(() => {
const images = data?.me?.images
if (images) {
Expand All @@ -54,7 +67,8 @@ export function ImageProvider ({ me, children }) {
const contextValue = {
unsubmittedImages,
setUnsubmittedImages,
deleteImage
deleteImage,
markImagesAsSubmitted
}

return (
Expand Down
9 changes: 8 additions & 1 deletion components/job-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import ActionTooltip from './action-tooltip'
import { jobSchema } from '../lib/validate'
import CancelButton from './cancel-button'
import { MAX_TITLE_LENGTH } from '../lib/constants'
import { useImages } from './image'

function satsMin2Mo (minute) {
return minute * 30 * 24 * 60
Expand All @@ -40,15 +41,21 @@ export default function JobForm ({ item, sub }) {
const storageKeyPrefix = item ? undefined : `${sub.name}-job`
const router = useRouter()
const [logoId, setLogoId] = useState(item?.uploadId)
const { markImagesAsSubmitted } = useImages()
const [upsertJob] = useMutation(gql`
mutation upsertJob($sub: String!, $id: ID, $title: String!, $company: String!, $location: String,
$remote: Boolean, $text: String!, $url: String!, $maxBid: Int!, $status: String, $logo: Int, $hash: String, $hmac: String) {
upsertJob(sub: $sub, id: $id, title: $title, company: $company,
location: $location, remote: $remote, text: $text,
url: $url, maxBid: $maxBid, status: $status, logo: $logo, hash: $hash, hmac: $hmac) {
id
text
}
}`
}`, {
onCompleted ({ upsertJob: { text } }) {
markImagesAsSubmitted(text)
}
}
)

const onSubmit = useCallback(
Expand Down
10 changes: 9 additions & 1 deletion components/link-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import CancelButton from './cancel-button'
import { normalizeForwards } from '../lib/form'
import { MAX_TITLE_LENGTH } from '../lib/constants'
import { useMe } from './me'
import { useImages } from './image'

export function LinkForm ({ item, sub, editThreshold, children }) {
const router = useRouter()
Expand Down Expand Up @@ -52,6 +53,7 @@ export function LinkForm ({ item, sub, editThreshold, children }) {
}
}
}`)
const { markImagesAsSubmitted } = useImages

const related = []
for (const item of relatedData?.related?.items || []) {
Expand All @@ -73,8 +75,14 @@ export function LinkForm ({ item, sub, editThreshold, children }) {
mutation upsertLink($sub: String, $id: ID, $title: String!, $url: String!, $boost: Int, $forward: [ItemForwardInput], $hash: String, $hmac: String) {
upsertLink(sub: $sub, id: $id, title: $title, url: $url, boost: $boost, forward: $forward, hash: $hash, hmac: $hmac) {
id
text
}
}`
}`,
{
onCompleted ({ upsertLink: { text } }) {
markImagesAsSubmitted(text)
}
}
)

const onSubmit = useCallback(
Expand Down
9 changes: 8 additions & 1 deletion components/poll-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@ import CancelButton from './cancel-button'
import { useCallback } from 'react'
import { normalizeForwards } from '../lib/form'
import { useMe } from './me'
import { useImages } from './image'

export function PollForm ({ item, sub, editThreshold, children }) {
const router = useRouter()
const client = useApolloClient()
const me = useMe()
const schema = pollSchema({ client, me, existingBoost: item?.boost })
const { markImagesAsSubmitted } = useImages()

const [upsertPoll] = useMutation(
gql`
Expand All @@ -27,8 +29,13 @@ export function PollForm ({ item, sub, editThreshold, children }) {
upsertPoll(sub: $sub, id: $id, title: $title, text: $text,
options: $options, boost: $boost, forward: $forward, hash: $hash, hmac: $hmac) {
id
text
}
}`
}`, {
onCompleted ({ upsertPoll: { text } }) {
markImagesAsSubmitted(text)
}
}
)

const onSubmit = useCallback(
Expand Down
5 changes: 5 additions & 0 deletions components/reply.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { commentsViewedAfterComment } from '../lib/new-comments'
import { commentSchema } from '../lib/validate'
import Info from './info'
import { quote } from '../lib/md'
import { useImages } from './image'

export function ReplyOnAnotherPage ({ parentId }) {
return (
Expand Down Expand Up @@ -40,6 +41,7 @@ export default forwardRef(function Reply ({ item, onSuccess, replyOpen, children
const parentId = item.id
const replyInput = useRef(null)
const formInnerRef = useRef()
const { markImagesAsSubmitted } = useImages()

// Start block to handle iOS Safari's weird selection clearing behavior
const savedRange = useRef()
Expand Down Expand Up @@ -107,6 +109,9 @@ export default forwardRef(function Reply ({ item, onSuccess, replyOpen, children
}
}
}`, {
onCompleted ({ upsertComment: { text } }) {
markImagesAsSubmitted(text)
},
update (cache, { data: { upsertComment } }) {
cache.modify({
id: `Item:${parentId}`,
Expand Down

0 comments on commit 323fae1

Please sign in to comment.