Compare commits
No commits in common. "c8975038bdee5ce4cd4c5655724ac0baada9b21a" and "e09e1398fd3cfac46b03a8a346a0e4acc9cbe39d" have entirely different histories.
c8975038bd
...
e09e1398fd
@ -1315,19 +1315,16 @@ export const updateItem = async (parent, { sub: subName, forward, hash, hmac, ..
|
|||||||
|
|
||||||
if (old.bio) {
|
if (old.bio) {
|
||||||
// prevent editing a bio like a regular item
|
// prevent editing a bio like a regular item
|
||||||
item = { id: Number(item.id), text: item.text, title: `@${user.name}'s bio` }
|
item = { id: Number(item.id), text: item.text, title: `@${user.name}'s bio`, userId: meId }
|
||||||
} else if (old.parentId) {
|
} else if (old.parentId) {
|
||||||
// prevent editing a comment like a post
|
// prevent editing a comment like a post
|
||||||
item = { id: Number(item.id), text: item.text }
|
item = { id: Number(item.id), text: item.text, userId: meId }
|
||||||
} else {
|
} else {
|
||||||
item = { subName, ...item }
|
item = { subName, userId: meId, ...item }
|
||||||
item.forwardUsers = await getForwardUsers(models, forward)
|
item.forwardUsers = await getForwardUsers(models, forward)
|
||||||
}
|
}
|
||||||
item.uploadIds = uploadIdsFromText(item.text, { models })
|
item.uploadIds = uploadIdsFromText(item.text, { models })
|
||||||
|
|
||||||
// never change author of item
|
|
||||||
item.userId = old.userId
|
|
||||||
|
|
||||||
const resultItem = await performPaidAction('ITEM_UPDATE', item, { models, me, lnd })
|
const resultItem = await performPaidAction('ITEM_UPDATE', item, { models, me, lnd })
|
||||||
|
|
||||||
resultItem.comments = []
|
resultItem.comments = []
|
||||||
|
@ -29,12 +29,11 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// width and height is 0 for videos
|
|
||||||
if (width * height > IMAGE_PIXELS_MAX) {
|
if (width * height > IMAGE_PIXELS_MAX) {
|
||||||
throw new GqlInputError(`image must be less than ${IMAGE_PIXELS_MAX} pixels`)
|
throw new GqlInputError(`image must be less than ${IMAGE_PIXELS_MAX} pixels`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const fileParams = {
|
const imgParams = {
|
||||||
type,
|
type,
|
||||||
size,
|
size,
|
||||||
width,
|
width,
|
||||||
@ -45,10 +44,10 @@ export default {
|
|||||||
|
|
||||||
if (avatar) {
|
if (avatar) {
|
||||||
if (!me) throw new GqlAuthenticationError()
|
if (!me) throw new GqlAuthenticationError()
|
||||||
fileParams.paid = undefined
|
imgParams.paid = undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
const upload = await models.upload.create({ data: { ...fileParams } })
|
const upload = await models.upload.create({ data: { ...imgParams } })
|
||||||
return createPresignedPost({ key: String(upload.id), type, size })
|
return createPresignedPost({ key: String(upload.id), type, size })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,8 +39,8 @@ export const FileUpload = forwardRef(({ children, className, onSelect, onUpload,
|
|||||||
try {
|
try {
|
||||||
({ data } = await getSignedPOST({ variables }))
|
({ data } = await getSignedPOST({ variables }))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
toaster.danger('error initiating upload: ' + e.message || e.toString?.())
|
||||||
onError?.({ ...variables, name: file.name, file })
|
onError?.({ ...variables, name: file.name, file })
|
||||||
reject(e)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,8 +58,10 @@ export const FileUpload = forwardRef(({ children, className, onSelect, onUpload,
|
|||||||
|
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
// TODO make sure this is actually a helpful error message and does not expose anything to the user we don't want
|
// TODO make sure this is actually a helpful error message and does not expose anything to the user we don't want
|
||||||
|
const err = res.statusText
|
||||||
|
toaster.danger('error uploading: ' + err)
|
||||||
onError?.({ ...variables, name: file.name, file })
|
onError?.({ ...variables, name: file.name, file })
|
||||||
reject(new Error(res.statusText))
|
reject(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,20 +96,16 @@ export const FileUpload = forwardRef(({ children, className, onSelect, onUpload,
|
|||||||
onChange={async (e) => {
|
onChange={async (e) => {
|
||||||
const fileList = e.target.files
|
const fileList = e.target.files
|
||||||
for (const file of Array.from(fileList)) {
|
for (const file of Array.from(fileList)) {
|
||||||
try {
|
if (accept.indexOf(file.type) === -1) {
|
||||||
if (accept.indexOf(file.type) === -1) {
|
toaster.danger(`image must be ${accept.map(t => t.replace('image/', '').replace('video/', '')).join(', ')}`)
|
||||||
throw new Error(`file must be ${accept.map(t => t.replace(/^(image|video)\//, '')).join(', ')}`)
|
|
||||||
}
|
|
||||||
if (onSelect) await onSelect?.(file, s3Upload)
|
|
||||||
else await s3Upload(file)
|
|
||||||
} catch (e) {
|
|
||||||
toaster.danger(`upload of '${file.name}' failed: ` + e.message || e.toString?.())
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if (onSelect) await onSelect?.(file, s3Upload)
|
||||||
|
else await s3Upload(file)
|
||||||
|
// reset file input
|
||||||
|
// see https://bobbyhadz.com/blog/react-reset-file-input#reset-a-file-input-in-react
|
||||||
|
e.target.value = null
|
||||||
}
|
}
|
||||||
// reset file input
|
|
||||||
// see https://bobbyhadz.com/blog/react-reset-file-input#reset-a-file-input-in-react
|
|
||||||
e.target.value = null
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
|
@ -49,11 +49,9 @@ export default function ItemInfo ({
|
|||||||
}, [item])
|
}, [item])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const authorEdit = item.mine
|
const invoice = window.localStorage.getItem(`item:${item.id}:hash:hmac`)
|
||||||
const invParams = window.localStorage.getItem(`item:${item.id}:hash:hmac`)
|
setCanEdit((item.mine || invoice) && (Date.now() < editThreshold))
|
||||||
const hmacEdit = !!invParams && !me && Number(item.user.id) === USER_ID.anon
|
}, [item.id, item.mine, editThreshold])
|
||||||
setCanEdit((authorEdit || hmacEdit) && (Date.now() < editThreshold))
|
|
||||||
}, [me, item.id, item.mine, editThreshold])
|
|
||||||
|
|
||||||
// territory founders can pin any post in their territory
|
// territory founders can pin any post in their territory
|
||||||
// and OPs can pin any root reply in their post
|
// and OPs can pin any root reply in their post
|
||||||
|
@ -6,8 +6,6 @@ import { useCallback } from 'react'
|
|||||||
import { normalizeForwards, toastUpsertSuccessMessages } from '@/lib/form'
|
import { normalizeForwards, toastUpsertSuccessMessages } from '@/lib/form'
|
||||||
import { RETRY_PAID_ACTION } from '@/fragments/paidAction'
|
import { RETRY_PAID_ACTION } from '@/fragments/paidAction'
|
||||||
import gql from 'graphql-tag'
|
import gql from 'graphql-tag'
|
||||||
import { USER_ID } from '@/lib/constants'
|
|
||||||
import { useMe } from './me'
|
|
||||||
|
|
||||||
// this is intented to be compatible with upsert item mutations
|
// this is intented to be compatible with upsert item mutations
|
||||||
// so that it can be reused for all post types and comments and we don't have
|
// so that it can be reused for all post types and comments and we don't have
|
||||||
@ -21,7 +19,6 @@ export default function useItemSubmit (mutation,
|
|||||||
const toaster = useToast()
|
const toaster = useToast()
|
||||||
const crossposter = useCrossposter()
|
const crossposter = useCrossposter()
|
||||||
const [upsertItem] = usePaidMutation(mutation)
|
const [upsertItem] = usePaidMutation(mutation)
|
||||||
const { me } = useMe()
|
|
||||||
|
|
||||||
return useCallback(
|
return useCallback(
|
||||||
async ({ boost, crosspost, title, options, bounty, maxBid, start, stop, ...values }, { resetForm }) => {
|
async ({ boost, crosspost, title, options, bounty, maxBid, start, stop, ...values }, { resetForm }) => {
|
||||||
@ -30,11 +27,10 @@ export default function useItemSubmit (mutation,
|
|||||||
options = options.slice(item?.poll?.options?.length || 0).filter(o => o.trim().length > 0)
|
options = options.slice(item?.poll?.options?.length || 0).filter(o => o.trim().length > 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
const hmacEdit = item?.id && Number(item.user.id) === USER_ID.anon && !me
|
if (item?.id) {
|
||||||
if (hmacEdit) {
|
const invoiceData = window.localStorage.getItem(`item:${item.id}:hash:hmac`)
|
||||||
const invParams = window.localStorage.getItem(`item:${item.id}:hash:hmac`)
|
if (invoiceData) {
|
||||||
if (invParams) {
|
const [hash, hmac] = invoiceData.split(':')
|
||||||
const [hash, hmac] = invParams.split(':')
|
|
||||||
values.hash = hash
|
values.hash = hash
|
||||||
values.hmac = hmac
|
values.hmac = hmac
|
||||||
}
|
}
|
||||||
@ -93,7 +89,7 @@ export default function useItemSubmit (mutation,
|
|||||||
await router.push(sub ? `/~${sub.name}/recent` : '/recent')
|
await router.push(sub ? `/~${sub.name}/recent` : '/recent')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [me, upsertItem, router, crossposter, item, sub, onSuccessfulSubmit,
|
}, [upsertItem, router, crossposter, item, sub, onSuccessfulSubmit,
|
||||||
navigateOnSubmit, extraValues, paidMutationOptions]
|
navigateOnSubmit, extraValues, paidMutationOptions]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user