@fe-free/ai 4.1.27 → 4.1.28

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
@@ -1,5 +1,14 @@
1
1
  # @fe-free/ai
2
2
 
3
+ ## 4.1.28
4
+
5
+ ### Patch Changes
6
+
7
+ - feat: ai
8
+ - @fe-free/core@4.1.28
9
+ - @fe-free/icons@4.1.28
10
+ - @fe-free/tool@4.1.28
11
+
3
12
  ## 4.1.27
4
13
 
5
14
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fe-free/ai",
3
- "version": "4.1.27",
3
+ "version": "4.1.28",
4
4
  "description": "",
5
5
  "main": "./src/index.ts",
6
6
  "author": "",
@@ -19,7 +19,7 @@
19
19
  "lodash-es": "^4.17.21",
20
20
  "uuid": "^13.0.0",
21
21
  "zustand": "^4.5.7",
22
- "@fe-free/core": "4.1.27"
22
+ "@fe-free/core": "4.1.28"
23
23
  },
24
24
  "peerDependencies": {
25
25
  "antd": "^5.27.1",
@@ -29,8 +29,8 @@
29
29
  "i18next-icu": "^2.4.1",
30
30
  "react": "^19.2.0",
31
31
  "react-i18next": "^16.4.0",
32
- "@fe-free/icons": "4.1.27",
33
- "@fe-free/tool": "4.1.27"
32
+ "@fe-free/icons": "4.1.28",
33
+ "@fe-free/tool": "4.1.28"
34
34
  },
35
35
  "scripts": {
36
36
  "test": "echo \"Error: no test specified\" && exit 1",
@@ -12,7 +12,7 @@ function Actions(
12
12
  setType: (type: 'input' | 'record') => void;
13
13
  },
14
14
  ) {
15
- const { refText, loading, onSubmit, value, onChange, setType, allowSpeech } = props;
15
+ const { loading, onSubmit, value, onChange, setType, allowSpeech } = props;
16
16
 
17
17
  const isLoading = loading;
18
18
 
@@ -33,10 +33,10 @@ function Actions(
33
33
  // reset
34
34
  onChange?.({});
35
35
 
36
- // focus
37
- refText.current?.focus();
36
+ // 移动端 不 focus
37
+ // refText.current?.focus();
38
38
  }
39
- }, [isLoading, value, onSubmit, onChange, refText]);
39
+ }, [isLoading, value, onSubmit, onChange]);
40
40
 
