stacker.news/components/use-can-edit.js
soxa f0e3516cf0
Refactor live comments and comment injection (#2462)
* Fix duplicate comment on pessimistic creation

- comment creation checks for comment's ID existence in cache
- invoice.confirmedAt included in useCanEdit deps for anons live comments

* switch to some as sets are not worth it

* only check for duplicates if a pessimistic payment method has been used

* default to empty array

* add comment about side-effects

* record ownership of an item to avoid injecting it via live comments

* trigger check only if the incoming comment is ours, cleanup

* correct conditions, correct comments, light cleanup

* fix: add defensive condition to ownership recorder, better name

* refactor: unified comment injection logic with deduplication, useCommentsView hook; revert sessionStorage-based fix

* adjust live comments naming around the codebase

* listen for hmac presence for anon edits

* always return the injected comment createdAt to bump live comments

* refactor: improve live comments hook readability

- latest comment createdAt persistence helper
- preserveScroll returns the returning value of the callback
- compact conditional logic
- refresh code comments
- refresh naming
- group constants
- reorder imports

* flat comment injection, fetch flat comments instead of the entire subtree that would've been deduplicated anyway, cleanup

* always align new comment fragment to the comments query structure

* generic useCommentsView hook

* update comment counts if live injecting into fragments without comments field

* fix: pass parentId, if a comment has a top level parent it always has the comments field

* fix: update CommentsViewAt only if we actually injected a comment into cache

* correct injectComment result usage

* pass markViewedAt to further centralize side effects, remove live from Item server typedefs

* fix: don't update counts for ancestors that are already up to date, update commentsViewedAt per batch not per comment

* port: fix coalesce, useCommentsView hook and outline changes

* update hmac field in cache on paid invoice, hmac as useCanEdit effect dependency

* comments and light cleanup, update useCommentsView

* efficient hasComments logic for live comments, establish a gql fragment

* fix: typo on topLevel evaluation

* limit extra evaluations to live comments scenarios

* update comments

* support live comments ncomments increments for anon view tracking
2025-09-07 16:04:34 -05:00

28 lines
1.2 KiB
JavaScript

import { useEffect, useState } from 'react'
import { datePivot } from '@/lib/time'
import { useMe } from '@/components/me'
import { ITEM_EDIT_SECONDS, USER_ID } from '@/lib/constants'
export default function useCanEdit (item) {
const editThreshold = datePivot(new Date(item.invoice?.confirmedAt ?? item.createdAt), { seconds: ITEM_EDIT_SECONDS })
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)
// update when the hmac gets set
}, [item?.invoice?.hmac])
return [canEdit, setCanEdit, editThreshold]
}