enhance image detection and proxy
This commit is contained in:
parent
059d8d68ac
commit
3c711b6083
|
@ -1,5 +1,5 @@
|
|||
import { createHmac } from 'node:crypto'
|
||||
import { extractUrls } from '../../lib/md'
|
||||
import { extractUrls } from '../../../lib/md'
|
||||
|
||||
const IMGPROXY_URL = process.env.NEXT_PUBLIC_IMGPROXY_URL
|
||||
const IMGPROXY_SALT = process.env.IMGPROXY_SALT
|
||||
|
@ -20,7 +20,7 @@ const createImageProxyUrl = url => {
|
|||
const b64Url = Buffer.from(url, 'utf-8').toString('base64url')
|
||||
const target = `${processingOptions}/${b64Url}`
|
||||
const signature = sign(target)
|
||||
return `${IMGPROXY_URL}/${signature}${target}`
|
||||
return `${IMGPROXY_URL}${signature}${target}`
|
||||
}
|
||||
|
||||
const isImageURL = async url => {
|
||||
|
@ -35,13 +35,13 @@ const isImageURL = async url => {
|
|||
}
|
||||
}
|
||||
|
||||
export const useImageProxy = async text => {
|
||||
export const proxyImages = async text => {
|
||||
const urls = extractUrls(text)
|
||||
for (const url of urls) {
|
||||
if (url.startsWith(IMGPROXY_URL)) continue
|
||||
if (!(await isImageURL(url))) continue
|
||||
const proxyUrl = createImageProxyUrl(url)
|
||||
text = text.replace(new RegExp(url, 'g'), proxyUrl)
|
||||
text = text.replaceAll(url, proxyUrl)
|
||||
}
|
||||
return text
|
||||
}
|
|
@ -13,7 +13,7 @@ import { parse } from 'tldts'
|
|||
import uu from 'url-unshort'
|
||||
import { amountSchema, bountySchema, commentSchema, discussionSchema, jobSchema, linkSchema, pollSchema, ssValidate } from '../../lib/validate'
|
||||
import { sendUserNotification } from '../webPush'
|
||||
import { useImageProxy } from '../imgproxy'
|
||||
import { proxyImages } from './imgproxy'
|
||||
|
||||
async function comments (me, models, id, sort) {
|
||||
let orderBy
|
||||
|
@ -1251,8 +1251,8 @@ export const updateItem = async (parent, { id, data: { sub, title, url, text, bo
|
|||
}
|
||||
}
|
||||
|
||||
url = await useImageProxy(url)
|
||||
text = await useImageProxy(text)
|
||||
url = await proxyImages(url)
|
||||
text = await proxyImages(text)
|
||||
|
||||
const [item] = await serialize(models,
|
||||
models.$queryRaw(
|
||||
|
@ -1286,8 +1286,8 @@ const createItem = async (parent, { sub, title, url, text, boost, forward, bount
|
|||
}
|
||||
}
|
||||
|
||||
url = await useImageProxy(url)
|
||||
text = await useImageProxy(text)
|
||||
url = await proxyImages(url)
|
||||
text = await proxyImages(text)
|
||||
|
||||
const [item] = await serialize(
|
||||
models,
|
||||
|
|
|
@ -9,6 +9,7 @@ import PollIcon from '../svgs/bar-chart-horizontal-fill.svg'
|
|||
import BountyIcon from '../svgs/bounty-bag.svg'
|
||||
import ActionTooltip from './action-tooltip'
|
||||
import Flag from '../svgs/flag-fill.svg'
|
||||
import ImageIcon from '../svgs/image-fill.svg'
|
||||
import { abbrNum } from '../lib/format'
|
||||
import ItemInfo from './item-info'
|
||||
|
||||
|
@ -22,6 +23,8 @@ export default function Item ({ item, rank, belowTitle, right, full, children })
|
|||
const titleRef = useRef()
|
||||
const [pendingSats, setPendingSats] = useState(0)
|
||||
|
||||
const image = item.url && item.url.startsWith(process.env.NEXT_PUBLIC_IMGPROXY_URL)
|
||||
|
||||
return (
|
||||
<>
|
||||
{rank
|
||||
|
@ -39,16 +42,17 @@ export default function Item ({ item, rank, belowTitle, right, full, children })
|
|||
<Link href={`/items/${item.id}`} passHref>
|
||||
<a ref={titleRef} className={`${styles.title} text-reset mr-2`}>
|
||||
{item.searchTitle ? <SearchTitle title={item.searchTitle} /> : item.title}
|
||||
{item.pollCost && <span> <PollIcon className='fill-grey vertical-align-baseline' height={14} width={14} /></span>}
|
||||
{item.pollCost && <span> <PollIcon className='fill-grey ml-1' height={14} width={14} /></span>}
|
||||
{item.bounty > 0 &&
|
||||
<span>
|
||||
<ActionTooltip notForm overlayText={`${abbrNum(item.bounty)} ${item.bountyPaidTo?.length ? 'sats paid' : 'sats bounty'}`}>
|
||||
<BountyIcon className={`${styles.bountyIcon} ${item.bountyPaidTo?.length ? 'fill-success vertical-align-middle' : 'fill-grey vertical-align-middle'}`} height={16} width={16} />
|
||||
<BountyIcon className={`${styles.bountyIcon} ${item.bountyPaidTo?.length ? 'fill-success' : 'fill-grey'}`} height={16} width={16} />
|
||||
</ActionTooltip>
|
||||
</span>}
|
||||
{image && <span><ImageIcon className='fill-grey ml-2' height={16} width={16} /></span>}
|
||||
</a>
|
||||
</Link>
|
||||
{item.url &&
|
||||
{item.url && !image &&
|
||||
<>
|
||||
{/* eslint-disable-next-line */}
|
||||
<a
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
font-weight: 500;
|
||||
white-space: normal;
|
||||
max-width: 100%;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
a.title:visited {
|
||||
|
|
|
@ -27,7 +27,7 @@ export function extractUrls (md) {
|
|||
|
||||
const urls = new Set()
|
||||
visit(tree, ({ type }) => {
|
||||
return type === 'link'
|
||||
return type === 'link' || type === 'image'
|
||||
}, ({ url }) => {
|
||||
urls.add(url)
|
||||
})
|
||||
|
|
|
@ -94,6 +94,10 @@
|
|||
margin-bottom: .5rem;
|
||||
}
|
||||
|
||||
.fullItemContainer img {
|
||||
border-radius: .4rem;
|
||||
}
|
||||
|
||||
.fullItemContainer:empty {
|
||||
margin: 0;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 5H4V19L13.2923 9.70649C13.6828 9.31595 14.3159 9.31591 14.7065 9.70641L20 15.0104V5ZM2 3.9934C2 3.44476 2.45531 3 2.9918 3H21.0082C21.556 3 22 3.44495 22 3.9934V20.0066C22 20.5552 21.5447 21 21.0082 21H2.9918C2.44405 21 2 20.5551 2 20.0066V3.9934ZM8 11C6.89543 11 6 10.1046 6 9C6 7.89543 6.89543 7 8 7C9.10457 7 10 7.89543 10 9C10 10.1046 9.10457 11 8 11Z"></path></svg>
|
After Width: | Height: | Size: 443 B |
Loading…
Reference in New Issue