don't hate me, old git is fuck up

This commit is contained in:
Ren Amamiya
2023-02-21 14:58:47 +07:00
commit 672298daf9
103 changed files with 12172 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
import Image from 'next/image';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export default function ImagePreview({ data }: { data: object }) {
return (
<div
className={`relative mt-2 flex flex-col overflow-hidden rounded-xl border border-zinc-800`}>
<div className="relative h-full w-full">
<Image
src={data['image']}
alt="image preview"
width="0"
height="0"
sizes="100vw"
className="h-auto w-full object-cover"
/>
</div>
</div>
);
}

View File

@@ -0,0 +1,70 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { MarkdownPreviewProps } from '@uiw/react-markdown-preview';
import dynamic from 'next/dynamic';
import { useCallback, useEffect, useMemo, useRef } from 'react';
const MarkdownPreview = dynamic<MarkdownPreviewProps>(() => import('@uiw/react-markdown-preview'), {
ssr: false,
});
export default function Content({ data }: { data: string }) {
const imagesRef = useRef([]);
const videosRef = useRef([]);
const urls = useMemo(
() =>
data.match(
/((http|ftp|https):\/\/)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)?/gi
),
[data]
);
const extractURL = useCallback((urls: any[]) => {
if (urls !== null && urls.length > 0) {
urls.forEach((url: string | URL) => {
const parseURL = new URL(url);
const path = parseURL.pathname.toLowerCase();
switch (path) {
case path.match(/\.(jpg|jpeg|gif|png|webp)$/)?.input:
imagesRef.current.push(parseURL.href);
break;
case path.match(
/(http:|https:)?\/\/(www\.)?(youtube.com|youtu.be)\/(watch)?(\?v=)?(\S+)?/
)?.input:
videosRef.current.push(parseURL.href);
break;
case path.match(/\.(mp4|webm|m4v|mov|avi|mkv|flv)$/)?.input:
videosRef.current.push(parseURL.href);
break;
default:
break;
}
});
}
}, []);
useEffect(() => {
extractURL(urls);
}, [extractURL, urls]);
return (
<div className="flex flex-col">
<MarkdownPreview
source={data}
className={
'prose prose-zinc max-w-none break-words dark:prose-invert prose-headings:mt-3 prose-headings:mb-2 prose-p:m-0 prose-p:leading-normal prose-ul:mt-2 prose-li:my-1'
}
linkTarget="_blank"
disallowedElements={[
'Table',
'Heading ID',
'Highlight',
'Fenced Code Block',
'Footnote',
'Definition List',
'Task List',
]}
/>
</div>
);
}

View File

@@ -0,0 +1,20 @@
import Image from 'next/image';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export default function ImageCard({ data }: { data: object }) {
return (
<div
className={`relative mt-2 flex flex-col overflow-hidden rounded-xl border border-zinc-800`}>
<div className="relative h-full w-full">
<Image
src={data['image']}
alt="image preview"
width="0"
height="0"
sizes="100vw"
className="h-auto w-full object-cover"
/>
</div>
</div>
);
}

View File

@@ -0,0 +1,23 @@
import Image from 'next/image';
import Link from 'next/link';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export default function LinkCard({ data }: { data: object }) {
return (
<Link
href={data['url']}
target={'_blank'}
className="relative mt-2 flex flex-col overflow-hidden rounded-xl border border-zinc-700">
<div className="relative aspect-video h-auto w-full">
<Image src={data['image']} alt="image preview" fill={true} className="object-cover" />
</div>
<div className="flex flex-col gap-2 p-4">
<div>
<h5 className="font-semibold leading-tight">{data['title']}</h5>
<p className="text-sm text-zinc-300">{data['description']}</p>
</div>
<span className="text-sm text-zinc-500">{data['url']}</span>
</div>
</Link>
);
}

View File

@@ -0,0 +1,17 @@
import ReactPlayer from 'react-player/lazy';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export default function Video({ data }: { data: object }) {
return (
<div className="relative mt-2 flex flex-col overflow-hidden rounded-xl border border-zinc-800">
<ReactPlayer
url={data['url']}
controls={true}
volume={0}
className="aspect-video w-full"
width="100%"
height="100%"
/>
</div>
);
}