mirror of
https://github.com/aljazceru/rabbit.git
synced 2025-12-18 06:24:25 +01:00
feat: lazy load
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { Component, JSX, Switch, Match, createEffect } from 'solid-js';
|
||||
import { Component, JSX, Switch, Match, createEffect, Show } from 'solid-js';
|
||||
|
||||
import LazyLoad from '@/components/utils/LazyLoad';
|
||||
import SafeLink from '@/components/utils/SafeLink';
|
||||
import useConfig from '@/core/useConfig';
|
||||
import { useOgp } from '@/utils/ogp';
|
||||
@@ -28,65 +29,89 @@ const youtubeUrl = (videoId: string): string => {
|
||||
return iframeUrl.href;
|
||||
};
|
||||
|
||||
const PreviewedLink: Component<PreviewdLinkProps> = (props) => {
|
||||
const TwitterEmbed: Component<{ class?: string; href: string }> = (props) => {
|
||||
let twitterRef: HTMLQuoteElement | undefined;
|
||||
|
||||
const { config } = useConfig();
|
||||
|
||||
const { ogp } = useOgp(() => ({
|
||||
url: props.href,
|
||||
}));
|
||||
|
||||
createEffect(() => {
|
||||
if (isTwitterUrl(props.href)) {
|
||||
window.twttr?.widgets?.load(twitterRef);
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<blockquote class="twitter-tweet" ref={twitterRef}>
|
||||
<a
|
||||
class={props.class}
|
||||
href={twitterUrl(props.href)}
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
>
|
||||
{twitterUrl(props.href)}
|
||||
</a>
|
||||
</blockquote>
|
||||
);
|
||||
};
|
||||
|
||||
const OgpEmbed: Component<{ url: string }> = (props) => {
|
||||
const { ogp } = useOgp(() => ({
|
||||
url: props.url,
|
||||
}));
|
||||
|
||||
return (
|
||||
<Show when={ogp()} fallback={<SafeLink href={props.url} />} keyed>
|
||||
{(ogpProps) => (
|
||||
<SafeLink href={props.url}>
|
||||
<div class="my-2 rounded-lg border transition-colors hover:bg-slate-100">
|
||||
<img
|
||||
alt={ogpProps.title}
|
||||
class="max-w-full rounded-t-lg object-contain shadow"
|
||||
src={ogpProps.image}
|
||||
/>
|
||||
<div class="mb-1 p-1">
|
||||
<div class="text-xs text-slate-500">{new URL(ogpProps.url).host}</div>
|
||||
<div class="text-sm">{ogpProps.title}</div>
|
||||
<div class="text-xs text-slate-500">{ogpProps.description}</div>
|
||||
</div>
|
||||
</div>
|
||||
</SafeLink>
|
||||
)}
|
||||
</Show>
|
||||
);
|
||||
};
|
||||
|
||||
const PreviewedLink: Component<PreviewdLinkProps> = (props) => {
|
||||
const { config } = useConfig();
|
||||
|
||||
return (
|
||||
<Switch fallback={<SafeLink class={props.class} href={props.href} />}>
|
||||
<Match when={config().embedding.twitter && isTwitterUrl(props.href)}>
|
||||
<blockquote class="twitter-tweet" ref={twitterRef}>
|
||||
<a
|
||||
class={props.class}
|
||||
href={twitterUrl(props.href)}
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
>
|
||||
{twitterUrl(props.href)}
|
||||
</a>
|
||||
</blockquote>
|
||||
<LazyLoad>{() => <TwitterEmbed class={props.class} href={props.href} />}</LazyLoad>
|
||||
</Match>
|
||||
<Match when={config().embedding.youtube && parseYouTubeVideoUrl(props.href)} keyed>
|
||||
{({ videoId }) => (
|
||||
<div class="my-2 aspect-video w-full">
|
||||
<iframe
|
||||
loading="lazy"
|
||||
title="YouTube"
|
||||
class="my-2 h-full w-full"
|
||||
src={youtubeUrl(videoId)}
|
||||
allowfullscreen
|
||||
/>
|
||||
</div>
|
||||
<LazyLoad
|
||||
fallback={
|
||||
<div class="aspect-video max-w-full">
|
||||
<SafeLink href={props.href} />
|
||||
</div>
|
||||
}
|
||||
>
|
||||
{() => (
|
||||
<div class="my-2 aspect-video w-full">
|
||||
<iframe
|
||||
loading="lazy"
|
||||
title="YouTube"
|
||||
class="my-2 h-full w-full"
|
||||
src={youtubeUrl(videoId)}
|
||||
allowfullscreen
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</LazyLoad>
|
||||
)}
|
||||
</Match>
|
||||
<Match when={config().embedding.ogp && ogp()} keyed>
|
||||
{(ogpProps) => (
|
||||
<SafeLink href={props.href}>
|
||||
<div class="my-2 rounded-lg border transition-colors hover:bg-slate-100">
|
||||
<img
|
||||
alt={ogpProps.title}
|
||||
class="max-w-full rounded-t-lg object-contain shadow"
|
||||
src={ogpProps.image}
|
||||
/>
|
||||
<div class="mb-1 p-1">
|
||||
<div class="text-xs text-slate-500">{new URL(ogpProps.url).host}</div>
|
||||
<div class="text-sm">{ogpProps.title}</div>
|
||||
<div class="text-xs text-slate-500">{ogpProps.description}</div>
|
||||
</div>
|
||||
</div>
|
||||
</SafeLink>
|
||||
)}
|
||||
<Match when={config().embedding.ogp}>
|
||||
<LazyLoad>{() => <OgpEmbed url={props.href} />}</LazyLoad>
|
||||
</Match>
|
||||
</Switch>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user