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 { makeOverallScoreInfo } from '../lib/overallScore'
|
||||||
import { urlWithParams } from '../lib/urls'
|
import { urlWithParams } from '../lib/urls'
|
||||||
|
|
||||||
|
import type { VerificationStatus } from '@prisma/client'
|
||||||
import type { APIContext } from 'astro'
|
import type { APIContext } from 'astro'
|
||||||
import type { Prettify } from 'ts-essentials'
|
import type { Prettify } from 'ts-essentials'
|
||||||
|
|
||||||
@@ -107,6 +108,7 @@ export const ogImageTemplates = {
|
|||||||
categories,
|
categories,
|
||||||
score,
|
score,
|
||||||
imageUrl,
|
imageUrl,
|
||||||
|
verificationStatus,
|
||||||
}: {
|
}: {
|
||||||
title: string
|
title: string
|
||||||
description: string
|
description: string
|
||||||
@@ -116,6 +118,7 @@ export const ogImageTemplates = {
|
|||||||
}[]
|
}[]
|
||||||
score: number
|
score: number
|
||||||
imageUrl: string | null
|
imageUrl: string | null
|
||||||
|
verificationStatus: VerificationStatus | null
|
||||||
},
|
},
|
||||||
context
|
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" />
|
<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>
|
</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>
|
</div>
|
||||||
),
|
),
|
||||||
defaultOptions
|
defaultOptions
|
||||||
|
|||||||
@@ -7,13 +7,21 @@ import { cn } from '../lib/cn'
|
|||||||
|
|
||||||
import type { HTMLAttributes } from 'astro/types'
|
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
|
url: string
|
||||||
referral: string | null
|
referral: string | null
|
||||||
enableMinWidth?: boolean
|
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) {
|
function makeLink(url: string, referral: string | null) {
|
||||||
const hostname = new URL(url).hostname
|
const hostname = new URL(url).hostname
|
||||||
@@ -124,28 +132,39 @@ const link = makeLink(baseUrl, referral)
|
|||||||
if (!z.string().url().safeParse(link.url).success) {
|
if (!z.string().url().safeParse(link.url).success) {
|
||||||
console.error(`Invalid service URL with referral: ${link.url}`)
|
console.error(`Invalid service URL with referral: ${link.url}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Tag = isScam ? 'span' : 'a'
|
||||||
---
|
---
|
||||||
|
|
||||||
<a
|
<Tag
|
||||||
href={link.url}
|
href={isScam ? undefined : link.url}
|
||||||
target="_blank"
|
target={isScam ? undefined : '_blank'}
|
||||||
rel="noopener noreferrer"
|
rel={isScam ? undefined : 'noopener noreferrer'}
|
||||||
class={cn(
|
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',
|
'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
|
className
|
||||||
)}
|
)}
|
||||||
|
title={link.url}
|
||||||
{...htmlProps}
|
{...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 })}>
|
<span class={cn('font-title font-bold', { 'min-w-[29ch]': enableMinWidth })}>
|
||||||
{
|
{
|
||||||
link.textBits.map((textBit) => (
|
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>
|
</span>
|
||||||
<Icon
|
{
|
||||||
name="ri:arrow-right-line"
|
!isScam && (
|
||||||
class="2xs:size-6 mr-1 size-4 rounded-full bg-orange-500 p-0.5 text-white"
|
<Icon
|
||||||
/>
|
name="ri:arrow-right-line"
|
||||||
</a>
|
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,
|
APPROVED: undefined,
|
||||||
}[service.verificationStatus]
|
}[service.verificationStatus]
|
||||||
|
|
||||||
const isScam = service.verificationStatus === 'VERIFICATION_FAILED'
|
|
||||||
|
|
||||||
const shuffledLinks = {
|
const shuffledLinks = {
|
||||||
clearnet: shuffle(service.serviceUrls),
|
clearnet: shuffle(service.serviceUrls),
|
||||||
onion: shuffle(service.onionUrls),
|
onion: shuffle(service.onionUrls),
|
||||||
@@ -416,6 +414,7 @@ const ogImageTemplateData = {
|
|||||||
categories: service.categories.map((category) => pick(category, ['name', 'icon'])),
|
categories: service.categories.map((category) => pick(category, ['name', 'icon'])),
|
||||||
score: service.overallScore,
|
score: service.overallScore,
|
||||||
imageUrl: service.imageUrl,
|
imageUrl: service.imageUrl,
|
||||||
|
verificationStatus: service.verificationStatus,
|
||||||
} satisfies OgImageAllTemplatesWithProps
|
} satisfies OgImageAllTemplatesWithProps
|
||||||
|
|
||||||
const serviceVisibilityInfo = getServiceVisibilityInfo(service.serviceVisibility)
|
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">
|
<ul aria-label="Service links" class="xs:justify-start mt-4 flex flex-wrap justify-center gap-2">
|
||||||
{shownLinks.map((url) => (
|
{shownLinks.map((url) => (
|
||||||
<li>
|
<li>
|
||||||
{isScam ? (
|
<ServiceLinkButton
|
||||||
<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">
|
url={url}
|
||||||
<Icon name="ri:alert-line" class="size-4 text-red-400" />
|
referral={service.referral}
|
||||||
{urlDomain(url)}
|
enableMinWidth={shuffledLinks.onion.length + shuffledLinks.i2p.length > 0}
|
||||||
</span>
|
isScam={service.verificationStatus === 'VERIFICATION_FAILED'}
|
||||||
) : (
|
/>
|
||||||
<ServiceLinkButton
|
|
||||||
url={url}
|
|
||||||
referral={service.referral}
|
|
||||||
enableMinWidth={shuffledLinks.onion.length + shuffledLinks.i2p.length > 0}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
@@ -828,18 +821,12 @@ const sortedVerificationSteps = orderBy(
|
|||||||
|
|
||||||
{hiddenLinks.map((url) => (
|
{hiddenLinks.map((url) => (
|
||||||
<li class="hidden peer-checked:block">
|
<li class="hidden peer-checked:block">
|
||||||
{isScam ? (
|
<ServiceLinkButton
|
||||||
<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">
|
url={url}
|
||||||
<Icon name="ri:alert-line" class="size-4 text-red-400" />
|
referral={service.referral}
|
||||||
{urlDomain(url)}
|
enableMinWidth={shuffledLinks.onion.length + shuffledLinks.i2p.length > 0}
|
||||||
</span>
|
isScam={service.verificationStatus === 'VERIFICATION_FAILED'}
|
||||||
) : (
|
/>
|
||||||
<ServiceLinkButton
|
|
||||||
url={url}
|
|
||||||
referral={service.referral}
|
|
||||||
enableMinWidth={shuffledLinks.onion.length + shuffledLinks.i2p.length > 0}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
Reference in New Issue
Block a user