@antv/dumi-theme-antv 0.8.0-beta.7 → 0.8.0-beta.9

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.
@@ -12,7 +12,7 @@ import { DatasourceCard } from "./DatasourceCard";
12
12
  import { useEventListener } from 'ahooks';
13
13
  import classnames from 'classnames';
14
14
  import _ from 'lodash';
15
- import React, { useState } from 'react';
15
+ import React, { useRef, useState } from 'react';
16
16
  import styles from "./index.module.less";
17
17
  import { SendButton } from "./SendButton";
18
18
  import { ChooseLib } from "./ChooseLib";
@@ -41,6 +41,7 @@ export var PromptTextarea = /*#__PURE__*/React.memo(function PromptTextareaInner
41
41
  var authSnap = useSnapshot(authStore);
42
42
  var _useIntl = useIntl(),
43
43
  formatMessage = _useIntl.formatMessage;
44
+ var textareaRef = useRef(null);
44
45
 
45
46
  // 将fileMeta状态移到组件内部管理
46
47
  var _useState = useState(null),
@@ -92,14 +93,17 @@ export var PromptTextarea = /*#__PURE__*/React.memo(function PromptTextareaInner
92
93
  }
93
94
  var datasourceNode = renderDatasourceCard();
94
95
  var promptTextValid = Boolean(value);
96
+ var pureSend = function pureSend() {
97
+ if (promptTextValid) {
98
+ onConfirm === null || onConfirm === void 0 || onConfirm();
99
+ }
100
+ };
95
101
  var send = function send() {
96
102
  if (!authSnap.isAuthenticated) {
97
- showLoginModal();
103
+ showLoginModal(pureSend);
98
104
  return;
99
105
  }
100
- if (promptTextValid) {
101
- onConfirm === null || onConfirm === void 0 || onConfirm();
102
- }
106
+ pureSend();
103
107
  };
104
108
  useEventListener('keydown', function (event) {
105
109
  if (event.key === 'Enter') {
@@ -109,6 +113,8 @@ export var PromptTextarea = /*#__PURE__*/React.memo(function PromptTextareaInner
109
113
  send(); // 触发自定义事件
110
114
  }
111
115
  }
116
+ }, {
117
+ target: textareaRef
112
118
  });
113
119
  return /*#__PURE__*/React.createElement("div", {
114
120
  className: classnames(styles.container, _defineProperty(_defineProperty(_defineProperty({}, styles.active, focus), styles.compact, isCompact), styles.withDatasource, Boolean(datasourceNode))),
@@ -124,6 +130,7 @@ export var PromptTextarea = /*#__PURE__*/React.memo(function PromptTextareaInner
124
130
  },
125
131
  id: "prompt-textarea",
126
132
  className: classnames(styles.promptTextarea),
133
+ ref: textareaRef,
127
134
  placeholder:
128
135
  // (!isCompact && !themeConfig.isAntVSite && ic(themeConfig.metas.description)) ||
129
136
  !isCompact && !themeConfig.isAntVSite ? typedPlaceholder : formatMessage({
@@ -7,19 +7,17 @@ import { FormattedMessage } from 'dumi';
7
7
  export var Card = function Card(_ref) {
8
8
  var _AIModeMeta$tag;
9
9
  var item = _ref.item,
10
- index = _ref.index;
10
+ index = _ref.index,
11
+ onClick = _ref.onClick;
11
12
  var query = item.query,
12
13
  description = item.description,
13
14
  _item$imageUrls = item.imageUrls,
14
15
  imageUrls = _item$imageUrls === void 0 ? [] : _item$imageUrls,
15
- link = item.link,
16
16
  tag = item.tag;
17
17
  var style = COLORS[index];
18
18
  var handleClick = function handleClick(e) {
19
19
  e.stopPropagation();
20
- var urlObj = new URL(location.href);
21
- urlObj.hash = "";
22
- window.open(urlObj.toString(), '_blank');
20
+ onClick === null || onClick === void 0 || onClick();
23
21
  };
24
22
  var popoverContent = /*#__PURE__*/React.createElement("div", {
25
23
  className: styles.popoverContent
@@ -15,12 +15,15 @@ import styles from "./index.module.less";
15
15
  import { ReloadOutlined } from "@ant-design/icons";
16
16
  import RecommendJson from "./recommend.json";
17
17
  import classnames from "classnames";
18
- import { FormattedMessage } from 'dumi';
18
+ import { FormattedMessage, useSiteData } from 'dumi';
19
+ import { sampleSize } from "lodash-es";
19
20
  export var RecommendCase = function RecommendCase(props) {
20
21
  var _useState = useState(false),
21
22
  _useState2 = _slicedToArray(_useState, 2),
22
23
  loading = _useState2[0],
23
24
  setLoading = _useState2[1];
25
+ var _useSiteData = useSiteData(),
26
+ themeConfig = _useSiteData.themeConfig;
24
27
  var _useState3 = useState([]),
25
28
  _useState4 = _slicedToArray(_useState3, 2),
26
29
  list = _useState4[0],
@@ -30,20 +33,40 @@ export var RecommendCase = function RecommendCase(props) {
30
33
  return _regeneratorRuntime().wrap(function _callee$(_context) {
31
34
  while (1) switch (_context.prev = _context.next) {
32
35
  case 0:
33
- try {
34
- setLoading(true);
35
- data = RecommendJson;
36
- setList(data.slice(0, 4));
37
- } catch (err) {
38
- console.log(err);
39
- } finally {
40
- setLoading(false);
36
+ _context.prev = 0;
37
+ setLoading(true);
38
+ data = [];
39
+ if (!(themeConfig !== null && themeConfig !== void 0 && themeConfig.recommend)) {
40
+ _context.next = 9;
41
+ break;
41
42
  }
42
- case 1:
43
+ _context.next = 6;
44
+ return fetch(themeConfig.recommend).then(function (res) {
45
+ return res.json();
46
+ });
47
+ case 6:
48
+ data = _context.sent;
49
+ _context.next = 10;
50
+ break;
51
+ case 9:
52
+ data = RecommendJson;
53
+ case 10:
54
+ setList(sampleSize(data, 4));
55
+ _context.next = 16;
56
+ break;
57
+ case 13:
58
+ _context.prev = 13;
59
+ _context.t0 = _context["catch"](0);
60
+ console.log(_context.t0);
61
+ case 16:
62
+ _context.prev = 16;
63
+ setLoading(false);
64
+ return _context.finish(16);
65
+ case 19:
43
66
  case "end":
44
67
  return _context.stop();
45
68
  }
46
- }, _callee);
69
+ }, _callee, null, [[0, 13, 16, 19]]);
47
70
  })), [list]);
48
71
  useEffect(function () {
49
72
  fetchList();
@@ -75,7 +98,11 @@ export var RecommendCase = function RecommendCase(props) {
75
98
  return /*#__PURE__*/React.createElement(Card, {
76
99
  key: item.caseId,
77
100
  item: item,
78
- index: index
101
+ index: index,
102
+ onClick: function onClick() {
103
+ var _props$onClick;
104
+ (_props$onClick = props.onClick) === null || _props$onClick === void 0 || _props$onClick.call(props, item);
105
+ }
79
106
  });
80
107
  }))));
81
108
  };
@@ -2,6 +2,7 @@
2
2
  margin-top: 32px;
3
3
  margin-left: auto;
4
4
  margin-right: auto;
5
+ z-index: 10;
5
6
  }
6
7
 
7
8
  .title {
@@ -69,6 +69,11 @@ export function HomeDialog(props) {
69
69
  style: props.promptTextareaStyle,
70
70
  onDataSummaryChange: setFileSummary
71
71
  }), /*#__PURE__*/React.createElement(RecommendCase, {
72
- className: props.recommendCaseClassName
72
+ className: props.recommendCaseClassName,
73
+ onClick: function onClick(val) {
74
+ if (val !== null && val !== void 0 && val.query) {
75
+ setPromptText(val.query);
76
+ }
77
+ }
73
78
  }));
