mirror of
https://github.com/lobehub/lobehub.git
synced 2026-03-27 13:29:15 +07:00
💄 style: update share style (#11716)
* style: update share style * style: update share style * style: update share style * style: update share style
This commit is contained in:
@@ -3,7 +3,8 @@
|
||||
import { EDITOR_DEBOUNCE_TIME } from '@lobechat/const';
|
||||
import { ActionIcon, Flexbox } from '@lobehub/ui';
|
||||
import { useDebounceFn } from 'ahooks';
|
||||
import { App, Empty, message } from 'antd';
|
||||
import { App, message } from 'antd';
|
||||
import { Empty } from '@lobehub/ui';
|
||||
import dayjs, { type Dayjs } from 'dayjs';
|
||||
import { Trash2 } from 'lucide-react';
|
||||
import { memo, useCallback, useEffect, useRef, useState, useSyncExternalStore } from 'react';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { Flexbox } from '@lobehub/ui';
|
||||
import { createStyles } from 'antd-style';
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
import { Crown, Users } from 'lucide-react';
|
||||
import { memo, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -17,7 +17,7 @@ import { systemStatusSelectors } from '@/store/global/selectors';
|
||||
import AgentBuilderToggle from './AgentBuilderToggle';
|
||||
import ChromeTabs, { type ChromeTabItem } from './ChromeTabs';
|
||||
|
||||
const useStyles = createStyles(({ css, token }) => ({
|
||||
const styles = createStaticStyles(({ css, cssVar }) => ({
|
||||
header: css`
|
||||
overflow: hidden;
|
||||
flex: none;
|
||||
@@ -26,7 +26,7 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
height: 44px;
|
||||
padding-block: 8px;
|
||||
padding-inline: 12px;
|
||||
border-block-end: 1px solid ${token.colorBorderSecondary};
|
||||
border-block-end: 1px solid ${cssVar.colorBorderSecondary};
|
||||
`,
|
||||
tabsWrapper: css`
|
||||
scrollbar-width: none;
|
||||
@@ -42,7 +42,6 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
|
||||
const Header = memo(() => {
|
||||
const { t } = useTranslation('chat');
|
||||
const { styles } = useStyles();
|
||||
|
||||
const [showAddModal, setShowAddModal] = useState(false);
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { getKlavisServerByServerIdentifier, getLobehubSkillProviderById } from '@lobechat/const';
|
||||
import { Avatar, Flexbox, Icon } from '@lobehub/ui';
|
||||
import { createStyles } from 'antd-style';
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
import { Blocks } from 'lucide-react';
|
||||
import { type ReactNode, createElement, memo, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -11,7 +11,7 @@ import SkillStore from '@/features/SkillStore';
|
||||
import { serverConfigSelectors, useServerConfigStore } from '@/store/serverConfig';
|
||||
import { useToolStore } from '@/store/tool';
|
||||
|
||||
const useStyles = createStyles(({ css, token }) => ({
|
||||
const styles = createStaticStyles(({ css, cssVar }) => ({
|
||||
banner: css`
|
||||
cursor: pointer;
|
||||
|
||||
@@ -28,24 +28,24 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
margin-block-end: 6px;
|
||||
padding-block: 42px 10px;
|
||||
padding-inline: 16px;
|
||||
border: 1px solid ${token.colorBorderSecondary};
|
||||
border: 1px solid ${cssVar.colorBorderSecondary};
|
||||
border-radius: 20px;
|
||||
|
||||
background: ${token.colorFillQuaternary};
|
||||
background: ${cssVar.colorFillQuaternary};
|
||||
box-shadow: 0 12px 32px rgb(0 0 0 / 4%);
|
||||
|
||||
transition: background 0.2s ease-in-out;
|
||||
|
||||
&:hover {
|
||||
background: ${token.colorFillQuaternary};
|
||||
background: ${cssVar.colorFillQuaternary};
|
||||
}
|
||||
`,
|
||||
icon: css`
|
||||
color: ${token.colorTextSecondary};
|
||||
color: ${cssVar.colorTextSecondary};
|
||||
`,
|
||||
text: css`
|
||||
font-size: 13px;
|
||||
color: ${token.colorTextSecondary};
|
||||
color: ${cssVar.colorTextSecondary};
|
||||
`,
|
||||
}));
|
||||
|
||||
@@ -60,7 +60,6 @@ const BANNER_SKILL_IDS = [
|
||||
] as const;
|
||||
|
||||
const SkillInstallBanner = memo(() => {
|
||||
const { styles } = useStyles();
|
||||
const { t } = useTranslation('plugin');
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
'use client';
|
||||
|
||||
import { isDesktop } from '@lobechat/const';
|
||||
import { Flexbox, FormGroup, Text } from '@lobehub/ui';
|
||||
import { Skeleton as AntSkeleton, Divider } from 'antd';
|
||||
import { Flexbox, FormGroup, Skeleton, Text } from '@lobehub/ui';
|
||||
import { Divider } from 'antd';
|
||||
import { useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@@ -28,20 +28,20 @@ const SkeletonRow = ({ mobile }: { mobile?: boolean }) => {
|
||||
return (
|
||||
<Flexbox gap={12} style={rowStyle}>
|
||||
<Flexbox align="center" horizontal justify="space-between">
|
||||
<AntSkeleton.Input active size="small" style={{ height: 22, width: 60 }} />
|
||||
<AntSkeleton.Input active size="small" style={{ height: 22, width: 80 }} />
|
||||
<Skeleton.Button active size="small" style={{ height: 22, width: 60 }} />
|
||||
<Skeleton.Button active size="small" style={{ height: 22, width: 80 }} />
|
||||
</Flexbox>
|
||||
<AntSkeleton.Input active size="small" style={{ height: 22, width: 120 }} />
|
||||
<Skeleton.Button active size="small" style={{ height: 22, width: 120 }} />
|
||||
</Flexbox>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Flexbox align="center" gap={24} horizontal justify="space-between" style={rowStyle}>
|
||||
<Flexbox align="center" gap={24} horizontal style={{ flex: 1 }}>
|
||||
<AntSkeleton.Input active size="small" style={{ ...labelStyle, height: 22 }} />
|
||||
<AntSkeleton.Input active size="small" style={{ height: 22, minWidth: 120, width: 160 }} />
|
||||
<Skeleton.Button active size="small" style={{ ...labelStyle, height: 22 }} />
|
||||
<Skeleton.Button active size="small" style={{ height: 22, minWidth: 120, width: 160 }} />
|
||||
</Flexbox>
|
||||
<AntSkeleton.Input active size="small" style={{ height: 22, width: 100 }} />
|
||||
<Skeleton.Button active size="small" style={{ height: 22, width: 100 }} />
|
||||
</Flexbox>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -394,7 +394,6 @@ const ProviderConfig = memo<ProviderConfigProps>(
|
||||
),
|
||||
desc: t('providerModels.config.checker.desc'),
|
||||
label: t('providerModels.config.checker.title'),
|
||||
minWidth: undefined,
|
||||
}
|
||||
: undefined,
|
||||
showAceGcm && aceGcmItem,
|
||||
|
||||
@@ -64,7 +64,6 @@ const Actions = memo<ActionsProps>(({ identifier, type, isMCP }) => {
|
||||
setSettingsOpen(true);
|
||||
}
|
||||
}}
|
||||
type="default"
|
||||
>
|
||||
{t('store.actions.configure')}
|
||||
</Button>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { type KlavisServerType } from '@lobechat/const';
|
||||
import { ActionIcon, Avatar, DropdownMenu, Flexbox, Icon } from '@lobehub/ui';
|
||||
import { App, Button } from 'antd';
|
||||
import { createStyles, cssVar } from 'antd-style';
|
||||
import { createStaticStyles, cssVar } from 'antd-style';
|
||||
import { Loader2, MoreVerticalIcon, SquareArrowOutUpRight, Unplug } from 'lucide-react';
|
||||
import { memo, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -17,10 +17,10 @@ import { userProfileSelectors } from '@/store/user/selectors';
|
||||
const POLL_INTERVAL_MS = 1000;
|
||||
const POLL_TIMEOUT_MS = 15_000;
|
||||
|
||||
const useStyles = createStyles(({ css, token }) => ({
|
||||
const styles = createStaticStyles(({ css, cssVar }) => ({
|
||||
connected: css`
|
||||
font-size: 14px;
|
||||
color: ${token.colorSuccess};
|
||||
color: ${cssVar.colorSuccess};
|
||||
`,
|
||||
container: css`
|
||||
padding-block: 12px;
|
||||
@@ -28,11 +28,11 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
`,
|
||||
disconnected: css`
|
||||
font-size: 14px;
|
||||
color: ${token.colorTextTertiary};
|
||||
color: ${cssVar.colorTextTertiary};
|
||||
`,
|
||||
error: css`
|
||||
font-size: 14px;
|
||||
color: ${token.colorError};
|
||||
color: ${cssVar.colorError};
|
||||
`,
|
||||
icon: css`
|
||||
display: flex;
|
||||
@@ -44,20 +44,20 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
height: 48px;
|
||||
border-radius: 12px;
|
||||
|
||||
background: ${token.colorFillTertiary};
|
||||
background: ${cssVar.colorFillTertiary};
|
||||
`,
|
||||
pending: css`
|
||||
font-size: 14px;
|
||||
color: ${token.colorWarning};
|
||||
color: ${cssVar.colorWarning};
|
||||
`,
|
||||
title: css`
|
||||
cursor: pointer;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: ${token.colorText};
|
||||
color: ${cssVar.colorText};
|
||||
|
||||
&:hover {
|
||||
color: ${token.colorPrimary};
|
||||
color: ${cssVar.colorPrimary};
|
||||
}
|
||||
`,
|
||||
}));
|
||||
@@ -69,7 +69,6 @@ interface KlavisSkillItemProps {
|
||||
|
||||
const KlavisSkillItem = memo<KlavisSkillItemProps>(({ serverType, server }) => {
|
||||
const { t } = useTranslation('setting');
|
||||
const { styles } = useStyles();
|
||||
const { modal } = App.useApp();
|
||||
const [isConnecting, setIsConnecting] = useState(false);
|
||||
const [isWaitingAuth, setIsWaitingAuth] = useState(false);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { type LobehubSkillProviderType } from '@lobechat/const';
|
||||
import { ActionIcon, Avatar, DropdownMenu, Flexbox, Icon } from '@lobehub/ui';
|
||||
import { App, Button } from 'antd';
|
||||
import { createStyles, cssVar } from 'antd-style';
|
||||
import { createStaticStyles, cssVar } from 'antd-style';
|
||||
import { Loader2, MoreVerticalIcon, SquareArrowOutUpRight, Unplug } from 'lucide-react';
|
||||
import { memo, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -18,10 +18,10 @@ import {
|
||||
const POLL_INTERVAL_MS = 1000;
|
||||
const POLL_TIMEOUT_MS = 15_000;
|
||||
|
||||
const useStyles = createStyles(({ css, token }) => ({
|
||||
const styles = createStaticStyles(({ css, cssVar }) => ({
|
||||
connected: css`
|
||||
font-size: 14px;
|
||||
color: ${token.colorSuccess};
|
||||
color: ${cssVar.colorSuccess};
|
||||
`,
|
||||
container: css`
|
||||
padding-block: 12px;
|
||||
@@ -29,17 +29,17 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
`,
|
||||
disconnected: css`
|
||||
font-size: 14px;
|
||||
color: ${token.colorTextTertiary};
|
||||
color: ${cssVar.colorTextTertiary};
|
||||
`,
|
||||
disconnectedIcon: css`
|
||||
opacity: 0.5;
|
||||
`,
|
||||
disconnectedTitle: css`
|
||||
color: ${token.colorTextTertiary};
|
||||
color: ${cssVar.colorTextTertiary};
|
||||
`,
|
||||
error: css`
|
||||
font-size: 14px;
|
||||
color: ${token.colorError};
|
||||
color: ${cssVar.colorError};
|
||||
`,
|
||||
icon: css`
|
||||
display: flex;
|
||||
@@ -51,16 +51,16 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
height: 48px;
|
||||
border-radius: 12px;
|
||||
|
||||
background: ${token.colorFillTertiary};
|
||||
background: ${cssVar.colorFillTertiary};
|
||||
`,
|
||||
title: css`
|
||||
cursor: pointer;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: ${token.colorText};
|
||||
color: ${cssVar.colorText};
|
||||
|
||||
&:hover {
|
||||
color: ${token.colorPrimary};
|
||||
color: ${cssVar.colorPrimary};
|
||||
}
|
||||
`,
|
||||
}));
|
||||
@@ -72,7 +72,6 @@ interface LobehubSkillItemProps {
|
||||
|
||||
const LobehubSkillItem = memo<LobehubSkillItemProps>(({ provider, server }) => {
|
||||
const { t } = useTranslation('setting');
|
||||
const { styles } = useStyles();
|
||||
const { modal } = App.useApp();
|
||||
const [isConnecting, setIsConnecting] = useState(false);
|
||||
const [isWaitingAuth, setIsWaitingAuth] = useState(false);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { Block, Flexbox, Modal } from '@lobehub/ui';
|
||||
import { createStyles } from 'antd-style';
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
import { memo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@@ -15,7 +15,7 @@ import { type LobeToolType } from '@/types/tool/tool';
|
||||
|
||||
import Actions from './Actions';
|
||||
|
||||
const useStyles = createStyles(({ css, token }) => ({
|
||||
const styles = createStaticStyles(({ css, cssVar }) => ({
|
||||
container: css`
|
||||
padding-block: 12px;
|
||||
padding-inline: 0;
|
||||
@@ -33,10 +33,10 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
cursor: pointer;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: ${token.colorText};
|
||||
color: ${cssVar.colorText};
|
||||
|
||||
&:hover {
|
||||
color: ${token.colorPrimary};
|
||||
color: ${cssVar.colorPrimary};
|
||||
}
|
||||
`,
|
||||
}));
|
||||
@@ -52,7 +52,6 @@ interface McpSkillItemProps {
|
||||
|
||||
const McpSkillItem = memo<McpSkillItemProps>(
|
||||
({ identifier, title, avatar, type, runtimeType, author }) => {
|
||||
const { styles } = useStyles();
|
||||
const { t } = useTranslation('plugin');
|
||||
const isMCP = runtimeType === 'mcp';
|
||||
const isCustomPlugin = type === 'customPlugin';
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
getLobehubSkillProviderById,
|
||||
} from '@lobechat/const';
|
||||
import { Divider } from 'antd';
|
||||
import { createStyles } from 'antd-style';
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
import isEqual from 'fast-deep-equal';
|
||||
import { memo, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -33,7 +33,7 @@ import McpSkillItem from './McpSkillItem';
|
||||
import KlavisSkillItem from './KlavisSkillItem';
|
||||
import LobehubSkillItem from './LobehubSkillItem';
|
||||
|
||||
const useStyles = createStyles(({ css, token }) => ({
|
||||
const styles = createStaticStyles(({ css, cssVar }) => ({
|
||||
container: css`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -41,18 +41,17 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
`,
|
||||
description: css`
|
||||
margin-block-end: 8px;
|
||||
color: ${token.colorTextSecondary};
|
||||
color: ${cssVar.colorTextSecondary};
|
||||
`,
|
||||
empty: css`
|
||||
padding: 24px;
|
||||
color: ${token.colorTextTertiary};
|
||||
color: ${cssVar.colorTextTertiary};
|
||||
text-align: center;
|
||||
`,
|
||||
}));
|
||||
|
||||
const SkillList = memo(() => {
|
||||
const { t } = useTranslation('setting');
|
||||
const { styles } = useStyles();
|
||||
|
||||
const isLobehubSkillEnabled = useServerConfigStore(serverConfigSelectors.enableLobehubSkill);
|
||||
const isKlavisEnabled = useServerConfigStore(serverConfigSelectors.enableKlavis);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
'use client';
|
||||
|
||||
import { Flexbox } from '@lobehub/ui';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
|
||||
import { ChatList, ConversationProvider, MessageItem } from '@/features/Conversation';
|
||||
@@ -44,9 +43,7 @@ const SharedMessageList = memo<SharedMessageListProps>(({ agentId, groupId, shar
|
||||
replaceMessages(messages, { context: ctx });
|
||||
}}
|
||||
>
|
||||
<Flexbox flex={1}>
|
||||
<ChatList disableActionsBar itemContent={itemContent} />
|
||||
</Flexbox>
|
||||
<ChatList disableActionsBar itemContent={itemContent} />
|
||||
</ConversationProvider>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,52 +1,27 @@
|
||||
'use client';
|
||||
|
||||
import { Avatar, Flexbox } from '@lobehub/ui';
|
||||
import { Typography } from 'antd';
|
||||
import { createStyles, cssVar } from 'antd-style';
|
||||
import { Alert, Center, Flexbox, Text } from '@lobehub/ui';
|
||||
import { cx } from 'antd-style';
|
||||
import NextLink from 'next/link';
|
||||
import { PropsWithChildren, memo, useEffect, useMemo } from 'react';
|
||||
import { PropsWithChildren, memo, useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Link, Outlet, useParams } from 'react-router-dom';
|
||||
import useSWR from 'swr';
|
||||
|
||||
import { ProductLogo } from '@/components/Branding';
|
||||
import { DEFAULT_AVATAR } from '@/const/meta';
|
||||
import GroupAvatar from '@/features/GroupAvatar';
|
||||
import UserAvatar from '@/features/User/UserAvatar';
|
||||
import { useIsDark } from '@/hooks/useIsDark';
|
||||
import { lambdaClient } from '@/libs/trpc/client';
|
||||
import { useAgentStore } from '@/store/agent';
|
||||
import { useUserStore } from '@/store/user';
|
||||
import { authSelectors } from '@/store/user/slices/auth/selectors';
|
||||
|
||||
import SharePortal from '../features/Portal';
|
||||
|
||||
const useStyles = createStyles(({ css, token }) => ({
|
||||
container: css`
|
||||
width: 100vw;
|
||||
min-height: 100vh;
|
||||
background: ${token.colorBgLayout};
|
||||
`,
|
||||
content: css`
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
padding-block: 24px;
|
||||
padding-inline: 24px;
|
||||
`,
|
||||
footer: css`
|
||||
padding-block: 16px;
|
||||
padding-inline: 24px;
|
||||
color: ${token.colorTextTertiary};
|
||||
text-align: center;
|
||||
`,
|
||||
header: css`
|
||||
height: 52px;
|
||||
padding: 8px;
|
||||
`,
|
||||
}));
|
||||
import { styles } from './style';
|
||||
|
||||
const ShareTopicLayout = memo<PropsWithChildren>(({ children }) => {
|
||||
const { styles } = useStyles();
|
||||
const { t } = useTranslation('chat');
|
||||
const isDarkMode = useIsDark();
|
||||
const { id } = useParams<{ id: string }>();
|
||||
const dispatchAgentMap = useAgentStore((s) => s.internal_dispatchAgentMap);
|
||||
const isLogin = useUserStore(authSelectors.isLogin);
|
||||
@@ -69,100 +44,51 @@ const ShareTopicLayout = memo<PropsWithChildren>(({ children }) => {
|
||||
}
|
||||
}, [data?.agentId, data?.agentMeta, dispatchAgentMap]);
|
||||
|
||||
const isGroup = !!data?.groupId;
|
||||
const isInboxAgent = !isGroup && data?.agentMeta?.slug === 'inbox';
|
||||
const agentOrGroupTitle =
|
||||
data?.groupMeta?.title || (isInboxAgent ? 'LobeAI' : data?.agentMeta?.title);
|
||||
const agentMarketIdentifier = data?.agentMeta?.marketIdentifier;
|
||||
|
||||
// Build group avatars for GroupAvatar component
|
||||
const groupAvatars = useMemo(() => {
|
||||
if (!isGroup || !data?.groupMeta?.members) return [];
|
||||
return data.groupMeta.members.map((member) => ({
|
||||
avatar: member.avatar || DEFAULT_AVATAR,
|
||||
backgroundColor: member.backgroundColor || undefined,
|
||||
}));
|
||||
}, [isGroup, data?.groupMeta?.members]);
|
||||
|
||||
const renderAgentOrGroupAvatar = () => {
|
||||
// For group: use GroupAvatar with members
|
||||
if (isGroup && groupAvatars.length > 0) {
|
||||
return <GroupAvatar avatars={groupAvatars} size={24} />;
|
||||
}
|
||||
|
||||
// For inbox agent: skip avatar as it's the same as product icon
|
||||
if (isInboxAgent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// For agent: use single Avatar
|
||||
if (data?.agentMeta?.avatar) {
|
||||
return (
|
||||
<Avatar
|
||||
avatar={data.agentMeta.avatar}
|
||||
background={data.agentMeta.backgroundColor || cssVar.colorFillTertiary}
|
||||
shape="square"
|
||||
size={24}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const renderAgentOrGroupTitle = () => {
|
||||
if (!agentOrGroupTitle) return null;
|
||||
|
||||
// If agent has marketIdentifier, render as link to assistant page
|
||||
if (agentMarketIdentifier && !data?.groupMeta?.title) {
|
||||
return (
|
||||
<a href={`/community/agent/${agentMarketIdentifier}`} rel="noreferrer" target="_blank">
|
||||
<Typography.Text ellipsis strong>
|
||||
{agentOrGroupTitle}
|
||||
</Typography.Text>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Typography.Text ellipsis strong>
|
||||
{agentOrGroupTitle}
|
||||
</Typography.Text>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Flexbox className={styles.container}>
|
||||
<Flexbox align="center" className={styles.header} gap={12} horizontal justify="space-between">
|
||||
<Flexbox align="center" flex={1} gap={12} horizontal>
|
||||
{isLogin ? (
|
||||
<Link to="/">
|
||||
<ProductLogo size={24} />
|
||||
</Link>
|
||||
) : (
|
||||
<NextLink href="/login">
|
||||
<ProductLogo size={24} />
|
||||
</NextLink>
|
||||
)}
|
||||
{renderAgentOrGroupAvatar()}
|
||||
{renderAgentOrGroupTitle()}
|
||||
<Flexbox className={styles.outerContainer} height={'100%'} padding={8} width={'100%'}>
|
||||
<Flexbox
|
||||
className={cx(isDarkMode ? styles.innerContainerDark : styles.innerContainerLight)}
|
||||
height={'100%'}
|
||||
width={'100%'}
|
||||
>
|
||||
<Flexbox
|
||||
align={'center'}
|
||||
gap={8}
|
||||
horizontal
|
||||
justify={'space-between'}
|
||||
padding={8}
|
||||
width={'100%'}
|
||||
>
|
||||
<Flexbox align="center" flex={1} gap={12} horizontal>
|
||||
{isLogin ? (
|
||||
<Link to="/">
|
||||
<UserAvatar size={32} />
|
||||
</Link>
|
||||
) : (
|
||||
<NextLink href="/login">
|
||||
<ProductLogo size={32} />
|
||||
</NextLink>
|
||||
)}
|
||||
</Flexbox>
|
||||
<Center flex={2} gap={12} horizontal>
|
||||
{data?.title && (
|
||||
<Text align={'center'} ellipsis style={{ textAlign: 'center' }} weight={500}>
|
||||
{data.title}
|
||||
</Text>
|
||||
)}
|
||||
</Center>
|
||||
<Flexbox align="center" flex={1} gap={12} horizontal justify={'flex-end'} />
|
||||
</Flexbox>
|
||||
{data?.title && (
|
||||
<Typography.Text ellipsis strong style={{ textAlign: 'center' }}>
|
||||
{data.title}
|
||||
</Typography.Text>
|
||||
)}
|
||||
<Flexbox align="center" flex={1} horizontal justify="flex-end">
|
||||
{isLogin && <UserAvatar size={24} />}
|
||||
<Flexbox className={styles.content} horizontal style={{ overflow: 'hidden' }}>
|
||||
<Flexbox flex={1} style={{ overflow: 'hidden' }}>
|
||||
{children ?? <Outlet />}
|
||||
</Flexbox>
|
||||
<SharePortal />
|
||||
</Flexbox>
|
||||
<Center padding={8} style={{ opacity: 0.25 }}>
|
||||
<Alert title={t('sharePageDisclaimer')} type={'secondary'} variant={'borderless'} />
|
||||
</Center>
|
||||
</Flexbox>
|
||||
<Flexbox className={styles.content} horizontal style={{ overflow: 'hidden' }}>
|
||||
<Flexbox flex={1} style={{ overflow: 'hidden' }}>
|
||||
{children ?? <Outlet />}
|
||||
</Flexbox>
|
||||
<SharePortal />
|
||||
</Flexbox>
|
||||
<Typography.Text className={styles.footer}>{t('sharePageDisclaimer')}</Typography.Text>
|
||||
</Flexbox>
|
||||
);
|
||||
});
|
||||
|
||||
59
src/app/[variants]/share/t/[id]/_layout/style.ts
Normal file
59
src/app/[variants]/share/t/[id]/_layout/style.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
|
||||
export const styles = createStaticStyles(({ css, cssVar }) => ({
|
||||
container: css`
|
||||
width: 100vw;
|
||||
min-height: 100vh;
|
||||
background: ${cssVar.colorBgLayout};
|
||||
`,
|
||||
|
||||
content: css`
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
`,
|
||||
|
||||
// Divider 样式
|
||||
divider: css`
|
||||
height: 24px;
|
||||
`,
|
||||
|
||||
footer: css`
|
||||
padding-block: 16px;
|
||||
padding-inline: 24px;
|
||||
color: ${cssVar.colorTextTertiary};
|
||||
text-align: center;
|
||||
`,
|
||||
|
||||
header: css`
|
||||
height: 52px;
|
||||
padding: 8px;
|
||||
`,
|
||||
|
||||
// 内层容器 - 深色模式
|
||||
innerContainerDark: css`
|
||||
position: relative;
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
border: 1px solid ${cssVar.colorBorderSecondary};
|
||||
border-radius: ${cssVar.borderRadius};
|
||||
|
||||
background: ${cssVar.colorBgContainer};
|
||||
`,
|
||||
|
||||
// 内层容器 - 浅色模式
|
||||
innerContainerLight: css`
|
||||
position: relative;
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
border: 1px solid ${cssVar.colorBorder};
|
||||
border-radius: ${cssVar.borderRadius};
|
||||
|
||||
background: ${cssVar.colorBgContainer};
|
||||
`,
|
||||
// 外层容器
|
||||
outerContainer: css`
|
||||
position: relative;
|
||||
`,
|
||||
}));
|
||||
@@ -1,7 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { DraggablePanel } from '@lobehub/ui';
|
||||
import { createStyles } from 'antd-style';
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
import { memo } from 'react';
|
||||
|
||||
import { CHAT_PORTAL_TOOL_UI_WIDTH } from '@/const/layoutTokens';
|
||||
@@ -9,7 +9,7 @@ import { PortalContent } from '@/features/Portal/router';
|
||||
import { useChatStore } from '@/store/chat';
|
||||
import { chatPortalSelectors } from '@/store/chat/selectors';
|
||||
|
||||
const useStyles = createStyles(({ css, token }) => ({
|
||||
const styles = createStaticStyles(({ cssVar, css }) => ({
|
||||
body: css`
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
@@ -30,17 +30,16 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
min-height: 100%;
|
||||
max-height: 100%;
|
||||
|
||||
background: ${token.colorBgContainer};
|
||||
background: ${cssVar.colorBgContainer};
|
||||
`,
|
||||
drawer: css`
|
||||
z-index: 10;
|
||||
height: 100%;
|
||||
background: ${token.colorBgContainer};
|
||||
background: ${cssVar.colorBgContainer};
|
||||
`,
|
||||
}));
|
||||
|
||||
const SharePortal = memo(() => {
|
||||
const { styles } = useStyles();
|
||||
const showPortal = useChatStore(chatPortalSelectors.showPortal);
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,29 +1,27 @@
|
||||
'use client';
|
||||
|
||||
import { Flexbox } from '@lobehub/ui';
|
||||
import { Button, Center } from '@lobehub/ui';
|
||||
import { TRPCClientError } from '@trpc/client';
|
||||
import { Button, Result, Skeleton } from 'antd';
|
||||
import { createStyles } from 'antd-style';
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import useSWR from 'swr';
|
||||
|
||||
import NotFound from '@/components/404';
|
||||
import Loading from '@/components/Loading/BrandTextLoading';
|
||||
import { lambdaClient } from '@/libs/trpc/client';
|
||||
|
||||
import SharedMessageList from './SharedMessageList';
|
||||
|
||||
const useStyles = createStyles(({ css }) => ({
|
||||
container: css`
|
||||
flex: 1;
|
||||
`,
|
||||
const styles = createStaticStyles(({ css }) => ({
|
||||
errorContainer: css`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
min-height: 400px;
|
||||
height: 80vh;
|
||||
padding: 48px;
|
||||
|
||||
text-align: center;
|
||||
@@ -31,7 +29,6 @@ const useStyles = createStyles(({ css }) => ({
|
||||
}));
|
||||
|
||||
const ShareTopicPage = memo(() => {
|
||||
const { styles } = useStyles();
|
||||
const { t } = useTranslation('chat');
|
||||
const { id } = useParams<{ id: string }>();
|
||||
|
||||
@@ -41,12 +38,11 @@ const ShareTopicPage = memo(() => {
|
||||
{ revalidateOnFocus: false },
|
||||
);
|
||||
|
||||
if (isLoading) {
|
||||
if (!error && isLoading) {
|
||||
return (
|
||||
<Flexbox className={styles.container} gap={16}>
|
||||
<Skeleton active paragraph={{ rows: 1 }} title={false} />
|
||||
<Skeleton active paragraph={{ rows: 6 }} />
|
||||
</Flexbox>
|
||||
<Center className={styles.errorContainer}>
|
||||
<Loading debugId="share" />
|
||||
</Center>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -56,56 +52,53 @@ const ShareTopicPage = memo(() => {
|
||||
|
||||
if (errorCode === 'UNAUTHORIZED') {
|
||||
return (
|
||||
<Flexbox className={styles.errorContainer}>
|
||||
<Result
|
||||
<Center className={styles.errorContainer}>
|
||||
<NotFound
|
||||
desc={t('sharePage.error.unauthorized.subtitle')}
|
||||
extra={
|
||||
<Button href="/login" type="primary">
|
||||
{t('sharePage.error.unauthorized.action')}
|
||||
</Button>
|
||||
}
|
||||
status="403"
|
||||
subTitle={t('sharePage.error.unauthorized.subtitle')}
|
||||
status={''}
|
||||
title={t('sharePage.error.unauthorized.title')}
|
||||
/>
|
||||
</Flexbox>
|
||||
</Center>
|
||||
);
|
||||
}
|
||||
|
||||
if (errorCode === 'FORBIDDEN') {
|
||||
return (
|
||||
<Flexbox className={styles.errorContainer}>
|
||||
<Result
|
||||
status="403"
|
||||
subTitle={t('sharePage.error.forbidden.subtitle')}
|
||||
<Center className={styles.errorContainer}>
|
||||
<NotFound
|
||||
desc={t('sharePage.error.forbidden.subtitle')}
|
||||
status={403}
|
||||
title={t('sharePage.error.forbidden.title')}
|
||||
/>
|
||||
</Flexbox>
|
||||
</Center>
|
||||
);
|
||||
}
|
||||
|
||||
// NOT_FOUND or other errors
|
||||
return (
|
||||
<Flexbox className={styles.errorContainer}>
|
||||
<Result
|
||||
status="404"
|
||||
subTitle={t('sharePage.error.notFound.subtitle')}
|
||||
<Center className={styles.errorContainer}>
|
||||
<NotFound
|
||||
desc={t('sharePage.error.notFound.subtitle')}
|
||||
title={t('sharePage.error.notFound.title')}
|
||||
/>
|
||||
</Flexbox>
|
||||
</Center>
|
||||
);
|
||||
}
|
||||
|
||||
if (!data) return null;
|
||||
|
||||
return (
|
||||
<Flexbox className={styles.container}>
|
||||
<SharedMessageList
|
||||
agentId={data.agentId}
|
||||
groupId={data.groupId}
|
||||
shareId={data.shareId}
|
||||
topicId={data.topicId}
|
||||
/>
|
||||
</Flexbox>
|
||||
<SharedMessageList
|
||||
agentId={data.agentId}
|
||||
groupId={data.groupId}
|
||||
shareId={data.shareId}
|
||||
topicId={data.topicId}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
'use client';
|
||||
|
||||
import { Button, Flexbox, FluentEmoji } from '@lobehub/ui';
|
||||
import { memo } from 'react';
|
||||
import { ReactNode, memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { MAX_WIDTH } from '@/const/layoutTokens';
|
||||
|
||||
const NotFound = memo(() => {
|
||||
const NotFound = memo<{
|
||||
desc?: string;
|
||||
extra?: ReactNode;
|
||||
status?: number | string;
|
||||
title?: string;
|
||||
}>(({ extra, status = 404, title, desc }) => {
|
||||
const { t } = useTranslation('error');
|
||||
return (
|
||||
<Flexbox align={'center'} justify={'center'} style={{ minHeight: '100%', width: '100%' }}>
|
||||
@@ -21,20 +26,21 @@ const NotFound = memo(() => {
|
||||
zIndex: 0,
|
||||
}}
|
||||
>
|
||||
404
|
||||
{status}
|
||||
</h1>
|
||||
<FluentEmoji emoji={'👀'} size={64} />
|
||||
<h2 style={{ fontWeight: 'bold', marginTop: '1em', textAlign: 'center' }}>
|
||||
{t('notFound.title')}
|
||||
{title || t('notFound.title')}
|
||||
</h2>
|
||||
<div style={{ lineHeight: '1.8', marginBottom: '2em', textAlign: 'center' }}>
|
||||
<div>{t('notFound.desc')}</div>
|
||||
<div>{desc || t('notFound.desc')}</div>
|
||||
<div style={{ marginTop: '0.5em' }}>{t('notFound.check')}</div>
|
||||
</div>
|
||||
|
||||
<Button onClick={() => (window.location.href = '/')} type={'primary'}>
|
||||
{t('notFound.backHome')}
|
||||
</Button>
|
||||
{extra || (
|
||||
<Button onClick={() => (window.location.href = '/')} type={'primary'}>
|
||||
{t('notFound.backHome')}
|
||||
</Button>
|
||||
)}
|
||||
</Flexbox>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable no-undef */
|
||||
import { Center, Flexbox, Icon } from '@lobehub/ui';
|
||||
import { createStyles } from 'antd-style';
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
import { FileImage, FileText, FileUpIcon } from 'lucide-react';
|
||||
import { memo } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
@@ -11,22 +11,22 @@ import { getContainer, useDragUpload } from './useDragUpload';
|
||||
const BLOCK_SIZE = 64;
|
||||
const ICON_SIZE = { size: 36, strokeWidth: 1.5 };
|
||||
|
||||
const useStyles = createStyles(({ css, token }) => {
|
||||
const styles = createStaticStyles(({ css, cssVar }) => {
|
||||
return {
|
||||
container: css`
|
||||
width: 320px;
|
||||
height: 200px;
|
||||
padding: calc(${token.borderRadiusLG}px + 4px);
|
||||
padding: calc(${cssVar.borderRadiusLG} + 4px);
|
||||
border-radius: 16px;
|
||||
|
||||
background: ${token.geekblue};
|
||||
background: ${cssVar.geekblue};
|
||||
`,
|
||||
content: css`
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 16px;
|
||||
border: 1.5px dashed #fff;
|
||||
border-radius: ${token.borderRadiusLG}px;
|
||||
border-radius: ${cssVar.borderRadiusLG};
|
||||
`,
|
||||
desc: css`
|
||||
font-size: 14px;
|
||||
@@ -34,24 +34,24 @@ const useStyles = createStyles(({ css, token }) => {
|
||||
color: #fff;
|
||||
`,
|
||||
icon: css`
|
||||
border-radius: ${token.borderRadiusLG}px;
|
||||
color: color-mix(in srgb, ${token.geekblue} 95%, black);
|
||||
background: color-mix(in srgb, ${token.geekblue} 38%, white);
|
||||
border-radius: ${cssVar.borderRadiusLG};
|
||||
color: color-mix(in srgb, ${cssVar.geekblue} 95%, black);
|
||||
background: color-mix(in srgb, ${cssVar.geekblue} 38%, white);
|
||||
`,
|
||||
iconGroup: css`
|
||||
margin-block-start: -44px;
|
||||
`,
|
||||
iconLeft: css`
|
||||
transform: rotateZ(-20deg) translateX(10px);
|
||||
border-radius: ${token.borderRadiusLG}px;
|
||||
color: color-mix(in srgb, ${token.geekblue} 95%, black);
|
||||
background: color-mix(in srgb, ${token.geekblue} 68%, white);
|
||||
border-radius: ${cssVar.borderRadiusLG};
|
||||
color: color-mix(in srgb, ${cssVar.geekblue} 95%, black);
|
||||
background: color-mix(in srgb, ${cssVar.geekblue} 68%, white);
|
||||
`,
|
||||
iconRight: css`
|
||||
transform: rotateZ(20deg) translateX(-10px);
|
||||
border-radius: ${token.borderRadiusLG}px;
|
||||
color: color-mix(in srgb, ${token.geekblue} 95%, black);
|
||||
background: color-mix(in srgb, ${token.geekblue} 68%, white);
|
||||
border-radius: ${cssVar.borderRadiusLG};
|
||||
color: color-mix(in srgb, ${cssVar.geekblue} 95%, black);
|
||||
background: color-mix(in srgb, ${cssVar.geekblue} 68%, white);
|
||||
`,
|
||||
title: css`
|
||||
font-size: 20px;
|
||||
@@ -66,7 +66,7 @@ const useStyles = createStyles(({ css, token }) => {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
background: ${token.colorBgMask};
|
||||
background: ${cssVar.colorBgMask};
|
||||
|
||||
transition: all 0.3s ease-in-out;
|
||||
`,
|
||||
@@ -80,7 +80,6 @@ interface DragUploadProps {
|
||||
|
||||
const DragUpload = memo<DragUploadProps>(({ enabledFiles = true, onUploadFiles }) => {
|
||||
const { t } = useTranslation('components');
|
||||
const { styles } = useStyles();
|
||||
|
||||
const isDragging = useDragUpload(onUploadFiles);
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { type IEditor } from '@lobehub/editor';
|
||||
import { Alert } from '@lobehub/ui';
|
||||
import { Skeleton } from 'antd';
|
||||
import { Alert, Skeleton } from '@lobehub/ui';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { createStoreUpdater } from 'zustand-utils';
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
} from '@lobechat/const';
|
||||
import { Flexbox, Icon, Image, Modal, Tag, Text, Typography } from '@lobehub/ui';
|
||||
import { Button, Divider } from 'antd';
|
||||
import { createStyles, cssVar } from 'antd-style';
|
||||
import { createStaticStyles, cssVar } from 'antd-style';
|
||||
import { ExternalLink, Loader2, SquareArrowOutUpRight } from 'lucide-react';
|
||||
import { memo, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -18,7 +18,7 @@ import { klavisStoreSelectors, lobehubSkillStoreSelectors } from '@/store/tool/s
|
||||
import { KlavisServerStatus } from '@/store/tool/slices/klavisStore';
|
||||
import { LobehubSkillStatus } from '@/store/tool/slices/lobehubSkillStore/types';
|
||||
|
||||
const useStyles = createStyles(({ css, token }) => ({
|
||||
const styles = createStaticStyles(({ css, cssVar }) => ({
|
||||
authorLink: css`
|
||||
cursor: pointer;
|
||||
|
||||
@@ -26,7 +26,7 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
gap: 4px;
|
||||
align-items: center;
|
||||
|
||||
color: ${token.colorPrimary};
|
||||
color: ${cssVar.colorPrimary};
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
@@ -39,7 +39,7 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
`,
|
||||
detailLabel: css`
|
||||
font-size: 12px;
|
||||
color: ${token.colorTextTertiary};
|
||||
color: ${cssVar.colorTextTertiary};
|
||||
`,
|
||||
header: css`
|
||||
display: flex;
|
||||
@@ -49,7 +49,7 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
padding: 16px;
|
||||
border-radius: 12px;
|
||||
|
||||
background: ${token.colorFillTertiary};
|
||||
background: ${cssVar.colorFillTertiary};
|
||||
`,
|
||||
icon: css`
|
||||
display: flex;
|
||||
@@ -61,25 +61,25 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
height: 56px;
|
||||
border-radius: 12px;
|
||||
|
||||
background: ${token.colorBgContainer};
|
||||
background: ${cssVar.colorBgContainer};
|
||||
`,
|
||||
introduction: css`
|
||||
font-size: 14px;
|
||||
line-height: 1.8;
|
||||
color: ${token.colorText};
|
||||
color: ${cssVar.colorText};
|
||||
`,
|
||||
sectionTitle: css`
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: ${token.colorText};
|
||||
color: ${cssVar.colorText};
|
||||
`,
|
||||
title: css`
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: ${token.colorText};
|
||||
color: ${cssVar.colorText};
|
||||
`,
|
||||
toolTag: css`
|
||||
font-family: ${token.fontFamilyCode};
|
||||
font-family: ${cssVar.fontFamilyCode};
|
||||
font-size: 12px;
|
||||
`,
|
||||
toolsContainer: css`
|
||||
@@ -90,7 +90,7 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
trustWarning: css`
|
||||
font-size: 12px;
|
||||
line-height: 1.6;
|
||||
color: ${token.colorTextTertiary};
|
||||
color: ${cssVar.colorTextTertiary};
|
||||
`,
|
||||
}));
|
||||
|
||||
@@ -107,7 +107,6 @@ export interface IntegrationDetailModalProps {
|
||||
|
||||
const IntegrationDetailModal = memo<IntegrationDetailModalProps>(
|
||||
({ open, onClose, type, identifier, isConnecting, onConnect }) => {
|
||||
const { styles } = useStyles();
|
||||
const { t } = useTranslation(['plugin', 'setting']);
|
||||
|
||||
// Get static config based on type
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
import { BRANDING_NAME } from '@lobechat/business-const';
|
||||
import { Flexbox } from '@lobehub/ui';
|
||||
import { createStyles, cssVar } from 'antd-style';
|
||||
import { memo, useEffect } from 'react';
|
||||
import { createStaticStyles, useTheme } from 'antd-style';
|
||||
import { memo, useEffect, useMemo } from 'react';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
|
||||
import { useResourceManagerStore } from '@/app/[variants]/(main)/resource/features/store';
|
||||
@@ -19,7 +19,7 @@ import UploadDock from './components/UploadDock';
|
||||
|
||||
const ChunkDrawer = dynamic(() => import('./components/ChunkDrawer'), { ssr: false });
|
||||
|
||||
const useStyles = createStyles(({ css, token }) => {
|
||||
const styles = createStaticStyles(({ css, cssVar }) => {
|
||||
return {
|
||||
container: css`
|
||||
position: relative;
|
||||
@@ -33,7 +33,7 @@ const useStyles = createStyles(({ css, token }) => {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
background-color: ${token.colorBgContainerSecondary};
|
||||
background-color: var(--editor-overlay-bg, ${cssVar.colorBgContainer});
|
||||
`,
|
||||
pageEditorOverlay: css`
|
||||
position: absolute;
|
||||
@@ -56,7 +56,7 @@ export type ResouceManagerMode = 'editor' | 'explorer' | 'page';
|
||||
* Business component, no need be reusable.
|
||||
*/
|
||||
const ResourceManager = memo(() => {
|
||||
const { styles } = useStyles();
|
||||
const theme = useTheme();
|
||||
const [, setSearchParams] = useSearchParams();
|
||||
const [mode, currentViewItemId, libraryId, setMode, setCurrentViewItemId] =
|
||||
useResourceManagerStore((s) => [
|
||||
@@ -69,6 +69,13 @@ const ResourceManager = memo(() => {
|
||||
|
||||
const currentDocument = useFileStore(documentSelectors.getDocumentById(currentViewItemId));
|
||||
|
||||
const cssVariables = useMemo<Record<string, string>>(
|
||||
() => ({
|
||||
'--editor-overlay-bg': theme.colorBgContainerSecondary,
|
||||
}),
|
||||
[theme.colorBgContainerSecondary],
|
||||
);
|
||||
|
||||
// Fetch specific document when switching to page mode if not already loaded
|
||||
useEffect(() => {
|
||||
if (mode === 'page' && currentViewItemId && !currentDocument) {
|
||||
@@ -98,7 +105,7 @@ const ResourceManager = memo(() => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flexbox className={styles.container} height={'100%'}>
|
||||
<Flexbox className={styles.container} height={'100%'} style={cssVariables}>
|
||||
{/* Explorer is always rendered to preserve its state */}
|
||||
<Explorer />
|
||||
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import { ModelTag } from '@lobehub/icons';
|
||||
import { Avatar, Flexbox, Markdown } from '@lobehub/ui';
|
||||
import { ChatHeaderTitle } from '@lobehub/ui/chat';
|
||||
import { Avatar, Flexbox, Markdown, Text } from '@lobehub/ui';
|
||||
import { cx } from 'antd-style';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { ProductLogo } from '@/components/Branding';
|
||||
import PluginTag from '@/features/PluginTag';
|
||||
@@ -19,21 +17,17 @@ import { type FieldType } from './type';
|
||||
|
||||
const Preview = memo<FieldType & { title?: string }>(
|
||||
({ title, withSystemRole, withBackground, withFooter, widthMode }) => {
|
||||
const [model, plugins, systemRole, isInbox, description, avatar, backgroundColor] =
|
||||
useAgentStore((s) => [
|
||||
agentSelectors.currentAgentModel(s),
|
||||
agentSelectors.displayableAgentPlugins(s),
|
||||
agentSelectors.currentAgentSystemRole(s),
|
||||
builtinAgentSelectors.isInboxAgent(s),
|
||||
agentSelectors.currentAgentDescription(s),
|
||||
agentSelectors.currentAgentAvatar(s),
|
||||
agentSelectors.currentAgentBackgroundColor(s),
|
||||
]);
|
||||
|
||||
const { t } = useTranslation('chat');
|
||||
const [model, plugins, systemRole, isInbox, avatar, backgroundColor] = useAgentStore((s) => [
|
||||
agentSelectors.currentAgentModel(s),
|
||||
agentSelectors.displayableAgentPlugins(s),
|
||||
agentSelectors.currentAgentSystemRole(s),
|
||||
builtinAgentSelectors.isInboxAgent(s),
|
||||
agentSelectors.currentAgentDescription(s),
|
||||
agentSelectors.currentAgentAvatar(s),
|
||||
agentSelectors.currentAgentBackgroundColor(s),
|
||||
]);
|
||||
|
||||
const displayTitle = isInbox ? 'Lobe AI' : title;
|
||||
const displayDesc = isInbox ? t('inbox.desc') : description;
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -50,24 +44,21 @@ const Preview = memo<FieldType & { title?: string }>(
|
||||
gap={16}
|
||||
>
|
||||
<div className={styles.header}>
|
||||
<Flexbox align={'flex-start'} gap={12} horizontal>
|
||||
<Flexbox align={'center'} gap={12} horizontal>
|
||||
<Avatar
|
||||
avatar={avatar}
|
||||
background={backgroundColor}
|
||||
shape={'square'}
|
||||
size={40}
|
||||
size={28}
|
||||
title={title}
|
||||
/>
|
||||
<ChatHeaderTitle
|
||||
desc={displayDesc}
|
||||
tag={
|
||||
<Flexbox gap={4} horizontal>
|
||||
<ModelTag model={model} />
|
||||
{plugins?.length > 0 && <PluginTag plugins={plugins} />}
|
||||
</Flexbox>
|
||||
}
|
||||
title={displayTitle}
|
||||
/>
|
||||
<Text fontSize={16} strong>
|
||||
{displayTitle}
|
||||
</Text>
|
||||
<Flexbox gap={4} horizontal>
|
||||
<ModelTag model={model} />
|
||||
{plugins?.length > 0 && <PluginTag plugins={plugins} />}
|
||||
</Flexbox>
|
||||
</Flexbox>
|
||||
{withSystemRole && systemRole && (
|
||||
<div className={styles.role}>
|
||||
|
||||
@@ -12,7 +12,7 @@ export const styles = createStaticStyles(({ css, cssVar }) => ({
|
||||
background-size: 120% 120%;
|
||||
`,
|
||||
container: css`
|
||||
background: ${cssVar.colorBgLayout};
|
||||
background: ${cssVar.colorBgContainer};
|
||||
`,
|
||||
container_withBackground_true: css`
|
||||
overflow: hidden;
|
||||
@@ -25,7 +25,8 @@ export const styles = createStaticStyles(({ css, cssVar }) => ({
|
||||
`,
|
||||
header: css`
|
||||
margin-block-end: -24px;
|
||||
padding: 16px;
|
||||
padding-block: 16px;
|
||||
padding-inline: 24px;
|
||||
border-block-end: 1px solid ${cssVar.colorBorder};
|
||||
background: ${cssVar.colorBgContainer};
|
||||
`,
|
||||
|
||||
@@ -60,7 +60,11 @@ const ShareModal = memo<ModalProps>(({ onCancel, open }) => {
|
||||
title={t('share', { ns: 'common' })}
|
||||
width={'min(90vw, 1024px)'}
|
||||
>
|
||||
<Flexbox gap={isMobile ? 8 : 24} style={{ overflow: 'hidden', position: 'relative' }}>
|
||||
<Flexbox
|
||||
gap={isMobile ? 8 : 24}
|
||||
height={'100%'}
|
||||
style={{ overflow: 'hidden', position: 'relative' }}
|
||||
>
|
||||
<Segmented
|
||||
block
|
||||
onChange={(value) => setTab(value as Tab)}
|
||||
|
||||
@@ -5,6 +5,7 @@ export { styles as containerStyles } from './useContainerStyles';
|
||||
|
||||
export const styles = createStaticStyles(({ css, cssVar }) => ({
|
||||
body: css`
|
||||
height: 100%;
|
||||
${responsive.sm} {
|
||||
padding-block-end: 68px;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ export const styles = createStaticStyles(({ css, cssVar }) => ({
|
||||
border: 1px solid ${cssVar.colorBorder};
|
||||
border-radius: ${cssVar.borderRadiusLG};
|
||||
|
||||
background: ${cssVar.colorBgLayout};
|
||||
background: ${cssVar.colorBgContainer};
|
||||
|
||||
/* stylelint-disable selector-class-pattern */
|
||||
.react-pdf__Document *,
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
'use client';
|
||||
|
||||
import { Button, Flexbox, Popover, copyToClipboard, usePopoverContext } from '@lobehub/ui';
|
||||
import { App, Divider, Select, Skeleton, Typography } from 'antd';
|
||||
import {
|
||||
Button,
|
||||
Flexbox,
|
||||
Popover,
|
||||
Skeleton,
|
||||
Text,
|
||||
copyToClipboard,
|
||||
usePopoverContext,
|
||||
} from '@lobehub/ui';
|
||||
import { App, Divider, Select } from 'antd';
|
||||
import { ExternalLinkIcon, LinkIcon, LockIcon } from 'lucide-react';
|
||||
import { type ReactNode, memo, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -12,7 +20,7 @@ import { useIsMobile } from '@/hooks/useIsMobile';
|
||||
import { topicService } from '@/services/topic';
|
||||
import { useChatStore } from '@/store/chat';
|
||||
|
||||
import { useStyles } from './style';
|
||||
import { styles } from './style';
|
||||
|
||||
type Visibility = 'private' | 'link';
|
||||
|
||||
@@ -23,7 +31,6 @@ interface SharePopoverContentProps {
|
||||
const SharePopoverContent = memo<SharePopoverContentProps>(({ onOpenModal }) => {
|
||||
const { t } = useTranslation('chat');
|
||||
const { message, modal } = App.useApp();
|
||||
const { styles } = useStyles();
|
||||
const [updating, setUpdating] = useState(false);
|
||||
const { close } = usePopoverContext();
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
@@ -103,7 +110,7 @@ const SharePopoverContent = memo<SharePopoverContentProps>(({ onOpenModal }) =>
|
||||
if (isLoading || !shareInfo) {
|
||||
return (
|
||||
<Flexbox className={styles.container} gap={16}>
|
||||
<Typography.Text strong>{t('share', { ns: 'common' })}</Typography.Text>
|
||||
<Text strong>{t('share', { ns: 'common' })}</Text>
|
||||
<Skeleton active paragraph={{ rows: 2 }} />
|
||||
</Flexbox>
|
||||
);
|
||||
@@ -135,10 +142,10 @@ const SharePopoverContent = memo<SharePopoverContentProps>(({ onOpenModal }) =>
|
||||
|
||||
return (
|
||||
<Flexbox className={styles.container} gap={12} ref={containerRef}>
|
||||
<Typography.Text strong>{t('shareModal.popover.title')}</Typography.Text>
|
||||
<Text strong>{t('shareModal.popover.title')}</Text>
|
||||
|
||||
<Flexbox gap={4}>
|
||||
<Typography.Text type="secondary">{t('shareModal.popover.visibility')}</Typography.Text>
|
||||
<Text type="secondary">{t('shareModal.popover.visibility')}</Text>
|
||||
<Select
|
||||
disabled={updating}
|
||||
getPopupContainer={() => containerRef.current || document.body}
|
||||
@@ -164,9 +171,9 @@ const SharePopoverContent = memo<SharePopoverContentProps>(({ onOpenModal }) =>
|
||||
/>
|
||||
</Flexbox>
|
||||
|
||||
<Typography.Text className={styles.hint} type="secondary">
|
||||
<Text className={styles.hint} type="secondary">
|
||||
{getVisibilityHint()}
|
||||
</Typography.Text>
|
||||
</Text>
|
||||
|
||||
<Divider style={{ margin: '4px 0' }} />
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { createStyles } from 'antd-style';
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
|
||||
export const useStyles = createStyles(({ css }) => ({
|
||||
export const styles = createStaticStyles(({ css }) => ({
|
||||
container: css`
|
||||
padding: 16px;
|
||||
`,
|
||||
|
||||
@@ -17,10 +17,10 @@ import { useToolStore } from '@/store/tool';
|
||||
import { mcpStoreSelectors, pluginSelectors } from '@/store/tool/selectors';
|
||||
import { type DiscoverMcpItem } from '@/types/discover';
|
||||
|
||||
import { useItemStyles } from '../style';
|
||||
import { itemStyles } from '../style';
|
||||
|
||||
const Item = memo<DiscoverMcpItem>(({ name, description, icon, identifier }) => {
|
||||
const { styles } = useItemStyles();
|
||||
const styles = itemStyles;
|
||||
const { t } = useTranslation('plugin');
|
||||
const { modal } = App.useApp();
|
||||
const [detailOpen, setDetailOpen] = useState(false);
|
||||
|
||||
@@ -8,7 +8,7 @@ import { Loader2, MoreVerticalIcon, Plus, Unplug } from 'lucide-react';
|
||||
import React, { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { useItemStyles } from '../style';
|
||||
import { itemStyles } from '../style';
|
||||
import { useSkillConnect } from './useSkillConnect';
|
||||
|
||||
interface ItemProps {
|
||||
@@ -25,7 +25,7 @@ interface ItemProps {
|
||||
const Item = memo<ItemProps>(
|
||||
({ description, icon, identifier, label, onOpenDetail, serverName, type }) => {
|
||||
const { t } = useTranslation('setting');
|
||||
const { styles } = useItemStyles();
|
||||
const styles = itemStyles;
|
||||
const { modal } = App.useApp();
|
||||
|
||||
const { handleConnect, handleDisconnect, isConnected, isConnecting } = useSkillConnect({
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { KLAVIS_SERVER_TYPES, LOBEHUB_SKILL_PROVIDERS } from '@lobechat/const';
|
||||
import { createStyles } from 'antd-style';
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
import isEqual from 'fast-deep-equal';
|
||||
import type { Klavis } from 'klavis';
|
||||
import { memo, useMemo, useState } from 'react';
|
||||
@@ -17,7 +17,7 @@ import Empty from '../Empty';
|
||||
import Item from './Item';
|
||||
import { useSkillConnect } from './useSkillConnect';
|
||||
|
||||
const useStyles = createStyles(({ css }) => ({
|
||||
const styles = createStaticStyles(({ css }) => ({
|
||||
grid: css`
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
@@ -69,7 +69,6 @@ const DetailModalWithConnect = memo<DetailModalWithConnectProps>(({ detailState,
|
||||
DetailModalWithConnect.displayName = 'DetailModalWithConnect';
|
||||
|
||||
export const LobeHubList = memo<LobeHubListProps>(({ keywords }) => {
|
||||
const { styles } = useStyles();
|
||||
const [detailState, setDetailState] = useState<DetailState | null>(null);
|
||||
|
||||
const isLobehubSkillEnabled = useServerConfigStore(serverConfigSelectors.enableLobehubSkill);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { createStyles } from 'antd-style';
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
|
||||
export const useItemStyles = createStyles(({ css, token }) => ({
|
||||
export const itemStyles = createStaticStyles(({ css, cssVar }) => ({
|
||||
container: css`
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
@@ -11,7 +11,7 @@ export const useItemStyles = createStyles(({ css, token }) => ({
|
||||
overflow: hidden;
|
||||
|
||||
font-size: 12px;
|
||||
color: ${token.colorTextSecondary};
|
||||
color: ${cssVar.colorTextSecondary};
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
`,
|
||||
@@ -20,7 +20,7 @@ export const useItemStyles = createStyles(({ css, token }) => ({
|
||||
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: ${token.colorText};
|
||||
color: ${cssVar.colorText};
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
`,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
'use client';
|
||||
|
||||
import { Button, Flexbox, Icon } from '@lobehub/ui';
|
||||
import { createStyles } from 'antd-style';
|
||||
import { createStaticStyles, useTheme } from 'antd-style';
|
||||
import { TriangleAlert, X } from 'lucide-react';
|
||||
import { useState } from 'react';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { MANUAL_UPGRADE_URL } from '@/const/url';
|
||||
@@ -12,7 +12,7 @@ import { useElectronStore } from '@/store/electron';
|
||||
import { electronSyncSelectors } from '@/store/electron/selectors';
|
||||
import { useGlobalStore } from '@/store/global';
|
||||
|
||||
const useStyles = createStyles(({ css, token }) => ({
|
||||
const styles = createStaticStyles(({ css, cssVar }) => ({
|
||||
closeButton: css`
|
||||
cursor: pointer;
|
||||
|
||||
@@ -26,15 +26,15 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: ${token.borderRadius}px;
|
||||
border-radius: ${cssVar.borderRadius};
|
||||
|
||||
color: ${token.colorTextSecondary};
|
||||
color: ${cssVar.colorTextSecondary};
|
||||
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover {
|
||||
color: ${token.colorText};
|
||||
background: ${token.colorFillSecondary};
|
||||
color: ${cssVar.colorText};
|
||||
background: ${cssVar.colorFillSecondary};
|
||||
}
|
||||
`,
|
||||
container: css`
|
||||
@@ -46,7 +46,7 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
background: ${token.colorBgMask};
|
||||
background: ${cssVar.colorBgMask};
|
||||
`,
|
||||
content: css`
|
||||
position: relative;
|
||||
@@ -55,47 +55,55 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
|
||||
max-width: 480px;
|
||||
padding: 24px;
|
||||
border: 1px solid ${token.yellowBorder};
|
||||
border-radius: ${token.borderRadiusLG}px;
|
||||
border: 1px solid var(--content-yellow-border, ${cssVar.colorWarningBorder});
|
||||
border-radius: ${cssVar.borderRadiusLG};
|
||||
|
||||
background: ${token.colorBgContainer};
|
||||
box-shadow: ${token.boxShadowSecondary};
|
||||
background: ${cssVar.colorBgContainer};
|
||||
box-shadow: ${cssVar.boxShadowSecondary};
|
||||
`,
|
||||
desc: css`
|
||||
line-height: 1.6;
|
||||
color: ${token.colorTextSecondary};
|
||||
color: ${cssVar.colorTextSecondary};
|
||||
`,
|
||||
title: css`
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: ${token.colorWarningText};
|
||||
color: ${cssVar.colorWarningText};
|
||||
`,
|
||||
titleIcon: css`
|
||||
flex-shrink: 0;
|
||||
color: ${token.colorWarning};
|
||||
color: ${cssVar.colorWarning};
|
||||
`,
|
||||
warning: css`
|
||||
padding: 12px;
|
||||
border-radius: ${token.borderRadius}px;
|
||||
color: ${token.colorWarningText};
|
||||
background: ${token.yellowBg};
|
||||
border-radius: ${cssVar.borderRadius};
|
||||
color: ${cssVar.colorWarningText};
|
||||
background: var(--warning-yellow-bg, ${cssVar.colorWarningBg});
|
||||
`,
|
||||
}));
|
||||
|
||||
const ServerVersionOutdatedAlert = () => {
|
||||
const { styles } = useStyles();
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation('common');
|
||||
const [dismissed, setDismissed] = useState(false);
|
||||
const isServerVersionOutdated = useGlobalStore((s) => s.isServerVersionOutdated);
|
||||
const storageMode = useElectronStore(electronSyncSelectors.storageMode);
|
||||
|
||||
const cssVariables = useMemo<Record<string, string>>(
|
||||
() => ({
|
||||
'--content-yellow-border': theme.yellowBorder,
|
||||
'--warning-yellow-bg': theme.yellowBg,
|
||||
}),
|
||||
[theme.yellowBorder, theme.yellowBg],
|
||||
);
|
||||
|
||||
// Only show alert when using self-hosted server, not cloud
|
||||
if (storageMode !== 'selfHost') return null;
|
||||
if (!isServerVersionOutdated || dismissed) return null;
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.content}>
|
||||
<div className={styles.content} style={cssVariables}>
|
||||
<div className={styles.closeButton} onClick={() => setDismissed(true)}>
|
||||
<Icon icon={X} />
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user