@huyooo/ai-chat-frontend-react 0.1.6 → 0.2.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.
Files changed (91) hide show
  1. package/README.md +368 -0
  2. package/dist/index.css +2575 -0
  3. package/dist/index.css.map +1 -0
  4. package/dist/index.d.ts +378 -135
  5. package/dist/index.js +3956 -1042
  6. package/dist/index.js.map +1 -1
  7. package/dist/style.css +48 -987
  8. package/package.json +7 -4
  9. package/src/adapter.ts +10 -70
  10. package/src/components/ChatPanel.tsx +373 -117
  11. package/src/components/common/ConfirmDialog.css +136 -0
  12. package/src/components/common/ConfirmDialog.tsx +91 -0
  13. package/src/components/common/CopyButton.css +22 -0
  14. package/src/components/common/CopyButton.tsx +46 -0
  15. package/src/components/common/IndexingSettings.css +207 -0
  16. package/src/components/common/IndexingSettings.tsx +398 -0
  17. package/src/components/common/SettingsPanel.css +256 -0
  18. package/src/components/common/SettingsPanel.tsx +120 -0
  19. package/src/components/common/Toast.css +50 -0
  20. package/src/components/common/Toast.tsx +38 -0
  21. package/src/components/common/ToggleSwitch.css +52 -0
  22. package/src/components/common/ToggleSwitch.tsx +20 -0
  23. package/src/components/header/ChatHeader.css +285 -0
  24. package/src/components/header/ChatHeader.tsx +376 -0
  25. package/src/components/input/AtFilePicker.css +147 -0
  26. package/src/components/input/AtFilePicker.tsx +519 -0
  27. package/src/components/input/ChatInput.css +204 -0
  28. package/src/components/input/ChatInput.tsx +506 -0
  29. package/src/components/input/DropdownSelector.css +159 -0
  30. package/src/components/input/DropdownSelector.tsx +195 -0
  31. package/src/components/input/ImagePreviewModal.css +124 -0
  32. package/src/components/input/ImagePreviewModal.tsx +118 -0
  33. package/src/components/input/at-views/AtBranchView.tsx +34 -0
  34. package/src/components/input/at-views/AtBrowserView.tsx +34 -0
  35. package/src/components/input/at-views/AtChatsView.tsx +34 -0
  36. package/src/components/input/at-views/AtDocsView.tsx +34 -0
  37. package/src/components/input/at-views/AtFilesView.tsx +168 -0
  38. package/src/components/input/at-views/AtTerminalsView.tsx +34 -0
  39. package/src/components/input/at-views/AtViewStyles.css +143 -0
  40. package/src/components/input/at-views/index.ts +9 -0
  41. package/src/components/message/ContentRenderer.css +9 -0
  42. package/src/components/message/ContentRenderer.tsx +63 -0
  43. package/src/components/message/MessageBubble.css +190 -0
  44. package/src/components/message/MessageBubble.tsx +231 -0
  45. package/src/components/message/PartsRenderer.css +4 -0
  46. package/src/components/message/PartsRenderer.tsx +114 -0
  47. package/src/components/message/ToolResultRenderer.tsx +21 -0
  48. package/src/components/message/WelcomeMessage.css +221 -0
  49. package/src/components/message/WelcomeMessage.tsx +93 -0
  50. package/src/components/message/blocks/CodeBlock.tsx +60 -0
  51. package/src/components/message/blocks/TextBlock.tsx +15 -0
  52. package/src/components/message/blocks/blocks.css +141 -0
  53. package/src/components/message/blocks/index.ts +6 -0
  54. package/src/components/message/parts/CollapsibleCard.css +78 -0
  55. package/src/components/message/parts/CollapsibleCard.tsx +77 -0
  56. package/src/components/message/parts/ErrorPart.css +9 -0
  57. package/src/components/message/parts/ErrorPart.tsx +40 -0
  58. package/src/components/message/parts/ImagePart.css +50 -0
  59. package/src/components/message/parts/ImagePart.tsx +54 -0
  60. package/src/components/message/parts/SearchPart.css +44 -0
  61. package/src/components/message/parts/SearchPart.tsx +63 -0
  62. package/src/components/message/parts/TextPart.css +10 -0
  63. package/src/components/message/parts/TextPart.tsx +20 -0
  64. package/src/components/message/parts/ThinkingPart.css +9 -0
  65. package/src/components/message/parts/ThinkingPart.tsx +48 -0
  66. package/src/components/message/parts/ToolCallPart.css +220 -0
  67. package/src/components/message/parts/ToolCallPart.tsx +285 -0
  68. package/src/components/message/parts/ToolResultPart.css +68 -0
  69. package/src/components/message/parts/ToolResultPart.tsx +96 -0
  70. package/src/components/message/parts/index.ts +11 -0
  71. package/src/components/message/tool-results/DefaultToolResult.tsx +26 -0
  72. package/src/components/message/tool-results/SearchResults.tsx +69 -0
  73. package/src/components/message/tool-results/WeatherCard.tsx +63 -0
  74. package/src/components/message/tool-results/index.ts +7 -0
  75. package/src/components/message/tool-results/tool-results.css +179 -0
  76. package/src/components/message/welcome-types.ts +46 -0
  77. package/src/context/AutoRunConfigContext.tsx +13 -0
  78. package/src/context/ChatAdapterContext.tsx +8 -0
  79. package/src/context/ChatInputContext.tsx +40 -0
  80. package/src/context/RenderersContext.tsx +41 -0
  81. package/src/hooks/useChat.ts +855 -237
  82. package/src/hooks/useImageUpload.ts +253 -0
  83. package/src/index.ts +96 -39
  84. package/src/styles.css +48 -987
  85. package/src/types/index.ts +172 -103
  86. package/src/utils/fileIcon.ts +49 -0
  87. package/src/components/ChatInput.tsx +0 -368
  88. package/src/components/chat/messages/ExecutionSteps.tsx +0 -234
  89. package/src/components/chat/messages/MessageBubble.tsx +0 -130
  90. package/src/components/chat/ui/ChatHeader.tsx +0 -301
  91. package/src/components/chat/ui/WelcomeMessage.tsx +0 -107
