Compare commits

...

2 Commits

Author SHA1 Message Date
keyan
00ca35465c replace node-fetch usage with existing cross-fetch 2024-04-15 19:26:40 -05:00
keyan
5689378b07 turn #1063 logic into a component for use in all comment lists 2024-04-15 16:23:26 -05:00
9 changed files with 71 additions and 74 deletions

View File

@ -10,7 +10,6 @@ import EyeClose from '@/svgs/eye-close-line.svg'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import CommentEdit from './comment-edit' import CommentEdit from './comment-edit'
import { ANON_USER_ID, COMMENT_DEPTH_LIMIT, UNKNOWN_LINK_REL } from '@/lib/constants' import { ANON_USER_ID, COMMENT_DEPTH_LIMIT, UNKNOWN_LINK_REL } from '@/lib/constants'
import { ignoreClick } from '@/lib/clicks'
import PayBounty from './pay-bounty' import PayBounty from './pay-bounty'
import BountyIcon from '@/svgs/bounty-bag.svg' import BountyIcon from '@/svgs/bounty-bag.svg'
import ActionTooltip from './action-tooltip' import ActionTooltip from './action-tooltip'
@ -25,6 +24,7 @@ import { DownZap } from './dont-link-this'
import Skull from '@/svgs/death-skull.svg' import Skull from '@/svgs/death-skull.svg'
import { commentSubTreeRootId } from '@/lib/item' import { commentSubTreeRootId } from '@/lib/item'
import Pin from '@/svgs/pushpin-fill.svg' import Pin from '@/svgs/pushpin-fill.svg'
import LinkToContext from './link-to-context'
function Parent ({ item, rootText }) { function Parent ({ item, rootText }) {
const root = useRoot() const root = useRoot()
@ -76,17 +76,17 @@ export function CommentFlat ({ item, rank, siblingComments, ...props }) {
{rank} {rank}
</div>) </div>)
: <div />} : <div />}
<div <LinkToContext
className={`clickToContext ${siblingComments ? 'py-3' : 'py-2'}`} className={siblingComments ? 'py-3' : 'py-2'}
onClick={e => { onClick={e => {
if (ignoreClick(e)) return
router.push(href, as) router.push(href, as)
}} }}
href={href}
> >
<RootProvider root={item.root}> <RootProvider root={item.root}>
<Comment item={item} {...props} /> <Comment item={item} {...props} />
</RootProvider> </RootProvider>
</div> </LinkToContext>
</> </>
) )
} }

View File

