feat: video popup

This commit is contained in:
DIYgod 2024-07-04 01:20:25 +08:00
parent 2d0537b57e
commit 3bdb494f5e
No known key found for this signature in database
2 changed files with 28 additions and 9 deletions

View File

@ -1,18 +1,18 @@
export const urlToIframe = (url?: string | null) => {
export const urlToIframe = (url?: string | null, mini?: boolean) => {
if (url?.match(/\/\/www.bilibili.com\/video\/BV\w+/)) {
return `https://www.bilibili.com/blackboard/newplayer.html?${new URLSearchParams({
isOutside: "true",
autoplay: "true",
danmaku: "true",
muted: "true",
muted: mini ? "true" : "false",
highQuality: "true",
bvid: url.match(/\/\/www.bilibili.com\/video\/(BV\w+)/)?.[1] || "",
}).toString()}`
} else if (url?.match(/\/\/www.youtube.com\/watch\?v=[-\w]+/)) {
return `https://www.youtube-nocookie.com/embed/${url.match(/\/\/www.youtube.com\/watch\?v=([-\w]+)/)?.[1]}?${new URLSearchParams({
controls: "0",
controls: mini ? "0" : "1",
autoplay: "1",
mute: "1",
mute: mini ? "1" : "0",
}).toString()}`
} else {
return null

View File

@ -1,4 +1,6 @@
import { Image } from "@renderer/components/ui/image"
import { useModalStack } from "@renderer/components/ui/modal"
import { NoopChildren } from "@renderer/components/ui/modal/stacked/utils"
import { useRouteParamsSelector } from "@renderer/hooks/biz/useRouteParams"
import { urlToIframe } from "@renderer/lib/url-to-iframe"
import { cn } from "@renderer/lib/utils"
@ -15,7 +17,8 @@ export function VideoItem({ entryId, entryPreview, translation }: UniversalItemP
const isActive = useRouteParamsSelector(({ entryId }) => entryId === entry?.entries.id)
const iframeSrc = useMemo(() => urlToIframe(entry?.entries.url), [entry?.entries.url])
const [miniIframeSrc, iframeSrc] = useMemo(() => [urlToIframe(entry?.entries.url, true), urlToIframe(entry?.entries.url)], [entry?.entries.url])
const modalStack = useModalStack()
const ref = useRef<HTMLDivElement>(null)
const [hovered, setHovered] = useState(false)
@ -31,13 +34,29 @@ export function VideoItem({ entryId, entryPreview, translation }: UniversalItemP
if (!entry) return <ReactVirtuosoItemPlaceholder />
return (
<GridItem entryId={entryId} entryPreview={entryPreview} translation={translation}>
<div className="w-full">
<div className="overflow-x-auto" ref={ref}>
{iframeSrc && hovered ? (
<div
className="w-full"
onClick={() => iframeSrc && modalStack.present({
title: "",
content: ({ dismiss }) => (
// eslint-disable-next-line @eslint-react/dom/no-missing-iframe-sandbox
<iframe
src={iframeSrc}
className={cn("aspect-video w-full shrink-0 rounded-md bg-black object-cover", isActive && "rounded-b-none")}
className="size-full p-12"
onClick={() => dismiss()}
/>
),
clickOutsideToDismiss: true,
CustomModalComponent: NoopChildren,
overlay: true,
})}
>
<div className="overflow-x-auto" ref={ref}>
{miniIframeSrc && hovered ? (
// eslint-disable-next-line @eslint-react/dom/no-missing-iframe-sandbox
<iframe
src={miniIframeSrc}
className={cn("pointer-events-none aspect-video w-full shrink-0 rounded-md bg-black object-cover", isActive && "rounded-b-none")}
/>
) : (
<Image