💄 style: improve plugin message ui

This commit is contained in:
arvinxx
2023-10-25 22:49:45 +08:00
parent aec68c8f9b
commit 6edd25bf10
5 changed files with 93 additions and 27 deletions
@@ -1,8 +1,15 @@
import { LoadingOutlined } from '@ant-design/icons';
import { Loading3QuartersOutlined } from '@ant-design/icons';
import { LobePluginType } from '@lobehub/chat-plugin-sdk';
import { ActionIcon, Avatar, Highlighter, Icon } from '@lobehub/ui';
import { Tabs } from 'antd';
import { LucideChevronDown, LucideChevronUp, LucideOrbit, LucideToyBrick } from 'lucide-react';
import isEqual from 'fast-deep-equal';
import {
LucideBug,
LucideBugOff,
LucideChevronDown,
LucideChevronUp,
LucideToyBrick,
} from 'lucide-react';
import { memo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Flexbox } from 'react-layout-kit';
@@ -33,14 +40,14 @@ const Inspector = memo<InspectorProps>(
setShow,
content,
id = 'unknown',
type,
// type,
}) => {
const { t } = useTranslation('plugin');
const { styles } = useStyles();
const [open, setOpen] = useState(false);
const item = usePluginStore(pluginSelectors.getPluginMetaById(id));
const item = usePluginStore(pluginSelectors.getPluginMetaById(id), isEqual);
const showRightAction = usePluginStore(pluginSelectors.hasPluginUI(id));
const pluginAvatar = pluginHelpers.getPluginAvatar(item?.meta);
const pluginTitle = pluginHelpers.getPluginTitle(item?.meta);
@@ -62,31 +69,32 @@ const Inspector = memo<InspectorProps>(
gap={8}
horizontal
onClick={() => {
setOpen(!open);
setShow?.(!showRender);
}}
>
{loading ? (
<div>
<LoadingOutlined />
<Loading3QuartersOutlined spin />
</div>
) : (
avatar
)}
{pluginTitle ?? t('plugins.unknown')}
<Icon icon={open ? LucideChevronUp : LucideChevronDown} />
{showRightAction && <Icon icon={showRender ? LucideChevronUp : LucideChevronDown} />}
</Flexbox>
<Flexbox horizontal>
{type === 'standalone' && <ActionIcon icon={LucideOrbit} />}
<Settings id={id} />
{setShow && (
{
<Flexbox horizontal>
{/*{type === 'standalone' && <ActionIcon icon={LucideOrbit} />}*/}
<ActionIcon
icon={showRender ? LucideChevronUp : LucideChevronDown}
icon={open ? LucideBugOff : LucideBug}
onClick={() => {
setShow(!showRender);
setOpen(!open);
}}
title={t(open ? 'debug.off' : 'debug.on')}
/>
)}
</Flexbox>
<Settings id={id} />
</Flexbox>
}
</Flexbox>
{open && (
<Tabs
@@ -6,6 +6,7 @@ export const useStyles = createStyles(({ css, token }) => ({
width: fit-content;
padding: 6px 8px;
padding-inline-end: 12px;
color: ${token.colorText};
@@ -1,5 +1,5 @@
import { Loading3QuartersOutlined } from '@ant-design/icons';
import { Skeleton } from 'antd';
import { createStyles } from 'antd-style';
import dynamic from 'next/dynamic';
import { Suspense, memo, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
@@ -11,6 +11,60 @@ import IFrameRender from './IFrameRender';
const SystemJsRender = dynamic(() => import('./SystemJsRender'), { ssr: false });
const useStyles = createStyles(
({ css, token }) => css`
position: relative;
overflow: hidden;
display: block;
width: 300px;
height: 12px;
border: 1px solid ${token.colorBorder};
border-radius: 10px;
&::after {
content: '';
position: absolute;
top: 0;
left: 0;
box-sizing: border-box;
width: 40%;
height: 100%;
background: ${token.colorPrimary};
animation: animloader 2s linear infinite;
}
@keyframes animloader {
0% {
left: 0;
transform: translateX(-100%);
}
100% {
left: 100%;
transform: translateX(0%);
}
}
`,
);
const Loading = () => {
const { t } = useTranslation('plugin');
const { styles } = useStyles();
return (
<Flexbox align={'center'} gap={8} padding={16}>
<span className={styles} />
{t('loading.content')}
</Flexbox>
);
};
export interface PluginDefaultTypeProps {
content: string;
loading?: boolean;
@@ -18,8 +72,6 @@ export interface PluginDefaultTypeProps {
}
const PluginDefaultType = memo<PluginDefaultTypeProps>(({ content, name }) => {
const { t } = useTranslation('plugin');
const manifest = usePluginStore((s) => s.pluginManifestMap[name || '']);
let isJSON = true;
try {
@@ -32,11 +84,8 @@ const PluginDefaultType = memo<PluginDefaultTypeProps>(({ content, name }) => {
if (!isJSON) {
return (
<Flexbox gap={8} horizontal>
<div>
<Loading3QuartersOutlined spin />
</div>
{t('loading.content')}
<Flexbox gap={8}>
<Loading />
</Flexbox>
);
}
@@ -49,7 +98,7 @@ const PluginDefaultType = memo<PluginDefaultTypeProps>(({ content, name }) => {
if (ui.mode === 'module')
return (
<Suspense fallback={<Skeleton active style={{ width: 300 }} />}>
<Suspense fallback={<Skeleton active style={{ width: 400 }} />}>
<SystemJsRender content={contentObj} name={name || 'unknown'} url={ui.url} />
</Suspense>
);
+3 -2
View File
@@ -2,6 +2,8 @@ export default {
debug: {
arguments: '调用参数',
function_call: '函数调用',
off: '关闭调试',
on: '查看插件调用信息',
response: '返回结果',
},
dev: {
@@ -88,10 +90,9 @@ export default {
},
},
loading: {
content: '数据获取中...',
content: '调用插件中...',
plugin: '插件运行中...',
},
pluginList: '插件列表',
plugins: {
unknown: '插件检测中...',
+7
View File
@@ -70,6 +70,12 @@ const displayPluginList = (s: PluginStoreState) =>
title: pluginHelpers.getPluginTitle(p.meta),
}));
const hasPluginUI = (id: string) => (s: PluginStoreState) => {
const manifest = getPluginManifestById(id)(s);
return !!manifest?.ui;
};
export const pluginSelectors = {
displayPluginList,
enabledSchema,
@@ -78,6 +84,7 @@ export const pluginSelectors = {
getPluginManifestLoadingStatus,
getPluginMetaById,
getPluginSettingsById,
hasPluginUI,
isCustomPlugin,
pluginList,
};