@ -66,7 +66,7 @@ export default function Items ({ ssrData, variables = {}, query, destructureData
export function ListItem ({ item, ...props }) { export function ListItem ({ item, ...props }) {
return ( return (
item.parentId item.parentId
? <CommentFlat item={item} noReply includeParent clickToContext {...props} /> ? <CommentFlat item={item} noReply includeParent {...props} />
: (item.isJob : (item.isJob
? <ItemJob item={item} /> ? <ItemJob item={item} />
: (item.searchText : (item.searchText

View File

@ -0,0 +1,17 @@
import classNames from 'classnames'
import styles from './link-to-context.module.css'
import Link from 'next/link'
export default function LinkToContext ({ children, onClick, href, className, ...props }) {
return (
<div className={classNames(className, styles.linkBoxParent, 'clickToContext')}>
<Link
className={styles.linkBox}
onClick={onClick}
href={href}
{...props}
/>
{children}
</div>
)
}

View File

@ -0,0 +1,30 @@
.linkBox {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.linkBox ~ * {
position: relative;
}
.linkBoxParent {
position: relative;
}
.linkBoxParent > * {
pointer-events: none;
}
.linkBoxParent :global(.upvoteParent),
.linkBoxParent :global(.pointer),
.linkBoxParent a,
.linkBoxParent form,
.linkBoxParent textarea,
.linkBoxParent button,
.linkBoxParent input,
.linkBoxParent iframe {
pointer-events: auto !important;
}

View File

@ -28,6 +28,7 @@ import BountyIcon from '@/svgs/bounty-bag.svg'
import { LongCountdown } from './countdown' import { LongCountdown } from './countdown'
import { nextBillingWithGrace } from '@/lib/territory' import { nextBillingWithGrace } from '@/lib/territory'
import { commentSubTreeRootId } from '@/lib/item' import { commentSubTreeRootId } from '@/lib/item'
import LinkToContext from './link-to-context'
function Notification ({ n, fresh }) { function Notification ({ n, fresh }) {
const type = n.__typename const type = n.__typename
@ -60,26 +61,23 @@ function NotificationLayout ({ children, nid, href, as, fresh }) {
const router = useRouter() const router = useRouter()
if (!href) return <div className={fresh ? styles.fresh : ''}>{children}</div> if (!href) return <div className={fresh ? styles.fresh : ''}>{children}</div>
return ( return (
<div <LinkToContext
className={`position-relative clickToContext ${styles.notificationLayout} ${fresh ? styles.fresh : ''} ${router?.query?.nid === nid ? 'outline-it' : ''}`} className={`${fresh ? styles.fresh : ''} ${router?.query?.nid === nid ? 'outline-it' : ''}`}
onClick={async (e) => {
e.preventDefault()
nid && await router.replace({
pathname: router.pathname,
query: {
...router.query,
nid
}
}, router.asPath, { ...router.options, shallow: true })
router.push(href, as)
}}
href={href}
> >
<Link
className={styles.linkBox}
onClick={async (e) => {
e.preventDefault()
nid && await router.replace({
pathname: router.pathname,
query: {
...router.query,
nid
}
}, router.asPath, { ...router.options, shallow: true })
router.push(href, as)
}}
href={typeof href === 'string' ? href : href.query.commentId ? as + '?commentId=' + href.query.commentId : as}
/>
{children} {children}
</div> </LinkToContext>
) )
} }

View File

@ -26,31 +26,4 @@
.subFormGroup > div { .subFormGroup > div {
margin-right: 0 !important; margin-right: 0 !important;
}
.linkBox {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.linkBox ~ * {
position: relative;
}
.notificationLayout > * {
pointer-events: none;
}
.notificationLayout :global(.upvoteParent),
.notificationLayout :global(.pointer),
.notificationLayout a,
.notificationLayout form,
.notificationLayout textarea,
.notificationLayout button,
.notificationLayout input,
.notificationLayout iframe {
pointer-events: auto !important;
} }

View File

@ -1,4 +1,4 @@
import fetch from 'node-fetch' import fetch from 'cross-fetch'
import https from 'https' import https from 'https'
import crypto from 'crypto' import crypto from 'crypto'

20
package-lock.json generated
View File

@ -51,7 +51,6 @@
"next-auth": "^4.23.2", "next-auth": "^4.23.2",
"next-plausible": "^3.11.1", "next-plausible": "^3.11.1",
"next-seo": "^6.1.0", "next-seo": "^6.1.0",
"node-fetch": "^2.6.7",
"node-s3-url-encode": "^0.0.4", "node-s3-url-encode": "^0.0.4",
"nodemailer": "^6.9.6", "nodemailer": "^6.9.6",
"nostr": "^0.2.8", "nostr": "^0.2.8",
@ -14737,25 +14736,6 @@
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz",
"integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA=="
}, },
"node_modules/node-fetch": {
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
},
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
}
},
"node_modules/node-gyp-build": { "node_modules/node-gyp-build": {
"version": "4.6.0", "version": "4.6.0",
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz",

View File

@ -56,7 +56,6 @@
"next-auth": "^4.23.2", "next-auth": "^4.23.2",
"next-plausible": "^3.11.1", "next-plausible": "^3.11.1",
"next-seo": "^6.1.0", "next-seo": "^6.1.0",
"node-fetch": "^2.6.7",
"node-s3-url-encode": "^0.0.4", "node-s3-url-encode": "^0.0.4",
"nodemailer": "^6.9.6", "nodemailer": "^6.9.6",
"nostr": "^0.2.8", "nostr": "^0.2.8",
@ -121,4 +120,4 @@
"jest": "^29.7.0", "jest": "^29.7.0",
"standard": "^17.1.0" "standard": "^17.1.0"
} }
} }