refine clickToContext handling for notifications/flat comments

This commit is contained in:
keyan 2022-01-20 13:03:48 -06:00
parent d102065479
commit 4c72a69b6c
5 changed files with 28 additions and 15 deletions

View File

@ -18,7 +18,7 @@ function Parent ({ item, rootText }) {
<> <>
<span> \ </span> <span> \ </span>
<Link href={`/items/${item.parentId}`} passHref> <Link href={`/items/${item.parentId}`} passHref>
<a onClick={e => e.stopPropagation()} className='text-reset'>parent</a> <a className='text-reset'>parent</a>
</Link> </Link>
</> </>
) )
@ -32,7 +32,7 @@ function Parent ({ item, rootText }) {
{Number(item.root.id) !== Number(item.parentId) && <ParentFrag />} {Number(item.root.id) !== Number(item.parentId) && <ParentFrag />}
<span> \ </span> <span> \ </span>
<Link href={`/items/${item.root.id}`} passHref> <Link href={`/items/${item.root.id}`} passHref>
<a onClick={e => e.stopPropagation()} className='text-reset'>{rootText || 'on:'} {item.root.title}</a> <a className='text-reset'>{rootText || 'on:'} {item.root.title}</a>
</Link> </Link>
</> </>
) )
@ -87,11 +87,11 @@ export default function Comment ({
<span> \ </span> <span> \ </span>
</>} </>}
<Link href={`/items/${item.id}`} passHref> <Link href={`/items/${item.id}`} passHref>
<a onClick={e => e.stopPropagation()} className='text-reset'>{item.ncomments} replies</a> <a className='text-reset'>{item.ncomments} replies</a>
</Link> </Link>
<span> \ </span> <span> \ </span>
<Link href={`/${item.user.name}`} passHref> <Link href={`/${item.user.name}`} passHref>
<a onClick={e => e.stopPropagation()}>@{item.user.name}<span className='text-boost font-weight-bold'>{op && ' OP'}</span></a> <a>@{item.user.name}<span className='text-boost font-weight-bold'>{op && ' OP'}</span></a>
</Link> </Link>
<span> </span> <span> </span>
<Link href={`/items/${item.id}`} passHref> <Link href={`/items/${item.id}`} passHref>
@ -103,7 +103,9 @@ export default function Comment ({
<span> \ </span> <span> \ </span>
<div <div
className={styles.edit} className={styles.edit}
onClick={() => setEdit(!edit)} onClick={e => {
setEdit(!edit)
}}
> >
{edit ? 'cancel' : 'edit'} {edit ? 'cancel' : 'edit'}
<Countdown <Countdown

View File

@ -3,6 +3,7 @@ import { MORE_FLAT_COMMENTS } from '../fragments/comments'
import Comment, { CommentSkeleton } from './comment' import Comment, { CommentSkeleton } from './comment'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import MoreFooter from './more-footer' import MoreFooter from './more-footer'
import { ignoreClick } from '../lib/clicks'
export default function CommentsFlat ({ variables, comments, cursor, ...props }) { export default function CommentsFlat ({ variables, comments, cursor, ...props }) {
const router = useRouter() const router = useRouter()
@ -24,7 +25,10 @@ export default function CommentsFlat ({ variables, comments, cursor, ...props })
<div <div
key={item.id} key={item.id}
className='clickToContext py-2' className='clickToContext py-2'
onClick={() => { onClick={e => {
if (ignoreClick(e)) {
return
}
router.push({ router.push({
pathname: '/items/[id]', pathname: '/items/[id]',
query: { id: item.root.id, commentId: item.id } query: { id: item.root.id, commentId: item.id }

View File

@ -5,13 +5,18 @@ import { NOTIFICATIONS } from '../fragments/notifications'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import MoreFooter from './more-footer' import MoreFooter from './more-footer'
import Invite from './invite' import Invite from './invite'
import { ignoreClick } from '../lib/clicks'
function Notification ({ n }) { function Notification ({ n }) {
const router = useRouter() const router = useRouter()
return ( return (
<div <div
className='clickToContext' className='clickToContext'
onClick={() => { onClick={e => {
if (ignoreClick(e)) {
return
}
if (n.__typename === 'Invitification') { if (n.__typename === 'Invitification') {
router.push('/invites') router.push('/invites')
} else if (!n.item.title) { } else if (!n.item.title) {

View File

@ -178,12 +178,10 @@ export default function UpVote ({ item, className }) {
return ( return (
<LightningConsumer> <LightningConsumer>
{({ strike }) => {({ strike }) =>
<div ref={ref}> <div ref={ref} className='upvoteParent'>
<LongPressable <LongPressable
onLongPress={ onLongPress={
async (e) => { async (e) => {
e.preventDefault()
e.stopPropagation()
if (!item || voteLock) return if (!item || voteLock) return
// we can't tip ourselves // we can't tip ourselves
@ -198,8 +196,6 @@ export default function UpVote ({ item, className }) {
onShortPress={ onShortPress={
me me
? async (e) => { ? async (e) => {
e.preventDefault()
e.stopPropagation()
if (!item || voteLock) return if (!item || voteLock) return
// we can't tip ourselves // we can't tip ourselves
@ -256,9 +252,6 @@ export default function UpVote ({ item, className }) {
filter: `drop-shadow(0 0 6px ${color}90)` filter: `drop-shadow(0 0 6px ${color}90)`
} }
: undefined} : undefined}
onClick={e => {
e.stopPropagation()
}}
/> />
</div> </div>
</ActionTooltip> </ActionTooltip>

9
lib/clicks.js Normal file
View File

@ -0,0 +1,9 @@
export function ignoreClick (e) {
return e.target.onclick || // the target has a click handler
// the target has an interactive parent
e.target.matches(':where(.upvoteParent, form, textarea, button, a, input) :scope') ||
// the target is an interactive element
['TEXTAREA', 'BUTTON', 'A', 'INPUT', 'FORM'].includes(e.target.tagName.toUpperCase()) ||
// the target is an interactive element
e.target.class === 'upvoteParent'
}