41
41
  return (
42
42
  <div className="mr-1 flex items-center gap-2">
@@ -44,7 +44,7 @@ function Actions(
44
44
  <Button
45
45
  type="primary"
46
46
  shape="circle"
47
- icon={<Icons component={IconRecord} />}
47
+ icon={<Icons component={IconRecord} className="!text-lg" />}
48
48
  onClick={() => {
49
49
  setType('record');
50
50
  }}
@@ -53,7 +53,7 @@ function Actions(
53
53
  <Button
54
54
  type="primary"
55
55
  shape="circle"
56
- icon={<Icons component={SendIcon} />}
56
+ icon={<Icons component={SendIcon} className="!text-lg" />}
57
57
  loading={isLoading}
58
58
  onClick={handleSubmit}
59
59
  />
@@ -61,46 +61,23 @@ export const Loading: Story = {
61
61
 
62
62
  export const AllowSpeech: Story = {
63
63
  render: (props) => {
64
- const { message } = App.useApp();
65
-
66
- const { start: startRecord, stop: stopRecord } = useMemo(() => {
67
- return getRecordAudioOfPCM();
68
- }, []);
69
-
70
64
  const handleSubmit = (value: MSenderValue) => {
71
65
  console.log('handleSubmit', value);
72
66
  };
73
67
 
74
68
  const handleRecordStart = useCallback(async () => {
75
- // 假设这是录音的文本
76
- try {
77
- await startRecord({
78
- onAudio: (data) => {
79
- console.log('onAudio', data);
80
- },
81
- onError: (err) => {
82
- message.error(err.message);
83
- },
84
- });
85
- } catch (err) {
86
- console.error(err);
87
- }
88
-
89
- return;
69
+ // fake
90
70
  }, []);
91
71
 
92
72
  const handleRecordEnd = useCallback(
93
73
  async (isSend) => {
94
74
  console.log('handleRecordEnd isSend', isSend);
95
75
 
96
- const voiceData = await stopRecord();
97
- console.log('voiceData', voiceData);
98
-
99
76
  if (isSend) {
100
77
  handleSubmit({ ...(props.value || {}), text: '假设这是识别的文字' });
101
78
  }
102
79
  },
103
- [props.value, stopRecord],
80
+ [props.value],
104
81
  );
105
82
 
106
83
  return (
@@ -137,7 +114,64 @@ export const AllowSpeech: Story = {
137
114
  },
138
115
  };
139
116
 
140
- export const AllowSpeech2: Story = {
117
+ export const AllowSpeechPCM: Story = {
118
+ render: (props) => {
119
+ const { message } = App.useApp();
120
+
121
+ const { start: startRecord, stop: stopRecord } = useMemo(() => {
122
+ return getRecordAudioOfPCM();
123
+ }, []);
124
+
125
+ const handleSubmit = (value: MSenderValue) => {
126
+ console.log('handleSubmit', value);
127
+ };
128
+
129
+ const handleRecordStart = useCallback(async () => {
130
+ // 假设这是录音的文本
131
+ try {
132
+ await startRecord({
133
+ onAudio: (data) => {
134
+ console.log('onAudio', data);
135
+ },
136
+ onError: (err) => {
137
+ message.error(err.message);
138
+ },
139
+ });
140
+ } catch (err) {
141
+ console.error(err);
142
+ }
143
+
144
+ return;
145
+ }, []);
146
+
147
+ const handleRecordEnd = useCallback(
148
+ async (isSend) => {
149
+ console.log('handleRecordEnd isSend', isSend);
150
+
151
+ const voiceData = await stopRecord();
152
+ console.log('voiceData', voiceData);
153
+
154
+ if (isSend) {
155
+ handleSubmit({ ...(props.value || {}), text: '假设这是识别的文字' });
156
+ }
157
+ },
158
+ [props.value, stopRecord],
159
+ );
160
+
161
+ return (
162
+ <Component
163
+ {...props}
164
+ defaultType="record"
165
+ allowSpeech={{
166
+ onRecordStart: handleRecordStart,
167
+ onRecordEnd: handleRecordEnd,
168
+ }}
169
+ />
170
+ );
171
+ },
172
+ };
173
+
174
+ export const AllowSpeechBlob: Story = {
141
175
  render: (props) => {
142
176
  const { message } = App.useApp();
143
177
 
@@ -182,16 +216,14 @@ export const AllowSpeech2: Story = {
182
216
  );
183
217
 
184
218
  return (
185
- <div className="flex flex-col gap-10">
186
- <Component
187
- {...props}
188
- defaultType="record"
189
- allowSpeech={{
190
- onRecordStart: handleRecordStart,
191
- onRecordEnd: handleRecordEnd,
192
- }}
193
- />
194
- </div>
219
+ <Component
220
+ {...props}
221
+ defaultType="record"
222
+ allowSpeech={{
223
+ onRecordStart: handleRecordStart,
224
+ onRecordEnd: handleRecordEnd,
225
+ }}
226
+ />
195
227
  );
196
228
  },
197
229
  };
@@ -8,9 +8,18 @@ import {
8
8
  LikeOutlined,
9
9
  } from '@fe-free/icons';
10
10
  import { App, Button, Tooltip } from 'antd';
11
+ import classNames from 'classnames';
11
12
  import { useCallback, useEffect, useState } from 'react';
12
13
 
13
- function MessageActionOfCopy({ value, onCopied }: { value: string; onCopied?: () => void }) {
14
+ function MessageActionOfCopy({
15
+ value,
16
+ onCopied,
17
+ className,
18
+ }: {
19
+ value: string;
20
+ onCopied?: () => void;
21
+ className?: string;
22
+ }) {
14
23
  const [active, setActive] = useState(false);
15
24
  const { message } = App.useApp();
16
25
 
@@ -22,7 +31,11 @@ function MessageActionOfCopy({ value, onCopied }: { value: string; onCopied?: ()
22
31
 
23
32
  return (
24
33
  <Tooltip title="复制">
25
- <Copy value={value} className="cursor-pointer text-03" onCopied={handleCopied}>
34
+ <Copy
35
+ value={value}
36
+ className={classNames('cursor-pointer text-03', className)}
37
+ onCopied={handleCopied}
38
+ >
26
39
  <Button
27
40
  type="text"
28
41
  size="small"
@@ -37,9 +50,11 @@ function MessageActionOfCopy({ value, onCopied }: { value: string; onCopied?: ()
37
50
  function MessageActionOfLike({
38
51
  active: propsActive,
39
52
  onClick,
53
+ className,
40
54
  }: {
41
55
  active?: boolean;
42
56
  onClick?: (active: boolean) => Promise<void>;
57
+ className?: string;
43
58
  }) {
44
59
  const { message } = App.useApp();
45
60
  const [active, setActive] = useState(propsActive || false);
@@ -60,7 +75,7 @@ function MessageActionOfLike({
60
75
  type="text"
61
76
  onClick={handleClick}
62
77
  size="small"
63
- className="text-03"
78
+ className={classNames('text-03', className)}
64
79
  icon={active ? <LikeFilled /> : <LikeOutlined />}
65
80
  />
66
81
  </Tooltip>
@@ -70,9 +85,11 @@ function MessageActionOfLike({
70
85
  function MessageActionOfDislike({
71
86
  active: propsActive,
72
87
  onClick,
88
+ className,
73
89
  }: {
74
90
  active?: boolean;
75
91
  onClick?: (active: boolean) => Promise<void>;
92
+ className?: string;
76
93
  }) {
77
94
  const [active, setActive] = useState(propsActive || false);
78
95
  const { message } = App.useApp();
@@ -93,7 +110,7 @@ function MessageActionOfDislike({
93
110
  type="text"
94
111
  onClick={handleClick}
95
112
  size="small"
96
- className="text-03"
113
+ className={classNames('text-03', className)}
97
114
  icon={active ? <DislikeFilled /> : <DislikeOutlined />}
98
115
  />
99
116
  </Tooltip>
@@ -103,9 +120,11 @@ function MessageActionOfDislike({
103
120
  function MessageActionOfLinkAndDislike({
104
121
  value: propsValue,
105
122
  onChange,
123
+ className,
106
124
  }: {
107
125
  value?: -1 | 0 | 1;
108
126
  onChange?: (value: -1 | 0 | 1) => void;
127
+ className?: string;
109
128
  }) {
110
129
  const [value, setValue] = useState<(-1 | 0 | 1) | undefined>(propsValue);
111
130
 
@@ -122,6 +141,7 @@ function MessageActionOfLinkAndDislike({
122
141
  await Promise.resolve(onChange?.(newValue));
123
142
  setValue(newValue);
124
143
  }}
144
+ className={className}
125
145
  />
126
146
  <MessageActionOfDislike
127
147
  active={value === -1}
@@ -130,6 +150,7 @@ function MessageActionOfLinkAndDislike({
130
150
  await Promise.resolve(onChange?.(newValue));
131
151
  setValue(newValue);
132
152
  }}
153
+ className={className}
133
154
  />
134
155
  </>
135
156
  );