@lobehub/chat 1.49.2 → 1.49.3

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,31 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 1.49.3](https://github.com/lobehub/lobe-chat/compare/v1.49.2...v1.49.3)
6
+
7
+ <sup>Released on **2025-01-27**</sup>
8
+
9
+ #### 🐛 Bug Fixes
10
+
11
+ - **misc**: Fix discover ssr hydration error.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's fixed
19
+
20
+ - **misc**: Fix discover ssr hydration error, closes [#5605](https://github.com/lobehub/lobe-chat/issues/5605) ([e3702a6](https://github.com/lobehub/lobe-chat/commit/e3702a6))
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
+
5
30
  ### [Version 1.49.2](https://github.com/lobehub/lobe-chat/compare/v1.49.1...v1.49.2)
6
31
 
7
32
  <sup>Released on **2025-01-27**</sup>
package/changelog/v1.json CHANGED
@@ -1,4 +1,13 @@
1
1
  [
2
+ {
3
+ "children": {
4
+ "fixes": [
5
+ "Fix discover ssr hydration error."
6
+ ]
7
+ },
8
+ "date": "2025-01-27",
9
+ "version": "1.49.3"
10
+ },
2
11
  {
3
12
  "children": {
4
13
  "improvements": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "1.49.2",
3
+ "version": "1.49.3",
4
4
  "description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
5
5
  "keywords": [
6
6
  "framework",
@@ -1,5 +1,4 @@
1
1
  import { Grid } from '@lobehub/ui';
2
- import Link from 'next/link';
3
2
  import { memo } from 'react';
4
3
  import urlJoin from 'url-join';
5
4
 
@@ -11,14 +10,21 @@ const AssistantList = memo<{ data: DiscoverAssistantItem[] }>(({ data }) => {
11
10
  return (
12
11
  <Grid maxItemWidth={280} rows={4}>
13
12
  {data.slice(0, 8).map((item) => (
14
- <Link href={urlJoin('/discover/assistant/', item.identifier)} key={item.identifier}>
15
- <Card showCategory {...item} />
16
- </Link>
13
+ <Card
14
+ href={urlJoin('/discover/assistant/', item.identifier)}
15
+ key={item.identifier}
16
+ showCategory
17
+ {...item}
18
+ />
17
19
  ))}
18
20
  {data.slice(8, 16).map((item) => (
19
- <Link href={urlJoin('/discover/assistant/', item.identifier)} key={item.identifier}>
20
- <Card showCategory variant={'compact'} {...item} />
21
- </Link>
21
+ <Card
22
+ href={urlJoin('/discover/assistant/', item.identifier)}
23
+ key={item.identifier}
24
+ showCategory
25
+ variant={'compact'}
26
+ {...item}
27
+ />
22
28
  ))}
23
29
  </Grid>
24
30
  );
@@ -1,5 +1,4 @@
1
1
  import { Grid } from '@lobehub/ui';
2
- import Link from 'next/link';
3
2
  import { memo } from 'react';
4
3
  import urlJoin from 'url-join';
5
4
 
@@ -11,9 +10,7 @@ const ModelList = memo<{ data: DiscoverModelItem[] }>(({ data }) => {
11
10
  return (
12
11
  <Grid maxItemWidth={280} rows={4}>
13
12
  {data.map((item) => (
14
- <Link href={urlJoin('/discover/model/', item.identifier)} key={item.identifier}>
15
- <Card {...item} />
16
- </Link>
13
+ <Card {...item} href={urlJoin('/discover/model/', item.identifier)} key={item.identifier} />
17
14
  ))}
18
15
  </Grid>
19
16
  );
@@ -1,5 +1,4 @@
1
1
  import { Grid } from '@lobehub/ui';
2
- import Link from 'next/link';
3
2
  import { memo } from 'react';
4
3
  import urlJoin from 'url-join';
5
4
 
@@ -11,9 +10,13 @@ const PluginList = memo<{ data: DiscoverPlugintem[] }>(({ data }) => {
11
10
  return (
12
11
  <Grid maxItemWidth={280} rows={4}>
13
12
  {data.map((item) => (
14
- <Link href={urlJoin('/discover/plugin/', item.identifier)} key={item.identifier}>
15
- <Card showCategory variant={'compact'} {...item} />
16
- </Link>
13
+ <Card
14
+ showCategory
15
+ variant={'compact'}
16
+ {...item}
17
+ href={urlJoin('/discover/plugin/', item.identifier)}
18
+ key={item.identifier}
19
+ />
17
20
  ))}
18
21
  </Grid>
19
22
  );
@@ -3,6 +3,7 @@ import { Skeleton, Typography } from 'antd';
3
3
  import { createStyles } from 'antd-style';
4
4
  import { startCase } from 'lodash-es';
5
5
  import dynamic from 'next/dynamic';
6
+ import { useRouter } from 'next/navigation';
6
7
  import qs from 'query-string';
7
8
  import { CSSProperties, memo } from 'react';
8
9
  import { Center, Flexbox } from 'react-layout-kit';
@@ -26,8 +27,6 @@ const useStyles = createStyles(({ css, token, isDarkMode }) => ({
26
27
  opacity: ${isDarkMode ? 0.9 : 0.4};
27
28
  `,
28
29
  container: css`
29
- cursor: pointer;
30
-
31
30
  position: relative;
32
31
 
33
32
  overflow: hidden;
@@ -64,18 +63,19 @@ const useStyles = createStyles(({ css, token, isDarkMode }) => ({
64
63
  export interface AssistantCardProps
65
64
  extends Omit<DiscoverAssistantItem, 'suggestions' | 'socialData' | 'config'> {
66
65
  className?: string;
66
+ href: string;
67
67
  showCategory?: boolean;
68
68
  style?: CSSProperties;
69
69
  variant?: 'default' | 'compact';
70
70
  }
71
71
 
72
72
  const AssistantCard = memo<AssistantCardProps>(
73
- ({ showCategory, className, meta, createdAt, author, variant, style }) => {
73
+ ({ showCategory, className, meta, createdAt, author, variant, style, href }) => {
74
74
  const { avatar, title, description, tags = [], category } = meta;
75
75
  const { cx, styles, theme } = useStyles();
76
76
  const categoryItem = useCategoryItem(category, 12);
77
77
  const isCompact = variant === 'compact';
78
-
78
+ const router = useRouter();
79
79
  const user = (
80
80
  <Flexbox
81
81
  align={'center'}
@@ -90,60 +90,79 @@ const AssistantCard = memo<AssistantCardProps>(
90
90
 
91
91
  return (
92
92
  <Flexbox className={cx(styles.container, className)} gap={24} style={style}>
93
- {!isCompact && <CardBanner avatar={avatar} />}
94
- <Flexbox gap={12} padding={16}>
95
- <Flexbox
96
- align={isCompact ? 'flex-start' : 'flex-end'}
97
- gap={16}
98
- horizontal
99
- justify={'space-between'}
100
- style={{ position: 'relative' }}
101
- width={'100%'}
93
+ {!isCompact && (
94
+ <div
95
+ onClick={() => {
96
+ router.push(href);
97
+ }}
102
98
  >
103
- <Flexbox
104
- gap={8}
105
- style={{ overflow: 'hidden', paddingTop: isCompact ? 4 : 0, position: 'relative' }}
106
- >
107
- <Title
108
- className={styles.title}
109
- ellipsis={{ rows: 1, tooltip: title }}
110
- level={3}
111
- style={{ fontSize: isCompact ? 16 : 18 }}
112
- >
113
- {title}
114
- </Title>
115
- {isCompact && user}
116
- </Flexbox>
117
- {isCompact ? (
118
- <Avatar avatar={avatar} size={40} style={{ display: 'block' }} title={title} />
119
- ) : (
120
- <Center
121
- flex={'none'}
122
- height={64}
123
- style={{
124
- background: theme.colorBgContainer,
125
- borderRadius: '50%',
126
- marginTop: -6,
127
- overflow: 'hidden',
128
- zIndex: 2,
129
- }}
130
- width={64}
99
+ <CardBanner avatar={avatar} />
100
+ </div>
101
+ )}
102
+ <Flexbox gap={12} padding={16}>
103
+ <Link href={href}>
104
+ <Flexbox gap={12}>
105
+ <Flexbox
106
+ align={isCompact ? 'flex-start' : 'flex-end'}
107
+ gap={16}
108
+ horizontal
109
+ justify={'space-between'}
110
+ style={{ position: 'relative' }}
111
+ width={'100%'}
131
112
  >
132
- <Avatar avatar={avatar} size={56} style={{ display: 'block' }} title={title} />
133
- </Center>
134
- )}
135
- </Flexbox>
136
- {!isCompact && (
137
- <Flexbox gap={8} horizontal style={{ fontSize: 12 }}>
138
- {user}
139
- <time className={styles.time} dateTime={new Date(createdAt).toISOString()}>
140
- {createdAt}
141
- </time>
113
+ <Flexbox
114
+ gap={8}
115
+ style={{
116
+ overflow: 'hidden',
117
+ paddingTop: isCompact ? 4 : 0,
118
+ position: 'relative',
119
+ }}
120
+ >
121
+ <Title
122
+ className={styles.title}
123
+ ellipsis={{ rows: 1, tooltip: title }}
124
+ level={3}
125
+ style={{ fontSize: isCompact ? 16 : 18 }}
126
+ >
127
+ {title}
128
+ </Title>
129
+ {isCompact && user}
130
+ </Flexbox>
131
+
132
+ {isCompact ? (
133
+ <Avatar avatar={avatar} size={40} style={{ display: 'block' }} title={title} />
134
+ ) : (
135
+ <Center
136
+ flex={'none'}
137
+ height={64}
138
+ style={{
139
+ background: theme.colorBgContainer,
140
+ borderRadius: '50%',
141
+ marginTop: -6,
142
+ overflow: 'hidden',
143
+ zIndex: 2,
144
+ }}
145
+ width={64}
146
+ >
147
+ <Avatar avatar={avatar} size={56} style={{ display: 'block' }} title={title} />
148
+ </Center>
149
+ )}
150
+ </Flexbox>
151
+
152
+ {!isCompact && (
153
+ <Flexbox gap={8} horizontal style={{ fontSize: 12 }}>
154
+ {user}
155
+ <time className={styles.time} dateTime={new Date(createdAt).toISOString()}>
156
+ {createdAt}
157
+ </time>
158
+ </Flexbox>
159
+ )}
160
+ <Paragraph className={styles.desc} ellipsis={{ rows: 2 }}>
161
+ {description}
162
+ </Paragraph>
142
163
  </Flexbox>
143
- )}
144
- <Paragraph className={styles.desc} ellipsis={{ rows: 2 }}>
145
- {description}
146
- </Paragraph>
164
+ </Link>
165
+
147
166
  <Flexbox gap={6} horizontal style={{ flexWrap: 'wrap' }}>
148
167
  {showCategory && categoryItem ? (
149
168
  <Link href={urlJoin('/discover/assistants', categoryItem.key)}>
@@ -2,7 +2,6 @@
2
2
 
3
3
  import { Grid } from '@lobehub/ui';
4
4
  import { Empty } from 'antd';
5
- import Link from 'next/link';
6
5
  import { memo, useMemo } from 'react';
7
6
  import { useTranslation } from 'react-i18next';
8
7
  import urlJoin from 'url-join';
@@ -42,9 +41,13 @@ const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] })
42
41
  data={all}
43
42
  initialItemCount={24}
44
43
  itemContent={(_, item) => (
45
- <Link href={urlJoin('/discover/assistant/', item.identifier)} key={item.identifier}>
46
- <Card showCategory variant={'compact'} {...item} />
47
- </Link>
44
+ <Card
45
+ href={urlJoin('/discover/assistant/', item.identifier)}
46
+ key={item.identifier}
47
+ showCategory
48
+ variant={'compact'}
49
+ {...item}
50
+ />
48
51
  )}
49
52
  style={{
50
53
  minHeight: '75vh',
@@ -59,9 +62,12 @@ const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] })
59
62
  <Title>{t('assistants.recentSubmits')}</Title>
60
63
  <Grid maxItemWidth={280} rows={4}>
61
64
  {recent.map((item) => (
62
- <Link href={urlJoin('/discover/assistant/', item.identifier)} key={item.identifier}>
63
- <Card showCategory={!category} {...item} />
64
- </Link>
65
+ <Card
66
+ href={urlJoin('/discover/assistant/', item.identifier)}
67
+ key={item.identifier}
68
+ showCategory={!category}
69
+ {...item}
70
+ />
65
71
  ))}
66
72
  </Grid>
67
73
  {last && last?.length > 0 && (
@@ -71,9 +77,13 @@ const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] })
71
77
  data={last}
72
78
  initialItemCount={12}
73
79
  itemContent={(_, item) => (
74
- <Link href={urlJoin('/discover/assistant/', item.identifier)} key={item.identifier}>
75
- <Card showCategory={!category} variant={'compact'} {...item} />
76
- </Link>
80
+ <Card
81
+ href={urlJoin('/discover/assistant/', item.identifier)}
82
+ key={item.identifier}
83
+ showCategory={!category}
84
+ variant={'compact'}
85
+ {...item}
86
+ />
77
87
  )}
78
88
  style={{
79
89
  minHeight: '75vh',
@@ -1,6 +1,7 @@
1
1
  import { ModelIcon } from '@lobehub/icons';
2
2
  import { Typography } from 'antd';
3
3
  import { createStyles } from 'antd-style';
4
+ import Link from 'next/link';
4
5
  import { CSSProperties, memo } from 'react';
5
6
  import { useTranslation } from 'react-i18next';
6
7
  import { Flexbox } from 'react-layout-kit';
@@ -16,8 +17,6 @@ const useStyles = createStyles(({ css, token, isDarkMode }) => ({
16
17
  opacity: ${isDarkMode ? 0.9 : 0.4};
17
18
  `,
18
19
  container: css`
19
- cursor: pointer;
20
-
21
20
  position: relative;
22
21
 
23
22
  overflow: hidden;
@@ -69,53 +68,56 @@ const useStyles = createStyles(({ css, token, isDarkMode }) => ({
69
68
 
70
69
  export interface ModelCardProps extends DiscoverModelItem {
71
70
  className?: string;
71
+ href: string;
72
72
  showCategory?: boolean;
73
73
  style?: CSSProperties;
74
74
  }
75
75
 
76
- const ModelCard = memo<ModelCardProps>(({ className, meta, identifier, style }) => {
76
+ const ModelCard = memo<ModelCardProps>(({ className, meta, identifier, style, href }) => {
77
77
  const { description, title, functionCall, vision, contextWindowTokens } = meta;
78
78
  const { t } = useTranslation('models');
79
79
  const { cx, styles } = useStyles();
80
80
 
81
81
  return (
82
- <Flexbox className={cx(styles.container, className)} gap={24} key={identifier} style={style}>
83
- <Flexbox
84
- gap={12}
85
- padding={16}
86
- style={{ overflow: 'hidden', position: 'relative' }}
87
- width={'100%'}
88
- >
82
+ <Link href={href}>
83
+ <Flexbox className={cx(styles.container, className)} gap={24} key={identifier} style={style}>
89
84
  <Flexbox
90
- align={'center'}
91
85
  gap={12}
92
- horizontal
86
+ padding={16}
93
87
  style={{ overflow: 'hidden', position: 'relative' }}
94
88
  width={'100%'}
95
89
  >
96
- <ModelIcon model={identifier} size={32} type={'avatar'} />
97
- <Flexbox style={{ overflow: 'hidden', position: 'relative' }}>
98
- <Title className={styles.title} ellipsis={{ rows: 1, tooltip: title }} level={3}>
99
- {title}
100
- </Title>
101
- <Paragraph className={styles.id} ellipsis={{ rows: 1 }}>
102
- {identifier}
103
- </Paragraph>
90
+ <Flexbox
91
+ align={'center'}
92
+ gap={12}
93
+ horizontal
94
+ style={{ overflow: 'hidden', position: 'relative' }}
95
+ width={'100%'}
96
+ >
97
+ <ModelIcon model={identifier} size={32} type={'avatar'} />
98
+ <Flexbox style={{ overflow: 'hidden', position: 'relative' }}>
99
+ <Title className={styles.title} ellipsis={{ rows: 1, tooltip: title }} level={3}>
100
+ {title}
101
+ </Title>
102
+ <Paragraph className={styles.id} ellipsis={{ rows: 1 }}>
103
+ {identifier}
104
+ </Paragraph>
105
+ </Flexbox>
104
106
  </Flexbox>
105
- </Flexbox>
106
- {description && (
107
- <Paragraph className={styles.desc} ellipsis={{ rows: 2 }}>
108
- {t(`${identifier}.description`)}
109
- </Paragraph>
110
- )}
107
+ {description && (
108
+ <Paragraph className={styles.desc} ellipsis={{ rows: 2 }}>
109
+ {t(`${identifier}.description`)}
110
+ </Paragraph>
111
+ )}
111
112
 
112
- <ModelFeatureTags
113
- functionCall={functionCall}
114
- tokens={contextWindowTokens}
115
- vision={vision}
116
- />
113
+ <ModelFeatureTags
114
+ functionCall={functionCall}
115
+ tokens={contextWindowTokens}
116
+ vision={vision}
117
+ />
118
+ </Flexbox>
117
119
  </Flexbox>
118
- </Flexbox>
120
+ </Link>
119
121
  );
120
122
  });
121
123
 
@@ -1,7 +1,6 @@
1
1
  'use client';
2
2
 
3
3
  import { Empty } from 'antd';
4
- import Link from 'next/link';
5
4
  import { memo } from 'react';
6
5
  import { useTranslation } from 'react-i18next';
7
6
  import urlJoin from 'url-join';
@@ -32,9 +31,12 @@ const List = memo<ListProps>(({ category, searchKeywords, items = [] }) => {
32
31
  data={items}
33
32
  initialItemCount={24}
34
33
  itemContent={(_, item) => (
35
- <Link href={urlJoin('/discover/model/', item.identifier)} key={item.identifier}>
36
- <Card showCategory {...item} />
37
- </Link>
34
+ <Card
35
+ href={urlJoin('/discover/model', item.identifier)}
36
+ key={item.identifier}
37
+ showCategory
38
+ {...item}
39
+ />
38
40
  )}
39
41
  style={{
40
42
  minHeight: '75vh',
@@ -51,9 +53,12 @@ const List = memo<ListProps>(({ category, searchKeywords, items = [] }) => {
51
53
  data={items}
52
54
  initialItemCount={24}
53
55
  itemContent={(_, item) => (
54
- <Link href={urlJoin('/discover/model/', item.identifier)} key={item.identifier}>
55
- <Card showCategory={!category} {...item} />
56
- </Link>
56
+ <Card
57
+ href={urlJoin('/discover/model/', item.identifier)}
58
+ key={item.identifier}
59
+ showCategory={!category}
60
+ {...item}
61
+ />
57
62
  )}
58
63
  style={{
59
64
  minHeight: '75vh',
@@ -25,8 +25,6 @@ const useStyles = createStyles(({ css, token, isDarkMode }) => ({
25
25
  opacity: ${isDarkMode ? 0.9 : 0.4};
26
26
  `,
27
27
  container: css`
28
- cursor: pointer;
29
-
30
28
  position: relative;
31
29
 
32
30
  overflow: hidden;
@@ -66,13 +64,14 @@ const useStyles = createStyles(({ css, token, isDarkMode }) => ({
66
64
  interface PluginCardProps
67
65
  extends Omit<DiscoverPlugintem, 'manifest' | 'suggestions' | 'socialData'> {
68
66
  className?: string;
67
+ href: string;
69
68
  showCategory?: boolean;
70
69
  style?: CSSProperties;
71
70
  variant?: 'default' | 'compact';
72
71
  }
73
72
 
74
73
  const PluginCard = memo<PluginCardProps>(
75
- ({ className, showCategory, meta, createdAt, author, variant, style }) => {
74
+ ({ className, showCategory, meta, createdAt, author, variant, style, href }) => {
76
75
  const { avatar, title, description, tags = [], category } = meta;
77
76
  const categoryItem = useCategoryItem(category, 12);
78
77
  const { cx, styles, theme } = useStyles();
@@ -81,47 +80,57 @@ const PluginCard = memo<PluginCardProps>(
81
80
  return (
82
81
  <Flexbox className={cx(styles.container, className)} gap={24} style={style}>
83
82
  {!isCompact && <CardBanner avatar={avatar} />}
84
- <Flexbox className={styles.inner} gap={12}>
85
- <Flexbox align={'flex-end'} gap={16} horizontal justify={'space-between'} width={'100%'}>
86
- <Title className={styles.title} ellipsis={{ rows: 1, tooltip: title }} level={3}>
87
- {title}
88
- </Title>
89
- {isCompact ? (
90
- <Avatar avatar={avatar} size={40} style={{ display: 'block' }} title={title} />
91
- ) : (
92
- <Center
93
- flex={'none'}
94
- height={64}
95
- style={{
96
- background: theme.colorBgContainer,
97
- borderRadius: '50%',
98
- marginTop: -6,
99
- overflow: 'hidden',
100
- zIndex: 2,
101
- }}
102
- width={64}
83
+ <Flexbox gap={12} padding={16}>
84
+ <Link href={href}>
85
+ <Flexbox gap={12}>
86
+ <Flexbox
87
+ align={'flex-end'}
88
+ gap={16}
89
+ horizontal
90
+ justify={'space-between'}
91
+ width={'100%'}
103
92
  >
104
- <Avatar
105
- alt={title}
106
- avatar={avatar}
107
- size={56}
108
- style={{ display: 'block' }}
109
- title={title}
110
- />
111
- </Center>
112
- )}
113
- </Flexbox>
114
- <Flexbox gap={8} horizontal style={{ fontSize: 12 }}>
115
- <div style={{ color: theme.colorTextSecondary }}>@{author}</div>
116
- {!isCompact && (
117
- <time className={styles.time} dateTime={new Date(createdAt).toISOString()}>
118
- {createdAt}
119
- </time>
120
- )}
121
- </Flexbox>
122
- <Paragraph className={styles.desc} ellipsis={{ rows: 2 }}>
123
- {description}
124
- </Paragraph>
93
+ <Title className={styles.title} ellipsis={{ rows: 1, tooltip: title }} level={3}>
94
+ {title}
95
+ </Title>
96
+ {isCompact ? (
97
+ <Avatar avatar={avatar} size={40} style={{ display: 'block' }} title={title} />
98
+ ) : (
99
+ <Center
100
+ flex={'none'}
101
+ height={64}
102
+ style={{
103
+ background: theme.colorBgContainer,
104
+ borderRadius: '50%',
105
+ marginTop: -6,
106
+ overflow: 'hidden',
107
+ zIndex: 2,
108
+ }}
109
+ width={64}
110
+ >
111
+ <Avatar
112
+ alt={title}
113
+ avatar={avatar}
114
+ size={56}
115
+ style={{ display: 'block' }}
116
+ title={title}
117
+ />
118
+ </Center>
119
+ )}
120
+ </Flexbox>
121
+ <Flexbox gap={8} horizontal style={{ fontSize: 12 }}>
122
+ <div style={{ color: theme.colorTextSecondary }}>@{author}</div>
123
+ {!isCompact && (
124
+ <time className={styles.time} dateTime={new Date(createdAt).toISOString()}>
125
+ {createdAt}
126
+ </time>
127
+ )}
128
+ </Flexbox>
129
+ <Paragraph className={styles.desc} ellipsis={{ rows: 2 }}>
130
+ {description}
131
+ </Paragraph>
132
+ </Flexbox>
133
+ </Link>
125
134
  <Flexbox gap={6} horizontal style={{ flexWrap: 'wrap' }}>
126
135
  {showCategory && categoryItem ? (
127
136
  <Link href={urlJoin('/discover/plugins', categoryItem.key)}>
@@ -2,7 +2,6 @@
2
2
 
3
3
  import { Grid } from '@lobehub/ui';
4
4
  import { Empty } from 'antd';
5
- import Link from 'next/link';
6
5
  import { memo, useMemo } from 'react';
7
6
  import { useTranslation } from 'react-i18next';
8
7
  import urlJoin from 'url-join';
@@ -41,9 +40,13 @@ const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] })
41
40
  data={all}
42
41
  initialItemCount={24}
43
42
  itemContent={(_, item) => (
44
- <Link href={urlJoin('/discover/plugin/', item.identifier)} key={item.identifier}>
45
- <Card showCategory variant={'compact'} {...item} />
46
- </Link>
43
+ <Card
44
+ showCategory
45
+ variant={'compact'}
46
+ {...item}
47
+ href={urlJoin('/discover/plugin/', item.identifier)}
48
+ key={item.identifier}
49
+ />
47
50
  )}
48
51
  style={{
49
52
  minHeight: '75vh',
@@ -58,9 +61,12 @@ const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] })
58
61
  <Title>{t('plugins.recentSubmits')}</Title>
59
62
  <Grid maxItemWidth={280} rows={4}>
60
63
  {recent.map((item) => (
61
- <Link href={urlJoin('/discover/plugin/', item.identifier)} key={item.identifier}>
62
- <Card showCategory={!category} {...item} />
63
- </Link>
64
+ <Card
65
+ showCategory={!category}
66
+ {...item}
67
+ href={urlJoin('/discover/plugin/', item.identifier)}
68
+ key={item.identifier}
69
+ />
64
70
  ))}
65
71
  </Grid>
66
72
  {last && last?.length > 0 && (
@@ -70,9 +76,13 @@ const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] })
70
76
  data={last}
71
77
  initialItemCount={12}
72
78
  itemContent={(_, item) => (
73
- <Link href={urlJoin('/discover/plugin/', item.identifier)} key={item.identifier}>
74
- <Card showCategory={!category} variant={'compact'} {...item} />
75
- </Link>
79
+ <Card
80
+ showCategory={!category}
81
+ variant={'compact'}
82
+ {...item}
83
+ href={urlJoin('/discover/plugin/', item.identifier)}
84
+ key={item.identifier}
85
+ />
76
86
  )}
77
87
  style={{
78
88
  minHeight: '75vh',
@@ -2,13 +2,15 @@
2
2
 
3
3
  import { MobileNavBar, MobileNavBarTitle } from '@lobehub/ui';
4
4
  import { Tag } from 'antd';
5
- import { useRouter, useSearchParams } from 'next/navigation';
6
5
  import { memo } from 'react';
7
6
  import { useTranslation } from 'react-i18next';
8
7
  import { Flexbox } from 'react-layout-kit';
9
8
 
10
9
  import { useActiveSettingsKey } from '@/hooks/useActiveTabKey';
10
+ import { useQueryRoute } from '@/hooks/useQueryRoute';
11
+ import { useShowMobileWorkspace } from '@/hooks/useShowMobileWorkspace';
11
12
  import { SettingsTabs } from '@/store/global/initialState';
13
+ import { useSessionStore } from '@/store/session';
12
14
  import { useUserStore } from '@/store/user';
13
15
  import { authSelectors } from '@/store/user/selectors';
14
16
  import { mobileHeaderSticky } from '@/styles/mobileHeader';
@@ -16,14 +18,15 @@ import { mobileHeaderSticky } from '@/styles/mobileHeader';
16
18
  const Header = memo(() => {
17
19
  const { t } = useTranslation('setting');
18
20
 
19
- const router = useRouter();
20
- const searchParams = useSearchParams();
21
+ const router = useQueryRoute();
22
+ const showMobileWorkspace = useShowMobileWorkspace();
21
23
  const activeSettingsKey = useActiveSettingsKey();
22
-
24
+ const isSessionActive = useSessionStore((s) => !!s.activeId);
23
25
  const enableAuth = useUserStore(authSelectors.enabledAuth);
26
+
24
27
  const handleBackClick = () => {
25
- if (searchParams.has('session') && searchParams.has('showMobileWorkspace')) {
26
- router.push(`/chat?${searchParams.toString()}`);
28
+ if (isSessionActive && showMobileWorkspace) {
29
+ router.push('/chat');
27
30
  } else {
28
31
  router.push(enableAuth ? '/me/settings' : '/me');
29
32
  }