diff --git a/src/app/App.tsx b/src/app/App.tsx
index 48ca831..e994607 100644
--- a/src/app/App.tsx
+++ b/src/app/App.tsx
@@ -1,7 +1,7 @@
import { CSSProperties, memo } from 'react';
import { Flexbox } from 'react-layout-kit';
+import ImagePreview from 'src/features/Preview';
-import ImagePreview from '@/features/ImagePreview';
import PromptInput from '@/features/Input';
import TaskList from '@/features/TaskList';
diff --git a/src/features/Preview/Actions.tsx b/src/features/Preview/Actions.tsx
new file mode 100644
index 0000000..536eafe
--- /dev/null
+++ b/src/features/Preview/Actions.tsx
@@ -0,0 +1,49 @@
+import { createStyles } from 'antd-style';
+import { memo, useMemo } from 'react';
+import { Flexbox } from 'react-layout-kit';
+
+import { midjourneySelectors, useStore } from '@/store';
+
+import ImagineAction from './ImagineAction';
+
+const useStyles = createStyles(({ css }) => ({
+ container: css`
+ position: absolute;
+ top: 0;
+ left: 0;
+
+ width: 100%;
+ height: 100%;
+ `,
+}));
+
+const Actions = memo(() => {
+ const currentTask = useStore(midjourneySelectors.currentActiveTask);
+ const { styles } = useStyles();
+ const content = useMemo(() => {
+ switch (currentTask?.action) {
+ case 'IMAGINE': {
+ return ;
+ }
+ case 'UPSCALE': {
+ break;
+ }
+ case 'VARIATION': {
+ break;
+ }
+ case 'REROLL': {
+ break;
+ }
+ case 'DESCRIBE': {
+ break;
+ }
+ case 'BLEND': {
+ break;
+ }
+ }
+ }, [currentTask?.action]);
+
+ return {content};
+});
+
+export default Actions;
diff --git a/src/features/ImagePreview/index.tsx b/src/features/Preview/Image.tsx
similarity index 53%
rename from src/features/ImagePreview/index.tsx
rename to src/features/Preview/Image.tsx
index 079e9ef..8a682df 100644
--- a/src/features/ImagePreview/index.tsx
+++ b/src/features/Preview/Image.tsx
@@ -1,16 +1,19 @@
import { Image } from '@lobehub/ui';
import { useSize } from 'ahooks';
-import { Progress, Skeleton } from 'antd';
+import { Skeleton } from 'antd';
import { createStyles } from 'antd-style';
import { memo, useEffect, useRef, useState } from 'react';
import { Dimensions, getImageSize } from 'react-image-size';
-import { Center, Flexbox } from 'react-layout-kit';
+import { Center } from 'react-layout-kit';
import { midjourneySelectors, useStore } from '@/store';
+import Actions from './Actions';
+
interface Size extends Dimensions {
aspectRadio: number;
}
+
const fetchImageSize = async (url: string): Promise => {
try {
const dim = await getImageSize(url);
@@ -26,29 +29,27 @@ const getContainerSize = (content?: Dimensions, container?: Dimensions) => {
let width = String(content?.width);
let height = String(content?.height);
- const spacing = 24;
- const maxWidth = container.width - spacing;
- const maxHeight = container.height - spacing;
+ const maxWidth = container.width;
+ const maxHeight = container.height;
+ let maxValue;
if (content?.height >= content?.width && content?.height >= maxHeight) {
+ maxValue = maxHeight;
height = maxHeight + 'px';
width = 'auto';
} else if (content?.width >= content?.height && content?.width >= maxWidth) {
height = 'auto';
width = maxWidth + 'px';
+ maxValue = maxWidth;
} else {
width = width + 'px';
height = height + 'px';
}
- return { height, width };
+ return { height, maxValue, width };
};
-const useStyles = createStyles(({ css, token, prefixCls }) => ({
- container: css`
- overflow: hidden;
- background: ${token.colorFillTertiary};
- border-radius: 24px;
- `,
+
+const useStyles = createStyles(({ css, prefixCls }) => ({
image: css`
border-radius: 24px;
`,
@@ -66,16 +67,14 @@ const useStyles = createStyles(({ css, token, prefixCls }) => ({
}));
const ImagePreview = memo(() => {
+ const { styles, cx, theme } = useStyles();
+
const [dim, setDims] = useState();
const containerRef = useRef(null);
const size = useSize(containerRef);
- const [progress, taskLoading] = useStore((s) => [
- midjourneySelectors.currentTaskProgress(s),
- midjourneySelectors.isCurrentTaskRunning(s),
- ]);
+ const imageContainerSize = getContainerSize(dim, size);
- const { styles, cx, theme } = useStyles();
const currentTask = useStore(midjourneySelectors.currentActiveTask);
useEffect(() => {
@@ -88,47 +87,36 @@ const ImagePreview = memo(() => {
});
}, [currentTask?.imageUrl]);
- const imageContainerSize = getContainerSize(dim, size);
-
return (
- (taskLoading || currentTask?.imageUrl) && (
-
- {currentTask?.imageUrl ? (
-
-
-
- ) : (
-
-
- Task is waiting to start...
-
-
- )}
- {progress !== 100 && }
-
- )
+
+ {currentTask?.imageUrl ? (
+
+ ) : (
+
+ Task is waiting to start...
+
+ )}
+
);
});
diff --git a/src/features/Preview/ImagineAction.tsx b/src/features/Preview/ImagineAction.tsx
new file mode 100644
index 0000000..f978c06
--- /dev/null
+++ b/src/features/Preview/ImagineAction.tsx
@@ -0,0 +1,14 @@
+import { Button } from 'antd';
+import { memo } from 'react';
+import { Flexbox } from 'react-layout-kit';
+
+const ImageAction = memo(() => {
+ return (
+
+
+
+
+ );
+});
+
+export default ImageAction;
diff --git a/src/features/Preview/index.tsx b/src/features/Preview/index.tsx
new file mode 100644
index 0000000..2582af0
--- /dev/null
+++ b/src/features/Preview/index.tsx
@@ -0,0 +1,43 @@
+import { Progress } from 'antd';
+import { createStyles } from 'antd-style';
+import { memo } from 'react';
+import { Flexbox } from 'react-layout-kit';
+
+import { midjourneySelectors, useStore } from '@/store';
+
+import ImagePreview from './Image';
+
+const useStyles = createStyles(({ css, token }) => ({
+ container: css`
+ overflow: hidden;
+ background: ${token.colorFillTertiary};
+ border-radius: 24px;
+ `,
+}));
+
+const Preview = memo(() => {
+ const [progress, taskLoading] = useStore((s) => [
+ midjourneySelectors.currentTaskProgress(s),
+ midjourneySelectors.isCurrentTaskRunning(s),
+ ]);
+
+ const { styles } = useStyles();
+ const currentTask = useStore(midjourneySelectors.currentActiveTask);
+
+ return (
+ (taskLoading || currentTask?.imageUrl) && (
+
+
+ {progress !== 100 && }
+
+ )
+ );
+});
+
+export default Preview;
diff --git a/src/services/Midjourney.ts b/src/services/Midjourney.ts
index 2fed682..c3fc1ec 100644
--- a/src/services/Midjourney.ts
+++ b/src/services/Midjourney.ts
@@ -12,9 +12,9 @@ interface DescribeResponse {
}
interface SimpleChangeDTO {
- content: string;
- notifyHook?: string;
- state?: string;
+ index: number;
+ taskId: string;
+ type: 'UPSCALE' | 'VARIATION';
}
interface SimpleChangeResponse {
code: 1;
@@ -87,12 +87,11 @@ class MidjourneyService {
return data.result;
}
- async createSimpleChangeTask({ content, notifyHook, state }: SimpleChangeDTO) {
- const data: SimpleChangeResponse = await this.post('/mj/submit/simple-change', {
- content,
- notifyHook,
- state,
- });
+ async createSimpleChangeTask({ taskId, index, type }: SimpleChangeDTO) {
+ // e.g. 1320098173412546 U2
+ const content = `${taskId} ${type[0]}${index}`;
+
+ const data: SimpleChangeResponse = await this.post('/mj/submit/simple-change', { content });
return data.result;
}
diff --git a/src/store/_mockdata.ts b/src/store/_mockdata.ts
index 90c4e5e..469d869 100644
--- a/src/store/_mockdata.ts
+++ b/src/store/_mockdata.ts
@@ -143,5 +143,61 @@ export const mockState: AppState = {
status: 'SUCCESS',
submitTime: 1705308810603,
},
+ {
+ action: 'IMAGINE',
+ description: '/imagine a bird',
+ failReason: null,
+ finishTime: 1705310324053,
+ id: '1705310285146113',
+ imageUrl:
+ 'https://cdn.discordapp.com/attachments/1174150905801736255/1196382952741945424/meng1011_a_bird_822d0ff9-e8da-4a35-b71f-78f59ad4ee1f.png?ex=65b76d73&is=65a4f873&hm=bb30ac4aa536d22fa28d06943127ba7a955047ae8138d48f3e86ccfaa4a24975&',
+ progress: '100%',
+ prompt: 'a bird',
+ promptEn: 'a bird',
+ properties: {
+ discordInstanceId: '1174150905801736255',
+ finalPrompt: 'a bird --v 6.0 --s 250',
+ flags: 0,
+ messageHash: '822d0ff9-e8da-4a35-b71f-78f59ad4ee1f',
+ messageId: '1196382953580810310',
+ nonce: '1467932102711394304',
+ notifyHook: null,
+ progressMessageId: '1196382794021097573',
+ },
+ startTime: 1705310285146,
+ state: null,
+ status: 'SUCCESS',
+ submitTime: 1705310285146,
+ },
+ {
+ action: 'IMAGINE',
+ description:
+ '/imagine Dragon sleeping on clouds, translucent glass, zbrush, ruby and gold style, anime aesthetics, furry art, red and white, elaborate, c4d rendering, super high detail, 3d --ar 9:16 --stylize 250 --v 6.0',
+ failReason: null,
+ finishTime: 1705310645445,
+ id: '1705310583960676',
+ imageUrl:
+ 'https://cdn.discordapp.com/attachments/1174150905801736255/1196384301101617262/meng1011_Dragon_sleeping_on_clouds_translucent_glass_zbrush_rub_4bed1f85-d7d9-4c68-b4d8-7652991e0b65.png?ex=65b76eb5&is=65a4f9b5&hm=198de4766243776970c66ba736a25a526110a051eadff6fcf46bbdeacda88d4d&',
+ progress: '100%',
+ prompt:
+ 'Dragon sleeping on clouds, translucent glass, zbrush, ruby and gold style, anime aesthetics, furry art, red and white, elaborate, c4d rendering, super high detail, 3d --ar 9:16 --stylize 250 --v 6.0',
+ promptEn:
+ 'Dragon sleeping on clouds, translucent glass, zbrush, ruby and gold style, anime aesthetics, furry art, red and white, elaborate, c4d rendering, super high detail, 3d --ar 9:16 --stylize 250 --v 6.0',
+ properties: {
+ discordInstanceId: '1174150905801736255',
+ finalPrompt:
+ 'Dragon sleeping on clouds, translucent glass, zbrush, ruby and gold style, anime aesthetics, furry art, red and white, elaborate, c4d rendering, super high detail, 3d --ar 9:16 --stylize 250 --v 6.0',
+ flags: 0,
+ messageHash: '4bed1f85-d7d9-4c68-b4d8-7652991e0b65',
+ messageId: '1196384301479116861',
+ nonce: '1467933356028149760',
+ notifyHook: null,
+ progressMessageId: '1196384047509815366',
+ },
+ startTime: 1705310583961,
+ state: null,
+ status: 'SUCCESS',
+ submitTime: 1705310583960,
+ },
],
};