feat: video popup
This commit is contained in:
parent
2d0537b57e
commit
3bdb494f5e
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue