@lobehub/chat 0.46.1 → 0.48.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,56 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ## [Version 0.48.0](https://github.com/lobehub/lobe-chat/compare/v0.47.0...v0.48.0)
6
+
7
+ <sup>Released on **2023-08-15**</sup>
8
+
9
+ #### ✨ Features
10
+
11
+ - **misc**: Import SiOpenai icon and replace 'Tag' component in chat feature.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's improved
19
+
20
+ - **misc**: Import SiOpenai icon and replace 'Tag' component in chat feature ([98b0352](https://github.com/lobehub/lobe-chat/commit/98b0352))
21
+
22
+ </details>
23
+
24
+ <div align="right">
25
+
26
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
27
+
28
+ </div>
29
+
30
+ ## [Version 0.47.0](https://github.com/lobehub/lobe-chat/compare/v0.46.1...v0.47.0)
31
+
32
+ <sup>Released on **2023-08-15**</sup>
33
+
34
+ #### ✨ Features
35
+
36
+ - **misc**: Add and update UI elements and agent configuration.
37
+
38
+ <br/>
39
+
40
+ <details>
41
+ <summary><kbd>Improvements and Fixes</kbd></summary>
42
+
43
+ #### What's improved
44
+
45
+ - **misc**: Add and update UI elements and agent configuration ([eb7fbee](https://github.com/lobehub/lobe-chat/commit/eb7fbee))
46
+
47
+ </details>
48
+
49
+ <div align="right">
50
+
51
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
52
+
53
+ </div>
54
+
5
55
  ### [Version 0.46.1](https://github.com/lobehub/lobe-chat/compare/v0.46.0...v0.46.1)
6
56
 
7
57
  <sup>Released on **2023-08-14**</sup>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "0.46.1",
3
+ "version": "0.48.0",
4
4
  "description": "Lobe Chat is an open-source chatbot client using LangChain, Typescript and Next.js",
5
5
  "keywords": [
6
6
  "chatbot",
package/src/const/meta.ts CHANGED
@@ -4,6 +4,4 @@ export const DEFAULT_AVATAR = '🤖';
4
4
  export const DEFAULT_USER_AVATAR = '😀';
5
5
  export const DEFAULT_BACKGROUND_COLOR = 'rgba(0,0,0,0)';
6
6
  export const DEFAULT_AGENT_META: MetaData = {};
7
-
8
- export const DEFAULT_INBOX_AVATAR =
9
- 'https://npm.elemecdn.com/@lobehub/assets-logo/assets/logo-3d.webp';
7
+ export const DEFAULT_INBOX_AVATAR = '🤯';
@@ -1,11 +1,10 @@
1
- import { Form, ItemGroup } from '@lobehub/ui';
1
+ import { Form, ItemGroup, SliderWithInput } from '@lobehub/ui';
2
2
  import { ConfigProvider, Input, Segmented, Select, Switch } from 'antd';
3
3
  import { useTheme } from 'antd-style';
4
4
  import { debounce } from 'lodash-es';
5
5
  import { BrainCog, MessagesSquare } from 'lucide-react';
6
6
  import { memo, useMemo } from 'react';
7
7
  import { useTranslation } from 'react-i18next';
8
- import SliderWithInput from 'src/components/SliderWithInput';
9
8
 
10
9
  import { FORM_STYLE } from '@/const/layoutTokens';
11
10
  import { AgentAction } from '@/store/session/slices/agentConfig';
@@ -13,11 +13,11 @@ import { AgentAction } from '@/store/session/slices/agentConfig';
13
13
  import { LobeAgentConfig } from '@/types/session';
14
14
 
15
15
  export const useStyles = createStyles(({ css, token }) => ({
16
- input: css`
17
- border: 1px solid ${token.colorBorderSecondary};
18
- `,
19
16
  markdown: css`
20
- border: 1px solid transparent;
17
+ border: unset;
18
+ `,
19
+ textarea: css`
20
+ background: ${token.colorFillTertiary};
21
21
  `,
22
22
  }));
23
23
 
@@ -60,7 +60,7 @@ const AgentPrompt = memo<AgentPromptProps>(({ config, updateConfig }) => {
60
60
  editButtonSize={'small'}
61
61
  editing={editing}
62
62
  height={'auto'}
63
- inputType={'block'}
63
+ inputType={'ghost'}
64
64
  onChange={(e) => {
65
65
  updateConfig({ systemRole: e });
66
66
  }}
@@ -1,4 +1,4 @@
1
- import { ActionIcon, Icon } from '@lobehub/ui';
1
+ import { ActionIcon, DiscordIcon, Icon } from '@lobehub/ui';
2
2
  import { Dropdown, MenuProps, Upload } from 'antd';
3
3
  import {
4
4
  Feather,
@@ -14,7 +14,6 @@ import Router from 'next/router';
14
14
  import { memo, useMemo } from 'react';
15
15
  import { useTranslation } from 'react-i18next';
16
16
 
17
- import DiscordIcon from '@/components/DiscordIcon';
18
17
  import { ABOUT, CHANGELOG, DISCORD, FEEDBACK, GITHUB } from '@/const/url';
19
18
  import { useExportConfig } from '@/hooks/useExportConfig';
20
19
  import { useImportConfig } from '@/hooks/useImportConfig';
@@ -0,0 +1,50 @@
1
+ import { Icon } from '@lobehub/ui';
2
+ import { Collapse, CollapseProps } from 'antd';
3
+ import { createStyles } from 'antd-style';
4
+ import { ChevronDown } from 'lucide-react';
5
+ import { memo } from 'react';
6
+
7
+ const useStyles = createStyles(({ css, prefixCls, token }) => ({
8
+ container: css`
9
+ border-radius: 0;
10
+ .${prefixCls}-collapse-header {
11
+ padding-inline: 16px !important;
12
+ color: ${token.colorTextDescription} !important;
13
+
14
+ &:hover {
15
+ color: ${token.colorText} !important;
16
+ background: ${token.colorFillTertiary};
17
+ }
18
+ }
19
+ .${prefixCls}-collapse-content-box {
20
+ padding: 0 !important;
21
+ }
22
+ `,
23
+ icon: css`
24
+ transition: all 100ms ${token.motionEaseOut};
25
+ `,
26
+ }));
27
+
28
+ const CollapseGroup = memo<CollapseProps>((props) => {
29
+ const { styles } = useStyles();
30
+ return (
31
+ <Collapse
32
+ bordered={false}
33
+ className={styles.container}
34
+ expandIcon={({ isActive }) => (
35
+ <Icon
36
+ className={styles.icon}
37
+ icon={ChevronDown}
38
+ size={{ fontSize: 16 }}
39
+ style={isActive ? {} : { rotate: '-90deg' }}
40
+ />
41
+ )}
42
+ expandIconPosition={'end'}
43
+ ghost
44
+ size={'small'}
45
+ {...props}
46
+ />
47
+ );
48
+ });
49
+
50
+ export default CollapseGroup;
@@ -1,21 +1,39 @@
1
1
  import { Avatar, List } from '@lobehub/ui';
2
+ import { useHover } from 'ahooks';
2
3
  import Link from 'next/link';
3
- import { memo } from 'react';
4
+ import { memo, useMemo, useRef } from 'react';
4
5
  import { useTranslation } from 'react-i18next';
5
6
 
6
7
  import { DEFAULT_INBOX_AVATAR } from '@/const/meta';
7
8
  import { INBOX_SESSION_ID } from '@/const/session';
8
9
  import { useSessionStore } from '@/store/session';
9
10
 
11
+ const { Item } = List;
12
+
10
13
  const Inbox = memo(() => {
14
+ const ref = useRef(null);
15
+ const isHovering = useHover(ref);
11
16
  const { t } = useTranslation('common');
12
17
  const [activeId] = useSessionStore((s) => [s.activeId]);
13
18
 
19
+ const avatarRender = useMemo(
20
+ () => (
21
+ <Avatar
22
+ animation={isHovering}
23
+ avatar={DEFAULT_INBOX_AVATAR}
24
+ size={46}
25
+ style={{ padding: 3 }}
26
+ />
27
+ ),
28
+ [isHovering],
29
+ );
30
+
14
31
  return (
15
32
  <Link href={'/chat'}>
16
- <List.Item
33
+ <Item
17
34
  active={activeId === INBOX_SESSION_ID}
18
- avatar={<Avatar avatar={DEFAULT_INBOX_AVATAR} size={46} style={{ padding: 3 }} />}
35
+ avatar={avatarRender}
36
+ ref={ref}
19
37
  style={{ alignItems: 'center' }}
20
38
  title={t('inbox.title')}
21
39
  />
@@ -0,0 +1,22 @@
1
+ import { Icon } from '@lobehub/ui';
2
+ import { Button, type ButtonProps } from 'antd';
3
+ import { Plus } from 'lucide-react';
4
+ import { memo } from 'react';
5
+ import { useTranslation } from 'react-i18next';
6
+ import { Flexbox } from 'react-layout-kit';
7
+
8
+ import { useSessionStore } from '@/store/session';
9
+
10
+ const AddButton = memo<ButtonProps>((props) => {
11
+ const { t } = useTranslation('common');
12
+ const createSession = useSessionStore((s) => s.createSession);
13
+ return (
14
+ <Flexbox style={{ margin: '12px 16px' }}>
15
+ <Button block icon={<Icon icon={Plus} />} onClick={createSession} {...props}>
16
+ {t('newAgent')}
17
+ </Button>
18
+ </Flexbox>
19
+ );
20
+ });
21
+
22
+ export default AddButton;
@@ -1,6 +1,6 @@
1
- import { Avatar, List } from '@lobehub/ui';
1
+ import { SiOpenai } from '@icons-pack/react-simple-icons';
2
+ import { Avatar, List, Tag } from '@lobehub/ui';
2
3
  import { useHover } from 'ahooks';
3
- import { Tag } from 'antd';
4
4
  import { createStyles } from 'antd-style';
5
5
  import { memo, useMemo, useRef, useState } from 'react';
6
6
  import { Flexbox } from 'react-layout-kit';
@@ -88,7 +88,7 @@ const SessionItem = memo<SessionItemProps>(({ id }) => {
88
88
  () =>
89
89
  !showModel ? undefined : (
90
90
  <Flexbox gap={4} horizontal style={{ flexWrap: 'wrap' }}>
91
- {showModel && <Tag bordered={false}>{model}</Tag>}
91
+ {showModel && <Tag icon={<SiOpenai size={'1em'} />}>{model}</Tag>}
92
92
  </Flexbox>
93
93
  ),
94
94
  [showModel, model],
@@ -5,6 +5,7 @@ import { Flexbox } from 'react-layout-kit';
5
5
 
6
6
  import { sessionSelectors, useSessionHydrated, useSessionStore } from '@/store/session';
7
7
 
8
+ import AddButton from './AddButton';
8
9
  import SessionItem from './Item';
9
10
  import SkeletonList from './SkeletonList';
10
11
 
@@ -15,7 +16,7 @@ const SessionList = memo(() => {
15
16
 
16
17
  return !isInit ? (
17
18
  <SkeletonList />
18
- ) : (
19
+ ) : list.length > 0 ? (
19
20
  <Flexbox>
20
21
  {list.map(({ id }) => (
21
22
  <Link href={`/chat/${id}`} key={id}>
@@ -23,6 +24,8 @@ const SessionList = memo(() => {
23
24
  </Link>
24
25
  ))}
25
26
  </Flexbox>
27
+ ) : (
28
+ <AddButton />
26
29
  );
27
30
  });
28
31
 
@@ -1,10 +1,12 @@
1
1
  import { DraggablePanelBody } from '@lobehub/ui';
2
- import { memo } from 'react';
2
+ import { CollapseProps } from 'antd';
3
+ import { memo, useMemo } from 'react';
3
4
  import { useTranslation } from 'react-i18next';
4
5
  import { Flexbox } from 'react-layout-kit';
5
6
 
6
7
  import FolderPanel from '@/features/FolderPanel';
7
8
 
9
+ import CollapseGroup from './CollapseGroup';
8
10
  import Header from './Header';
9
11
  import Inbox from './Inbox';
10
12
  import SessionList from './List';
@@ -12,17 +14,24 @@ import SessionList from './List';
12
14
  export const Sessions = memo(() => {
13
15
  const { t } = useTranslation('common');
14
16
 
17
+ const items: CollapseProps['items'] = useMemo(
18
+ () => [
19
+ {
20
+ children: <SessionList />,
21
+ key: 'sessionList',
22
+ label: t('sessionList'),
23
+ },
24
+ ],
25
+ [],
26
+ );
27
+
15
28
  return (
16
29
  <FolderPanel>
17
30
  <Header />
18
31
  <DraggablePanelBody style={{ padding: 0 }}>
19
- <Flexbox gap={8}>
32
+ <Flexbox>
20
33
  <Inbox />
21
-
22
- <Flexbox paddingInline={20} style={{ fontSize: 12, marginTop: 8 }}>
23
- {t('sessionList')}
24
- </Flexbox>
25
- <SessionList />
34
+ <CollapseGroup defaultActiveKey={['sessionList']} items={items} />
26
35
  </Flexbox>
27
36
  </DraggablePanelBody>
28
37
  </FolderPanel>
@@ -1,11 +1,10 @@
1
- import { ActionIcon, ChatHeader } from '@lobehub/ui';
1
+ import { ActionIcon, ChatHeader, ChatHeaderTitle } from '@lobehub/ui';
2
2
  import { Dropdown, MenuProps } from 'antd';
3
3
  import { FolderOutput, Share2 } from 'lucide-react';
4
4
  import Router from 'next/router';
5
5
  import { memo, useMemo } from 'react';
6
6
  import { useTranslation } from 'react-i18next';
7
7
 
8
- import HeaderTitle from '@/components/HeaderTitle';
9
8
  import { exportSingleAgent, exportSingleSession } from '@/helpers/export';
10
9
  import { useSessionStore } from '@/store/session';
11
10
 
@@ -39,7 +38,7 @@ const Header = memo(() => {
39
38
 
40
39
  return (
41
40
  <ChatHeader
42
- left={<HeaderTitle title={t('header.session')} />}
41
+ left={<ChatHeaderTitle title={t('header.session')} />}
43
42
  onBackClick={() => Router.back()}
44
43
  right={
45
44
  <>
@@ -1,8 +1,9 @@
1
+ import { SiOpenai } from '@icons-pack/react-simple-icons';
2
+ import { Tag } from '@lobehub/ui';
1
3
  import { createStyles } from 'antd-style';
2
4
  import { ReactNode } from 'react';
3
5
  import { Flexbox } from 'react-layout-kit';
4
6
 
5
- import Tag from '@/components/Tag';
6
7
  import { agentSelectors, useSessionStore } from '@/store/session';
7
8
  import { ChatMessage } from '@/types/chatMessage';
8
9
 
@@ -44,7 +45,7 @@ const MessageExtra = ({
44
45
 
45
46
  const modelTag = (
46
47
  <div>
47
- <Tag>{extra?.fromModel as string}</Tag>
48
+ <Tag icon={<SiOpenai size={'1em'} />}>{extra?.fromModel as string}</Tag>
48
49
  </div>
49
50
  );
50
51
 
@@ -1,11 +1,10 @@
1
- import { ActionIcon } from '@lobehub/ui';
1
+ import { ActionIcon, SliderWithInput } from '@lobehub/ui';
2
2
  import { Dropdown, Popover, Switch } from 'antd';
3
3
  import { BrainCog, Thermometer, Timer, TimerOff } from 'lucide-react';
4
4
  import { memo } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
6
  import { Flexbox } from 'react-layout-kit';
7
7
 
8
- import SliderWithInput from '@/components/SliderWithInput';
9
8
  import { agentSelectors, useSessionStore } from '@/store/session';
10
9
  import { LanguageModel } from '@/types/llm';
11
10
 
@@ -1,11 +1,10 @@
1
- import { Avatar, Icon } from '@lobehub/ui';
1
+ import { Avatar, Icon, Tag } from '@lobehub/ui';
2
2
  import type { MenuProps } from 'antd';
3
3
  import { Dropdown } from 'antd';
4
4
  import { LucideToyBrick } from 'lucide-react';
5
5
  import { memo } from 'react';
6
6
  import { useTranslation } from 'react-i18next';
7
7
 
8
- import Tag from '@/components/Tag';
9
8
  import { PluginsMap } from '@/plugins';
10
9
 
11
10
  export interface PluginTagProps {
@@ -1,5 +1,5 @@
1
1
  import { SiOpenai } from '@icons-pack/react-simple-icons';
2
- import { ActionIcon, Avatar, ChatHeader } from '@lobehub/ui';
2
+ import { ActionIcon, Avatar, ChatHeader, ChatHeaderTitle, Tag } from '@lobehub/ui';
3
3
  import { Skeleton } from 'antd';
4
4
  import { PanelRightClose, PanelRightOpen, Settings } from 'lucide-react';
5
5
  import Router from 'next/router';
@@ -7,8 +7,6 @@ import { memo } from 'react';
7
7
  import { useTranslation } from 'react-i18next';
8
8
  import { Flexbox } from 'react-layout-kit';
9
9
 
10
- import HeaderTitle from '@/components/HeaderTitle';
11
- import Tag from '@/components/Tag';
12
10
  import { INBOX_SESSION_ID } from '@/const/session';
13
11
  import { useGlobalStore } from '@/store/global';
14
12
  import { agentSelectors, useSessionChatInit, useSessionStore } from '@/store/session';
@@ -56,14 +54,11 @@ const Header = memo<{ settings?: boolean }>(({ settings = true }) => {
56
54
  ) : (
57
55
  <Flexbox align={'flex-start'} gap={12} horizontal>
58
56
  <Avatar avatar={avatar} background={backgroundColor} size={40} title={title} />
59
- <HeaderTitle
57
+ <ChatHeaderTitle
60
58
  desc={displayDesc}
61
59
  tag={
62
60
  <>
63
- <Tag>
64
- <SiOpenai size={'11px'} style={{ marginTop: 2 }} />
65
- {model}
66
- </Tag>
61
+ <Tag icon={<SiOpenai size={'1em'} />}>{model}</Tag>
67
62
  {plugins?.length > 0 && <PluginTag plugins={plugins} />}
68
63
  </>
69
64
  }
@@ -1,5 +1,5 @@
1
- import { Icon } from '@lobehub/ui';
2
- import { Tag, Typography } from 'antd';
1
+ import { Icon, Tag } from '@lobehub/ui';
2
+ import { Typography } from 'antd';
3
3
  import { useTheme } from 'antd-style';
4
4
  import { MessageSquareDashed } from 'lucide-react';
5
5
  import { memo } from 'react';
@@ -1,18 +1,16 @@
1
- import { ChatHeader } from '@lobehub/ui';
1
+ import { ChatHeader, ChatHeaderTitle, Tag } from '@lobehub/ui';
2
2
  import Router from 'next/router';
3
3
  import { memo } from 'react';
4
4
  import { useTranslation } from 'react-i18next';
5
5
 
6
6
  import pkg from '@/../package.json';
7
- import HeaderTitle from '@/components/HeaderTitle';
8
- import Tag from '@/components/Tag';
9
7
 
10
8
  const Header = memo(() => {
11
9
  const { t } = useTranslation('setting');
12
10
 
13
11
  return (
14
12
  <ChatHeader
15
- left={<HeaderTitle tag={<Tag>{`v${pkg.version}`}</Tag>} title={t('header.global')} />}
13
+ left={<ChatHeaderTitle tag={<Tag>{`v${pkg.version}`}</Tag>} title={t('header.global')} />}
16
14
  onBackClick={() => Router.back()}
17
15
  showBackButton
18
16
  />
@@ -1,4 +1,4 @@
1
- import { Form, type ItemGroup, ThemeSwitch } from '@lobehub/ui';
1
+ import { Form, type ItemGroup, SliderWithInput, ThemeSwitch } from '@lobehub/ui';
2
2
  import { Form as AntForm, App, Button, Input, Select } from 'antd';
3
3
  import isEqual from 'fast-deep-equal';
4
4
  import { changeLanguage } from 'i18next';
@@ -6,7 +6,6 @@ import { debounce } from 'lodash-es';
6
6
  import { AppWindow, Palette, Webhook } from 'lucide-react';
7
7
  import { memo, useCallback, useMemo } from 'react';
8
8
  import { useTranslation } from 'react-i18next';
9
- import SliderWithInput from 'src/components/SliderWithInput';
10
9
 
11
10
  import { FORM_STYLE } from '@/const/layoutTokens';
12
11
  import { DEFAULT_SETTINGS } from '@/const/settings';
@@ -1,10 +1,9 @@
1
- import { ActionIcon } from '@lobehub/ui';
1
+ import { ActionIcon, DiscordIcon } from '@lobehub/ui';
2
2
  import { useTheme } from 'antd-style';
3
3
  import { Book, Github } from 'lucide-react';
4
4
  import { memo } from 'react';
5
5
  import { Flexbox } from 'react-layout-kit';
6
6
 
7
- import Discord from '@/components/DiscordIcon';
8
7
  import { CHANGELOG, DISCORD, GITHUB } from '@/const/url';
9
8
 
10
9
  const Footer = memo(() => {
@@ -14,7 +13,11 @@ const Footer = memo(() => {
14
13
  <Flexbox align={'center'} horizontal justify={'space-between'} style={{ padding: 16 }}>
15
14
  <span style={{ color: theme.colorTextDescription }}>©{new Date().getFullYear()} LobeHub</span>
16
15
  <Flexbox horizontal>
17
- <ActionIcon icon={Discord} onClick={() => window.open(DISCORD, '__blank')} size={'site'} />
16
+ <ActionIcon
17
+ icon={DiscordIcon}
18
+ onClick={() => window.open(DISCORD, '__blank')}
19
+ size={'site'}
20
+ />
18
21
  <ActionIcon icon={Book} onClick={() => window.open(CHANGELOG, '__blank')} size={'site'} />
19
22
  <ActionIcon icon={Github} onClick={() => window.open(GITHUB, '__blank')} size={'site'} />
20
23
  </Flexbox>
@@ -51,7 +51,7 @@ export const currentChatsWithGuideMessage = (s: SessionStore): ChatMessage[] =>
51
51
 
52
52
  const [activeId, isInbox] = [s.activeId, s.activeId === INBOX_SESSION_ID];
53
53
  const systemRole = agentSelectors.currentAgentSystemRole(s);
54
-
54
+ const meta = agentSelectors.currentAgentMeta(s);
55
55
  const emptyInboxGuideMessage = {
56
56
  content: isInbox
57
57
  ? t('inbox.defaultMessage')
@@ -61,7 +61,7 @@ export const currentChatsWithGuideMessage = (s: SessionStore): ChatMessage[] =>
61
61
  createAt: Date.now(),
62
62
  extra: {},
63
63
  id: 'default',
64
- meta: {
64
+ meta: meta || {
65
65
  avatar: DEFAULT_INBOX_AVATAR,
66
66
  },
67
67
  role: 'assistant',
@@ -1,15 +0,0 @@
1
- import { type LucideIcon, createLucideIcon } from 'lucide-react';
2
-
3
- const Discord: LucideIcon = createLucideIcon('Discord', [
4
- [
5
- 'path',
6
- {
7
- d: 'M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z',
8
- key: '18tl5t',
9
- },
10
- ],
11
- ]);
12
-
13
- const DiscordIcon = (props: LucideIcon) => <Discord style={{ overflow: 'visible' }} {...props} />;
14
-
15
- export default DiscordIcon as LucideIcon;
@@ -1,76 +0,0 @@
1
- import { createStyles } from 'antd-style';
2
- import { ReactNode, memo } from 'react';
3
- import { Flexbox } from 'react-layout-kit';
4
-
5
- const useStyles = createStyles(({ css, token }) => ({
6
- container: css`
7
- position: relative;
8
- overflow: hidden;
9
- flex: 1;
10
- max-width: 100%;
11
- `,
12
- desc: css`
13
- overflow: hidden;
14
-
15
- width: 100%;
16
-
17
- font-size: 12px;
18
- color: ${token.colorTextTertiary};
19
- text-overflow: ellipsis;
20
- white-space: nowrap;
21
- `,
22
- tag: css`
23
- flex: none;
24
- `,
25
- title: css`
26
- overflow: hidden;
27
-
28
- font-size: 16px;
29
- font-weight: bold;
30
- text-overflow: ellipsis;
31
- white-space: nowrap;
32
- `,
33
- titleContainer: css`
34
- flex: 1;
35
- `,
36
- titleWithDesc: css`
37
- overflow: hidden;
38
- font-weight: bold;
39
- text-overflow: ellipsis;
40
- white-space: nowrap;
41
- `,
42
- }));
43
-
44
- export interface HeaderTitleProps {
45
- desc?: string | ReactNode;
46
- tag?: ReactNode;
47
- title: string | ReactNode;
48
- }
49
-
50
- const HeaderTitle = memo<HeaderTitleProps>(({ title, desc, tag }) => {
51
- const { styles } = useStyles();
52
- if (desc)
53
- return (
54
- <Flexbox className={styles.container}>
55
- <Flexbox align={'center'} className={styles.titleContainer} gap={8} horizontal>
56
- <div className={styles.titleWithDesc}>{title}</div>
57
- <Flexbox className={styles.tag} horizontal>
58
- {tag}
59
- </Flexbox>
60
- </Flexbox>
61
- <Flexbox align={'center'} horizontal>
62
- <div className={styles.desc}>{desc}</div>
63
- </Flexbox>
64
- </Flexbox>
65
- );
66
- return (
67
- <Flexbox align={'center'} className={styles.container} gap={8} horizontal>
68
- <div className={styles.title}>{title}</div>
69
- <Flexbox className={styles.tag} horizontal>
70
- {tag}
71
- </Flexbox>
72
- </Flexbox>
73
- );
74
- });
75
-
76
- export default HeaderTitle;
@@ -1,69 +0,0 @@
1
- import { InputNumber, type InputNumberProps, Slider } from 'antd';
2
- import { SliderSingleProps } from 'antd/es/slider';
3
- import { isNull } from 'lodash-es';
4
- import { memo, useCallback } from 'react';
5
- import { Flexbox } from 'react-layout-kit';
6
-
7
- export interface SliderWithInputProps extends SliderSingleProps {
8
- controls?: InputNumberProps['controls'];
9
- size?: InputNumberProps['size'];
10
- }
11
-
12
- const SliderWithInput = memo<SliderWithInputProps>(
13
- ({
14
- step,
15
- value,
16
- onChange,
17
- max,
18
- min,
19
- defaultValue,
20
- size,
21
- controls,
22
- style,
23
- className,
24
- disabled,
25
- ...props
26
- }) => {
27
- const handleOnchange = useCallback((value: number | null) => {
28
- if (Number.isNaN(value) || isNull(value)) return;
29
- onChange?.(value);
30
- }, []);
31
-
32
- return (
33
- <Flexbox
34
- align={'center'}
35
- className={className}
36
- direction={'horizontal'}
37
- gap={8}
38
- style={style}
39
- >
40
- <Slider
41
- defaultValue={defaultValue}
42
- disabled={disabled}
43
- max={max}
44
- min={min}
45
- onChange={handleOnchange}
46
- step={step}
47
- style={size === 'small' ? { flex: 1, margin: 0 } : { flex: 1 }}
48
- tooltip={{ open: false }}
49
- value={typeof value === 'number' ? value : 0}
50
- {...props}
51
- />
52
- <InputNumber
53
- controls={size !== 'small' || controls}
54
- defaultValue={defaultValue}
55
- disabled={disabled}
56
- max={max}
57
- min={min}
58
- onChange={handleOnchange}
59
- size={size}
60
- step={Number.isNaN(step) || isNull(step) ? undefined : step}
61
- style={{ flex: 1, maxWidth: size === 'small' ? 40 : 64 }}
62
- value={typeof value === 'number' ? value : 0}
63
- />
64
- </Flexbox>
65
- );
66
- },
67
- );
68
-
69
- export default SliderWithInput;
@@ -1,51 +0,0 @@
1
- import { Tag as AntTag, type TagProps as AntTagProps } from 'antd';
2
- import { createStyles } from 'antd-style';
3
- import { ReactNode, memo } from 'react';
4
- import { Flexbox } from 'react-layout-kit';
5
-
6
- const useStyles = createStyles(({ cx, css, token }) => ({
7
- count: css`
8
- display: flex;
9
- align-items: center;
10
-
11
- height: 20px;
12
- padding: 0 8px;
13
-
14
- font-size: 12px;
15
- line-height: 1;
16
-
17
- background: ${token.colorFillTertiary};
18
- border: ${token.borderRadius}px;
19
- `,
20
- tag: cx(
21
- css`
22
- color: ${token.colorTextSecondary} !important;
23
- background: ${token.colorFillSecondary};
24
- border: ${token.borderRadius}px;
25
-
26
- &:hover {
27
- color: ${token.colorText};
28
- background: ${token.colorFill};
29
- }
30
- `,
31
- ),
32
- }));
33
-
34
- export interface TagProps extends AntTagProps {
35
- icon?: ReactNode;
36
- }
37
-
38
- const Tag = memo<TagProps>(({ icon, children, ...props }) => {
39
- const { styles } = useStyles();
40
-
41
- return (
42
- <AntTag bordered={false} className={styles.tag} {...props}>
43
- <Flexbox align={'center'} gap={4} horizontal>
44
- {icon}
45
- {children}
46
- </Flexbox>
47
- </AntTag>
48
- );
49
- });
50
-
51
- export default Tag;