enhance image detection and proxy

This commit is contained in:
keyan 2023-07-13 15:18:04 -05:00
parent 059d8d68ac
commit 3c711b6083
7 changed files with 24 additions and 13 deletions

View File

@ -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
}

View File

@ -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,

View File

@ -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

View File

@ -2,6 +2,8 @@
font-weight: 500;
white-space: normal;
max-width: 100%;
display: inline-flex;
align-items: center;
}
a.title:visited {

View File

@ -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)
})

View File

@ -94,6 +94,10 @@
margin-bottom: .5rem;
}
.fullItemContainer img {
border-radius: .4rem;
}
.fullItemContainer:empty {
margin: 0;
}

1
svgs/image-fill.svg Normal file
View File

@ -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