Fix edit countdown on deleted items (#1571)
* Clarify conditions to show edit countdown * Fix edit countdown shown for deleted items * refactor: Minimize canEdit state I noticed that only anonEdit requires state because it needs to use useEffect to fetch from local storage. The other conditions can simply be checked during render. * refactor: Use datePivot for edit countdown
This commit is contained in:
parent
406ae81693
commit
fdd34b2eb3
@ -1375,7 +1375,7 @@ export const updateItem = async (parent, { sub: subName, forward, hash, hmac, ..
|
|||||||
|
|
||||||
// prevent update if it's not explicitly allowed, not their bio, not their job and older than 10 minutes
|
// prevent update if it's not explicitly allowed, not their bio, not their job and older than 10 minutes
|
||||||
const myBio = user.bioId === old.id
|
const myBio = user.bioId === old.id
|
||||||
const timer = Date.now() < new Date(old.invoicePaidAt ?? old.createdAt).getTime() + 10 * 60_000
|
const timer = Date.now() < datePivot(new Date(old.invoicePaidAt ?? old.createdAt), { minutes: 10 })
|
||||||
|
|
||||||
// timer permission check
|
// timer permission check
|
||||||
if (!adminEdit && !myBio && !timer && !isJob(item)) {
|
if (!adminEdit && !myBio && !timer && !isJob(item)) {
|
||||||
|
@ -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 { timeSince } from '@/lib/time'
|
import { datePivot, 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'
|
||||||
@ -34,10 +34,9 @@ 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 = new Date(item.invoice?.confirmedAt ?? item.createdAt).getTime() + 10 * 60000
|
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 [canEdit, setCanEdit] = useState(item.mine && !item.bio && (Date.now() < editThreshold))
|
|
||||||
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
|
||||||
@ -48,12 +47,18 @@ 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(() => {
|
useEffect(() => {
|
||||||
const authorEdit = item.mine && !item.bio
|
|
||||||
const invParams = window.localStorage.getItem(`item:${item.id}:hash:hmac`)
|
const invParams = window.localStorage.getItem(`item:${item.id}:hash:hmac`)
|
||||||
const hmacEdit = !!invParams && !me && Number(item.user.id) === USER_ID.anon
|
setAnonEdit(!!invParams && !me && Number(item.user.id) === USER_ID.anon)
|
||||||
setCanEdit((authorEdit || hmacEdit) && (Date.now() < editThreshold))
|
}, [])
|
||||||
}, [me, item.id, item.mine, editThreshold])
|
|
||||||
|
// 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
|
||||||
@ -152,7 +157,7 @@ export default function ItemInfo ({
|
|||||||
<>
|
<>
|
||||||
<EditInfo
|
<EditInfo
|
||||||
item={item} edit={edit} canEdit={canEdit}
|
item={item} edit={edit} canEdit={canEdit}
|
||||||
setCanEdit={setCanEdit} toggleEdit={toggleEdit} editText={editText} editThreshold={editThreshold}
|
setCanEdit={setAnonEdit} toggleEdit={toggleEdit} editText={editText} editThreshold={editThreshold}
|
||||||
/>
|
/>
|
||||||
<PaymentInfo item={item} disableRetry={disableRetry} setDisableRetry={setDisableRetry} />
|
<PaymentInfo item={item} disableRetry={disableRetry} setDisableRetry={setDisableRetry} />
|
||||||
<ActionDropdown>
|
<ActionDropdown>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user