package/dist/style.css CHANGED
@@ -1,1036 +1,97 @@
1
1
  /**
2
- * AI Chat 组件样式
3
- * Vue 版本 CSS 变量保持一致
2
+ * AI Chat 全局样式
3
+ * 仅包含 CSS 变量和 ChatPanel 基础布局
4
4
  */
5
5
 
6
6
  /* CSS 变量默认值 */
7
7
  :root {
8
8
  --chat-bg: #1e1e1e;
9
+ --chat-header-bg: #1e1e1e;
9
10
  --chat-input-bg: #2d2d2d;
10
- --chat-muted: #3c3c3c;
11
- --chat-muted-hover: #444;
12
- --chat-border: #444;
11
+ --chat-dropdown-bg: #252526;
12
+ --chat-muted: #2d2d2d;
13
+ --chat-muted-hover: #3c3c3c;
14
+ --chat-border: #333;
13
15
  --chat-text: #ccc;
14
16
  --chat-text-muted: #888;
15
- --chat-scrollbar: rgba(255, 255, 255, 0.2);
16
- --chat-scrollbar-hover: rgba(255, 255, 255, 0.3);
17
- --chat-dropdown-bg: #252526;
17
+ --chat-primary: #2563eb;
18
+ --chat-primary-hover: #1d4ed8;
18
19
  --chat-destructive: #ef4444;
19
20
  --chat-destructive-hover: #dc2626;
21
+ --chat-success: #22c55e;
22
+ --chat-code-bg: #1f2937;
23
+ --chat-code-text: #e5e7eb;
24
+ --chat-scrollbar: rgba(255, 255, 255, 0.2);
25
+ --chat-scrollbar-hover: rgba(255, 255, 255, 0.3);
20
26
  }
21
27
 
