Mark images as submitted on client after successful mutation
This commit is contained in:
parent
f79792cd4d
commit
086e1aea3a
@ -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,
|
||||
@ -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`
|
||||
@ -55,7 +57,11 @@ export function BountyForm ({
|
||||
id
|
||||
}
|
||||
}
|
||||
`
|
||||
`, {
|
||||
onCompleted ({ upsertBounty: { text } }) {
|
||||
markImagesAsSubmitted(text)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const onSubmit = useCallback(
|
||||
|
@ -5,8 +5,10 @@ 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!) {
|
||||
@ -14,6 +16,9 @@ export default function CommentEdit ({ comment, editThreshold, onSuccess, onCanc
|
||||
text
|
||||
}
|
||||
}`, {
|
||||
onCompleted ({ upsertComment: { text } }) {
|
||||
markImagesAsSubmitted(text)
|
||||
},
|
||||
update (cache, { data: { upsertComment } }) {
|
||||
cache.modify({
|
||||
id: `Item:${comment.id}`,
|
||||
|
@ -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',
|
||||
@ -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(
|
||||
|
@ -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: [] })
|
||||
|
||||
@ -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) {
|
||||
@ -54,7 +67,8 @@ export function ImageProvider ({ me, children }) {
|
||||
const contextValue = {
|
||||
unsubmittedImages,
|
||||
setUnsubmittedImages,
|
||||
deleteImage
|
||||
deleteImage,
|
||||
markImagesAsSubmitted
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -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
|
||||
@ -40,6 +41,7 @@ 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) {
|
||||
@ -47,8 +49,13 @@ export default function JobForm ({ item, sub }) {
|
||||
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(
|
||||
|
@ -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()
|
||||
@ -52,6 +53,7 @@ export function LinkForm ({ item, sub, editThreshold, children }) {
|
||||
}
|
||||
}
|
||||
}`)
|
||||
const { markImagesAsSubmitted } = useImages
|
||||
|
||||
const related = []
|
||||
for (const item of relatedData?.related?.items || []) {
|
||||
@ -73,8 +75,14 @@ export function LinkForm ({ item, sub, editThreshold, children }) {
|
||||
mutation upsertLink($sub: String, $id: ID, $title: String!, $url: String!, $text: String, $boost: Int, $forward: [ItemForwardInput], $hash: String, $hmac: String) {
|
||||
upsertLink(sub: $sub, id: $id, title: $title, url: $url, text: $text, boost: $boost, forward: $forward, hash: $hash, hmac: $hmac) {
|
||||
id
|
||||
text
|
||||
}
|
||||
}`
|
||||
}`,
|
||||
{
|
||||
onCompleted ({ upsertLink: { text } }) {
|
||||
markImagesAsSubmitted(text)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const onSubmit = useCallback(
|
||||
|
@ -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`
|
||||
@ -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(
|
||||
|
@ -11,6 +11,7 @@ import { commentSchema } from '../lib/validate'
|
||||
import Info from './info'
|
||||
import { quote } from '../lib/md'
|
||||
import { COMMENT_DEPTH_LIMIT } from '../lib/constants'
|
||||
import { useImages } from './image'
|
||||
|
||||
export function ReplyOnAnotherPage ({ item }) {
|
||||
const path = item.path.split('.')
|
||||
@ -49,6 +50,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()
|
||||
@ -116,6 +118,9 @@ export default forwardRef(function Reply ({ item, onSuccess, replyOpen, children
|
||||
}
|
||||
}
|
||||
}`, {
|
||||
onCompleted ({ upsertComment: { text } }) {
|
||||
markImagesAsSubmitted(text)
|
||||
},
|
||||
update (cache, { data: { upsertComment } }) {
|
||||
cache.modify({
|
||||
id: `Item:${parentId}`,
|
||||
|
Loading…
x
Reference in New Issue
Block a user