Skip to content

Commit

Permalink
✨ feat: support save onLocal
Browse files Browse the repository at this point in the history
  • Loading branch information
arvinxx committed Jan 18, 2024
1 parent d4ac44b commit fa191dd
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 35 deletions.
8 changes: 3 additions & 5 deletions src/features/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ import { TextArea } from '@lobehub/ui';
import { Button, Flex } from 'antd';
import { memo } from 'react';

import { midjourneySelectors, useStore } from '@/store';
import { useStore } from '@/store';

const PromptInput = memo(() => {
const [prompts, running, updatePrompts, createImagineTask] = useStore((s) => [
const [prompts, updatePrompts, createImagineTask] = useStore((s) => [
s.prompts,
midjourneySelectors.isAnyTaskRunning(s),
s.updatePrompts,
s.createImagineTask,
]);
Expand All @@ -25,11 +24,10 @@ const PromptInput = memo(() => {
value={prompts}
/>
<Flex gap={8} vertical>
<Button loading={running} onClick={() => createImagineTask()} type={'primary'}>
<Button onClick={() => createImagineTask()} type={'primary'}>
生成
</Button>
<Button
disabled={running}
onClick={() => {
updatePrompts('');
}}
Expand Down
11 changes: 8 additions & 3 deletions src/features/Preview/Actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ const useStyles = createStyles(({ css }) => ({
width: 100%;
height: 100%;
:hover {
.action-reroll {
opacity: 1;
}
}
`,
}));

Expand All @@ -22,15 +28,14 @@ const Actions = memo<{ setMask: (mask: boolean) => void }>(({ setMask }) => {
const { styles } = useStyles();
const content = useMemo(() => {
switch (currentTask?.action) {
case 'VARIATION':
case 'IMAGINE': {
return <ImagineAction id={currentTask.id || ''} setMask={setMask} />;
}
case 'UPSCALE': {
break;
}
case 'VARIATION': {
break;
}

case 'REROLL': {
break;
}
Expand Down
10 changes: 8 additions & 2 deletions src/features/Preview/ImagineAction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,18 @@ const useStyles = createStyles(({ css, cx }) => {
position: absolute;
top: 16px;
right: 16px;
opacity: 0;
transition: opacity 0.3s;
`,
rerollInLobeChat: css`
position: absolute;
bottom: -44px;
left: 50%;
transform: translateX(-50%);
transition: opacity 0.3s;
`,
};
});
Expand All @@ -50,7 +56,7 @@ interface ImageActionProps {
setMask: (mask: boolean) => void;
}
const ImageAction = memo<ImageActionProps>(({ setMask, id }) => {
const { styles } = useStyles();
const { styles, cx } = useStyles();

const [inLobeChat, createSimpleChangeTask, isSuccess] = useStore((s) => [
s.inLobeChat,
Expand Down Expand Up @@ -99,7 +105,7 @@ const ImageAction = memo<ImageActionProps>(({ setMask, id }) => {
</Flexbox>
))}
</Flexbox>
<div className={inLobeChat ? styles.rerollInLobeChat : styles.reroll}>
<div className={cx('action-reroll', inLobeChat ? styles.rerollInLobeChat : styles.reroll)}>
<Button
onClick={(e) => {
e.stopPropagation();
Expand Down
51 changes: 37 additions & 14 deletions src/features/Preview/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,23 @@ import ImagePreview from './Image';

const useStyles = createStyles(({ css, token }) => ({
container: css`
position: relative;
overflow: hidden;
background: ${token.colorFillTertiary};
`,
process: css`
position: absolute;
right: 0;
bottom: -4px;
left: 0;
width: 100%;
> .ant-progress-line {
margin-bottom: 0;
margin-inline-end: 0;
}
`,
}));

const Preview = memo(() => {
Expand All @@ -21,23 +35,32 @@ const Preview = memo(() => {
s.inLobeChat,
]);

const { styles } = useStyles();
const { styles, theme } = useStyles();
const currentTask = useStore(midjourneySelectors.currentActiveTask);

const showImage = taskLoading || currentTask?.imageUrl;
return (
(taskLoading || currentTask?.imageUrl) && (
<Flexbox
className={styles.container}
flex={1}
gap={8}
height={'calc(100vh - 80px - 64px - 8*2px - 2*16px )'}
padding={16}
style={{ borderRadius: inLobeChat ? 8 : 24 }}
>
<ImagePreview />
{progress !== 100 && <Progress percent={progress} />}
</Flexbox>
)
<Flexbox
className={styles.container}
flex={1}
gap={8}
height={'calc(100vh - 80px - 64px - 8*2px - 2*16px )'}
padding={16}
style={{ borderRadius: inLobeChat ? 8 : 24 }}
>
{showImage && <ImagePreview />}
{taskLoading && progress !== 100 && (
<div className={styles.process}>
<Progress
percent={progress}
showInfo={false}
size={['100%', 16]}
strokeColor={{ from: theme.blue7, to: theme.green7 }}
strokeLinecap={'square'}
/>
</div>
)}
</Flexbox>
);
});

Expand Down
2 changes: 1 addition & 1 deletion src/features/TaskList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const TaskList = memo(() => {
const tasks = useStore((s) => s.tasks.map((t) => t.id), isEqual);

return (
<Flexbox gap={6} horizontal>
<Flexbox gap={6} height={64} horizontal>
{tasks.map((task) => (
<TaskItem id={task} key={task} />
))}
Expand Down
23 changes: 23 additions & 0 deletions src/services/storageService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { lobeChat } from '@lobehub/chat-plugin-sdk/client';

class StorageService {
private storageKey = 'MIDJOURNEY_DATA';
async saveToLocalStorage(state: object) {
const data = await this.getFromLocalStorage();

localStorage.setItem(this.storageKey, JSON.stringify({ ...data, ...state }));
}

async getFromLocalStorage(): Promise<object> {
return JSON.parse(localStorage.getItem(this.storageKey) || '{}');
}

async saveToLobeChat(state: object) {
// TODO: 替换为更好用的 setPluginState 方法
for (const [key, value] of Object.entries(state)) {
lobeChat.setPluginState(key, value);
}
}
}

export const storageService = new StorageService();
21 changes: 11 additions & 10 deletions src/store/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@ import useSWR, { SWRResponse } from 'swr';
import { StateCreator } from 'zustand';

import { ChangeTaskDTO, midjourneyService } from '@/services/Midjourney';
import { storageService } from '@/services/storageService';
import { TaskDispatch, tasksReducer } from '@/store/reducers/task';
import { MidjourneyTask } from '@/types/task';

import { MidjourneyStore } from '.';
import { AppSettings, AppState, initialState } from './initialState';

const useMockData = process.env.NEXT_PUBLIC_USE_MOCK_DATA !== undefined;

interface MJFunction {
prompts: string;
}
Expand Down Expand Up @@ -149,15 +152,14 @@ export const actions: StateCreator<
}
},

updateAppState: (state, action) => {
updateAppState: async (state, action) => {
set({ ...state }, false, action);

if (!get().inLobeChat) return;

// TODO: 替换为更好用的 setPluginState 方法
for (const [key, value] of Object.entries(state)) {
lobeChat.setPluginState(key, value);
if (!get().inLobeChat) {
await storageService.saveToLocalStorage(state);
}

await storageService.saveToLobeChat(state);
},

updatePrompts: (data) => {
Expand All @@ -175,14 +177,13 @@ export const actions: StateCreator<

// 说明不在 LobeChat 中
if (!payload) {
// 开发环境下,使用 mock 数据
if (process.env.NODE_ENV === 'development') {
// 开发环境下,按需开启 mock 数据
if (useMockData && process.env.NODE_ENV === 'development') {
const { mockState } = await import('./_mockdata');

return mockState;
}

return;
return await storageService.getFromLocalStorage();
}

if (payload?.name === 'showMJ') {
Expand Down

0 comments on commit fa191dd

Please sign in to comment.