mirror of
https://github.com/lobehub/lobe-chat.git
synced 2026-06-14 03:30:19 +00:00
💄 style: improve plugin message ui
This commit is contained in:
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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: '插件检测中...',
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user