@lobehub/chat 0.2.0 → 0.4.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,57 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ## [Version 0.4.0](https://github.com/lobehub/lobe-chat/compare/v0.3.0...v0.4.0)
6
+
7
+ <sup>Released on **2023-07-20**</sup>
8
+
9
+ #### ✨ Features
10
+
11
+ - **misc**: Add styles and modify layout of FolderPanel, SliderWithInput, SessionList, EditPage, ChatLayout, and SettingLayout components, Introduce FOLDER_WIDTH constant and update components.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's improved
19
+
20
+ - **misc**: Add styles and modify layout of FolderPanel, SliderWithInput, SessionList, EditPage, ChatLayout, and SettingLayout components ([7f19a09](https://github.com/lobehub/lobe-chat/commit/7f19a09))
21
+ - **misc**: Introduce FOLDER_WIDTH constant and update components ([c511964](https://github.com/lobehub/lobe-chat/commit/c511964))
22
+
23
+ </details>
24
+
25
+ <div align="right">
26
+
27
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
28
+
29
+ </div>
30
+
31
+ ## [Version 0.3.0](https://github.com/lobehub/lobe-chat/compare/v0.2.0...v0.3.0)
32
+
33
+ <sup>Released on **2023-07-18**</sup>
34
+
35
+ #### ✨ Features
36
+
37
+ - **misc**: Add new files, modify components, and adjust layout and styling.
38
+
39
+ <br/>
40
+
41
+ <details>
42
+ <summary><kbd>Improvements and Fixes</kbd></summary>
43
+
44
+ #### What's improved
45
+
46
+ - **misc**: Add new files, modify components, and adjust layout and styling ([b8c3b38](https://github.com/lobehub/lobe-chat/commit/b8c3b38))
47
+
48
+ </details>
49
+
50
+ <div align="right">
51
+
52
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
53
+
54
+ </div>
55
+
5
56
  ## [Version 0.2.0](https://github.com/lobehub/lobe-chat/compare/v0.1.6...v0.2.0)
6
57
 
7
58
  <sup>Released on **2023-07-18**</sup>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Lobe Chat is an open-source chatbot client using LangChain, Typescript and Next.js",
5
5
  "keywords": [
6
6
  "chatbot",
@@ -0,0 +1,5 @@
1
+ export const HEADER_HEIGHT = 64;
2
+ export const CHAT_TEXTAREA_HEIGHT = 200;
3
+ export const CHAT_SIDEBAR_WIDTH = 280;
4
+
5
+ export const FOLDER_WIDTH = 256;
@@ -27,7 +27,7 @@ interface AvatarWithUploadProps {
27
27
  size?: number;
28
28
  }
29
29
 
30
- export default memo<AvatarWithUploadProps>(({ size = 40 }) => {
30
+ const AvatarWithUpload = memo<AvatarWithUploadProps>(({ size = 40 }) => {
31
31
  const [avatar, setSettings] = useSettings((st) => [st.settings.avatar, st.setSettings], shallow);
32
32
  const { styles } = useStyle();
33
33
 
@@ -43,3 +43,5 @@ export default memo<AvatarWithUploadProps>(({ size = 40 }) => {
43
43
  </div>
44
44
  );
45
45
  });
46
+
47
+ export default AvatarWithUpload;
@@ -1,9 +1,10 @@
1
- import { DraggablePanel } from '@lobehub/ui';
1
+ import { DraggablePanel, DraggablePanelContainer } from '@lobehub/ui';
2
2
  import { createStyles } from 'antd-style';
3
3
  import isEqual from 'fast-deep-equal';
4
4
  import { PropsWithChildren, memo, useState } from 'react';
5
5
  import { shallow } from 'zustand/shallow';
6
6
 
7
+ import { FOLDER_WIDTH } from '@/const/layoutTokens';
7
8
  import { useSettings } from '@/store/settings';
8
9
 
9
10
  export const useStyles = createStyles(({ css, token }) => ({
@@ -14,7 +15,7 @@ export const useStyles = createStyles(({ css, token }) => ({
14
15
  `,
15
16
  }));
16
17
 
17
- export default memo<PropsWithChildren>(({ children }) => {
18
+ const FolderPanel = memo<PropsWithChildren>(({ children }) => {
18
19
  const { styles } = useStyles();
19
20
  const [sessionsWidth, sessionExpandable] = useSettings(
20
21
  (s) => [s.sessionsWidth, s.sessionExpandable],
@@ -29,7 +30,7 @@ export default memo<PropsWithChildren>(({ children }) => {
29
30
  defaultSize={{ width: tmpWidth }}
30
31
  expand={sessionExpandable}
31
32
  maxWidth={400}
32
- minWidth={256}
33
+ minWidth={FOLDER_WIDTH}
33
34
  onExpandChange={(expand) => {
34
35
  useSettings.setState({
35
36
  sessionExpandable: expand,
@@ -49,7 +50,11 @@ export default memo<PropsWithChildren>(({ children }) => {
49
50
  placement="left"
50
51
  size={{ height: '100vh', width: sessionsWidth }}
51
52
  >
52
- {children}
53
+ <DraggablePanelContainer style={{ flex: 'none', height: '100%', minWidth: FOLDER_WIDTH }}>
54
+ {children}
55
+ </DraggablePanelContainer>
53
56
  </DraggablePanel>
54
57
  );
55
58
  });
59
+
60
+ export default FolderPanel;
@@ -0,0 +1,7 @@
1
+ import { memo } from 'react';
2
+
3
+ import { HEADER_HEIGHT } from '@/const/layoutTokens';
4
+
5
+ const HeaderSpacing = memo(() => <div style={{ flex: 'none', height: HEADER_HEIGHT }} />);
6
+
7
+ export default HeaderSpacing;
@@ -28,7 +28,7 @@ const SliderWithInput = memo<SliderSingleProps>(
28
28
  max={max}
29
29
  min={min}
30
30
  onChange={handleOnchange}
31
- step={Number(step)}
31
+ step={Number.isNaN(step) || isNull(step) ? undefined : step}
32
32
  style={{ flex: 1, maxWidth: 64 }}
33
33
  value={typeof value === 'number' ? value : 0}
34
34
  />
@@ -1,16 +1,13 @@
1
1
  import isEqual from 'fast-deep-equal';
2
2
  import Link from 'next/link';
3
3
  import { memo } from 'react';
4
- import { Flexbox } from 'react-layout-kit';
5
4
  import { shallow } from 'zustand/shallow';
6
5
 
7
6
  import { sessionSelectors, useSessionStore } from '@/store/session';
8
7
 
9
8
  import SessionItem from './SessionItem';
10
- import { useStyles } from './style';
11
9
 
12
10
  const SessionList = memo(() => {
13
- const { styles, cx } = useStyles();
14
11
  const list = useSessionStore((s) => sessionSelectors.chatList(s), isEqual);
15
12
  const [activeId, loading] = useSessionStore(
16
13
  (s) => [s.activeId, s.autocompleteLoading.title],
@@ -18,13 +15,13 @@ const SessionList = memo(() => {
18
15
  );
19
16
 
20
17
  return (
21
- <Flexbox className={cx(styles.list)}>
18
+ <>
22
19
  {list.map(({ id }) => (
23
20
  <Link href={`/chat/${id}`} key={id}>
24
21
  <SessionItem active={activeId === id} id={id} loading={loading && id === activeId} />
25
22
  </Link>
26
23
  ))}
27
- </Flexbox>
24
+ </>
28
25
  );
29
26
  });
30
27
 
@@ -1,7 +1,7 @@
1
1
  import { createStyles } from 'antd-style';
2
2
  import { rgba } from 'polished';
3
3
 
4
- export const useStyles = createStyles(({ css, token, cx, stylish }) => {
4
+ export const useStyles = createStyles(({ css, token }) => {
5
5
  return {
6
6
  active: css`
7
7
  display: flex;
@@ -63,13 +63,6 @@ export const useStyles = createStyles(({ css, token, cx, stylish }) => {
63
63
  }
64
64
  }
65
65
  `,
66
- list: cx(
67
- stylish.noScrollbar,
68
- css`
69
- overflow-x: hidden;
70
- overflow-y: scroll;
71
- `,
72
- ),
73
66
  time: css`
74
67
  align-self: flex-start;
75
68
  `,
@@ -1,5 +1,5 @@
1
+ import { DraggablePanelBody } from '@lobehub/ui';
1
2
  import { memo } from 'react';
2
- import { Flexbox } from 'react-layout-kit';
3
3
 
4
4
  import FolderPanel from '@/features/FolderPanel';
5
5
 
@@ -9,10 +9,10 @@ import SessionList from './List';
9
9
  export const Sessions = memo(() => {
10
10
  return (
11
11
  <FolderPanel>
12
- <Flexbox gap={8} height={'100%'}>
13
- <Header />
12
+ <Header />
13
+ <DraggablePanelBody style={{ padding: 0 }}>
14
14
  <SessionList />
15
- </Flexbox>
15
+ </DraggablePanelBody>
16
16
  </FolderPanel>
17
17
  );
18
18
  });
@@ -1,21 +1,30 @@
1
- import { ActionIcon, DraggablePanel, DraggablePanelContainer } from '@lobehub/ui';
1
+ import {
2
+ ActionIcon,
3
+ DraggablePanel,
4
+ DraggablePanelBody,
5
+ DraggablePanelContainer,
6
+ } from '@lobehub/ui';
2
7
  import { createStyles } from 'antd-style';
3
8
  import { LucideEdit, LucideX } from 'lucide-react';
4
9
  import Router from 'next/router';
10
+ import { rgba } from 'polished';
5
11
  import { useTranslation } from 'react-i18next';
6
12
  import { Flexbox } from 'react-layout-kit';
7
13
  import { shallow } from 'zustand/shallow';
8
14
 
15
+ import { CHAT_SIDEBAR_WIDTH } from '@/const/layoutTokens';
16
+ import HeaderSpacing from '@/features/HeaderSpacing';
9
17
  import { useSessionStore } from '@/store/session';
10
18
 
11
19
  import ReadMode from './ReadMode';
12
20
 
13
- const WIDTH = 280;
14
-
15
- const useStyles = createStyles(({ css, token }) => ({
16
- drawer: css`
17
- background: ${token.colorBgLayout};
18
- `,
21
+ const useStyles = createStyles(({ cx, css, token, stylish }) => ({
22
+ drawer: cx(
23
+ stylish.blurStrong,
24
+ css`
25
+ background: ${rgba(token.colorBgLayout, 0.4)};
26
+ `,
27
+ ),
19
28
  header: css`
20
29
  border-bottom: 1px solid ${token.colorBorder};
21
30
  `,
@@ -33,15 +42,14 @@ const Config = () => {
33
42
  <DraggablePanel
34
43
  className={styles.drawer}
35
44
  expand={showAgentSettings}
36
- expandable={false}
37
- maxWidth={WIDTH}
38
- minWidth={WIDTH}
39
- mode={'float'}
40
- pin
45
+ maxWidth={CHAT_SIDEBAR_WIDTH}
46
+ minWidth={CHAT_SIDEBAR_WIDTH}
47
+ onExpandChange={toggleConfig}
41
48
  placement={'right'}
42
- resize={{ left: false }}
49
+ resize={false}
43
50
  >
44
- <DraggablePanelContainer style={{ flex: 'none', minWidth: WIDTH }}>
51
+ <HeaderSpacing />
52
+ <DraggablePanelContainer style={{ flex: 'none', minWidth: CHAT_SIDEBAR_WIDTH }}>
45
53
  <Flexbox
46
54
  align={'center'}
47
55
  className={styles.header}
@@ -70,7 +78,9 @@ const Config = () => {
70
78
  />
71
79
  </Flexbox>
72
80
  </Flexbox>
73
- <ReadMode />
81
+ <DraggablePanelBody>
82
+ <ReadMode />
83
+ </DraggablePanelBody>
74
84
  </DraggablePanelContainer>
75
85
  </DraggablePanel>
76
86
  );
@@ -5,6 +5,7 @@ import { Archive, Eraser, Languages } from 'lucide-react';
5
5
  import { memo, useMemo, useState } from 'react';
6
6
  import { shallow } from 'zustand/shallow';
7
7
 
8
+ import { CHAT_TEXTAREA_HEIGHT, HEADER_HEIGHT } from '@/const/layoutTokens';
8
9
  import { ModelTokens } from '@/const/modelTokens';
9
10
  import { agentSelectors, chatSelectors, useSessionStore } from '@/store/session';
10
11
  import { useSettings } from '@/store/settings';
@@ -29,7 +30,8 @@ const ChatInput = () => {
29
30
  <DraggablePanel
30
31
  expandable={false}
31
32
  fullscreen={expand}
32
- minHeight={200}
33
+ headerHeight={HEADER_HEIGHT}
34
+ minHeight={CHAT_TEXTAREA_HEIGHT}
33
35
  onSizeChange={(_, size) => {
34
36
  if (!size) return;
35
37
  useSettings.setState({
@@ -38,6 +40,7 @@ const ChatInput = () => {
38
40
  }}
39
41
  placement="bottom"
40
42
  size={{ height: inputHeight, width: '100%' }}
43
+ style={{ zIndex: 10 }}
41
44
  >
42
45
  <ChatInputArea
43
46
  actions={
@@ -49,7 +52,7 @@ const ChatInput = () => {
49
52
  }
50
53
  expand={expand}
51
54
  footer={<Button icon={<Icon icon={Archive} />} />}
52
- minHeight={200}
55
+ minHeight={CHAT_TEXTAREA_HEIGHT}
53
56
  onExpandChange={setExpand}
54
57
  onInputChange={setText}
55
58
  onSend={sendMessage}
@@ -1,17 +1,20 @@
1
1
  import { memo } from 'react';
2
+ import { Flexbox } from 'react-layout-kit';
2
3
 
4
+ import HeaderSpacing from '@/features/HeaderSpacing';
3
5
  import ChatInput from '@/pages/chat/[id]/Conversation/Input';
4
6
 
5
7
  import ChatList from './ChatList';
6
8
 
7
9
  const Conversation = () => {
8
10
  return (
9
- <>
11
+ <Flexbox flex={1}>
10
12
  <div style={{ flex: 1, overflowY: 'scroll' }}>
13
+ <HeaderSpacing />
11
14
  <ChatList />
12
15
  </div>
13
16
  <ChatInput />
14
- </>
17
+ </Flexbox>
15
18
  );
16
19
  };
17
20
 
@@ -1,7 +1,6 @@
1
1
  import { ActionIcon, Avatar, ChatHeader } from '@lobehub/ui';
2
2
  import { createStyles } from 'antd-style';
3
- import { ArchiveIcon, LucideEdit, MoreVerticalIcon, Share2Icon } from 'lucide-react';
4
- import Router from 'next/router';
3
+ import { ArchiveIcon, MoreVerticalIcon, Share2 } from 'lucide-react';
5
4
  import { memo } from 'react';
6
5
  import { useTranslation } from 'react-i18next';
7
6
  import { Flexbox } from 'react-layout-kit';
@@ -54,7 +53,7 @@ const Header = memo(() => {
54
53
  id && (
55
54
  <>
56
55
  <ActionIcon
57
- icon={Share2Icon}
56
+ icon={Share2}
58
57
  onClick={() => {
59
58
  // genShareUrl();
60
59
  }}
@@ -62,14 +61,6 @@ const Header = memo(() => {
62
61
  title={t('share')}
63
62
  />
64
63
  <ActionIcon icon={ArchiveIcon} size={{ fontSize: 24 }} title={t('archive')} />
65
- <ActionIcon
66
- icon={LucideEdit}
67
- onClick={() => {
68
- Router.push(`/chat/${id}/edit`);
69
- }}
70
- size={{ blockSize: 32, fontSize: 20 }}
71
- title={t('edit')}
72
- />
73
64
  <ActionIcon
74
65
  icon={MoreVerticalIcon}
75
66
  onClick={() => toggleConfig()}
@@ -93,7 +93,7 @@ const AgentMeta = () => {
93
93
  <Button
94
94
  disabled={!hasSystemRole}
95
95
  loading={Object.values(loading).some((i) => !!i)}
96
- onClick={(e) => {
96
+ onClick={(e: any) => {
97
97
  e.stopPropagation();
98
98
  console.log(id);
99
99
  if (!id) return;
@@ -1,11 +1,14 @@
1
- import { ChatHeader } from '@lobehub/ui';
2
- import { Button } from 'antd';
1
+ import { ActionIcon, ChatHeader } from '@lobehub/ui';
3
2
  import { createStyles } from 'antd-style';
3
+ import { Download, Share2 } from 'lucide-react';
4
+ import Head from 'next/head';
4
5
  import Router from 'next/router';
5
6
  import { memo } from 'react';
6
7
  import { useTranslation } from 'react-i18next';
7
8
  import { Flexbox } from 'react-layout-kit';
8
9
 
10
+ import HeaderSpacing from '@/features/HeaderSpacing';
11
+
9
12
  import ChatLayout from '../../layout';
10
13
  import AgentConfig from './AgentConfig';
11
14
  import AgentMeta from './AgentMeta';
@@ -34,28 +37,32 @@ const EditPage = memo(() => {
34
37
 
35
38
  const { styles } = useStyles();
36
39
 
40
+ const pageTitle = t('editAgentProfile');
41
+
37
42
  return (
38
- <ChatLayout>
39
- <Flexbox height={'100vh'} style={{ position: 'relative' }} width={'100%'}>
40
- {/*header*/}
43
+ <>
44
+ <Head>
45
+ <title>{pageTitle}</title>
46
+ </Head>
47
+ <ChatLayout>
41
48
  <ChatHeader
42
49
  left={<div className={styles.title}>{t('editAgentProfile')}</div>}
43
50
  onBackClick={() => Router.back()}
44
51
  right={
45
52
  <>
46
- <Button>{t('share')}</Button>
47
- <Button type={'primary'}>{t('export')}</Button>
53
+ <ActionIcon icon={Share2} size={{ fontSize: 24 }} title={t('share')} />
54
+ <ActionIcon icon={Download} size={{ fontSize: 24 }} title={t('export')} />
48
55
  </>
49
56
  }
50
57
  showBackButton
51
58
  />
52
- {/*form*/}
53
59
  <Flexbox className={styles.form} flex={1} gap={10} padding={24}>
60
+ <HeaderSpacing />
54
61
  <AgentMeta />
55
62
  <AgentConfig />
56
63
  </Flexbox>
57
- </Flexbox>
58
- </ChatLayout>
64
+ </ChatLayout>
65
+ </>
59
66
  );
60
67
  });
61
68
 
@@ -23,13 +23,9 @@ const Chat = memo(() => {
23
23
  <Head>
24
24
  <title>{pageTitle}</title>
25
25
  </Head>
26
-
27
- <Flexbox flex={1} height={'100vh'} style={{ overflow: 'hidden', position: 'relative' }}>
26
+ <Flexbox id={'lobe-conversion-container'} style={{ height: '100vh', position: 'relative' }}>
28
27
  <Header />
29
- <Flexbox
30
- id={'lobe-conversion-container'}
31
- style={{ height: 'calc(100vh - 64px)', position: 'relative' }}
32
- >
28
+ <Flexbox flex={1} horizontal>
33
29
  <Conversation />
34
30
  <Config />
35
31
  </Flexbox>
@@ -43,7 +43,9 @@ const ChatLayout = memo<PropsWithChildren>(({ children }) => {
43
43
  <Flexbox horizontal width={'100%'}>
44
44
  <SideBar />
45
45
  <Sessions />
46
- {children}
46
+ <Flexbox flex={1} height={'100vh'} style={{ position: 'relative' }}>
47
+ {children}
48
+ </Flexbox>
47
49
  </Flexbox>
48
50
  );
49
51
  });
@@ -8,8 +8,8 @@ import { useTranslation } from 'react-i18next';
8
8
  import { shallow } from 'zustand/shallow';
9
9
 
10
10
  import AvatarWithUpload from '@/features/AvatarWithUpload';
11
+ import SliderWithInput from '@/features/SliderWithInput';
11
12
  import { options } from '@/locales/options';
12
- import SliderWithInput from '@/pages/setting/SliderWithInput';
13
13
  import { settingsSelectors, useSettings } from '@/store/settings';
14
14
  import { DEFAULT_SETTINGS } from '@/store/settings/initialState';
15
15
  import { ConfigKeys } from '@/types/exportConfig';
@@ -3,9 +3,9 @@ import { memo, useEffect } from 'react';
3
3
  import { useTranslation } from 'react-i18next';
4
4
  import { Flexbox } from 'react-layout-kit';
5
5
 
6
- import SideBar from '@/features/SideBar';
6
+ import HeaderSpacing from '@/features/HeaderSpacing';
7
7
  import { createI18nNext } from '@/locales/create';
8
- import { Sessions } from '@/pages/chat/SessionList';
8
+ import ChatLayout from '@/pages/chat/layout';
9
9
 
10
10
  import Header from './Header';
11
11
  import SettingForm from './SettingForm';
@@ -24,16 +24,13 @@ const SettingLayout = memo(() => {
24
24
  <Head>
25
25
  <title>{pageTitle}</title>
26
26
  </Head>
27
- <Flexbox height={'100vh'} horizontal width={'100%'}>
28
- <SideBar />
29
- <Sessions />
30
- <Flexbox flex={1}>
31
- <Header />
32
- <Flexbox align={'center'} flex={1} padding={24} style={{ overflow: 'auto' }}>
33
- <SettingForm />
34
- </Flexbox>
27
+ <ChatLayout>
28
+ <Header />
29
+ <Flexbox align={'center'} flex={1} padding={24} style={{ overflow: 'auto' }}>
30
+ <HeaderSpacing />
31
+ <SettingForm />
35
32
  </Flexbox>
36
- </Flexbox>
33
+ </ChatLayout>
37
34
  </>
38
35
  );
39
36
  });
package/tsconfig.json CHANGED
@@ -22,7 +22,15 @@
22
22
  }
23
23
  },
24
24
  "exclude": ["node_modules"],
25
- "include": ["next-env.d.ts", "**/*.ts", "**/*.d.ts", "**/*.tsx"],
25
+ "include": [
26
+ "next-env.d.ts",
27
+ "vitest.config.ts",
28
+ "src",
29
+ "tests",
30
+ "**/*.ts",
31
+ "**/*.d.ts",
32
+ "**/*.tsx"
33
+ ],
26
34
  "ts-node": {
27
35
  "compilerOptions": {
28
36
  "module": "commonjs"