Compare commits
1 Commits
release-10
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9285d952a5 |
@@ -9,6 +9,7 @@ import defaultOGImage from '../assets/ogimage.png'
|
||||
import { makeOverallScoreInfo } from '../lib/overallScore'
|
||||
import { urlWithParams } from '../lib/urls'
|
||||
|
||||
import type { VerificationStatus } from '@prisma/client'
|
||||
import type { APIContext } from 'astro'
|
||||
import type { Prettify } from 'ts-essentials'
|
||||
|
||||
@@ -107,6 +108,7 @@ export const ogImageTemplates = {
|
||||
categories,
|
||||
score,
|
||||
imageUrl,
|
||||
verificationStatus,
|
||||
}: {
|
||||
title: string
|
||||
description: string
|
||||
@@ -116,6 +118,7 @@ export const ogImageTemplates = {
|
||||
}[]
|
||||
score: number
|
||||
imageUrl: string | null
|
||||
verificationStatus: VerificationStatus | null
|
||||
},
|
||||
context
|
||||
) => {
|
||||
@@ -272,6 +275,37 @@ export const ogImageTemplates = {
|
||||
>
|
||||
<path d="M1 0a1 1 0 0 0-1 1v26a1 1 0 0 0 1 1h74a1 1 0 0 0 1-1V1a1 1 0 0 0-1-1Zm4 4h2a1 1 0 0 1 1 1v6a1 1 0 0 0 1 1h6a1 1 0 0 1 1 1v3h3a1 1 0 0 1 1 1v3h3a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1h-2a1 1 0 0 1-1-1v-3h-3a1 1 0 0 1-1-1v-3H9a1 1 0 0 0-1 1v6a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1Zm12 0h3a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1h-3a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1zm12.82 0h2.37a1 1 0 0 1 .85.46L38 12.27l4.97-7.8A1 1 0 0 1 43.8 4h2.37a1 1 0 0 1 .85 1.54l-6.87 10.8a1 1 0 0 0-.16.53V23a1 1 0 0 1-1 1h-2a1 1 0 0 1-1-1v-6.13a1 1 0 0 0-.15-.53l-6.87-10.8A1 1 0 0 1 29.82 4ZM57 4h14a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1H56v12h15a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1H57a1 1 0 0 1-1-1v-3h-3a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1h3V5a1 1 0 0 1 1-1zm24 0a1 1 0 0 0-1 1v18a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1V7.6l9.18 15.9c.18.3.5.5.86.5H99a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1h-2a1 1 0 0 0-1 1v15.4L86.83 4.5a1 1 0 0 0-.87-.5Zm29 0a1 1 0 0 0-1 1v3h12V5a1 1 0 0 0-1-1zm11 4v12h3a1 1 0 0 0 1-1V9a1 1 0 0 0-1-1zm0 12h-12v3a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1zm-12 0V8h-3a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1zm21-16a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1V8h4v15a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1V8h4v3a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1zm27 0a1 1 0 0 0-1 1v18a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1V11.4l5.53 12.02a1 1 0 0 0 .91.58h3.12a1 1 0 0 0 .91-.58L176 11.4V23a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1h-3.36a1 1 0 0 0-.9.58L168 19.21l-6.73-14.63a1 1 0 0 0-.9-.58Zm32 0a1 1 0 0 0-1 1v3h15a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1zm-1 4h-3a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h18a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1h-14a1 1 0 0 1-1-1v-3h7a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1h-7zm-38 12a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1z" />
|
||||
</svg>
|
||||
{verificationStatus === 'VERIFICATION_FAILED' && (
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
transform: 'rotate(-20deg)',
|
||||
fontSize: 200,
|
||||
fontWeight: 'bold',
|
||||
color: 'red',
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
||||
boxShadow: '0 0 15px 30px rgba(0, 0, 0, 0.5)',
|
||||
border: '15px solid red',
|
||||
borderRadius: 15,
|
||||
padding: '10px 50px',
|
||||
textAlign: 'center',
|
||||
}}
|
||||
>
|
||||
SCAM
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
),
|
||||
defaultOptions
|
||||
|
||||
@@ -7,13 +7,21 @@ import { cn } from '../lib/cn'
|
||||
|
||||
import type { HTMLAttributes } from 'astro/types'
|
||||
|
||||
type Props = Omit<HTMLAttributes<'a'>, 'href' | 'rel' | 'target'> & {
|
||||
type Props = Omit<HTMLAttributes<'a' | 'span'>, 'href' | 'rel' | 'target'> & {
|
||||
url: string
|
||||
referral: string | null
|
||||
enableMinWidth?: boolean
|
||||
isScam?: boolean
|
||||
}
|
||||
|
||||
const { url: baseUrl, referral, class: className, enableMinWidth = false, ...htmlProps } = Astro.props
|
||||
const {
|
||||
url: baseUrl,
|
||||
referral,
|
||||
class: className,
|
||||
enableMinWidth = false,
|
||||
isScam = false,
|
||||
...htmlProps
|
||||
} = Astro.props
|
||||
|
||||
function makeLink(url: string, referral: string | null) {
|
||||
const hostname = new URL(url).hostname
|
||||
@@ -124,28 +132,39 @@ const link = makeLink(baseUrl, referral)
|
||||
if (!z.string().url().safeParse(link.url).success) {
|
||||
console.error(`Invalid service URL with referral: ${link.url}`)
|
||||
}
|
||||
|
||||
const Tag = isScam ? 'span' : 'a'
|
||||
---
|
||||
|
||||
<a
|
||||
href={link.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
<Tag
|
||||
href={isScam ? undefined : link.url}
|
||||
target={isScam ? undefined : '_blank'}
|
||||
rel={isScam ? undefined : 'noopener noreferrer'}
|
||||
class={cn(
|
||||
'2xs:text-sm 2xs:h-8 2xs:gap-2 focus-visible:ring-offset-night-700 inline-flex h-6 items-center gap-1 rounded-full bg-white text-xs whitespace-nowrap text-black focus-visible:ring-4 focus-visible:ring-orange-500 focus-visible:ring-offset-2 focus-visible:outline-none',
|
||||
isScam && 'bg-day-800 cursor-not-allowed text-red-300',
|
||||
className
|
||||
)}
|
||||
title={link.url}
|
||||
{...htmlProps}
|
||||
>
|
||||
<Icon name={link.icon} class="2xs:ml-2 2xs:size-5 2xs:-mr-0.5 -mr-0.25 ml-1 size-4" />
|
||||
<Icon
|
||||
name={isScam ? 'ri:alert-line' : link.icon}
|
||||
class={cn('2xs:ml-2 2xs:size-5 2xs:-mr-0.5 -mr-0.25 ml-1 size-4', isScam && 'text-red-400')}
|
||||
/>
|
||||
<span class={cn('font-title font-bold', { 'min-w-[29ch]': enableMinWidth })}>
|
||||
{
|
||||
link.textBits.map((textBit) => (
|
||||
<span class={cn(textBit.style === 'irrelevant' && 'text-zinc-500')}>{textBit.text}</span>
|
||||
<span class={cn(textBit.style === 'irrelevant' && 'opacity-60')}>{textBit.text}</span>
|
||||
))
|
||||
}
|
||||
</span>
|
||||
<Icon
|
||||
name="ri:arrow-right-line"
|
||||
class="2xs:size-6 mr-1 size-4 rounded-full bg-orange-500 p-0.5 text-white"
|
||||
/>
|
||||
</a>
|
||||
{
|
||||
!isScam && (
|
||||
<Icon
|
||||
name="ri:arrow-right-line"
|
||||
class="2xs:size-6 mr-1 size-4 rounded-full bg-orange-500 p-0.5 text-white"
|
||||
/>
|
||||
)
|
||||
}
|
||||
</Tag>
|
||||
|
||||
@@ -298,8 +298,6 @@ const statusIcon = {
|
||||
APPROVED: undefined,
|
||||
}[service.verificationStatus]
|
||||
|
||||
const isScam = service.verificationStatus === 'VERIFICATION_FAILED'
|
||||
|
||||
const shuffledLinks = {
|
||||
clearnet: shuffle(service.serviceUrls),
|
||||
onion: shuffle(service.onionUrls),
|
||||
@@ -416,6 +414,7 @@ const ogImageTemplateData = {
|
||||
categories: service.categories.map((category) => pick(category, ['name', 'icon'])),
|
||||
score: service.overallScore,
|
||||
imageUrl: service.imageUrl,
|
||||
verificationStatus: service.verificationStatus,
|
||||
} satisfies OgImageAllTemplatesWithProps
|
||||
|
||||
const serviceVisibilityInfo = getServiceVisibilityInfo(service.serviceVisibility)
|
||||
@@ -793,18 +792,12 @@ const sortedVerificationSteps = orderBy(
|
||||
<ul aria-label="Service links" class="xs:justify-start mt-4 flex flex-wrap justify-center gap-2">
|
||||
{shownLinks.map((url) => (
|
||||
<li>
|
||||
{isScam ? (
|
||||
<span class="2xs:text-sm 2xs:h-8 2xs:gap-2 2xs:px-4 bg-day-800 inline-flex h-6 items-center gap-1 rounded-full px-2 text-xs whitespace-nowrap text-red-400">
|
||||
<Icon name="ri:alert-line" class="size-4 text-red-400" />
|
||||
{urlDomain(url)}
|
||||
</span>
|
||||
) : (
|
||||
<ServiceLinkButton
|
||||
url={url}
|
||||
referral={service.referral}
|
||||
enableMinWidth={shuffledLinks.onion.length + shuffledLinks.i2p.length > 0}
|
||||
/>
|
||||
)}
|
||||
<ServiceLinkButton
|
||||
url={url}
|
||||
referral={service.referral}
|
||||
enableMinWidth={shuffledLinks.onion.length + shuffledLinks.i2p.length > 0}
|
||||
isScam={service.verificationStatus === 'VERIFICATION_FAILED'}
|
||||
/>
|
||||
</li>
|
||||
))}
|
||||
|
||||
@@ -828,18 +821,12 @@ const sortedVerificationSteps = orderBy(
|
||||
|
||||
{hiddenLinks.map((url) => (
|
||||
<li class="hidden peer-checked:block">
|
||||
{isScam ? (
|
||||
<span class="2xs:text-sm 2xs:h-8 2xs:gap-2 2xs:px-4 bg-day-800 inline-flex h-6 items-center gap-1 rounded-full px-2 text-xs whitespace-nowrap text-red-400">
|
||||
<Icon name="ri:alert-line" class="size-4 text-red-400" />
|
||||
{urlDomain(url)}
|
||||
</span>
|
||||
) : (
|
||||
<ServiceLinkButton
|
||||
url={url}
|
||||
referral={service.referral}
|
||||
enableMinWidth={shuffledLinks.onion.length + shuffledLinks.i2p.length > 0}
|
||||
/>
|
||||
)}
|
||||
<ServiceLinkButton
|
||||
url={url}
|
||||
referral={service.referral}
|
||||
enableMinWidth={shuffledLinks.onion.length + shuffledLinks.i2p.length > 0}
|
||||
isScam={service.verificationStatus === 'VERIFICATION_FAILED'}
|
||||
/>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
Reference in New Issue
Block a user