mirror of https://github.com/buster-so/buster.git
Update MediaEmbedNode.tsx
This commit is contained in:
parent
ce7ecbe4bb
commit
3b4394874e
|
@ -6,12 +6,19 @@ import LiteYouTubeEmbed from 'react-lite-youtube-embed';
|
|||
import type { TMediaEmbedElement } from 'platejs';
|
||||
import type { PlateElementProps } from 'platejs/react';
|
||||
|
||||
import { parseTwitterUrl, parseVideoUrl } from '@platejs/media';
|
||||
import {
|
||||
parseTwitterUrl,
|
||||
parseVideoUrl,
|
||||
parseIframeUrl,
|
||||
parseMediaUrl,
|
||||
type EmbedUrlParser
|
||||
} from '@platejs/media';
|
||||
import { MediaEmbedPlugin, useMediaState } from '@platejs/media/react';
|
||||
import { ResizableProvider, useResizableValue } from '@platejs/resizable';
|
||||
import {
|
||||
PlateElement,
|
||||
useEditorRef,
|
||||
useElement,
|
||||
useFocused,
|
||||
useReadOnly,
|
||||
useSelected,
|
||||
|
@ -25,17 +32,27 @@ import { MediaToolbar } from './MediaToolbar';
|
|||
import { mediaResizeHandleVariants, Resizable, ResizeHandle } from './ResizeHandle';
|
||||
import { Code3 } from '../../icons';
|
||||
import { PopoverAnchor, PopoverBase, PopoverContent } from '../../popover';
|
||||
import { Title, Text } from '../../typography';
|
||||
import { Text } from '../../typography';
|
||||
import { Input } from '../../inputs';
|
||||
import { Button } from '../../buttons';
|
||||
import { Separator } from '../../separator';
|
||||
import { useBusterNotifications } from '@/context/BusterNotifications';
|
||||
import { useEffect } from 'react';
|
||||
import { useMount } from '@/hooks';
|
||||
import { useClickAway } from '@/hooks/useClickAway';
|
||||
|
||||
const parseGenericUrl: EmbedUrlParser = (url: string) => {
|
||||
return {
|
||||
url,
|
||||
provider: 'generic'
|
||||
};
|
||||
};
|
||||
|
||||
const urlParsers: EmbedUrlParser[] = [parseTwitterUrl, parseVideoUrl, parseGenericUrl];
|
||||
|
||||
export const MediaEmbedElement = withHOC(
|
||||
ResizableProvider,
|
||||
function MediaEmbedElement(props: PlateElementProps<TMediaEmbedElement>) {
|
||||
const url = props.element.url;
|
||||
const {
|
||||
align = 'center',
|
||||
embed,
|
||||
|
@ -44,13 +61,14 @@ export const MediaEmbedElement = withHOC(
|
|||
isVideo,
|
||||
isYoutube,
|
||||
readOnly,
|
||||
selected
|
||||
selected,
|
||||
...rest
|
||||
} = useMediaState({
|
||||
urlParsers: [parseTwitterUrl, parseVideoUrl]
|
||||
urlParsers
|
||||
});
|
||||
const width = useResizableValue('width');
|
||||
const provider = embed?.provider;
|
||||
const hasElement = !!embed?.url;
|
||||
const hasElement = !!url;
|
||||
|
||||
if (!hasElement) {
|
||||
return <MediaEmbedPlaceholder {...props} />;
|
||||
|
@ -115,7 +133,19 @@ export const MediaEmbedElement = withHOC(
|
|||
/>
|
||||
</div>
|
||||
)
|
||||
) : null}
|
||||
) : (
|
||||
<div className="bg-gray-light/30 h-full min-h-16 w-full overflow-hidden rounded">
|
||||
<iframe
|
||||
className={cn(
|
||||
'absolute top-0 left-0 size-full min-h-16 rounded-sm',
|
||||
focused && selected && 'ring-ring ring-2 ring-offset-2'
|
||||
)}
|
||||
title="embed"
|
||||
src={embed?.url ?? url}
|
||||
allowFullScreen
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<ResizeHandle
|
||||
className={mediaResizeHandleVariants({ direction: 'right' })}
|
||||
|
@ -141,8 +171,11 @@ export const MediaEmbedPlaceholder = (props: PlateElementProps<TMediaEmbedElemen
|
|||
const focused = useFocused();
|
||||
const editor = useEditorRef();
|
||||
const inputRef = React.useRef<HTMLInputElement>(null);
|
||||
const popoverRef = React.useRef<HTMLDivElement>(null);
|
||||
const anchorRef = React.useRef<HTMLDivElement>(null);
|
||||
const { openInfoMessage } = useBusterNotifications();
|
||||
const [forceOpen, setForceOpen] = React.useState(false);
|
||||
const element = useElement();
|
||||
|
||||
const isFocused = focused && selected && !readOnly;
|
||||
|
||||
|
@ -153,6 +186,9 @@ export const MediaEmbedPlaceholder = (props: PlateElementProps<TMediaEmbedElemen
|
|||
return;
|
||||
}
|
||||
|
||||
// Update the current node with the URL
|
||||
editor.tf.setNodes({ url }, { at: editor.api.findPath(props.element) });
|
||||
|
||||
setForceOpen(false);
|
||||
};
|
||||
|
||||
|
@ -162,11 +198,21 @@ export const MediaEmbedPlaceholder = (props: PlateElementProps<TMediaEmbedElemen
|
|||
}
|
||||
}, [isFocused]);
|
||||
|
||||
useClickAway(
|
||||
(e) => {
|
||||
setForceOpen(false);
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
},
|
||||
[popoverRef, anchorRef]
|
||||
);
|
||||
|
||||
return (
|
||||
<PlateElement className="media-embed py-2.5" {...props}>
|
||||
<PopoverBase open={forceOpen} onOpenChange={setForceOpen}>
|
||||
<PopoverBase open={forceOpen}>
|
||||
<PopoverAnchor>
|
||||
<div
|
||||
ref={anchorRef}
|
||||
className={cn(
|
||||
'bg-muted hover:bg-primary/10 flex cursor-pointer items-center rounded-sm p-3 pr-9 select-none'
|
||||
)}
|
||||
|
@ -181,13 +227,12 @@ export const MediaEmbedPlaceholder = (props: PlateElementProps<TMediaEmbedElemen
|
|||
</PopoverAnchor>
|
||||
|
||||
<PopoverContent
|
||||
ref={popoverRef}
|
||||
className="flex w-[300px] flex-col px-0 py-2"
|
||||
onOpenAutoFocus={(e) => {
|
||||
console.log('onOpenAutoFocus', e);
|
||||
e.preventDefault();
|
||||
}}
|
||||
onCloseAutoFocus={(e) => {
|
||||
console.log('onCloseAutoFocus', e);
|
||||
e.preventDefault();
|
||||
}}>
|
||||
<div className="px-3">
|
||||
|
|
Loading…
Reference in New Issue