@blocklet/editor 2.3.79 → 2.3.81
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/main/editor.js +2 -3
- package/lib/main/plugins/ComponentPickerPlugin/index.js +1 -2
- package/package.json +2 -3
- package/lib/ext/AiImage/generate/context.d.ts +0 -23
- package/lib/ext/AiImage/generate/context.js +0 -16
- package/lib/ext/AiImage/generate/index.d.ts +0 -10
- package/lib/ext/AiImage/generate/index.js +0 -45
- package/lib/ext/AiImage/generate/output/index.d.ts +0 -7
- package/lib/ext/AiImage/generate/output/index.js +0 -182
- package/lib/ext/AiImage/generate/output/loading-image.d.ts +0 -9
- package/lib/ext/AiImage/generate/output/loading-image.js +0 -60
- package/lib/ext/AiImage/generate/output/lottie-error.json +0 -6689
- package/lib/ext/AiImage/generate/output/lottie-loading.json +0 -5879
- package/lib/ext/AiImage/generate/output/lottie-welcome.json +0 -6785
- package/lib/ext/AiImage/generate/output/lottie.d.ts +0 -4
- package/lib/ext/AiImage/generate/output/lottie.js +0 -6
- package/lib/ext/AiImage/generate/prompt.d.ts +0 -4
- package/lib/ext/AiImage/generate/prompt.js +0 -122
- package/lib/ext/AiImage/index.d.ts +0 -3
- package/lib/ext/AiImage/index.js +0 -3
- package/lib/ext/AiImage/node.d.ts +0 -5
- package/lib/ext/AiImage/node.js +0 -23
- package/lib/ext/AiImage/plugin.d.ts +0 -5
- package/lib/ext/AiImage/plugin.js +0 -24
- package/lib/ext/AiImage/util.d.ts +0 -3
- package/lib/ext/AiImage/util.js +0 -8
package/lib/main/editor.js
CHANGED
|
@@ -64,7 +64,6 @@ import Placeholder from './ui/Placeholder';
|
|
|
64
64
|
import { useEditorConfig } from '../config';
|
|
65
65
|
import AidePlugin from '../ext/AIPlugin';
|
|
66
66
|
import MarkdownHeadTextPlugin from '../ext/HeadTextPlugin';
|
|
67
|
-
import { AiImagePlugin } from '../ext/AiImage';
|
|
68
67
|
import { EditorRefPlugin } from '../ext/LexicalEditorRefPlugin';
|
|
69
68
|
import AlertPlugin from '../ext/Alert/AlertPlugin';
|
|
70
69
|
import { HeadingsIdPlugin } from '../ext/HeadingsIdPlugin';
|
|
@@ -109,7 +108,7 @@ export default function Editor({ children, prepend, placeholder, onChange, autoF
|
|
|
109
108
|
}
|
|
110
109
|
}, [hasNodes('image'), hasUploader]);
|
|
111
110
|
if (minimalMode) {
|
|
112
|
-
return (_jsxs(_Fragment, { children: [prepend, isRichText && editable && showToolbar && _jsx(ToolbarPlugin, {}), hasNodes('image') && hasUploader && _jsx(DragDropPaste, {}), autoFocus && _jsx(AutoFocusPlugin, { defaultSelection: "rootEnd" }), _jsx(ClearEditorPlugin, {}), !!editable && _jsx(ComponentPickerPlugin, {}), !!editable && _jsx(MentionsPlugin, {}), hasNodes('link') && _jsx(AutoEmbedPlugin, {}), _jsx(PasteSlackImagePlugin, {}), _jsx(StyledEditorContent, { ref: onRef, className: cx('be-content', editable && 'editable'), children: _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: cx('be-editable', 'notranslate') }), placeholder: _jsx(Placeholder, { className: "be-placeholder", children: placeholder }), ErrorBoundary: LexicalErrorBoundary }) }), hasNodes('code', 'code-highlight') && _jsx(CodeHighlightPlugin, {}), hasNodes('image') && hasUploader && _jsx(ImagesPlugin, {}), hasNodes('video') && _jsx(VideoPlugin, {}), hasNodes('link') && _jsx(LinkPlugin, {}), hasNodes('tweet') && _jsx(TwitterPlugin, {}), hasNodes('youtube') && _jsx(YouTubePlugin, {}), hasNodes('figma') && _jsx(FigmaPlugin, {}), _jsx(PostLinkEmbedPlugin, {}), _jsx(BookmarkPlugin, {}), editable && _jsx(CustomOnChangePlugin, { placeholder: placeholder }), editable && _jsx(TemplatePlugin, {}), !editable && _jsx(BlurTextPlugin, {}), hasNodes('pdf') && _jsx(PdfPlugin, {}), hasNodes('file') && _jsx(FilePlugin, {}), hasNodes('horizontalrule') && _jsx(HorizontalRulePlugin, {}), hasNodes('excalidraw') && _jsx(ExcalidrawPlugin, {}), hasNodes('alert') && _jsx(AlertPlugin, {}), hasNodes('pages-kit-component') && _jsx(PagesKitComponentPlugin, {}), _jsx(TabFocusPlugin, {}), onChange && _jsx(OnChangePlugin, { onChange: onChange }), floatingAnchorElem && editable && (_jsxs(_Fragment, { children: [hasNodes('code') && _jsx(CodeActionMenuPlugin, { anchorElem: floatingAnchorElem }), hasNodes('link') && _jsx(FloatingLinkEditorPlugin, { anchorElem: floatingAnchorElem })] })),
|
|
111
|
+
return (_jsxs(_Fragment, { children: [prepend, isRichText && editable && showToolbar && _jsx(ToolbarPlugin, {}), hasNodes('image') && hasUploader && _jsx(DragDropPaste, {}), autoFocus && _jsx(AutoFocusPlugin, { defaultSelection: "rootEnd" }), _jsx(ClearEditorPlugin, {}), !!editable && _jsx(ComponentPickerPlugin, {}), !!editable && _jsx(MentionsPlugin, {}), hasNodes('link') && _jsx(AutoEmbedPlugin, {}), _jsx(PasteSlackImagePlugin, {}), _jsx(StyledEditorContent, { ref: onRef, className: cx('be-content', editable && 'editable'), children: _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: cx('be-editable', 'notranslate') }), placeholder: _jsx(Placeholder, { className: "be-placeholder", children: placeholder }), ErrorBoundary: LexicalErrorBoundary }) }), hasNodes('code', 'code-highlight') && _jsx(CodeHighlightPlugin, {}), hasNodes('image') && hasUploader && _jsx(ImagesPlugin, {}), hasNodes('video') && _jsx(VideoPlugin, {}), hasNodes('link') && _jsx(LinkPlugin, {}), hasNodes('tweet') && _jsx(TwitterPlugin, {}), hasNodes('youtube') && _jsx(YouTubePlugin, {}), hasNodes('figma') && _jsx(FigmaPlugin, {}), _jsx(PostLinkEmbedPlugin, {}), _jsx(BookmarkPlugin, {}), editable && _jsx(CustomOnChangePlugin, { placeholder: placeholder }), editable && _jsx(TemplatePlugin, {}), !editable && _jsx(BlurTextPlugin, {}), hasNodes('pdf') && _jsx(PdfPlugin, {}), hasNodes('file') && _jsx(FilePlugin, {}), hasNodes('horizontalrule') && _jsx(HorizontalRulePlugin, {}), hasNodes('excalidraw') && _jsx(ExcalidrawPlugin, {}), hasNodes('alert') && _jsx(AlertPlugin, {}), hasNodes('pages-kit-component') && _jsx(PagesKitComponentPlugin, {}), _jsx(TabFocusPlugin, {}), onChange && _jsx(OnChangePlugin, { onChange: onChange }), floatingAnchorElem && editable && (_jsxs(_Fragment, { children: [hasNodes('code') && _jsx(CodeActionMenuPlugin, { anchorElem: floatingAnchorElem }), hasNodes('link') && _jsx(FloatingLinkEditorPlugin, { anchorElem: floatingAnchorElem })] })), editorRef && _jsx(EditorRefPlugin, { editorRef: editorRef }), children] }));
|
|
113
112
|
}
|
|
114
|
-
return (_jsxs(_Fragment, { children: [prepend, isRichText && editable && showToolbar && _jsx(ToolbarPlugin, {}), isMaxLength && _jsx(MaxLengthPlugin, { maxLength: 30 }), hasNodes('image') && hasUploader && _jsx(DragDropPaste, {}), autoFocus && _jsx(AutoFocusPlugin, { defaultSelection: "rootEnd" }), _jsx(ClearEditorPlugin, {}), !!editable && _jsx(ComponentPickerPlugin, {}), !!editable && _jsx(EmojiPickerPlugin, {}), hasNodes('link') && _jsx(AutoEmbedPlugin, {}), !!editable && _jsx(MentionsPlugin, {}), hasNodes('emoji') && _jsx(EmojisPlugin, {}), hasNodes('hashtag') && _jsx(HashtagPlugin, {}), hasNodes('autolink') && _jsx(AutoLinkPlugin, {}), isRichText ? (_jsxs(_Fragment, { children: [_jsx(PasteSlackImagePlugin, {}), _jsx(HistoryPlugin, { externalHistoryState: historyState }), _jsx(StyledEditorContent, { ref: onRef, className: cx('be-content', editable && 'editable'), children: _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: cx('be-editable', 'notranslate') }), placeholder: _jsx(Placeholder, { className: "be-placeholder", children: placeholder }), ErrorBoundary: LexicalErrorBoundary }) }), _jsx(MarkdownShortcutPlugin, {}), _jsx(TabIndentationPlugin, {}), hasNodes('code', 'code-highlight') && _jsx(CodeHighlightPlugin, {}), hasNodes('list', 'listitem') && _jsx(ListPlugin, {}), hasNodes('list', 'listitem') && _jsx(CheckListPlugin, {}), hasNodes('list', 'listitem') && _jsx(ListMaxIndentLevelPlugin, { maxDepth: 7 }), hasNodes('table', 'tablerow', 'tablecell') && editable && (_jsx(TablePlugin, { hasCellMerge: true, hasCellBackgroundColor: true, hasHorizontalScroll: true })), hasNodes('table', 'tablerow', 'tablecell') && _jsx(TableCellResizer, {}), hasNodes('image') && hasUploader && _jsx(ImagesPlugin, {}), hasNodes('video') && _jsx(VideoPlugin, {}), hasNodes('link') && _jsx(LinkPlugin, {}), hasNodes('tweet') && _jsx(TwitterPlugin, {}), hasNodes('youtube') && _jsx(YouTubePlugin, {}), hasNodes('figma') && _jsx(FigmaPlugin, {}), _jsx(BilibiliPlugin, {}), _jsx(BlockletEmbedPlugin, {}), _jsx(PostLinkEmbedPlugin, {}), _jsx(BookmarkPlugin, {}), _jsx(AidePlugin, {}), editable && _jsx(CustomOnChangePlugin, { placeholder: placeholder }), editable && _jsx(TemplatePlugin, {}), !editable && _jsx(BlurTextPlugin, {}), hasNodes('pdf') && _jsx(PdfPlugin, {}), hasNodes('file') && _jsx(FilePlugin, {}), hasNodes('link') && _jsx(ClickableLinkPlugin, {}), hasNodes('horizontalrule') && _jsx(HorizontalRulePlugin, {}), hasNodes('excalidraw') && _jsx(ExcalidrawPlugin, {}), hasNodes('alert') && _jsx(AlertPlugin, {}), hasNodes('pages-kit-component') && _jsx(PagesKitComponentPlugin, {}), _jsx(TabFocusPlugin, {}), hasNodes('collapsible-container', 'collapsible-content', 'collapsible-title') && _jsx(CollapsiblePlugin, {}), onChange && _jsx(OnChangePlugin, { onChange: onChange }), floatingAnchorElem && editable && (_jsxs(_Fragment, { children: [_jsx(DraggableBlockPlugin, { anchorElem: floatingAnchorElem }), hasNodes('code') && _jsx(CodeActionMenuPlugin, { anchorElem: floatingAnchorElem }), hasNodes('link') && _jsx(FloatingLinkEditorPlugin, { anchorElem: floatingAnchorElem }), hasNodes('table') && _jsx(TableCellActionMenuPlugin, { anchorElem: floatingAnchorElem, cellMerge: true }), _jsx(FloatingTextFormatToolbarPlugin, { anchorElem: floatingAnchorElem })] })), enableHeadingsIdPlugin && _jsx(HeadingsIdPlugin, {})] })) : (_jsxs(_Fragment, { children: [_jsx(PlainTextPlugin, { contentEditable: _jsx(ContentEditable, {}), placeholder: _jsx(Placeholder, { children: "placeholder" }), ErrorBoundary: LexicalErrorBoundary }), _jsx(HistoryPlugin, { externalHistoryState: historyState })] })), (isCharLimit || isCharLimitUtf8) && (_jsx(CharacterLimitPlugin, { charset: isCharLimit ? 'UTF-16' : 'UTF-8', maxLength: 5 })), _jsx("div", { children: showTableOfContents && _jsx(TableOfContentsPlugin, {}) }), _jsx(MarkdownHeadTextPlugin, {}), _jsx(
|
|
113
|
+
return (_jsxs(_Fragment, { children: [prepend, isRichText && editable && showToolbar && _jsx(ToolbarPlugin, {}), isMaxLength && _jsx(MaxLengthPlugin, { maxLength: 30 }), hasNodes('image') && hasUploader && _jsx(DragDropPaste, {}), autoFocus && _jsx(AutoFocusPlugin, { defaultSelection: "rootEnd" }), _jsx(ClearEditorPlugin, {}), !!editable && _jsx(ComponentPickerPlugin, {}), !!editable && _jsx(EmojiPickerPlugin, {}), hasNodes('link') && _jsx(AutoEmbedPlugin, {}), !!editable && _jsx(MentionsPlugin, {}), hasNodes('emoji') && _jsx(EmojisPlugin, {}), hasNodes('hashtag') && _jsx(HashtagPlugin, {}), hasNodes('autolink') && _jsx(AutoLinkPlugin, {}), isRichText ? (_jsxs(_Fragment, { children: [_jsx(PasteSlackImagePlugin, {}), _jsx(HistoryPlugin, { externalHistoryState: historyState }), _jsx(StyledEditorContent, { ref: onRef, className: cx('be-content', editable && 'editable'), children: _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: cx('be-editable', 'notranslate') }), placeholder: _jsx(Placeholder, { className: "be-placeholder", children: placeholder }), ErrorBoundary: LexicalErrorBoundary }) }), _jsx(MarkdownShortcutPlugin, {}), _jsx(TabIndentationPlugin, {}), hasNodes('code', 'code-highlight') && _jsx(CodeHighlightPlugin, {}), hasNodes('list', 'listitem') && _jsx(ListPlugin, {}), hasNodes('list', 'listitem') && _jsx(CheckListPlugin, {}), hasNodes('list', 'listitem') && _jsx(ListMaxIndentLevelPlugin, { maxDepth: 7 }), hasNodes('table', 'tablerow', 'tablecell') && editable && (_jsx(TablePlugin, { hasCellMerge: true, hasCellBackgroundColor: true, hasHorizontalScroll: true })), hasNodes('table', 'tablerow', 'tablecell') && _jsx(TableCellResizer, {}), hasNodes('image') && hasUploader && _jsx(ImagesPlugin, {}), hasNodes('video') && _jsx(VideoPlugin, {}), hasNodes('link') && _jsx(LinkPlugin, {}), hasNodes('tweet') && _jsx(TwitterPlugin, {}), hasNodes('youtube') && _jsx(YouTubePlugin, {}), hasNodes('figma') && _jsx(FigmaPlugin, {}), _jsx(BilibiliPlugin, {}), _jsx(BlockletEmbedPlugin, {}), _jsx(PostLinkEmbedPlugin, {}), _jsx(BookmarkPlugin, {}), _jsx(AidePlugin, {}), editable && _jsx(CustomOnChangePlugin, { placeholder: placeholder }), editable && _jsx(TemplatePlugin, {}), !editable && _jsx(BlurTextPlugin, {}), hasNodes('pdf') && _jsx(PdfPlugin, {}), hasNodes('file') && _jsx(FilePlugin, {}), hasNodes('link') && _jsx(ClickableLinkPlugin, {}), hasNodes('horizontalrule') && _jsx(HorizontalRulePlugin, {}), hasNodes('excalidraw') && _jsx(ExcalidrawPlugin, {}), hasNodes('alert') && _jsx(AlertPlugin, {}), hasNodes('pages-kit-component') && _jsx(PagesKitComponentPlugin, {}), _jsx(TabFocusPlugin, {}), hasNodes('collapsible-container', 'collapsible-content', 'collapsible-title') && _jsx(CollapsiblePlugin, {}), onChange && _jsx(OnChangePlugin, { onChange: onChange }), floatingAnchorElem && editable && (_jsxs(_Fragment, { children: [_jsx(DraggableBlockPlugin, { anchorElem: floatingAnchorElem }), hasNodes('code') && _jsx(CodeActionMenuPlugin, { anchorElem: floatingAnchorElem }), hasNodes('link') && _jsx(FloatingLinkEditorPlugin, { anchorElem: floatingAnchorElem }), hasNodes('table') && _jsx(TableCellActionMenuPlugin, { anchorElem: floatingAnchorElem, cellMerge: true }), _jsx(FloatingTextFormatToolbarPlugin, { anchorElem: floatingAnchorElem })] })), enableHeadingsIdPlugin && _jsx(HeadingsIdPlugin, {})] })) : (_jsxs(_Fragment, { children: [_jsx(PlainTextPlugin, { contentEditable: _jsx(ContentEditable, {}), placeholder: _jsx(Placeholder, { children: "placeholder" }), ErrorBoundary: LexicalErrorBoundary }), _jsx(HistoryPlugin, { externalHistoryState: historyState })] })), (isCharLimit || isCharLimitUtf8) && (_jsx(CharacterLimitPlugin, { charset: isCharLimit ? 'UTF-16' : 'UTF-8', maxLength: 5 })), _jsx("div", { children: showTableOfContents && _jsx(TableOfContentsPlugin, {}) }), _jsx(MarkdownHeadTextPlugin, {}), _jsx(EditorHolderPlugin, {}), editorRef && _jsx(EditorRefPlugin, { editorRef: editorRef }), onReady && _jsx(EditorReadyPlugin, { onReady: onReady }), children] }));
|
|
115
114
|
}
|
|
@@ -21,7 +21,6 @@ import { INSERT_IMAGE_COMMAND, isImage } from '../ImagesPlugin';
|
|
|
21
21
|
import { InsertTableDialog } from '../TablePlugin';
|
|
22
22
|
import { useEditorConfig } from '../../../config';
|
|
23
23
|
import createPortal from '../../../components/createPortal';
|
|
24
|
-
import { isExistAiKit } from '../../../ext/AiImage';
|
|
25
24
|
import { $insertAlert } from '../../../ext/Alert/AlertPlugin';
|
|
26
25
|
import { INSERT_VIDEO_COMMAND, isVideo } from '../../../ext/VideoPlugin';
|
|
27
26
|
import { INSERT_TEMPLATE_COMMAND } from '../../../ext/TemplatePlugin';
|
|
@@ -272,7 +271,7 @@ export default function ComponentPickerMenuPlugin() {
|
|
|
272
271
|
}))),
|
|
273
272
|
hasNodes('image') &&
|
|
274
273
|
hasUploader &&
|
|
275
|
-
new ComponentPickerOption(
|
|
274
|
+
new ComponentPickerOption('Media', {
|
|
276
275
|
icon: _jsx("i", { className: "iconify", "data-icon": icons.media }),
|
|
277
276
|
keywords: ['image', 'photo', 'picture', 'file', 'video', 'media', 'pdf'],
|
|
278
277
|
onSelect: () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocklet/editor",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.81",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -56,7 +56,6 @@
|
|
|
56
56
|
"leven": "^4.0.0",
|
|
57
57
|
"lexical": "^0.30.0",
|
|
58
58
|
"lodash": "^4.17.21",
|
|
59
|
-
"lottie-react": "^2.4.0",
|
|
60
59
|
"marked": "^15.0.8",
|
|
61
60
|
"markerjs-live": "^1.2.1",
|
|
62
61
|
"markerjs2": "^2.32.2",
|
|
@@ -69,7 +68,7 @@
|
|
|
69
68
|
"ufo": "^1.5.4",
|
|
70
69
|
"url-join": "^4.0.1",
|
|
71
70
|
"zustand": "^4.5.5",
|
|
72
|
-
"@blocklet/pdf": "^2.3.
|
|
71
|
+
"@blocklet/pdf": "^2.3.81"
|
|
73
72
|
},
|
|
74
73
|
"devDependencies": {
|
|
75
74
|
"@babel/core": "^7.25.2",
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { ReactNode } from 'react';
|
|
2
|
-
interface AiImageContextType {
|
|
3
|
-
disabledSize: boolean;
|
|
4
|
-
multiple: boolean;
|
|
5
|
-
loading: boolean;
|
|
6
|
-
embed: boolean;
|
|
7
|
-
onLoading: (loading: boolean) => void;
|
|
8
|
-
}
|
|
9
|
-
interface AiImageProviderProps {
|
|
10
|
-
children: ReactNode;
|
|
11
|
-
multiple?: boolean;
|
|
12
|
-
disabledSize: boolean;
|
|
13
|
-
embed: boolean;
|
|
14
|
-
}
|
|
15
|
-
export interface AiImagePromptProps {
|
|
16
|
-
prompt: string;
|
|
17
|
-
sizeWidth: number;
|
|
18
|
-
number: number;
|
|
19
|
-
}
|
|
20
|
-
export declare const AiImageContext: import("react").Context<AiImageContextType>;
|
|
21
|
-
export declare const useAiImageContext: () => AiImageContextType;
|
|
22
|
-
export declare function AiImageProvider({ multiple, disabledSize, embed, children, }: AiImageProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
23
|
-
export {};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { createContext, useContext, useMemo } from 'react';
|
|
3
|
-
import { useGetState } from 'ahooks';
|
|
4
|
-
export const AiImageContext = createContext({});
|
|
5
|
-
export const useAiImageContext = () => useContext(AiImageContext);
|
|
6
|
-
export function AiImageProvider({ multiple = false, disabledSize = false, embed = false, children, }) {
|
|
7
|
-
const [state, setState] = useGetState({
|
|
8
|
-
embed,
|
|
9
|
-
multiple,
|
|
10
|
-
loading: false,
|
|
11
|
-
disabledSize,
|
|
12
|
-
});
|
|
13
|
-
const onLoading = (loading) => setState((prev) => ({ ...prev, loading }));
|
|
14
|
-
const value = useMemo(() => ({ ...state, onLoading }), [state]);
|
|
15
|
-
return _jsx(AiImageContext.Provider, { value: value, children: children });
|
|
16
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
interface Props {
|
|
2
|
-
onSelect: (data: any) => void;
|
|
3
|
-
api: any;
|
|
4
|
-
width?: number | string;
|
|
5
|
-
height?: number | string;
|
|
6
|
-
embed?: boolean;
|
|
7
|
-
disabledSize?: boolean;
|
|
8
|
-
}
|
|
9
|
-
declare function AiImage({ onSelect, api, width, height, embed, disabledSize }: Props): import("react/jsx-runtime").JSX.Element;
|
|
10
|
-
export default AiImage;
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useState } from 'react';
|
|
3
|
-
import Box from '@mui/material/Box';
|
|
4
|
-
import Grid from '@mui/material/Grid';
|
|
5
|
-
import IconButton from '@mui/material/IconButton';
|
|
6
|
-
import { Close as CloseIcon } from '@mui/icons-material';
|
|
7
|
-
import Prompt from './prompt';
|
|
8
|
-
import Output from './output';
|
|
9
|
-
import { AiImageProvider } from './context';
|
|
10
|
-
function AiImage({ onSelect, api, width, height, embed = false, disabledSize = false }) {
|
|
11
|
-
const [parameters, setParameters] = useState();
|
|
12
|
-
const [open, setOpen] = useState(false);
|
|
13
|
-
const onFinish = () => setParameters(undefined);
|
|
14
|
-
const onClose = () => setOpen(false);
|
|
15
|
-
if (embed) {
|
|
16
|
-
const onUseImage = (data) => {
|
|
17
|
-
onSelect(data);
|
|
18
|
-
onClose();
|
|
19
|
-
};
|
|
20
|
-
return (_jsxs(AiImageProvider, { disabledSize: disabledSize, embed: embed, children: [_jsx(Box, { width: 1, height: 1, children: _jsx(Prompt, { onSubmit: (data) => {
|
|
21
|
-
setParameters(data);
|
|
22
|
-
setOpen(true);
|
|
23
|
-
} }) }), open && (_jsxs(Box, { sx: {
|
|
24
|
-
position: 'fixed',
|
|
25
|
-
left: 0,
|
|
26
|
-
right: 0,
|
|
27
|
-
top: 0,
|
|
28
|
-
bottom: 0,
|
|
29
|
-
zIndex: 13001,
|
|
30
|
-
background: '#fff',
|
|
31
|
-
display: 'flex',
|
|
32
|
-
flexDirection: 'column',
|
|
33
|
-
}, children: [_jsx(Box, { sx: { position: 'relative' }, children: _jsx(IconButton, { onClick: onClose, sx: {
|
|
34
|
-
position: 'absolute',
|
|
35
|
-
right: 8,
|
|
36
|
-
top: 8,
|
|
37
|
-
}, children: _jsx(CloseIcon, {}) }) }), _jsx(Box, { p: 2, flex: 1, children: _jsx(Output, { options: parameters, handleApi: api, onSelect: onUseImage, onFinish: onFinish }) })] }))] }));
|
|
38
|
-
}
|
|
39
|
-
return (_jsx(AiImageProvider, { disabledSize: disabledSize, embed: embed, children: _jsx(Box, { sx: {
|
|
40
|
-
display: 'flex',
|
|
41
|
-
width: { xs: width || '100%', sm: width || 1200 },
|
|
42
|
-
height: { xs: height || '100%', sm: height || 600 },
|
|
43
|
-
}, children: _jsxs(Grid, { container: true, sx: { flexGrow: 1 }, spacing: { xs: 2 }, children: [_jsx(Grid, { item: true, xs: 12, sm: 3, sx: { borderRight: { sm: '1px solid #eee', height: '100%' } }, children: _jsx(Box, { sx: { height: '100%', display: 'flex', flexDirection: 'column', px: 1.5 }, children: _jsx(Prompt, { onSubmit: setParameters }) }) }), _jsx(Grid, { item: true, xs: 12, sm: 9, sx: { height: '100%', overflow: 'hidden' }, children: _jsx(Output, { options: parameters, handleApi: api, onSelect: onSelect, onFinish: onFinish }) })] }) }) }));
|
|
44
|
-
}
|
|
45
|
-
export default AiImage;
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { AiImagePromptProps } from '../context';
|
|
2
|
-
export default function Output({ options, handleApi, onSelect, onFinish, }: {
|
|
3
|
-
options?: AiImagePromptProps;
|
|
4
|
-
handleApi: (data: any) => any;
|
|
5
|
-
onSelect: (data?: string[]) => void;
|
|
6
|
-
onFinish: () => void;
|
|
7
|
-
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import styled from '@emotion/styled';
|
|
3
|
-
import Button from '@mui/material/Button';
|
|
4
|
-
import Box from '@mui/material/Box';
|
|
5
|
-
import Grid from '@mui/material/Grid';
|
|
6
|
-
import Skeleton from '@mui/material/Skeleton';
|
|
7
|
-
import { useState } from 'react';
|
|
8
|
-
import { useReactive } from 'ahooks';
|
|
9
|
-
import { useAsyncEffect } from 'ahooks';
|
|
10
|
-
import { useAiImageContext } from '../context';
|
|
11
|
-
import LoadingImage from './loading-image';
|
|
12
|
-
import Lottie from './lottie';
|
|
13
|
-
import lottieJsonErrorUrl from './lottie-error.json';
|
|
14
|
-
import lottieJsonLoadingUrl from './lottie-loading.json';
|
|
15
|
-
import lottieJsonWelcomeUrl from './lottie-welcome.json';
|
|
16
|
-
export default function Output({ options, handleApi, onSelect, onFinish, }) {
|
|
17
|
-
const { loading, multiple, embed, onLoading } = useAiImageContext();
|
|
18
|
-
const [response, setResponse] = useState([]);
|
|
19
|
-
const [error, setError] = useState();
|
|
20
|
-
const selected = useReactive({});
|
|
21
|
-
const selectedUrls = Object.keys(selected).filter((key) => selected[key]);
|
|
22
|
-
useAsyncEffect(async () => {
|
|
23
|
-
if (!options) {
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
setError(undefined);
|
|
27
|
-
onLoading(true);
|
|
28
|
-
try {
|
|
29
|
-
const res = await handleApi({ ...options, responseFormat: embed ? 'b64_json' : 'url' });
|
|
30
|
-
if (res.data) {
|
|
31
|
-
const list = res.data || [];
|
|
32
|
-
const arr = embed
|
|
33
|
-
? list.map((item) => ({
|
|
34
|
-
src: `data:image/png;base64,${item.b64_json}`,
|
|
35
|
-
width: options.sizeWidth,
|
|
36
|
-
}))
|
|
37
|
-
: list.map((item) => ({ src: `${item.url}`, width: options.sizeWidth }));
|
|
38
|
-
if (response) {
|
|
39
|
-
setResponse([...arr, ...response]);
|
|
40
|
-
}
|
|
41
|
-
else {
|
|
42
|
-
setResponse(arr);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
else {
|
|
46
|
-
setError(res);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
catch (err) {
|
|
50
|
-
console.error('AiImage generate error: ', err);
|
|
51
|
-
setError(err?.response?.data || err);
|
|
52
|
-
}
|
|
53
|
-
finally {
|
|
54
|
-
onLoading(false);
|
|
55
|
-
onFinish();
|
|
56
|
-
}
|
|
57
|
-
}, [options?.number, options?.prompt, options?.sizeWidth]);
|
|
58
|
-
const onSelectImage = (src) => {
|
|
59
|
-
if (!multiple) {
|
|
60
|
-
Object.keys(selected).forEach((key) => {
|
|
61
|
-
selected[key] = false;
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
selected[src] = !selected[src];
|
|
65
|
-
};
|
|
66
|
-
const onDelete = (src) => {
|
|
67
|
-
if (response) {
|
|
68
|
-
const index = response.findIndex((item) => item.src === src);
|
|
69
|
-
if (index > -1) {
|
|
70
|
-
selected[src] = false;
|
|
71
|
-
response.splice(index, 1);
|
|
72
|
-
setResponse([...response]);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
};
|
|
76
|
-
const Loading = () => {
|
|
77
|
-
return (_jsx(_Fragment, { children: Array.from({ length: options?.number || 1 }).map((_, index) => {
|
|
78
|
-
return (_jsx(Grid, { item: true, children: _jsx(Skeleton, { className: "lazy-image-skeleton", animation: "wave", variant: "rectangular", style: {
|
|
79
|
-
width: options?.sizeWidth || 256,
|
|
80
|
-
height: options?.sizeWidth || 256,
|
|
81
|
-
} }) }, index));
|
|
82
|
-
}) }));
|
|
83
|
-
};
|
|
84
|
-
const render = () => {
|
|
85
|
-
if (error) {
|
|
86
|
-
return (_jsxs(Box, { width: 300, height: 300, m: "auto", mt: "100px", children: [_jsx(Lottie, { src: lottieJsonErrorUrl }, "error"), _jsx(Box, { sx: {
|
|
87
|
-
textAlign: 'center',
|
|
88
|
-
color: '#25292F',
|
|
89
|
-
wordBreak: 'break-all',
|
|
90
|
-
}, children: error?.message })] }));
|
|
91
|
-
}
|
|
92
|
-
if (response && Array.isArray(response) && response.length > 0) {
|
|
93
|
-
return (_jsxs(_Fragment, { children: [_jsx(Box, { flexGrow: 1, sx: { height: 0, overflowX: 'hidden', overflowY: 'auto' }, children: _jsx(ResponseItemRoot, { sx: { p: 2 }, children: _jsxs(Grid, { spacing: 2, container: true, className: "photo-wrapper", children: [loading && _jsx(Loading, {}), response.map((item, index) => {
|
|
94
|
-
return (_jsx(Grid, { item: true, className: "photo-item", children: _jsx(LoadingImage, { ...item, selected: selected[item.src], style: {
|
|
95
|
-
objectFit: 'cover',
|
|
96
|
-
width: item.width,
|
|
97
|
-
height: item.width,
|
|
98
|
-
cursor: 'pointer',
|
|
99
|
-
transition: 'all 0.3s',
|
|
100
|
-
border: selected[item.src] ? '2px solid #2482F6' : '2px solid transparent',
|
|
101
|
-
}, onClick: () => {
|
|
102
|
-
onSelectImage(item.src);
|
|
103
|
-
}, onDelete: () => {
|
|
104
|
-
onDelete(item.src);
|
|
105
|
-
} }) }, item.src));
|
|
106
|
-
})] }) }) }), _jsx(Button, { size: "small", color: "primary", variant: "contained", sx: { alignSelf: 'end', mt: 2 }, disabled: !Boolean(selectedUrls.length) || loading, onClick: () => {
|
|
107
|
-
onSelect(selectedUrls);
|
|
108
|
-
}, children: Boolean(selectedUrls.length) ? 'Use selected images' : 'Please select images' })] }));
|
|
109
|
-
}
|
|
110
|
-
if (options) {
|
|
111
|
-
return (_jsxs(Box, { width: 240, height: 240, m: "auto", mt: "100px", children: [_jsx(Lottie, { src: lottieJsonLoadingUrl }, "loading"), _jsx(Box, { textAlign: "center", color: "#25292F", fontSize: 14, className: "tips", children: `Generating image with promot ${options?.prompt}...` })] }));
|
|
112
|
-
}
|
|
113
|
-
return (_jsx(Box, { width: 300, height: 300, m: "auto", mt: "100px", children: _jsx(Lottie, { src: lottieJsonWelcomeUrl }, "welcome") }));
|
|
114
|
-
};
|
|
115
|
-
return _jsx(Root, { children: render() });
|
|
116
|
-
}
|
|
117
|
-
const Root = styled(Box) `
|
|
118
|
-
min-height: 100%;
|
|
119
|
-
display: flex;
|
|
120
|
-
flex-direction: column;
|
|
121
|
-
|
|
122
|
-
.lazy-image-wrapper {
|
|
123
|
-
border-radius: 12px;
|
|
124
|
-
|
|
125
|
-
img {
|
|
126
|
-
border-radius: 12px;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
.tips {
|
|
131
|
-
overflow: hidden;
|
|
132
|
-
display: -webkit-box;
|
|
133
|
-
-webkit-box-orient: vertical;
|
|
134
|
-
-webkit-line-clamp: 3;
|
|
135
|
-
}
|
|
136
|
-
`;
|
|
137
|
-
const ResponseItemRoot = styled(Box) `
|
|
138
|
-
display: flex;
|
|
139
|
-
flex-direction: column;
|
|
140
|
-
background: #fbfbfb;
|
|
141
|
-
border: 1px solid #f6f6f6;
|
|
142
|
-
border-radius: 12px;
|
|
143
|
-
min-height: 100%;
|
|
144
|
-
|
|
145
|
-
&:has(.Mui-focused) {
|
|
146
|
-
border: 1px solid #a482fe;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
> .input {
|
|
150
|
-
padding: 12px;
|
|
151
|
-
font-weight: 500;
|
|
152
|
-
font-size: 16px;
|
|
153
|
-
line-height: 19px;
|
|
154
|
-
color: #25292f;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
> .footer {
|
|
158
|
-
display: flex;
|
|
159
|
-
align-items: center;
|
|
160
|
-
justify-content: flex-end;
|
|
161
|
-
padding: 0 12px 12px;
|
|
162
|
-
|
|
163
|
-
> .counter {
|
|
164
|
-
flex: 1;
|
|
165
|
-
overflow: hidden;
|
|
166
|
-
text-overflow: ellipsis;
|
|
167
|
-
white-space: nowrap;
|
|
168
|
-
font-weight: 400;
|
|
169
|
-
font-size: 12px;
|
|
170
|
-
line-height: 14px;
|
|
171
|
-
color: #9397a1;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
> .copy {
|
|
175
|
-
height: 25px;
|
|
176
|
-
width: 25px;
|
|
177
|
-
min-width: 0;
|
|
178
|
-
padding: 0;
|
|
179
|
-
color: #9397a1;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
`;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
|
-
declare const LoadingImage: import("react").ForwardRefExoticComponent<Omit<{
|
|
3
|
-
[key: string]: any;
|
|
4
|
-
onDelete: (src: string) => void;
|
|
5
|
-
selected: boolean;
|
|
6
|
-
onLoad?: (() => void) | undefined;
|
|
7
|
-
src: string;
|
|
8
|
-
}, "ref"> & import("react").RefAttributes<unknown>>;
|
|
9
|
-
export default LoadingImage;
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
/* eslint-disable import/no-extraneous-dependencies */
|
|
3
|
-
import { Skeleton } from '@mui/material';
|
|
4
|
-
import { forwardRef, useRef } from 'react';
|
|
5
|
-
import { useReactive } from 'ahooks';
|
|
6
|
-
import IconButton from '@mui/material/IconButton';
|
|
7
|
-
import { Delete as DeleteIcon } from '@mui/icons-material';
|
|
8
|
-
import styled from '@emotion/styled';
|
|
9
|
-
import { RadioButtonUnchecked as RadioButtonUncheckedIcon } from '@mui/icons-material';
|
|
10
|
-
import { CheckCircle as CheckCircleIcon } from '@mui/icons-material';
|
|
11
|
-
import Box from '@mui/material/Box';
|
|
12
|
-
const LoadingImage = forwardRef(
|
|
13
|
-
// @ts-ignore
|
|
14
|
-
({ onDelete, selected, onLoad, src, width, ...rest }, ref) => {
|
|
15
|
-
const imageRef = useRef(null);
|
|
16
|
-
const state = useReactive({
|
|
17
|
-
loading: true,
|
|
18
|
-
});
|
|
19
|
-
return (_jsxs("div", { style: { position: 'relative' }, ref: ref || imageRef, children: [_jsx("div", { className: "lazy-image-wrapper", style: {
|
|
20
|
-
visibility: state.loading ? 'hidden' : 'visible',
|
|
21
|
-
background: '#f4f4f4',
|
|
22
|
-
width: '100%',
|
|
23
|
-
height: '100%',
|
|
24
|
-
display: 'flex',
|
|
25
|
-
alignItems: 'center',
|
|
26
|
-
justifyContent: 'center',
|
|
27
|
-
}, children: _jsx("img", { alt: "", src: src, ...rest, onLoad: () => {
|
|
28
|
-
state.loading = false;
|
|
29
|
-
try {
|
|
30
|
-
onLoad?.();
|
|
31
|
-
}
|
|
32
|
-
catch (error) {
|
|
33
|
-
console.error('image onLoad error: ', error);
|
|
34
|
-
}
|
|
35
|
-
}, loading: "eager" // must be eager to make sure the image is loaded
|
|
36
|
-
}) }), state.loading && (_jsx(Skeleton, { className: "lazy-image-skeleton", animation: "wave", variant: "rectangular", style: {
|
|
37
|
-
width: width,
|
|
38
|
-
height: width,
|
|
39
|
-
position: 'absolute',
|
|
40
|
-
top: 0,
|
|
41
|
-
} })), _jsx(DeleteButton, { onClick: () => onDelete(src), sx: { position: 'absolute', left: 10, bottom: 10 }, children: _jsx(DeleteIcon, { sx: { fontSize: 20 } }) }), _jsx(Box, { sx: { position: 'absolute', left: 10, top: 10 }, onClick: rest?.onClick, children: selected ? (_jsx(CheckCircleIcon, { sx: { fontSize: 30, color: '#2482F6' } })) : (_jsx(RadioButtonUncheckedIcon, { sx: { fontSize: 30, color: '#fff' } })) })] }));
|
|
42
|
-
});
|
|
43
|
-
export default LoadingImage;
|
|
44
|
-
const DeleteButton = styled(IconButton) `
|
|
45
|
-
height: 36px;
|
|
46
|
-
width: 36px;
|
|
47
|
-
padding: 0;
|
|
48
|
-
background: rgba(0, 0, 0, 0.42);
|
|
49
|
-
-webkit-backdrop-filter: blur(16px);
|
|
50
|
-
backdrop-filter: blur(16px);
|
|
51
|
-
color: #f7f8f8;
|
|
52
|
-
display: flex;
|
|
53
|
-
justify-content: center;
|
|
54
|
-
align-items: center;
|
|
55
|
-
border-radius: 6px;
|
|
56
|
-
|
|
57
|
-
&:hover {
|
|
58
|
-
background: rgba(0, 0, 0, 0.69);
|
|
59
|
-
}
|
|
60
|
-
`;
|