lazy load (#237)

This commit is contained in:
Philip Okugbe
2024-09-02 15:51:28 +01:00
committed by GitHub
parent 7fdd355cc3
commit 2b9765fb35
3 changed files with 65 additions and 39 deletions

View File

@ -1,13 +1,14 @@
import React, { ReactNode } from "react";
import data from "@emoji-mart/data";
import Picker from "@emoji-mart/react";
import React, { ReactNode } from 'react';
import {
ActionIcon,
Popover,
Button,
useMantineColorScheme,
} from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
} from '@mantine/core';
import { useDisclosure } from '@mantine/hooks';
import { Suspense } from 'react';
const Picker = React.lazy(() => import('@emoji-mart/react'));
export interface EmojiPickerInterface {
onEmojiSelect: (emoji: any) => void;
@ -48,23 +49,25 @@ function EmojiPicker({
{icon}
</ActionIcon>
</Popover.Target>
<Popover.Dropdown bg="000" style={{ border: "none" }}>
<Picker
data={data}
onEmojiSelect={handleEmojiSelect}
perLine={8}
skinTonePosition="search"
theme={colorScheme}
/>
<Popover.Dropdown bg="000" style={{ border: 'none' }}>
<Suspense fallback={null}>
<Picker
data={async () => (await import('@emoji-mart/data')).default}
onEmojiSelect={handleEmojiSelect}
perLine={8}
skinTonePosition="search"
theme={colorScheme}
/>
</Suspense>
<Button
variant="default"
c="gray"
size="xs"
style={{
position: "absolute",
position: 'absolute',
zIndex: 2,
bottom: "1rem",
right: "1rem",
bottom: '1rem',
right: '1rem',
}}
onClick={handleRemoveEmoji}
>

View File

@ -1,15 +1,21 @@
import { NodeViewContent, NodeViewProps, NodeViewWrapper } from "@tiptap/react";
import { ActionIcon, CopyButton, Group, Select, Tooltip } from "@mantine/core";
import { useEffect, useState } from "react";
import { IconCheck, IconCopy } from "@tabler/icons-react";
import MermaidView from "@/features/editor/components/code-block/mermaid-view.tsx";
import classes from "./code-block.module.css";
import { NodeViewContent, NodeViewProps, NodeViewWrapper } from '@tiptap/react';
import { ActionIcon, CopyButton, Group, Select, Tooltip } from '@mantine/core';
import { useEffect, useState } from 'react';
import { IconCheck, IconCopy } from '@tabler/icons-react';
//import MermaidView from "@/features/editor/components/code-block/mermaid-view.tsx";
import classes from './code-block.module.css';
import React from 'react';
import { Suspense } from 'react';
const MermaidView = React.lazy(
() => import('@/features/editor/components/code-block/mermaid-view.tsx')
);
export default function CodeBlockView(props: NodeViewProps) {
const { node, updateAttributes, extension, editor, getPos } = props;
const { language } = node.attrs;
const [languageValue, setLanguageValue] = useState<string | null>(
language || null,
language || null
);
const [isSelected, setIsSelected] = useState(false);
@ -24,9 +30,9 @@ export default function CodeBlockView(props: NodeViewProps) {
setIsSelected(isNodeSelected);
};
editor.on("selectionUpdate", updateSelection);
editor.on('selectionUpdate', updateSelection);
return () => {
editor.off("selectionUpdate", updateSelection);
editor.off('selectionUpdate', updateSelection);
};
}, [editor, getPos(), node.nodeSize]);
@ -47,7 +53,7 @@ export default function CodeBlockView(props: NodeViewProps) {
value={languageValue}
onChange={changeLanguage}
searchable
style={{ maxWidth: "130px" }}
style={{ maxWidth: '130px' }}
classNames={{ input: classes.selectInput }}
disabled={!editor.isEditable}
/>
@ -55,12 +61,12 @@ export default function CodeBlockView(props: NodeViewProps) {
<CopyButton value={node?.textContent} timeout={2000}>
{({ copied, copy }) => (
<Tooltip
label={copied ? "Copied" : "Copy"}
label={copied ? 'Copied' : 'Copy'}
withArrow
position="right"
>
<ActionIcon
color={copied ? "teal" : "gray"}
color={copied ? 'teal' : 'gray'}
variant="subtle"
onClick={copy}
>
@ -74,15 +80,19 @@ export default function CodeBlockView(props: NodeViewProps) {
<pre
spellCheck="false"
hidden={
((language === "mermaid" && !editor.isEditable) ||
(language === "mermaid" && !isSelected)) &&
((language === 'mermaid' && !editor.isEditable) ||
(language === 'mermaid' && !isSelected)) &&
node.textContent.length > 0
}
>
<NodeViewContent as="code" className={`language-${language}`} />
</pre>
{language === "mermaid" && <MermaidView props={props} />}
{language === 'mermaid' && (
<Suspense fallback={null}>
<MermaidView props={props} />
</Suspense>
)}
</NodeViewWrapper>
);
}

View File

@ -9,7 +9,6 @@ import {
useComputedColorScheme,
} from '@mantine/core';
import { useState } from 'react';
import { Excalidraw, exportToSvg, loadFromBlob } from '@excalidraw/excalidraw';
import { uploadFile } from '@/features/page/services/page-service.ts';
import { svgStringToFile } from '@/lib';
import { useDisclosure } from '@mantine/hooks';
@ -19,6 +18,14 @@ import { IAttachment } from '@/lib/types';
import ReactClearModal from 'react-clear-modal';
import clsx from 'clsx';
import { IconEdit } from '@tabler/icons-react';
import { lazy } from 'react';
import { Suspense } from 'react';
const Excalidraw = lazy(() =>
import('@excalidraw/excalidraw').then((module) => ({
default: module.Excalidraw,
}))
);
export default function ExcalidrawView(props: NodeViewProps) {
const { node, updateAttributes, editor, selected } = props;
@ -43,6 +50,8 @@ export default function ExcalidrawView(props: NodeViewProps) {
cache: 'no-store',
});
const { loadFromBlob } = await import('@excalidraw/excalidraw');
const data = await loadFromBlob(await request.blob(), null, null);
setExcalidrawData(data);
}
@ -58,6 +67,8 @@ export default function ExcalidrawView(props: NodeViewProps) {
return;
}
const { exportToSvg } = await import('@excalidraw/excalidraw');
const svg = await exportToSvg({
elements: excalidrawAPI?.getSceneElements(),
appState: {
@ -129,13 +140,15 @@ export default function ExcalidrawView(props: NodeViewProps) {
</Button>
</Group>
<div style={{ height: '90vh' }}>
<Excalidraw
excalidrawAPI={(api) => setExcalidrawAPI(api)}
initialData={{
...excalidrawData,
scrollToContent: true,
}}
/>
<Suspense fallback={null}>
<Excalidraw
excalidrawAPI={(api) => setExcalidrawAPI(api)}
initialData={{
...excalidrawData,
scrollToContent: true,
}}
/>
</Suspense>
</div>
</ReactClearModal>