Lexical: Add media preview

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
marcin mikołajczak
2023-07-28 23:23:04 +02:00
parent b3f9edd41e
commit 41ee08cd14
3 changed files with 52 additions and 21 deletions

View File

@@ -11,6 +11,7 @@ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext
import { useLexicalNodeSelection } from '@lexical/react/useLexicalNodeSelection';
import { mergeRegister } from '@lexical/utils';
import clsx from 'clsx';
import { List as ImmutableList } from 'immutable';
import {
$getNodeByKey,
$getSelection,
@@ -28,7 +29,10 @@ import {
import * as React from 'react';
import { Suspense, useCallback, useEffect, useRef, useState } from 'react';
import { IconButton } from 'soapbox/components/ui';
import { openModal } from 'soapbox/actions/modals';
import { HStack, IconButton } from 'soapbox/components/ui';
import { useAppDispatch } from 'soapbox/hooks';
import { normalizeAttachment } from 'soapbox/normalizers';
import { $isImageNode } from './image-node';
@@ -40,6 +44,7 @@ import type {
RangeSelection,
} from 'lexical';
const imageCache = new Set();
const useSuspenseImage = (src: string) => {
@@ -87,6 +92,8 @@ const ImageComponent = ({
nodeKey: NodeKey
src: string
}): JSX.Element => {
const dispatch = useAppDispatch();
const imageRef = useRef<null | HTMLImageElement>(null);
const buttonRef = useRef<HTMLButtonElement | null>(null);
const [isSelected, setSelected, clearSelection] =
@@ -109,6 +116,16 @@ const ImageComponent = ({
[nodeKey],
);
const previewImage = () => {
const image = normalizeAttachment({
type: 'image',
url: src,
altText,
});
dispatch(openModal('MEDIA', { media: ImmutableList.of(image), index: 0 }));
};
const onDelete = useCallback(
(payload: KeyboardEvent) => {
if (isSelected && $isNodeSelection($getSelection())) {
@@ -248,13 +265,22 @@ const ImageComponent = ({
<Suspense fallback={null}>
<>
<div className='relative' draggable={draggable}>
<IconButton
onClick={deleteNode}
src={require('@tabler/icons/x.svg')}
theme='dark'
className='absolute right-2 top-2 z-10 hover:scale-105 hover:bg-gray-900'
iconClassName='h-5 w-5'
/>
<HStack className='absolute right-2 top-2 z-10' space={2}>
<IconButton
onClick={previewImage}
src={require('@tabler/icons/zoom-in.svg')}
theme='dark'
className='!p-1.5 hover:scale-105 hover:bg-gray-900'
iconClassName='h-5 w-5'
/>
<IconButton
onClick={deleteNode}
src={require('@tabler/icons/x.svg')}
theme='dark'
className='!p-1.5 hover:scale-105 hover:bg-gray-900'
iconClassName='h-5 w-5'
/>
</HStack>
<LazyImage
className={
clsx('cursor-default', {