Fix edit timer stuck at 00:00 (#1673)
* Fix edit timer stuck at 00:00 * refactor with useCanEdit hook
This commit is contained in:
parent
8595a2b8b0
commit
01d5177006
|
@ -6,7 +6,7 @@ import Dropdown from 'react-bootstrap/Dropdown'
|
||||||
import Countdown from './countdown'
|
import Countdown from './countdown'
|
||||||
import { abbrNum, numWithUnits } from '@/lib/format'
|
import { abbrNum, numWithUnits } from '@/lib/format'
|
||||||
import { newComments, commentsViewedAt } from '@/lib/new-comments'
|
import { newComments, commentsViewedAt } from '@/lib/new-comments'
|
||||||
import { datePivot, timeSince } from '@/lib/time'
|
import { timeSince } from '@/lib/time'
|
||||||
import { DeleteDropdownItem } from './delete'
|
import { DeleteDropdownItem } from './delete'
|
||||||
import styles from './item.module.css'
|
import styles from './item.module.css'
|
||||||
import { useMe } from './me'
|
import { useMe } from './me'
|
||||||
|
@ -28,6 +28,7 @@ import { useToast } from './toast'
|
||||||
import { useShowModal } from './modal'
|
import { useShowModal } from './modal'
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
import SubPopover from './sub-popover'
|
import SubPopover from './sub-popover'
|
||||||
|
import useCanEdit from './use-can-edit'
|
||||||
|
|
||||||
export default function ItemInfo ({
|
export default function ItemInfo ({
|
||||||
item, full, commentsText = 'comments',
|
item, full, commentsText = 'comments',
|
||||||
|
@ -35,12 +36,12 @@ export default function ItemInfo ({
|
||||||
onQuoteReply, extraBadges, nested, pinnable, showActionDropdown = true, showUser = true,
|
onQuoteReply, extraBadges, nested, pinnable, showActionDropdown = true, showUser = true,
|
||||||
setDisableRetry, disableRetry
|
setDisableRetry, disableRetry
|
||||||
}) {
|
}) {
|
||||||
const editThreshold = datePivot(new Date(item.invoice?.confirmedAt ?? item.createdAt), { minutes: 10 })
|
|
||||||
const { me } = useMe()
|
const { me } = useMe()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const [hasNewComments, setHasNewComments] = useState(false)
|
const [hasNewComments, setHasNewComments] = useState(false)
|
||||||
const root = useRoot()
|
const root = useRoot()
|
||||||
const sub = item?.sub || root?.sub
|
const sub = item?.sub || root?.sub
|
||||||
|
const [canEdit, setCanEdit, editThreshold] = useCanEdit(item)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!full) {
|
if (!full) {
|
||||||
|
@ -48,19 +49,6 @@ export default function ItemInfo ({
|
||||||
}
|
}
|
||||||
}, [item])
|
}, [item])
|
||||||
|
|
||||||
// allow anon edits if they have the correct hmac for the item invoice
|
|
||||||
// (the server will verify the hmac)
|
|
||||||
const [anonEdit, setAnonEdit] = useState(false)
|
|
||||||
useEffect(() => {
|
|
||||||
const invParams = window.localStorage.getItem(`item:${item.id}:hash:hmac`)
|
|
||||||
setAnonEdit(!!invParams && !me && Number(item.user.id) === USER_ID.anon)
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
// deleted items can never be edited and every item has a 10 minute edit window
|
|
||||||
// except bios, they can always be edited but they should never show the countdown
|
|
||||||
const noEdit = !!item.deletedAt || (Date.now() >= editThreshold) || item.bio
|
|
||||||
const canEdit = !noEdit && ((me && item.mine) || anonEdit)
|
|
||||||
|
|
||||||
// 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
|
||||||
const isPost = !item.parentId
|
const isPost = !item.parentId
|
||||||
|
@ -160,7 +148,7 @@ export default function ItemInfo ({
|
||||||
<>
|
<>
|
||||||
<EditInfo
|
<EditInfo
|
||||||
item={item} edit={edit} canEdit={canEdit}
|
item={item} edit={edit} canEdit={canEdit}
|
||||||
setCanEdit={setAnonEdit} toggleEdit={toggleEdit} editText={editText} editThreshold={editThreshold}
|
setCanEdit={setCanEdit} toggleEdit={toggleEdit} editText={editText} editThreshold={editThreshold}
|
||||||
/>
|
/>
|
||||||
<PaymentInfo item={item} disableRetry={disableRetry} setDisableRetry={setDisableRetry} />
|
<PaymentInfo item={item} disableRetry={disableRetry} setDisableRetry={setDisableRetry} />
|
||||||
<ActionDropdown>
|
<ActionDropdown>
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
import { datePivot } from '@/lib/time'
|
||||||
|
import { useMe } from '@/components/me'
|
||||||
|
import { USER_ID } from '@/lib/constants'
|
||||||
|
|
||||||
|
export default function useCanEdit (item) {
|
||||||
|
const editThreshold = datePivot(new Date(item.invoice?.confirmedAt ?? item.createdAt), { minutes: 10 })
|
||||||
|
const { me } = useMe()
|
||||||
|
|
||||||
|
// deleted items can never be edited and every item has a 10 minute edit window
|
||||||
|
// except bios, they can always be edited but they should never show the countdown
|
||||||
|
const noEdit = !!item.deletedAt || (Date.now() >= editThreshold) || item.bio
|
||||||
|
const authorEdit = me && item.mine
|
||||||
|
const [canEdit, setCanEdit] = useState(!noEdit && authorEdit)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// allow anon edits if they have the correct hmac for the item invoice
|
||||||
|
// (the server will verify the hmac)
|
||||||
|
const invParams = window.localStorage.getItem(`item:${item.id}:hash:hmac`)
|
||||||
|
const anonEdit = !!invParams && !me && Number(item.user.id) === USER_ID.anon
|
||||||
|
// anonEdit should not override canEdit, but only allow edits if they aren't already allowed
|
||||||
|
setCanEdit(canEdit => canEdit || anonEdit)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return [canEdit, setCanEdit, editThreshold]
|
||||||
|
}
|
|
@ -12,6 +12,7 @@ import { useRouter } from 'next/router'
|
||||||
import PageLoading from '@/components/page-loading'
|
import PageLoading from '@/components/page-loading'
|
||||||
import { FeeButtonProvider } from '@/components/fee-button'
|
import { FeeButtonProvider } from '@/components/fee-button'
|
||||||
import SubSelect from '@/components/sub-select'
|
import SubSelect from '@/components/sub-select'
|
||||||
|
import useCanEdit from '@/components/use-can-edit'
|
||||||
|
|
||||||
export const getServerSideProps = getGetServerSideProps({
|
export const getServerSideProps = getGetServerSideProps({
|
||||||
query: ITEM,
|
query: ITEM,
|
||||||
|
@ -26,7 +27,7 @@ export default function PostEdit ({ ssrData }) {
|
||||||
const { item } = data || ssrData
|
const { item } = data || ssrData
|
||||||
const [sub, setSub] = useState(item.subName)
|
const [sub, setSub] = useState(item.subName)
|
||||||
|
|
||||||
const editThreshold = new Date(item?.invoice?.confirmedAt ?? item.createdAt).getTime() + 10 * 60000
|
const [,, editThreshold] = useCanEdit(item)
|
||||||
|
|
||||||
let FormType = DiscussionForm
|
let FormType = DiscussionForm
|
||||||
let itemType = 'DISCUSSION'
|
let itemType = 'DISCUSSION'
|
||||||
|
|
Loading…
Reference in New Issue