Skip to content

Commit

Permalink
✨ feat: AgentViewer 抽象
Browse files Browse the repository at this point in the history
  • Loading branch information
rdmclin2 committed May 15, 2024
1 parent abc1fcf commit 8d4ceab
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 142 deletions.
3 changes: 2 additions & 1 deletion src/app/chat/ViewerMode/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import classNames from 'classnames';
import React, { memo } from 'react';
import { Flexbox } from 'react-layout-kit';

import { HEADER_HEIGHT } from '@/constants/common';
import AgentViewer from '@/features/AgentViewer';
import Alert from '@/features/Alert';
import ChatDialog from '@/features/ChatDialog';
Expand All @@ -22,7 +23,7 @@ export default memo(() => {
return (
<Flexbox flex={1} style={{ position: 'relative' }}>
<div className={styles.viewer}>
<AgentViewer />
<AgentViewer height={`calc(100vh - ${HEADER_HEIGHT}px);`} />
</div>
{showChatDialog ? (
<ChatDialog className={classNames(styles.dialog, styles.content)} setOpen={setChatDialog} />
Expand Down
4 changes: 2 additions & 2 deletions src/app/role/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import React, { memo } from 'react';
import { Flexbox } from 'react-layout-kit';

import TopBanner from '@/components/TopBanner';
import RoleDisplay from '@/features/AgentViewer/RoleDisplay/index';
import AgentViewer from '@/features/AgentViewer/index';
import RoleEdit from '@/panels/RolePanel/RoleEdit';

import SideBar from './SideBar';
Expand All @@ -22,7 +22,7 @@ const Role = () => {
<RoleEdit />
</Flexbox>
<Flexbox className={styles.model} flex={1}>
<RoleDisplay />
<AgentViewer height={720} />
</Flexbox>
</Flexbox>
</Flexbox>
Expand Down
102 changes: 0 additions & 102 deletions src/features/AgentViewer/RoleDisplay/index.tsx

This file was deleted.

23 changes: 0 additions & 23 deletions src/features/AgentViewer/RoleDisplay/style.ts

This file was deleted.

73 changes: 63 additions & 10 deletions src/features/AgentViewer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,49 +1,102 @@
import classNames from 'classnames';
import localforage from 'localforage';
import React, { memo, useCallback, useEffect, useRef, useState } from 'react';

import PageLoading from '@/components/PageLoading';
import ToolBar from '@/features/AgentViewer/ToolBar';
import { agentListSelectors, useAgentStore } from '@/store/agent';
import { sessionSelectors, useSessionStore } from '@/store/session';
import { useViewerStore } from '@/store/viewer';

import { useStyles } from './style';

interface Props {
className?: string;
height?: number | string;
style?: React.CSSProperties;
}

function AgentViewer(props: Props) {
const viewer = useViewerStore((s) => s.viewer);
const { className, style } = props;
const { className, style, height } = props;
const { styles } = useStyles();
const [loading, setLoading] = useState(false);
const ref = useRef<HTMLDivElement>(null);
const currentAgentModel = useSessionStore((s) => sessionSelectors.currentAgentModel(s));
const currentAgentId = useAgentStore((s) => agentListSelectors.currentAgentId(s));
const updateAgentConfig = useAgentStore((s) => s.updateAgentConfig);

useEffect(() => {
if (currentAgentModel) {
const loadVrm = async (url?: string) => {
let vrmUrl = url;
if (url && url.startsWith('model:')) {
const blob = await localforage.getItem(url);
if (blob) {
vrmUrl = window.URL.createObjectURL(blob as Blob);
} else {
vrmUrl = undefined;
}
}
if (vrmUrl) {
setLoading(true);
viewer.loadVrm(currentAgentModel).finally(() => {
viewer.loadVrm(vrmUrl).finally(() => {
setLoading(false);
});
} else {
viewer.unloadVRM();
}
}, [currentAgentModel, viewer]);
};

useEffect(() => {
loadVrm(currentAgentModel);
}, [currentAgentModel]);

const canvasRef = useCallback(
(canvas: HTMLCanvasElement) => {
if (canvas) {
viewer.setup(canvas);
}
viewer.setup(canvas);

const dragoverHandler = (event: DragEvent) => {
event.preventDefault();
};

const dropHandler = (event: DragEvent) => {
event.preventDefault();

const files = event.dataTransfer?.files;
if (!files) {
return;
}

const file = files[0];
if (!file) {
return;
}

const file_type = file.name.split('.').pop();
if (file_type === 'vrm') {
const blob = new Blob([file], { type: 'application/octet-stream' });
const modelKey = `model:${currentAgentId}`;
localforage.setItem(modelKey, blob).then(() => {
updateAgentConfig({ meta: { model: modelKey } });
loadVrm(modelKey);
});
}
};

canvas.addEventListener('dragover', dragoverHandler);
canvas.addEventListener('drop', dropHandler);
return () => {
canvas.removeEventListener('dragover', dragoverHandler);
canvas.removeEventListener('drop', dropHandler);
};
},
[viewer],
[viewer, currentAgentId],
);

return (
<div ref={ref} className={classNames(styles.viewer, className)} style={style}>
<ToolBar className={styles.toolbar} viewerRef={ref} />
{loading ? <PageLoading title={'模型加载中,请稍后...'} /> : null}
<canvas ref={canvasRef} className={styles.canvas}></canvas>
<canvas ref={canvasRef} className={styles.canvas} style={{ height }}></canvas>
</div>
);
}
Expand Down
4 changes: 0 additions & 4 deletions src/features/AgentViewer/style.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { createStyles } from 'antd-style';

import { HEADER_HEIGHT } from '@/constants/common';

export const useStyles = createStyles(({ css, token }) => ({
toolbar: css`
position: absolute;
Expand All @@ -16,10 +14,8 @@ export const useStyles = createStyles(({ css, token }) => ({
`,
canvas: css`
display: block;
width: 100%;
max-width: 100%;
height: calc(100vh - ${HEADER_HEIGHT}px);
max-height: 100%;
`,
}));

0 comments on commit 8d4ceab

Please sign in to comment.