Files
blog-astro/src/components/notion/Bookmark.astro
2025-12-08 13:08:51 +08:00

156 lines
3.7 KiB
Plaintext

---
import type * as interfaces from '../../lib/interfaces.ts'
import { isAmazonURL, isGitHubURL } from '../../lib/blog-helpers.ts'
import GithubLinkPreview from './GitHubLinkPreview.astro'
import Caption from './Caption.astro'
export interface Props {
block: interfaces.Block
urlMap: { [key: string]: string }
}
const { block } = Astro.props
const target = block.Bookmark || block.LinkPreview || block.Embed
const urlString = target?.Url
let url: URL | null = null
try {
if (urlString) {
url = new URL(urlString)
}
} catch (err) {
console.log(err)
}
---
{
url && (
<>
{block.LinkPreview && isGitHubURL(url) ? (
<GithubLinkPreview url={url} />
) : isAmazonURL(url) ? (
<div class="no-metadata">
<a href={url.toString()}>{url.toString()}</a>
</div>
) : (
<div class="bookmark">
<a href={url.toString()} target="_blank" rel="noopener noreferrer">
<div>
<Caption richTexts={block.Bookmark?.Caption ?? []} />
<div class="muted">{url.hostname}</div>
<div>
<div>
<img
src={`https://www.google.com/s2/favicons?domain=${url.hostname}`}
alt="Favicon of the bookmark site"
loading="lazy"
/>
</div>
<div>{url.origin}</div>
</div>
</div>
</a>
</div>
)}
</>
)
}
<style>
.no-metadata > a {
border-bottom: 0.05em solid;
border-color: var(--anchor-border);
opacity: 0.7;
}
.bookmark {
display: block;
overflow: hidden;
width: 100%;
max-width: 100%;
font-size: 0.9rem;
}
.bookmark > a {
width: 100%;
box-sizing: border-box;
text-decoration: none;
border: 1px solid var(--notion-border);
background: var(--notion-surface);
border-radius: 3px;
display: flex;
overflow: hidden;
user-select: none;
transition: background-color 160ms ease, border-color 160ms ease;
}
.bookmark > a:hover {
background: var(--notion-surface-strong);
border-color: color-mix(in oklab, var(--notion-border) 70%, transparent);
}
.bookmark > a > div:first-child {
flex: 4 1 180px;
padding: 12px 14px 14px;
overflow: hidden;
text-align: left;
color: var(--fg);
}
.bookmark > a > div:first-child > div:first-child {
width: 120px;
min-width: 100%;
font-size: 14px;
line-height: 20px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
min-height: 24px;
margin-bottom: 2px;
}
.bookmark > a > div:first-child > div:nth-child(2) {
font-size: 12px;
line-height: 16px;
opacity: 0.8;
height: 32px;
overflow: hidden;
}
.bookmark > a > div:first-child > div:last-child {
display: flex;
margin-top: 6px;
}
.bookmark > a > div:first-child > div:last-child > div:first-child {
width: 16px;
height: 16px;
min-width: 16px;
margin-right: 6px;
}
.bookmark > a > div:first-child > div:last-child > div:first-child > img {
max-width: 100%;
display: inline-block;
}
.bookmark > a > div:first-child > div:last-child > div:last-child {
font-size: 12px;
line-height: 16px;
color: var(--fg);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.bookmark > a > div:last-child {
flex: 1 1 180px;
position: relative;
}
@media (max-width: 640px) {
.bookmark > a > div:last-child {
display: none;
}
}
.bookmark > a > div:last-child > img {
position: absolute !important;
width: 100%;
height: 100%;
object-fit: cover;
}
.bookmark .muted {
font-size: 12px;
opacity: 0.8;
}
</style>