74
79
  }
@@ -17,13 +17,11 @@ import { useRef, useState } from 'react';
17
17
  import { Form, Input, message } from 'antd';
18
18
  import CountDownButton from "../CountDownButton";
19
19
  import cls from 'classnames';
20
- import { UIA_UA_RE } from "../utils";
21
20
  import Captcha from "../Captcha";
22
21
  import { useIntl } from 'dumi';
23
22
  import "./index.less";
24
23
  import React from 'react';
25
24
  import { sendValidationCode } from "../../../model/auth";
26
- var isUIA = UIA_UA_RE.test(navigator.userAgent);
27
25
  function CheckCode(_ref) {
28
26
  var en = _ref.en,
29
27
  form = _ref.form,
@@ -15,7 +15,6 @@ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" !=
15
15
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
16
16
  import React, { useState } from 'react';
17
17
  import { Button, Checkbox, Form, Input, Modal } from 'antd';
18
- import { parse } from 'query-string';
19
18
  import { chinaMobilePhoneRE, getFingerprint, SignupRegion } from "./utils";
20
19
  import CheckCode from "./CheckCode";
21
20
  import classNames from 'classnames';
@@ -55,7 +54,7 @@ export default function LoginForm() {
55
54
  }
56
55
  function _handleLoginOrRegister() {
57
56
  _handleLoginOrRegister = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(values) {
58
- var platform, params, fingerprintRes, res, gotoFromServer, _parse, gotoFromUrl;
57
+ var platform, params, fingerprintRes;
59
58
  return _regeneratorRuntime().wrap(function _callee$(_context) {
60
59
  while (1) switch (_context.prev = _context.next) {
61
60
  case 0:
@@ -76,11 +75,6 @@ export default function LoginForm() {
76
75
  _context.next = 9;
77
76
  return loginOrRegister(params);
78
77
  case 9:
79
- res = _context.sent;
80
- gotoFromServer = res.goto;
81
- _parse = parse(window.location.search), gotoFromUrl = _parse.goto;
82
- window.location.href = gotoFromUrl || gotoFromServer || '/';
83
- case 13:
84
78
  case "end":
85
79
  return _context.stop();
86
80
  }
@@ -5,12 +5,14 @@ import React, { useEffect } from 'react';
5
5
  import { initializeAIChat } from "../../model/AIChat";
6
6
  import { initializeAuth } from "../../model/auth";
7
7
  var queryClient = new QueryClient();
8
- window.antd = antd;
9
8
  var GlobalLayout = function GlobalLayout() {
10
9
  var outlet = useOutlet();
11
10
  useEffect(function () {
12
11
  initializeAIChat();
13
12
  initializeAuth();
13
+ if (typeof window !== 'undefined') {
14
+ window.antd = antd;
15
+ }
14
16
  }, []);
15
17
  return outlet && /*#__PURE__*/React.createElement(QueryClientProvider, {
16
18
  client: queryClient
@@ -196,10 +196,16 @@ subscribeKey(AIChatStore, 'activeSessionId', function () {
196
196
  AIChatStore.codeBlock = null;
197
197
  });
198
198
  export var createPureNewSession = function createPureNewSession(title) {
199
+ var newConversationName = 'New Conversation';
200
+ if (AIChatStore.sessions.some(function (s) {
201
+ return s.title === newConversationName && s.messages.length === 0;
202
+ })) {
203
+ return;
204
+ }
199
205
  var newSessionId = crypto.randomUUID();
200
206
  AIChatStore.sessions.unshift({
201
207
  id: newSessionId,
202
- title: title !== null && title !== void 0 ? title : 'New Conversation',
208
+ title: title !== null && title !== void 0 ? title : newConversationName,
203
209
  createdAt: Date.now(),
204
210
  messages: []
205
211
  });
@@ -10,6 +10,9 @@ import request from "../utils/request";
10
10
  * @returns {boolean} 如果包含则返回 true, 否则返回 false
11
11
  */
12
12
  function hasSkipLoginParam() {
13
+ if (typeof window === 'undefined') {
14
+ return false;
15
+ }
13
16
  // 1. 获取当前 URL 的查询字符串 (例如 "?foo=bar&skipLogin=1")
14
17
  var queryString = window.location.search;
15
18
 
@@ -25,19 +28,20 @@ function hasSkipLoginParam() {
25
28
  export var authStore = proxy({
26
29
  isModalOpen: false,
27
30
  isAuthenticated: false,
28
- token: localStorage.getItem('authToken')
31
+ loginCallback: function loginCallback() {}
29
32
  });
30
33
 
31
34
  // 2. 定义 Actions (作为独立函数)
32
- export var showLoginModal = function showLoginModal() {
35
+ export var showLoginModal = function showLoginModal(callback) {
33
36
  authStore.isModalOpen = true;
37
+ authStore.loginCallback = callback;
34
38
  };
35
39
  export var hideLoginModal = function hideLoginModal() {
36
40
  authStore.isModalOpen = false;
37
41
  };
38
42
  export var loginOrRegister = /*#__PURE__*/function () {
39
43
  var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(params) {
40
- var result;
44
+ var _authStore$loginCallb;
41
45
  return _regeneratorRuntime().wrap(function _callee$(_context) {
42
46
  while (1) switch (_context.prev = _context.next) {
43
47
  case 0:
@@ -45,24 +49,20 @@ export var loginOrRegister = /*#__PURE__*/function () {
45
49
  _context.next = 3;
46
50
  return request.post('/api/modules/user/api/accounts/login_or_register', params);
47
51
  case 3:
48
- result = _context.sent;
49
- authStore.token = result.token;
50
52
  authStore.isAuthenticated = true;
51
- if (typeof window !== 'undefined') {
52
- localStorage.setItem('authToken', result.token);
53
- }
54
53
  hideLoginModal();
54
+ (_authStore$loginCallb = authStore.loginCallback) === null || _authStore$loginCallb === void 0 || _authStore$loginCallb.call(authStore);
55
55
  return _context.abrupt("return", true);
56
- case 11:
57
- _context.prev = 11;
56
+ case 9:
57
+ _context.prev = 9;
58
58
  _context.t0 = _context["catch"](0);
59
59
  console.error('Login failed in store:', _context.t0);
60
60
  return _context.abrupt("return", false);
61
- case 15:
61
+ case 13:
62
62
  case "end":
63
63
  return _context.stop();
64
64
  }
65
- }, _callee, null, [[0, 11]]);
65
+ }, _callee, null, [[0, 9]]);
66
66
  }));
67
67
  return function loginOrRegister(_x) {
68
68
  return _ref.apply(this, arguments);
@@ -85,15 +85,13 @@ export var logout = /*#__PURE__*/function () {
85
85
  console.error('Logout failed in store:', _context2.t0);
86
86
  case 8:
87
87
  _context2.prev = 8;
88
- authStore.token = null;
89
88
  authStore.isAuthenticated = false;
90
- localStorage.removeItem('authToken');
91
89
  return _context2.finish(8);
92
- case 13:
90
+ case 11:
93
91
  case "end":
94
92
  return _context2.stop();
95
93
  }
96
- }, _callee2, null, [[0, 5, 8, 13]]);
94
+ }, _callee2, null, [[0, 5, 8, 11]]);
97
95
  }));
98
96
  return function logout() {
99
97
  return _ref2.apply(this, arguments);
@@ -10,8 +10,7 @@ import { Dropdown, Input, Modal } from 'antd';
10
10
  import { Menu } from 'antd';
11
11
  import styles from "./index.module.less";
12
12
  import { useSnapshot } from 'valtio';
13
- import { AIChatStore, handleDeleteSession, handlePinSession, handleRenameSession } from "../../../../model/AIChat";
14
- import { history } from 'dumi';
13
+ import { AIChatStore, createPureNewSession, handleDeleteSession, handlePinSession, handleRenameSession } from "../../../../model/AIChat";
15
14
  import { useSetState } from "ahooks";
16
15
  import { useIntl } from 'dumi';
17
16
  export var ConversationsMenu = function ConversationsMenu() {
@@ -54,7 +53,7 @@ export var ConversationsMenu = function ConversationsMenu() {
54
53
  id: 'ai.conversations.new'
55
54
  }),
56
55
  onClick: function onClick() {
57
- return history.push('/');
56
+ return createPureNewSession();
58
57
  }
59
58
  }, {
60
59
  key: 'history',
@@ -19,7 +19,10 @@ import { useIntl } from 'dumi';
19
19
  export var MarkdownCodeBlock = function MarkdownCodeBlock(_ref) {
20
20
  var inline = _ref.inline,
21
21
  className = _ref.className,
22
- children = _ref.children;
22
+ children = _ref.children,
23
+ _ref$showRunButton = _ref.showRunButton,
24
+ showRunButtonProp = _ref$showRunButton === void 0 ? true : _ref$showRunButton;
25
+ var intl = useIntl();
23
26
  var _useCopyToClipboard = useCopyToClipboard(),
24
27
  _useCopyToClipboard2 = _slicedToArray(_useCopyToClipboard, 2),
25
28
  copyState = _useCopyToClipboard2[0],
@@ -39,7 +42,7 @@ export var MarkdownCodeBlock = function MarkdownCodeBlock(_ref) {
39
42
  var codeString = String(children).replace(/\n$/, '');
40
43
 
41
44
  // 4. 判断是否显示“运行”按钮
42
- var showRunButton = /\bimport\b/.test(codeString);
45
+ var showRunButton = showRunButtonProp && /\bimport\b/.test(codeString);
43
46
 
44
47
  // 5. 定义运行代码的逻辑
45
48
  var handleRunCode = function handleRunCode() {
@@ -48,7 +51,6 @@ export var MarkdownCodeBlock = function MarkdownCodeBlock(_ref) {
48
51
  };
49
52
 
50
53
  // 6. 返回最终的 JSX 结构
51
- var intl = useIntl();
52
54
  return /*#__PURE__*/React.createElement("div", {
53
55
  style: {
54
56
  position: 'relative',
@@ -9,7 +9,8 @@ import remarkGfm from 'remark-gfm';
9
9
  import { MarkdownCodeBlock } from "./MarkdownCodeBlock"; // 引入我们创建的自定义组件
10
10
 
11
11
  export var MarkdownComponent = function MarkdownComponent(_ref) {
12
- var content = _ref.content;
12
+ var content = _ref.content,
13
+ showRunButton = _ref.showRunButton;
13
14
  return /*#__PURE__*/React.createElement(Markdown, {
14
15
  remarkPlugins: [remarkGfm],
15
16
  rehypePlugins: [rehypeRaw],
@@ -27,7 +28,9 @@ export var MarkdownComponent = function MarkdownComponent(_ref) {
27
28
  },
28
29
  // 2. 【核心】重写 `code` 标签的渲染,使用我们自己的组件
29
30
  code: function code(props) {
30
- return /*#__PURE__*/React.createElement(MarkdownCodeBlock, props);
31
+ return /*#__PURE__*/React.createElement(MarkdownCodeBlock, _extends({
32
+ showRunButton: showRunButton
33
+ }, props));
31
34
  },
32
35
  // 3. 重写非标准 `description` 标签的渲染
33
36
  // @ts-expect-error - 告知 TypeScript 我们知道这是一个自定义的、非标准的 HTML 标签
@@ -9,7 +9,8 @@ import { Bubble } from '@ant-design/x';
9
9
  import { Button, Flex, Space, Tooltip } from 'antd';
10
10
  import { useChat } from '@ai-sdk/react';
11
11
  import { TextStreamChatTransport } from 'ai';
12
- import { history, useIntl, useSiteData } from 'dumi';
12
+ import { useIntl, useSiteData } from 'dumi';
13
+ import { findLast } from 'lodash-es';
13
14
  import React, { useEffect, useState, useMemo, useRef } from 'react';
14
15
  import { useCopyToClipboard } from 'react-use';
15
16
  import { useSnapshot } from 'valtio';
@@ -62,13 +63,11 @@ var getTextContent = function getTextContent(message) {
62
63
  }).join('');
63
64
  };
64
65
  function MsgBox(props) {
65
- var _derivedSnap$activeSe, _derivedSnap$activeSe3, _derivedSnap$activeSe5, _derivedSnap$activeSe6, _messages;
66
+ var _derivedSnap$activeSe, _derivedSnap$activeSe2, _derivedSnap$activeSe4, _derivedSnap$activeSe7, _derivedSnap$activeSe8, _messages;
66
67
  var _props$messages = props.messages,
67
68
  initialMessages = _props$messages === void 0 ? [] : _props$messages,
68
69
  _props$simple = props.simple,
69
70
  simple = _props$simple === void 0 ? false : _props$simple,
70
- _props$context = props.context,
71
- context = _props$context === void 0 ? '' : _props$context,
72
71
  onCodegen = props.onCodegen,
73
72
  title = props.title;
74
73
  var _useSiteData = useSiteData(),
@@ -93,16 +92,17 @@ function MsgBox(props) {
93
92
  _useCopyToClipboard2 = _slicedToArray(_useCopyToClipboard, 2),
94
93
  copyState = _useCopyToClipboard2[0],
95
94
  copyToClipboard = _useCopyToClipboard2[1];
96
-
95
+ var latestUserMessage = findLast((_derivedSnap$activeSe = derivedSnap.activeSession) === null || _derivedSnap$activeSe === void 0 ? void 0 : _derivedSnap$activeSe.messages, function (msg) {
96
+ return msg.role === 'user';
97
+ });
97
98
  // 使用 ref 存储动态值,避免重新创建 transport
98
99
  var anonymousUserIdRef = useRef(snap.anonymousUserId);
99
- var contextRef = useRef(props.context);
100
- var activeSessionIdRef = useRef((_derivedSnap$activeSe = derivedSnap.activeSession) === null || _derivedSnap$activeSe === void 0 ? void 0 : _derivedSnap$activeSe.id);
100
+ var activeSessionIdRef = useRef((_derivedSnap$activeSe2 = derivedSnap.activeSession) === null || _derivedSnap$activeSe2 === void 0 ? void 0 : _derivedSnap$activeSe2.id);
101
101
  useEffect(function () {
102
- var _derivedSnap$activeSe2;
102
+ var _derivedSnap$activeSe3;
103
103
  anonymousUserIdRef.current = snap.anonymousUserId;
104
- activeSessionIdRef.current = (_derivedSnap$activeSe2 = derivedSnap.activeSession) === null || _derivedSnap$activeSe2 === void 0 ? void 0 : _derivedSnap$activeSe2.id;
105
- }, [snap.anonymousUserId, (_derivedSnap$activeSe3 = derivedSnap.activeSession) === null || _derivedSnap$activeSe3 === void 0 ? void 0 : _derivedSnap$activeSe3.id]);
104
+ activeSessionIdRef.current = (_derivedSnap$activeSe3 = derivedSnap.activeSession) === null || _derivedSnap$activeSe3 === void 0 ? void 0 : _derivedSnap$activeSe3.id;
105
+ }, [snap.anonymousUserId, (_derivedSnap$activeSe4 = derivedSnap.activeSession) === null || _derivedSnap$activeSe4 === void 0 ? void 0 : _derivedSnap$activeSe4.id]);
106
106
 
107
107
  // 转换初始消息为新格式
108
108
  var convertedInitialMessages = useMemo(function () {
@@ -123,8 +123,9 @@ function MsgBox(props) {
123
123
  gptConversationId: activeSessionIdRef.current,
124
124
  anonymousUserId: anonymousUserIdRef.current,
125
125
  mountId: 'container',
126
- antvContext: props.context,
127
- library: lib
126
+ antvContext: (latestUserMessage === null || latestUserMessage === void 0 ? void 0 : latestUserMessage.context) || props.context,
127
+ library: (latestUserMessage === null || latestUserMessage === void 0 ? void 0 : latestUserMessage.lib) || lib,
128
+ mode: latestUserMessage === null || latestUserMessage === void 0 ? void 0 : latestUserMessage.mode
128
129
  };
129
130
  }
130
131
  }),
@@ -176,9 +177,12 @@ function MsgBox(props) {
176
177
 
177
178
  // 处理用户提交
178
179
  var handleSubmit = function handleSubmit() {
179
- var _derivedState$activeS3;
180
- if (!promptText.trim() || status === 'streaming' || status === 'submitted') return;
181
-
180
+ var _derivedSnap$activeSe5, _derivedState$activeS3;
181
+ var trimmedPrompt = promptText.trim();
182
+ if (!trimmedPrompt || status === 'streaming' || status === 'submitted') return;
183
+ if (!((_derivedSnap$activeSe5 = derivedSnap.activeSession.messages) !== null && _derivedSnap$activeSe5 !== void 0 && _derivedSnap$activeSe5.length)) {
184
+ derivedState.activeSession.title = trimmedPrompt;
185
+ }
182
186
  // 使用 sendMessage 函数发送新消息
183
187
  // 第二个参数传递每次请求特定的额外数据
184
188
  sendMessage({
@@ -208,17 +212,19 @@ function MsgBox(props) {
208
212
  return;
209
213
  }
210
214
  setTimeout(function () {
211
- var _derivedSnap$activeSe4;
212
- var sessionMessages = (_derivedSnap$activeSe4 = derivedSnap.activeSession) === null || _derivedSnap$activeSe4 === void 0 ? void 0 : _derivedSnap$activeSe4.messages;
215
+ var _derivedSnap$activeSe6;
216
+ var sessionMessages = (_derivedSnap$activeSe6 = derivedSnap.activeSession) === null || _derivedSnap$activeSe6 === void 0 ? void 0 : _derivedSnap$activeSe6.messages;
213
217
  if ((sessionMessages === null || sessionMessages === void 0 ? void 0 : sessionMessages.length) > 0) {
214
218
  var converted = convertToUIMessages(sessionMessages);
215
219
  // 避免无限循环,仅当消息数量或内容不同时更新
216
220
  if (messages.length !== converted.length || JSON.stringify(messages) !== JSON.stringify(converted)) {
217
221
  setMessages(converted);
218
222
  }
223
+ } else {
224
+ setMessages([]);
219
225
  }
220
226
  });
221
- }, [(_derivedSnap$activeSe5 = derivedSnap.activeSession) === null || _derivedSnap$activeSe5 === void 0 ? void 0 : _derivedSnap$activeSe5.id, (_derivedSnap$activeSe6 = derivedSnap.activeSession) === null || _derivedSnap$activeSe6 === void 0 || (_derivedSnap$activeSe6 = _derivedSnap$activeSe6.messages) === null || _derivedSnap$activeSe6 === void 0 ? void 0 : _derivedSnap$activeSe6.length]);
227
+ }, [(_derivedSnap$activeSe7 = derivedSnap.activeSession) === null || _derivedSnap$activeSe7 === void 0 ? void 0 : _derivedSnap$activeSe7.id, (_derivedSnap$activeSe8 = derivedSnap.activeSession) === null || _derivedSnap$activeSe8 === void 0 || (_derivedSnap$activeSe8 = _derivedSnap$activeSe8.messages) === null || _derivedSnap$activeSe8 === void 0 ? void 0 : _derivedSnap$activeSe8.length]);
222
228
 
223
229
  // 处理从外部(如demo页)发起的对话
224
230
  useEffect(function () {
@@ -242,13 +248,13 @@ function MsgBox(props) {
242
248
  }, []);
243
249
  useEffect(function () {
244
250
  chatScrollIntoView();
251
+ stop();
245
252
  }, [snap.activeSessionId]);
246
253
 
247
254
  // 将 messages 数组作为依赖项。当它变化时,Hook 会运行。
248
255
  var _useAutoScroll = useAutoScroll(messages),
249
256
  containerRef = _useAutoScroll.containerRef,
250
- anchorRef = _useAutoScroll.anchorRef,
251
- showScrollDownButton = _useAutoScroll.showScrollDownButton;
257
+ anchorRef = _useAutoScroll.anchorRef;
252
258
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Flex, {
253
259
  gap: "middle",
254
260
  vertical: true,
@@ -259,7 +265,8 @@ function MsgBox(props) {
259
265
  return /*#__PURE__*/React.createElement(Bubble, {
260
266
  key: msg.id || index,
261
267
  content: /*#__PURE__*/React.createElement(MarkdownComponent, {
262
- content: textContent
268
+ content: textContent,
269
+ showRunButton: !props.simple
263
270
  }),
264
271
  avatar: msg.role === 'assistant' ? avatar : null,
265
272
  footer: msg.role === 'assistant' && index > 0 && index === messages.length - 1 && status === 'ready' ? /*#__PURE__*/React.createElement(Space, {
@@ -303,7 +310,7 @@ function MsgBox(props) {
303
310
  }, /*#__PURE__*/React.createElement(Space, null, /*#__PURE__*/React.createElement("button", {
304
311
  type: "button",
305
312
  onClick: function onClick() {
306
- return history.push('/');
313
+ return createPureNewSession();
307
314
  },
308
315
  className: styles.newButton
309
316
  }, /*#__PURE__*/React.createElement(Space, null, /*#__PURE__*/React.createElement(PlusSquareOutlined, null), formatMessage({
@@ -15,7 +15,7 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
15
15
  import MonacoEditor, { loader } from '@monaco-editor/react';
16
16
  import { Drawer, Switch } from 'antd';
17
17
  import { autoType as d3AutoType, dsvFormat } from 'd3-dsv';
18
- import { useLocale, useSiteData, useIntl } from 'dumi';
18
+ import { useLocale, useSiteData, useIntl, useLocation } from 'dumi';
19
19
  import { debounce, noop } from 'lodash-es';
20
20
  import { format } from 'prettier';
21
21
  import parserBabel from 'prettier/parser-babel';
@@ -60,6 +60,7 @@ var CodeEditor = function CodeEditor(_ref) {
60
60
  onFullscreen = _ref$onFullscreen === void 0 ? noop : _ref$onFullscreen,
61
61
  _ref$showAI = _ref.showAI,
62
62
  showAI = _ref$showAI === void 0 ? true : _ref$showAI;
63
+ var umiLocation = useLocation();
63
64
  var locale = useLocale();
64
65
  var _useSiteData = useSiteData(),
65
66
  themeConfig = _useSiteData.themeConfig;
@@ -471,8 +472,10 @@ var CodeEditor = function CodeEditor(_ref) {
471
472
  return setShowAIDrawer(false);
472
473
  },
473
474
  rootClassName: styles.drawer,
474
- width: '90%'
475
+ width: '80%',
476
+ key: "".concat(umiLocation.hash, "_").concat(umiLocation.key)
475
477
  }, /*#__PURE__*/React.createElement(MsgBox, {
478
+ key: "".concat(umiLocation.hash, "_").concat(umiLocation.key),
476
479
  simple: true,
477
480
  messages: [{
478
481
  id: crypto.randomUUID(),
@@ -24,6 +24,15 @@ export var SearchResult = function SearchResult(_ref) {
24
24
  themeConfig = _useSiteData.themeConfig;
25
25
  var intl = useIntl();
26
26
  var authSnap = useSnapshot(authStore);
27
+ function pureSearch() {
28
+ createNewSession({
29
+ promptText: keywords,
30
+ mode: 'solve',
31
+ lib: !themeConfig.isAntVSite ? themeConfig.title : undefined,
32
+ jump: true,
33
+ lang: intl.locale === 'zh' ? 'zh' : 'en'
34
+ });
35
+ }
27
36
  return /*#__PURE__*/React.createElement("div", {
28
37
  className: styles.searchResult
29
38
  }, /*#__PURE__*/React.createElement("div", {
@@ -39,16 +48,10 @@ export var SearchResult = function SearchResult(_ref) {
39
48
  className: styles.result,
40
49
  onClick: function onClick() {
41
50
  if (!authSnap.isAuthenticated) {
42
- showLoginModal();
51
+ showLoginModal(pureSearch);
43
52
  return;
44
53
  }
45
- createNewSession({
46
- promptText: keywords,
47
- mode: "solve",
48
- lib: !themeConfig.isAntVSite ? themeConfig.title : undefined,
49
- jump: true,
50
- lang: intl.locale === 'zh' ? 'zh' : 'en'
51
- });
54
+ pureSearch();
52
55
  }
53
56
  }, /*#__PURE__*/React.createElement("div", {
54
57
  className: classnames(styles.title, styles.highlighted)
@@ -13,7 +13,7 @@ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o =
13
13
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
14
14
  function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
15
15
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
16
- import { CaretDownFilled, DownOutlined, GithubOutlined, LinkOutlined, LogoutOutlined, MenuOutlined, UserDeleteOutlined, UserOutlined, WechatOutlined } from '@ant-design/icons';
16
+ import { CaretDownFilled, DownOutlined, GithubOutlined, LinkOutlined, LogoutOutlined, MenuOutlined, UserDeleteOutlined, WechatOutlined } from '@ant-design/icons';
17
17
  import { Alert, Button, Dropdown, Menu, Modal, Popover } from 'antd';
18
18
  import cx from 'classnames';
19
19
  import { FormattedMessage, Link, useLocale, useSiteData } from 'dumi';
@@ -26,6 +26,7 @@ import { Navs } from "./Navs";
26
26
  import { Products } from "./Products";
27
27
  import { Search } from "./Search";
28
28
  import { findVersion } from "./utils";
29
+ import { ReactComponent as UserIcon } from "../../static/user.svg";
29
30
  import { Assistant } from '@petercatai/assistant';
30
31
  import '@petercatai/assistant/style';
31
32
  import { useLocation } from 'react-router-dom';
@@ -429,7 +430,9 @@ var HeaderComponent = function HeaderComponent(_ref) {
429
430
  icon: /*#__PURE__*/React.createElement(UserDeleteOutlined, null)
430
431
  }]
431
432
  }
432
- }, /*#__PURE__*/React.createElement("a", null, /*#__PURE__*/React.createElement(UserOutlined, null)))));
433
+ }, /*#__PURE__*/React.createElement("a", null, /*#__PURE__*/React.createElement(UserIcon, {
434
+ className: styles.userIcon
435
+ })))));
433
436
  return /*#__PURE__*/React.createElement("header", {
434
437
  className: cx(styles.header, _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({}, styles.transparent, !!transparent && !productMenuVisible), styles.isHomePage, !!isHomePage && !isAntVHome), styles.lightTheme, !!isAntVHome && !productMenuVisible && isWide), styles.isAntVHome, !!isAntVHome), styles.fixed, popupMenuVisible))
435
438
  }, bannerVisible && announcementTitle && /*#__PURE__*/React.createElement(Alert, {
@@ -460,3 +460,11 @@
460
460
  }
461
461
  }
462
462
  }
463
+
464
+ .userIcon {
465
+ font-size: 16px;
466
+ width: 1em;
467
+ height: 1em;
468
+ vertical-align: -0.2em;
469
+ fill: currentColor;
470
+ }
@@ -0,0 +1,3 @@
1
+ <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M512 74.666667C270.933333 74.666667 74.666667 270.933333 74.666667 512S270.933333 949.333333 512 949.333333 949.333333 753.066667 949.333333 512 753.066667 74.666667 512 74.666667z m0 160c70.4 0 128 57.6 128 128s-57.6 128-128 128-128-57.6-128-128 57.6-128 128-128z m236.8 507.733333c-23.466667 32-117.333333 100.266667-236.8 100.266667s-213.333333-68.266667-236.8-100.266667c-8.533333-10.666667-10.666667-21.333333-8.533333-32 29.866667-110.933333 130.133333-187.733333 245.333333-187.733333s215.466667 76.8 245.333333 187.733333c2.133333 10.666667 0 21.333333-8.533333 32z" fill="currentColor"></path>
3
+ </svg>
package/dist/utils/env.js CHANGED
@@ -11,10 +11,21 @@ export var safeWindow = function safeWindow(fn) {
11
11
  };
12
12
 
13
13
  /**
14
- * 根据当前窗口的域名动态获取 API 的 baseURL
14
+ * 根据当前环境动态获取 API 的 baseURL
15
+ * 在浏览器中,它会根据域名判断;在服务端,它会返回一个固定的生产环境地址。
15
16
  * @returns {string} API 的 baseURL
16
17
  */
17
18
  export var getBaseURL = function getBaseURL() {
19
+ // 关键:检查是否在浏览器环境
20
+ if (typeof window === 'undefined') {
21
+ // === 服务端环境 (SSR/Pre-render) ===
22
+ // 在服务端渲染时,我们无法知道用户最终会通过哪个域名访问。
23
+ // 通常,我们默认返回生产环境的 API 地址。
24
+ // 这样预渲染出的页面如果需要请求数据,会直接请求线上API。
25
+ return 'https://www.weavefox.cn';
26
+ }
27
+
28
+ // === 浏览器环境 ===
18
29
  var hostname = window.location.hostname;
19
30
 
20
31
  // 生产环境
@@ -31,5 +42,7 @@ export var getBaseURL = function getBaseURL() {
31
42
  if (hostname.endsWith('.alipay.net')) {
32
43
  return 'https://weavefox.alipay.net:8443';
33
44
  }
45
+
46
+ // 默认返回生产环境地址,适用于其他未知域名(如 localhost)
34
47
  return 'https://www.weavefox.cn';
35
48
  };
@@ -6,24 +6,12 @@ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol"
6
6
  function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
7
7
  import axios from 'axios';
8
8
  import { getBaseURL } from "./env";
9
- import { getToken } from "./auth";
10
9
  var req = axios.create({
11
10
  baseURL: getBaseURL(),
12
11
  timeout: 60000,
13
12
  withCredentials: true
14
13
  });
15
14
 
16
- // 请求拦截器
17
- req.interceptors.request.use(function (config) {
18
- var token = getToken();
19
- if (token && config.headers) {
20
- config.headers.Authorization = "Bearer ".concat(token);
21
- }
22
- return config;
23
- }, function (error) {
24
- return Promise.reject(error);
25
- });
26
-
27
15
  // 响应拦截器
28
16
  req.interceptors.response.use(
29
17
  // @ts-ignore - Temporarily ignore type mismatch if it occurs with custom ApiResponse
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antv/dumi-theme-antv",
3
- "version": "0.8.0-beta.7",
3
+ "version": "0.8.0-beta.9",
4
4
  "description": "AntV website theme based on dumi2.",
5
5
  "keywords": [
6
6
  "dumi",
@@ -1,10 +0,0 @@
1
- var TokenKey = 'My-App-Token';
2
- export var getToken = function getToken() {
3
- return localStorage.getItem(TokenKey);
4
- };
5
- export var setToken = function setToken(token) {
6
- return localStorage.setItem(TokenKey, token);
7
- };
8
- export var removeToken = function removeToken() {
9
- return localStorage.removeItem(TokenKey);
10
- };