Skip to content

Commit

Permalink
🚧 wip: 扩展动作
Browse files Browse the repository at this point in the history
  • Loading branch information
arvinxx committed Jan 15, 2024
1 parent df42a62 commit 6d93dcb
Show file tree
Hide file tree
Showing 7 changed files with 216 additions and 67 deletions.
2 changes: 1 addition & 1 deletion src/app/App.tsx
Original file line number Diff line number Diff line change
@@ -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';

Expand Down
49 changes: 49 additions & 0 deletions src/features/Preview/Actions.tsx
Original file line number Diff line number Diff line change
@@ -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 <ImagineAction />;
}
case 'UPSCALE': {
break;
}
case 'VARIATION': {
break;
}
case 'REROLL': {
break;
}
case 'DESCRIBE': {
break;
}
case 'BLEND': {
break;
}
}
}, [currentTask?.action]);

return <Flexbox className={styles.container}>{content}</Flexbox>;
});

export default Actions;
102 changes: 45 additions & 57 deletions src/features/ImagePreview/index.tsx → src/features/Preview/Image.tsx
Original file line number Diff line number Diff line change
@@ -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<Size | undefined> => {
try {
const dim = await getImageSize(url);
Expand All @@ -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;
`,
Expand All @@ -66,16 +67,14 @@ const useStyles = createStyles(({ css, token, prefixCls }) => ({
}));

const ImagePreview = memo(() => {
const { styles, cx, theme } = useStyles();

const [dim, setDims] = useState<Size>();
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(() => {
Expand All @@ -88,47 +87,36 @@ const ImagePreview = memo(() => {
});
}, [currentTask?.imageUrl]);

const imageContainerSize = getContainerSize(dim, size);

return (
(taskLoading || currentTask?.imageUrl) && (
<Flexbox
className={styles.container}
flex={1}
gap={8}
height={'calc(100vh - 80px - 64px - 8*2px - 2*16px )'}
padding={16}
>
{currentTask?.imageUrl ? (
<Center flex={1} height={'100%'} ref={containerRef} width={'100%'}>
<Image
className={styles.image}
src={currentTask.imageUrl}
{...imageContainerSize}
wrapperClassName={cx(
styles.imageWrapper,
currentTask.action === 'IMAGINE' && styles.imagine,
)}
/>
</Center>
) : (
<Center flex={1} height={'100%'} width={'100%'}>
<Skeleton.Node
active
style={{
borderRadius: 24,
color: theme.colorTextTertiary,
height: 600,
width: 600,
}}
>
Task is waiting to start...
</Skeleton.Node>
</Center>
)}
{progress !== 100 && <Progress percent={progress} />}
</Flexbox>
)
<Center flex={1} height={'100%'} ref={containerRef} width={'100%'}>
{currentTask?.imageUrl ? (
<div style={{ position: 'relative' }}>
<Image
className={styles.image}
src={currentTask.imageUrl}
wrapperClassName={cx(
styles.imageWrapper,
currentTask.action === 'IMAGINE' && styles.imagine,
)}
{...imageContainerSize}
/>
<Actions />
</div>
) : (
<Skeleton.Node
active
style={{
borderRadius: 24,
color: theme.colorTextTertiary,

height: imageContainerSize.maxValue || 600,
width: imageContainerSize.maxValue || 600,
}}
>
Task is waiting to start...
</Skeleton.Node>
)}
</Center>
);
});

Expand Down
14 changes: 14 additions & 0 deletions src/features/Preview/ImagineAction.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Button } from 'antd';
import { memo } from 'react';
import { Flexbox } from 'react-layout-kit';

const ImageAction = memo(() => {
return (
<Flexbox gap={8} horizontal>
<Button type={'primary'}>高清化</Button>
<Button>风格化</Button>
</Flexbox>
);
});

export default ImageAction;
43 changes: 43 additions & 0 deletions src/features/Preview/index.tsx
Original file line number Diff line number Diff line change
@@ -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) && (
<Flexbox
className={styles.container}
flex={1}
gap={8}
height={'calc(100vh - 80px - 64px - 8*2px - 2*16px )'}
padding={16}
>
<ImagePreview />
{progress !== 100 && <Progress percent={progress} />}
</Flexbox>
)
);
});

export default Preview;
17 changes: 8 additions & 9 deletions src/services/Midjourney.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down
56 changes: 56 additions & 0 deletions src/store/_mockdata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
],
};

0 comments on commit 6d93dcb

Please sign in to comment.