22
- /* ==================== ChatPanel ==================== */
23
- .chat-panel {
24
- display: flex;
25
- flex-direction: column;
26
- width: 420px;
27
- height: 100%;
28
- background: var(--chat-bg, #1e1e1e);
29
- border-left: 1px solid var(--chat-border, #333);
30
- flex-shrink: 0;
31
- overflow: hidden;
32
- }
33
-
34
- .messages-container {
35
- flex: 1;
36
- min-height: 0;
37
- overflow-y: auto;
38
- padding: 12px;
39
- scroll-behavior: smooth;
40
- }
41
-
42
- .messages-container::-webkit-scrollbar {
28
+ /* 统一滚动条样式 - 任何需要自定义滚动条的元素添加此类 */
29
+ .chat-scrollbar::-webkit-scrollbar {
43
30
  width: 6px;
44
31
  }
45
32
 
46
- .messages-container::-webkit-scrollbar-track {
33
+ .chat-scrollbar::-webkit-scrollbar-track {
47
34
  background: transparent;
48
35
  }
49
36
 
50
- .messages-container::-webkit-scrollbar-thumb {
37
+ .chat-scrollbar::-webkit-scrollbar-thumb {
51
38
  background: var(--chat-scrollbar, rgba(255, 255, 255, 0.2));
52
39
  border-radius: 3px;
53
40
  }
54
41
 
55
- .messages-container::-webkit-scrollbar-thumb:hover {
42
+ .chat-scrollbar::-webkit-scrollbar-thumb:hover {
56
43
  background: var(--chat-scrollbar-hover, rgba(255, 255, 255, 0.3));
57
44
  }
58
45
 
59
- /* ==================== ChatInput ==================== */
60
- .chat-input {
61
- padding: 12px;
62
- }
63
-
64
- .chat-input.message-variant {
65
- padding: 0;
66
- margin-bottom: 16px;
67
- }
68
-
69
- .input-container {
46
+ /* ChatPanel 基础布局 */
47
+ .chat-panel {
70
48
  display: flex;
71
49
  flex-direction: column;
72
- background: var(--chat-input-bg, #2d2d2d);
73
- border: 1px solid var(--chat-border, #444);
74
- border-radius: 12px;
75
- padding: 12px;
76
- transition: border-color 0.15s;
77
- }
78
-
79
- .input-container.focused {
80
- border-color: rgba(255, 255, 255, 0.2);
81
- }
82
-
83
- /* 附件预览 */
84
- .attachment-preview {
85
- margin-bottom: 8px;
86
- }
87
-
88
- .preview-images {
89
- display: flex;
90
- gap: 6px;
91
- flex-wrap: wrap;
92
- }
93
-
94
- .preview-item {
95
- position: relative;
96
- }
97
-
98
- .preview-thumb {
99
- width: 48px;
100
- height: 48px;
101
- object-fit: cover;
102
- border-radius: 8px;
103
- border: 1px solid var(--chat-border, #444);
104
- }
105
-
106
- .preview-more {
107
- display: flex;
108
- align-items: center;
109
- justify-content: center;
110
- width: 48px;
111
- height: 48px;
112
- background: var(--chat-muted, #3c3c3c);
113
- border-radius: 8px;
114
- color: var(--chat-text-muted, #888);
115
- font-size: 12px;
116
- }
117
-
118
- .remove-btn {
119
- position: absolute;
120
- top: -4px;
121
- right: -4px;
122
- width: 16px;
123
- height: 16px;
124
- display: flex;
125
- align-items: center;
126
- justify-content: center;
127
- background: var(--chat-bg, #1e1e1e);
128
- border: 1px solid var(--chat-border, #444);
129
- border-radius: 50%;
130
- color: var(--chat-text-muted, #888);
131
- cursor: pointer;
132
- padding: 0;
133
- }
134
-
135
- .remove-btn:hover {
136
- background: var(--chat-muted, #3c3c3c);
137
- color: var(--chat-text, #ccc);
138
- }
139
-
140
- /* 输入框 */
141
- .input-field-wrapper {
142
- margin-bottom: 8px;
143
- }
144
-
145
- .input-field {
146
50
  width: 100%;
147
- background: transparent;
148
- border: none;
149
- padding: 0;
150
- color: var(--chat-text, #ccc);
151
- font-size: 14px;
152
- resize: none;
153
- min-height: 24px;
154
- max-height: 150px;
155
- line-height: 1.5;
156
- font-family: inherit;
157
- }
158
-
159
- .input-field:focus {
160
- outline: none;
161
- }
162
-
163
- .input-field::placeholder {
164
- color: var(--chat-text-muted, #666);
165
- }
166
-
167
- /* 底部控制栏 */
168
- .input-controls {
169
- display: flex;
170
- align-items: center;
171
- justify-content: space-between;
172
- gap: 8px;
173
- }
174
-
175
- .input-left {
176
- display: flex;
177
- align-items: center;
178
- gap: 4px;
179
- }
180
-
181
- /* 选择器 */
182
- .selector {
183
- position: relative;
184
- display: flex;
185
- align-items: center;
186
- gap: 4px;
187
- padding: 4px 8px;
188
- background: var(--chat-muted, #3c3c3c);
189
- border: none;
190
- border-radius: 6px;
191
- font-size: 12px;
192
- color: var(--chat-text-muted, #888);
193
- cursor: pointer;
194
- transition: all 0.15s;
195
- }
196
-
197
- .selector:hover {
198
- background: var(--chat-muted-hover, #444);
199
- color: var(--chat-text, #ccc);
200
- }
201
-
202
- .chevron {
203
- color: var(--chat-text-muted, #666);
204
- }
205
-
206
- /* 下拉菜单 */
207
- .dropdown-menu {
208
- position: absolute;
209
- bottom: 100%;
210
- left: 0;
211
- margin-bottom: 4px;
212
- min-width: 160px;
213
- background: var(--chat-dropdown-bg, #252526);
214
- border: 1px solid rgba(255, 255, 255, 0.1);
215
- border-radius: 8px;
216
- box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
217
- z-index: 100;
218
- padding: 4px;
219
- }
220
-
221
- .dropdown-item {
222
- display: flex;
223
- align-items: center;
224
- gap: 8px;
225
- width: 100%;
226
- padding: 8px 10px;
227
- border: none;
228
- background: transparent;
229
- border-radius: 4px;
230
- font-size: 13px;
231
- color: var(--chat-text-muted, #999);
232
- cursor: pointer;
233
- transition: all 0.15s;
234
- }
235
-
236
- .dropdown-item:hover {
237
- background: rgba(255, 255, 255, 0.08);
238
- color: var(--chat-text, #ccc);
239
- }
240
-
241
- .dropdown-item.active {
242
- background: rgba(255, 255, 255, 0.1);
243
- color: var(--chat-text, #fff);
244
- }
245
-
246
- .check-icon {
247
- margin-left: auto;
248
- color: var(--chat-text, #ccc);
249
- }
250
-
251
- /* 右侧按钮 */
252
- .input-right {
253
- display: flex;
254
- align-items: center;
255
- gap: 2px;
256
- }
257
-
258
- .icon-btn {
259
- display: flex;
260
- align-items: center;
261
- justify-content: center;
262
- width: 28px;
263
- height: 28px;
264
- background: transparent;
265
- border: none;
266
- border-radius: 6px;
267
- color: var(--chat-text-muted, #666);
268
- cursor: pointer;
269
- transition: all 0.15s;
270
- }
271
-
272
- .icon-btn:hover {
273
- color: var(--chat-text, #ccc);
274
- }
275
-
276
- .toggle-btn {
277
- display: flex;
278
- align-items: center;
279
- justify-content: center;
280
- width: 28px;
281
- height: 28px;
282
- background: transparent;
283
- border: none;
284
- border-radius: 6px;
285
- color: var(--chat-text-muted, #666);
286
- cursor: pointer;
287
- transition: all 0.15s;
288
- }
289
-
290
- .toggle-btn:hover {
291
- color: var(--chat-text, #ccc);
292
- }
293
-
294
- .toggle-btn.active {
295
- color: var(--chat-text, #fff);
296
- background: rgba(255, 255, 255, 0.1);
297
- }
298
-
299
- .send-btn {
300
- display: flex;
301
- align-items: center;
302
- justify-content: center;
303
- width: 28px;
304
- height: 28px;
305
- background: rgba(255, 255, 255, 0.9);
306
- border: none;
307
- border-radius: 6px;
308
- color: #1e1e1e;
309
- cursor: pointer;
310
- transition: all 0.15s;
311
- }
312
-
313
- .send-btn:hover {
314
- background: #fff;
315
- }
316
-
317
- .send-btn.loading {
318
- background: var(--chat-destructive, #ef4444);
319
- color: #fff;
320
- }
321
-
322
- .send-btn.loading:hover {
323
- background: var(--chat-destructive-hover, #dc2626);
324
- }
325
-
326
- /* ==================== ChatHeader ==================== */
327
- .chat-header {
328
- display: flex;
329
- height: 40px;
330
- flex-shrink: 0;
331
- align-items: center;
332
- border-bottom: 1px solid var(--chat-border, #333);
333
- }
334
-
335
- .chat-tabs {
336
- flex: 1;
337
- display: flex;
338
- align-items: center;
339
- gap: 4px;
340
- padding-left: 12px;
341
- overflow-x: auto;
342
- }
343
-
344
- .chat-tabs::-webkit-scrollbar {
345
- display: none;
346
- }
347
-
348
- .chat-tab {
349
- position: relative;
350
- display: flex;
351
- align-items: center;
352
- padding: 4px 8px;
353
- max-width: 120px;
354
- background: transparent;
355
- border: none;
356
- border-radius: 6px;
357
- font-size: 13px;
358
- font-weight: 500;
359
- color: var(--chat-text-muted, #888);
360
- cursor: pointer;
361
- transition: all 0.15s;
362
- white-space: nowrap;
363
- overflow: hidden;
364
- }
365
-
366
- .chat-tab:hover {
367
- color: var(--chat-text, #ccc);
368
- }
369
-
370
- .chat-tab.active {
371
- background: var(--chat-muted, #3c3c3c);
372
- color: var(--chat-text, #ccc);
373
- }
374
-
375
- .chat-tab-title {
376
- overflow: hidden;
377
- text-overflow: ellipsis;
378
- }
379
-
380
- .chat-tab-close {
381
- position: absolute;
382
- right: 0;
383
- top: 0;
384
51
  height: 100%;
385
- width: 20px;
386
- display: none;
387
- align-items: center;
388
- justify-content: center;
389
- background: inherit;
390
- border-radius: 0 6px 6px 0;
391
- color: var(--chat-text-muted, #666);
392
- cursor: pointer;
393
- }
394
-
395
- .chat-tab:hover .chat-tab-close {
396
- display: flex;
397
- }
398
-
399
- .chat-tab-close:hover {
400
- color: var(--chat-text, #ccc);
401
- }
402
-
403
- .chat-header-actions {
404
- display: flex;
405
- align-items: center;
406
- gap: 2px;
407
- padding-right: 12px;
408
- }
409
-
410
- .header-btn {
411
- display: flex;
412
- align-items: center;
413
- justify-content: center;
414
- width: 24px;
415
- height: 24px;
416
- background: transparent;
417
- border: none;
418
- border-radius: 6px;
419
- color: var(--chat-text-muted, #666);
420
- cursor: pointer;
421
- transition: all 0.15s;
422
- }
423
-
424
- .header-btn:hover {
425
- color: var(--chat-text, #ccc);
426
- }
427
-
428
- .header-btn.active {
429
- color: var(--chat-text, #ccc);
430
- }
431
-
432
- /* ==================== History Panel ==================== */
433
- .history-panel {
434
- position: absolute;
435
- right: 0;
436
- top: calc(100% + 4px);
437
- width: 370px;
438
- max-height: 300px;
439
- overflow-y: auto;
440
- background: var(--chat-dropdown-bg, #252526);
441
- border: 1px solid rgba(255, 255, 255, 0.1);
442
- border-radius: 8px;
443
- box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
444
- z-index: 100;
445
- padding: 4px;
446
- }
447
-
448
- .history-empty {
449
- padding: 24px;
450
- text-align: center;
451
- font-size: 12px;
452
- color: var(--chat-text-muted, #666);
453
- }
454
-
455
- .history-item {
456
- display: flex;
457
- align-items: center;
458
- gap: 6px;
459
- padding: 6px 8px;
460
- border-radius: 4px;
461
- transition: all 0.15s;
462
- }
463
-
464
- .history-item:hover {
465
- background: rgba(255, 255, 255, 0.08);
466
- }
467
-
468
- .history-item.active {
469
- background: rgba(255, 255, 255, 0.1);
470
- }
471
-
472
- .history-item-content {
473
- flex: 1;
474
- display: flex;
475
- align-items: center;
476
- gap: 6px;
477
- min-width: 0;
478
- background: transparent;
479
- border: none;
480
- padding: 0;
481
- cursor: pointer;
482
- font-size: 12px;
483
- color: var(--chat-text-muted, #888);
484
- text-align: left;
485
- }
486
-
487
- .history-item:hover .history-item-content,
488
- .history-item.active .history-item-content {
489
- color: var(--chat-text, #ccc);
490
- }
491
-
492
- .history-item-title {
493
- flex: 1;
52
+ background: var(--chat-bg, #1e1e1e);
494
53
  overflow: hidden;
495
- text-overflow: ellipsis;
496
- white-space: nowrap;
497
- }
498
-
499
- .history-item-time {
500
- font-size: 10px;
501
- color: var(--chat-text-muted, #666);
502
- flex-shrink: 0;
503
- }
504
-
505
- .history-item-actions {
506
- display: flex;
507
- gap: 2px;
508
- opacity: 0;
509
- transition: opacity 0.15s;
510
- }
511
-
512
- .history-item:hover .history-item-actions {
513
- opacity: 1;
514
- }
515
-
516
- .history-action-btn {
517
- display: flex;
518
- align-items: center;
519
- justify-content: center;
520
- width: 20px;
521
- height: 20px;
522
- background: transparent;
523
- border: none;
524
- border-radius: 4px;
525
- color: var(--chat-text-muted, #666);
526
- cursor: pointer;
527
- transition: all 0.15s;
528
- }
529
-
530
- .history-action-btn:hover {
531
- background: rgba(255, 255, 255, 0.1);
532
- color: var(--chat-text, #ccc);
533
54
  }
534
55
 
535
- .history-action-btn.delete:hover {
536
- background: rgba(239, 68, 68, 0.1);
537
- color: var(--chat-destructive, #ef4444);
538
- }
539
-
540
- /* ==================== More Menu ==================== */
541
- .more-menu {
542
- position: absolute;
543
- right: 0;
544
- top: calc(100% + 4px);
545
- min-width: 180px;
546
- background: var(--chat-dropdown-bg, #252526);
547
- border: 1px solid rgba(255, 255, 255, 0.1);
548
- border-radius: 8px;
549
- box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
550
- z-index: 100;
551
- padding: 4px;
552
- }
553
-
554
- .menu-item {
555
- display: flex;
556
- align-items: center;
557
- justify-content: space-between;
558
- width: 100%;
559
- padding: 8px 10px;
560
- border: none;
561
- background: transparent;
562
- border-radius: 4px;
563
- font-size: 12px;
564
- color: var(--chat-text, #ccc);
565
- cursor: pointer;
566
- transition: all 0.15s;
567
- white-space: nowrap;
568
- }
569
-
570
- .menu-item:hover {
571
- background: rgba(255, 255, 255, 0.08);
572
- }
573
-
574
- .menu-shortcut {
575
- font-size: 10px;
576
- color: var(--chat-text-muted, #666);
577
- }
578
-
579
- .menu-divider {
580
- height: 1px;
581
- background: var(--chat-border, #333);
582
- margin: 4px 0;
583
- }
584
-
585
- /* ==================== Message Bubble ==================== */
586
- .message-bubble {
587
- margin-bottom: 16px;
588
- animation: fadeIn 0.2s ease-out;
589
- }
590
-
591
- @keyframes fadeIn {
592
- from {
593
- opacity: 0;
594
- transform: translateY(4px);
595
- }
596
- to {
597
- opacity: 1;
598
- transform: translateY(0);
599
- }
600
- }
601
-
602
- .assistant-message {
56
+ .messages-wrapper {
57
+ flex: 1;
58
+ min-height: 0;
59
+ position: relative;
603
60
  display: flex;
604
61
  flex-direction: column;
605
- gap: 4px;
606
62
  }
607
63
 
608
- .message-content {
609
- font-size: 14px;
610
- line-height: 1.7;
611
- color: var(--chat-text, #ccc);
612
- word-break: break-word;
613
- }
614
-
615
- .message-content pre {
616
- background: var(--chat-muted, #2d2d2d);
617
- border-radius: 6px;
64
+ .messages-container {
65
+ flex: 1;
66
+ min-height: 0;
67
+ overflow-y: auto;
618
68
  padding: 12px;
619
- overflow-x: auto;
620
- font-size: 13px;
621
- margin: 8px 0;
622
- }
623
-
624
- .message-content code {
625
- background: var(--chat-muted, #3c3c3c);
626
- padding: 2px 6px;
627
- border-radius: 4px;
628
- font-size: 13px;
629
- }
630
-
631
- .message-actions {
632
- display: flex;
633
- justify-content: flex-end;
634
- gap: 2px;
69
+ scroll-behavior: smooth;
635
70
  }
636
71
 
637
- .action-btn {
72
+ /* 滚动到底部按钮 */
73
+ .scroll-to-bottom-btn {
74
+ position: absolute;
75
+ bottom: 16px;
76
+ right: 16px;
638
77
  display: flex;
639
78
  align-items: center;
640
79
  justify-content: center;
641
- width: 24px;
642
- height: 24px;
643
- background: transparent;
644
- border: none;
645
- border-radius: 4px;
646
- color: var(--chat-text-muted, #666);
647
- cursor: pointer;
648
- transition: all 0.15s;
649
- }
650
-
651
- .action-btn:hover {
652
- color: var(--chat-text, #ccc);
653
- }
654
-
655
- .action-btn.copied {
656
- color: #22c55e;
657
- }
658
-
659
- /* ==================== Execution Steps ==================== */
660
- .execution-steps {
661
- margin-bottom: 8px;
662
- }
663
-
664
- .step-item {
665
- padding: 4px 0;
666
- }
667
-
668
- .step-header {
669
- display: flex;
670
- align-items: center;
671
- gap: 4px;
672
- font-size: 12px;
673
- font-weight: 500;
674
- color: var(--chat-text-muted, #888);
675
- cursor: pointer;
676
- background: transparent;
677
- border: none;
678
- padding: 0;
679
- width: 100%;
680
- text-align: left;
681
- transition: color 0.15s;
682
- }
683
-
684
- .step-header:hover {
685
- color: var(--chat-text, #ccc);
686
- }
687
-
688
- .step-header.running {
689
- color: var(--chat-text-muted, #888);
690
- }
691
-
692
- .step-icon {
693
- width: 14px;
694
- height: 14px;
695
- flex-shrink: 0;
696
- }
697
-
698
- .step-icon.pulse {
699
- animation: pulse 2s infinite;
700
- }
701
-
702
- @keyframes pulse {
703
- 0%,
704
- 100% {
705
- opacity: 1;
706
- }
707
- 50% {
708
- opacity: 0.5;
709
- }
710
- }
711
-
712
- .step-title {
713
- flex: 1;
714
- }
715
-
716
- .step-extra {
717
- font-size: 11px;
718
- color: var(--chat-text-muted, #666);
719
- margin-left: auto;
720
- }
721
-
722
- .step-chevron {
723
- width: 12px;
724
- height: 12px;
725
- opacity: 0.5;
726
- }
727
-
728
- .step-detail {
729
- margin-top: 6px;
730
- padding: 8px 12px;
731
- background: var(--chat-muted, #2d2d2d);
732
- border: 1px solid var(--chat-border, #333);
733
- border-radius: 6px;
734
- overflow: hidden;
735
- }
736
-
737
- .step-detail pre {
738
- margin: 0;
739
- font-size: 11px;
740
- line-height: 1.7;
741
- color: var(--chat-text-muted, #888);
742
- white-space: pre-wrap;
743
- word-break: break-word;
744
- }
745
-
746
- /* 搜索结果 */
747
- .search-result-item {
748
- display: block;
749
- padding: 6px 8px;
750
- background: var(--chat-bg, #1e1e1e);
751
- border: 1px solid var(--chat-border, #333);
752
- border-radius: 4px;
753
- margin-bottom: 6px;
754
- text-decoration: none;
755
- transition: all 0.15s;
756
- }
757
-
758
- .search-result-item:last-child {
759
- margin-bottom: 0;
760
- }
761
-
762
- .search-result-item:hover {
763
- background: var(--chat-muted, #2d2d2d);
764
- }
765
-
766
- .search-result-title {
767
- display: flex;
768
- align-items: center;
769
- gap: 6px;
770
- font-size: 11px;
771
- font-weight: 500;
772
- color: var(--chat-text, #ccc);
773
- }
774
-
775
- .search-result-title span {
776
- overflow: hidden;
777
- text-overflow: ellipsis;
778
- white-space: nowrap;
779
- }
780
-
781
- .search-result-snippet {
782
- font-size: 10px;
783
- color: var(--chat-text-muted, #666);
784
- margin-top: 4px;
785
- display: -webkit-box;
786
- -webkit-line-clamp: 2;
787
- -webkit-box-orient: vertical;
788
- overflow: hidden;
789
- }
790
-
791
- /* ==================== Welcome Message ==================== */
792
- .welcome-message {
793
- flex: 1;
794
- display: flex;
795
- flex-direction: column;
796
- padding: 24px 16px;
797
- overflow-y: auto;
798
- position: relative;
799
- }
800
-
801
- .welcome-glow {
802
- position: absolute;
803
- width: 224px;
804
- height: 224px;
80
+ width: 32px;
81
+ height: 32px;
805
82
  border-radius: 50%;
806
- filter: blur(100px);
807
- opacity: 0.5;
808
- pointer-events: none;
809
- animation: pulse 4s infinite;
810
- }
811
-
812
- .welcome-glow.purple {
813
- top: -80px;
814
- left: -80px;
815
- background: rgba(168, 85, 247, 0.2);
816
- }
817
-
818
- .welcome-glow.blue {
819
- top: 160px;
820
- right: -80px;
821
- background: rgba(59, 130, 246, 0.2);
822
- animation-delay: 2s;
823
- }
824
-
825
- .welcome-title-area {
826
- position: relative;
827
- z-index: 1;
828
- margin-bottom: 24px;
829
- animation: slideUp 0.7s ease-out;
830
- }
831
-
832
- @keyframes slideUp {
833
- from {
834
- opacity: 0;
835
- transform: translateY(16px);
836
- }
837
- to {
838
- opacity: 1;
839
- transform: translateY(0);
840
- }
841
- }
842
-
843
- .welcome-title {
844
- font-size: 30px;
845
- font-weight: 700;
846
- letter-spacing: -0.02em;
847
- background: linear-gradient(
848
- 135deg,
849
- #fff 0%,
850
- rgba(255, 255, 255, 0.9) 50%,
851
- rgba(255, 255, 255, 0.5) 100%
852
- );
853
- -webkit-background-clip: text;
854
- -webkit-text-fill-color: transparent;
855
- background-clip: text;
856
- margin: 0 0 8px 0;
857
- line-height: 1.2;
858
- }
859
-
860
- .welcome-title-accent {
861
- color: var(--chat-primary, #818cf8);
862
- -webkit-text-fill-color: var(--chat-primary, #818cf8);
863
- }
864
-
865
- .welcome-subtitle {
866
- font-size: 14px;
867
- color: var(--chat-text-muted, #666);
868
- font-weight: 300;
869
- letter-spacing: 0.02em;
870
- animation: slideUp 0.7s ease-out 0.2s both;
871
- }
872
-
873
- /* 快捷操作 */
874
- .quick-actions {
875
- position: relative;
876
- z-index: 1;
877
- display: grid;
878
- grid-template-columns: repeat(2, 1fr);
879
- gap: 12px;
880
- }
881
-
882
- .quick-action-btn {
883
- position: relative;
884
- overflow: hidden;
885
- padding: 16px;
886
- background: rgba(255, 255, 255, 0.02);
887
- border: 1px solid rgba(255, 255, 255, 0.05);
888
- border-radius: 16px;
83
+ background: var(--chat-bubble-bg, #2d2d2d);
84
+ border: 1px solid var(--chat-border, #3d3d3d);
85
+ color: var(--chat-text-secondary, #888);
889
86
  cursor: pointer;
890
- text-align: left;
891
- display: flex;
892
- flex-direction: column;
893
- justify-content: space-between;
894
- transition: all 0.5s;
895
- animation: slideUp 0.7s ease-out both;
87
+ transition: all 0.2s ease;
88
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
89
+ z-index: 10;
90
+ pointer-events: auto;
896
91
  }
897
92
 
898
- .quick-action-btn:nth-child(1) {
899
- animation-delay: 0.4s;
900
- }
901
- .quick-action-btn:nth-child(2) {
902
- animation-delay: 0.5s;
903
- }
904
- .quick-action-btn:nth-child(3) {
905
- animation-delay: 0.6s;
906
- }
907
- .quick-action-btn:nth-child(4) {
908
- animation-delay: 0.7s;
909
- }
910
-
911
- .quick-action-btn.featured {
912
- grid-column: span 2;
913
- height: 112px;
914
- }
915
-
916
- .quick-action-btn:not(.featured) {
917
- height: 96px;
918
- }
919
-
920
- .quick-action-btn:hover {
921
- border-color: rgba(255, 255, 255, 0.1);
922
- background: rgba(255, 255, 255, 0.04);
923
- transform: translateY(-2px);
924
- }
925
-
926
- .quick-action-gradient {
927
- position: absolute;
928
- inset: 0;
929
- opacity: 0;
930
- transition: opacity 0.7s;
931
- }
932
-
933
- .quick-action-btn:hover .quick-action-gradient {
934
- opacity: 0.3;
935
- }
936
-
937
- .quick-action-gradient.purple {
938
- background: linear-gradient(135deg, rgba(168, 85, 247, 0.2), rgba(59, 130, 246, 0.2));
939
- }
940
- .quick-action-gradient.blue {
941
- background: linear-gradient(135deg, rgba(59, 130, 246, 0.2), rgba(34, 211, 238, 0.2));
942
- }
943
- .quick-action-gradient.emerald {
944
- background: linear-gradient(135deg, rgba(16, 185, 129, 0.2), rgba(20, 184, 166, 0.2));
945
- }
946
- .quick-action-gradient.orange {
947
- background: linear-gradient(135deg, rgba(249, 115, 22, 0.2), rgba(239, 68, 68, 0.2));
948
- }
949
-
950
- .quick-action-icon {
951
- width: 20px;
952
- height: 20px;
953
- opacity: 0.8;
954
- transition: all 0.5s;
955
- }
956
-
957
- .quick-action-btn:hover .quick-action-icon {
93
+ .scroll-to-bottom-btn:hover {
94
+ background: var(--chat-bubble-bg-hover, #3a3a3a);
95
+ color: var(--chat-text, #e0e0e0);
958
96
  transform: scale(1.1);
959
- opacity: 1;
960
- }
961
-
962
- .quick-action-icon.purple {
963
- color: #a855f7;
964
- }
965
- .quick-action-icon.blue {
966
- color: #3b82f6;
967
- }
968
- .quick-action-icon.emerald {
969
- color: #10b981;
970
- }
971
- .quick-action-icon.orange {
972
- color: #f97316;
973
- }
974
-
975
- .quick-action-text {
976
- position: relative;
977
- z-index: 1;
978
- }
979
-
980
- .quick-action-label {
981
- display: block;
982
- font-size: 14px;
983
- font-weight: 500;
984
- color: rgba(255, 255, 255, 0.8);
985
- margin-bottom: 2px;
986
- transition: color 0.3s;
987
- }
988
-
989
- .quick-action-btn:hover .quick-action-label {
990
- color: #fff;
991
- }
992
-
993
- .quick-action-desc {
994
- display: block;
995
- font-size: 10px;
996
- font-weight: 500;
997
- letter-spacing: 0.05em;
998
- color: rgba(255, 255, 255, 0.3);
999
- transition: color 0.3s;
1000
- }
1001
-
1002
- .quick-action-btn:hover .quick-action-desc {
1003
- color: rgba(255, 255, 255, 0.5);
1004
- }
1005
-
1006
- .quick-action-glow {
1007
- position: absolute;
1008
- top: -32px;
1009
- right: -32px;
1010
- width: 80px;
1011
- height: 80px;
1012
- background: rgba(255, 255, 255, 0.02);
1013
- border-radius: 50%;
1014
- filter: blur(24px);
1015
- pointer-events: none;
1016
- transition: background 0.5s;
1017
- }
1018
-
1019
- .quick-action-btn:hover .quick-action-glow {
1020
- background: rgba(255, 255, 255, 0.05);
1021
- }
1022
-
1023
- .welcome-footer {
1024
- margin-top: 40px;
1025
- display: flex;
1026
- justify-content: center;
1027
- opacity: 0.3;
1028
- animation: fadeIn 1s ease-out 1s both;
1029
- }
1030
-
1031
- .welcome-footer-line {
1032
- width: 48px;
1033
- height: 4px;
1034
- border-radius: 2px;
1035
- background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.5), transparent);
1036
97
  }