1use ratatui::style::Color;
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
6pub enum ThemeName {
7 #[serde(rename = "dark")]
8 Dark,
9 #[serde(rename = "light")]
10 Light,
11 #[serde(rename = "midnight")]
12 Midnight,
13}
14
15impl Default for ThemeName {
16 fn default() -> Self {
17 ThemeName::Midnight
18 }
19}
20
21impl ThemeName {
22 pub fn all() -> &'static [ThemeName] {
24 &[ThemeName::Dark, ThemeName::Light, ThemeName::Midnight]
25 }
26
27 pub fn next(&self) -> ThemeName {
29 match self {
30 ThemeName::Dark => ThemeName::Light,
31 ThemeName::Light => ThemeName::Midnight,
32 ThemeName::Midnight => ThemeName::Dark,
33 }
34 }
35
36 pub fn display_name(&self) -> &'static str {
38 match self {
39 ThemeName::Dark => "Dark",
40 ThemeName::Light => "Light",
41 ThemeName::Midnight => "Midnight(默认)",
42 }
43 }
44
45 pub fn from_str(s: &str) -> ThemeName {
47 match s.to_lowercase().as_str() {
48 "dark" => ThemeName::Dark,
49 "light" => ThemeName::Light,
50 "midnight" => ThemeName::Midnight,
51 _ => ThemeName::default(),
52 }
53 }
54
55 pub fn to_str(&self) -> &'static str {
57 match self {
58 ThemeName::Dark => "dark",
59 ThemeName::Light => "light",
60 ThemeName::Midnight => "midnight",
61 }
62 }
63}
64
65#[derive(Debug, Clone)]
68pub struct Theme {
69 pub bg_primary: Color,
72 pub bg_title: Color,
74 pub bg_input: Color,
76 pub bg_panel: Color,
78
79 pub border_title: Color,
82 pub border_message: Color,
84 pub border_input: Color,
86 pub border_input_loading: Color,
88 pub border_config: Color,
90 pub separator: Color,
92
93 pub bubble_ai: Color,
96 pub bubble_ai_selected: Color,
98 pub bubble_user: Color,
100 pub bubble_user_selected: Color,
102
103 pub label_ai: Color,
106 pub label_user: Color,
108 pub label_selected: Color,
110
111 pub text_normal: Color,
114 pub text_bold: Color,
116 pub text_dim: Color,
118 pub text_very_dim: Color,
120 pub text_white: Color,
122 pub text_system: Color,
124
125 pub title_icon: Color,
128 pub title_separator: Color,
130 pub title_model: Color,
132 pub title_count: Color,
134 pub title_loading: Color,
136
137 pub input_prompt: Color,
140 pub input_prompt_loading: Color,
142 pub cursor_fg: Color,
144 pub cursor_bg: Color,
146
147 pub hint_key_fg: Color,
150 pub hint_key_bg: Color,
152 pub hint_desc: Color,
154 pub hint_separator: Color,
156
157 pub toast_success_border: Color,
160 pub toast_success_bg: Color,
162 pub toast_success_text: Color,
164 pub toast_error_border: Color,
166 pub toast_error_bg: Color,
168 pub toast_error_text: Color,
170
171 pub welcome_border: Color,
174 pub welcome_text: Color,
176 pub welcome_hint: Color,
178
179 pub model_sel_border: Color,
182 pub model_sel_title: Color,
184 pub model_sel_active: Color,
186 pub model_sel_inactive: Color,
188 pub model_sel_highlight_bg: Color,
190
191 pub config_title: Color,
194 pub config_section: Color,
196 pub config_pointer: Color,
198 pub config_label_selected: Color,
200 pub config_label: Color,
202 pub config_value: Color,
204 pub config_edit_bg: Color,
206 pub config_tab_active_bg: Color,
208 pub config_tab_active_fg: Color,
210 pub config_tab_inactive: Color,
212 pub config_hint_key: Color,
214 pub config_hint_desc: Color,
216 pub config_toggle_on: Color,
218 pub config_toggle_off: Color,
220 pub config_dim: Color,
222 pub config_api_key: Color,
224
225 pub md_h1: Color,
228 pub md_h2: Color,
230 pub md_h3: Color,
232 pub md_h4: Color,
234 pub md_heading_sep: Color,
236 pub md_inline_code_fg: Color,
238 pub md_inline_code_bg: Color,
240 pub md_list_bullet: Color,
242 pub md_blockquote_bar: Color,
244 pub md_blockquote_text: Color,
246 pub md_rule: Color,
248
249 pub code_border: Color,
252 pub code_bg: Color,
254 pub code_default: Color,
256 pub code_keyword: Color,
258 pub code_string: Color,
260 pub code_comment: Color,
262 pub code_number: Color,
264 pub code_type: Color,
266 pub code_primitive: Color,
268 pub code_macro: Color,
270 pub code_attribute: Color,
272 pub code_lifetime: Color,
274 pub code_shell_var: Color,
276
277 pub table_border: Color,
280 pub table_header: Color,
282 pub table_body: Color,
284
285 pub help_title: Color,
288 pub help_key: Color,
290 pub help_desc: Color,
292 pub help_path: Color,
294 pub help_bg: Color,
296}
297
298impl Theme {
299 pub fn from_name(name: &ThemeName) -> Self {
301 match name {
302 ThemeName::Dark => Self::dark(),
303 ThemeName::Light => Self::light(),
304 ThemeName::Midnight => Self::midnight(),
305 }
306 }
307
308 pub fn midnight() -> Self {
310 Self {
311 bg_primary: Color::Rgb(22, 22, 30),
313 bg_title: Color::Rgb(28, 28, 40),
314 bg_input: Color::Rgb(26, 26, 38),
315 bg_panel: Color::Rgb(24, 24, 34),
316
317 border_title: Color::Rgb(80, 100, 140),
319 border_message: Color::Rgb(50, 55, 70),
320 border_input: Color::Rgb(60, 100, 80),
321 border_input_loading: Color::Rgb(120, 100, 50),
322 border_config: Color::Rgb(80, 80, 110),
323 separator: Color::Rgb(50, 55, 70),
324
325 bubble_ai: Color::Rgb(38, 38, 52),
327 bubble_ai_selected: Color::Rgb(48, 48, 68),
328 bubble_user: Color::Rgb(40, 70, 120),
329 bubble_user_selected: Color::Rgb(55, 85, 140),
330
331 label_ai: Color::Rgb(120, 220, 160),
333 label_user: Color::Rgb(100, 160, 255),
334 label_selected: Color::Rgb(255, 200, 80),
335
336 text_normal: Color::Rgb(220, 220, 230),
338 text_bold: Color::Rgb(240, 210, 170),
339 text_dim: Color::Rgb(140, 140, 170),
340 text_very_dim: Color::Rgb(80, 80, 100),
341 text_white: Color::White,
342 text_system: Color::Rgb(100, 100, 120),
343
344 title_icon: Color::Rgb(120, 180, 255),
346 title_separator: Color::Rgb(60, 60, 80),
347 title_model: Color::Rgb(160, 220, 160),
348 title_count: Color::Rgb(180, 180, 200),
349 title_loading: Color::Rgb(255, 200, 80),
350
351 input_prompt: Color::Rgb(100, 200, 130),
353 input_prompt_loading: Color::Rgb(255, 200, 80),
354 cursor_fg: Color::Rgb(22, 22, 30),
355 cursor_bg: Color::Rgb(200, 210, 240),
356
357 hint_key_fg: Color::Rgb(22, 22, 30),
359 hint_key_bg: Color::Rgb(100, 110, 140),
360 hint_desc: Color::Rgb(120, 120, 150),
361 hint_separator: Color::Rgb(50, 50, 65),
362
363 toast_success_border: Color::Rgb(60, 160, 80),
365 toast_success_bg: Color::Rgb(18, 40, 25),
366 toast_success_text: Color::Rgb(140, 230, 160),
367 toast_error_border: Color::Rgb(200, 70, 70),
368 toast_error_bg: Color::Rgb(50, 18, 18),
369 toast_error_text: Color::Rgb(255, 130, 130),
370
371 welcome_border: Color::Rgb(60, 70, 90),
373 welcome_text: Color::Rgb(120, 140, 180),
374 welcome_hint: Color::Rgb(80, 90, 110),
375
376 model_sel_border: Color::Rgb(180, 160, 80),
378 model_sel_title: Color::Rgb(230, 210, 120),
379 model_sel_active: Color::Rgb(120, 220, 160),
380 model_sel_inactive: Color::Rgb(180, 180, 200),
381 model_sel_highlight_bg: Color::Rgb(50, 55, 80),
382
383 config_title: Color::Rgb(120, 180, 255),
385 config_section: Color::Rgb(160, 220, 160),
386 config_pointer: Color::Rgb(255, 200, 80),
387 config_label_selected: Color::Rgb(230, 210, 120),
388 config_label: Color::Rgb(140, 140, 160),
389 config_value: Color::Rgb(180, 180, 200),
390 config_edit_bg: Color::Rgb(50, 55, 80),
391 config_tab_active_bg: Color::Rgb(120, 180, 255),
392 config_tab_active_fg: Color::Rgb(22, 22, 30),
393 config_tab_inactive: Color::Rgb(150, 150, 170),
394 config_hint_key: Color::Rgb(230, 210, 120),
395 config_hint_desc: Color::Rgb(120, 120, 150),
396 config_toggle_on: Color::Rgb(120, 220, 160),
397 config_toggle_off: Color::Rgb(200, 100, 100),
398 config_dim: Color::Rgb(80, 80, 100),
399 config_api_key: Color::Rgb(100, 100, 120),
400
401 md_h1: Color::Rgb(100, 180, 255),
403 md_h2: Color::Rgb(130, 190, 255),
404 md_h3: Color::Rgb(160, 200, 255),
405 md_h4: Color::Rgb(180, 210, 255),
406 md_heading_sep: Color::Rgb(60, 70, 100),
407 md_inline_code_fg: Color::Rgb(230, 190, 120),
408 md_inline_code_bg: Color::Rgb(45, 45, 60),
409 md_list_bullet: Color::Rgb(100, 160, 255),
410 md_blockquote_bar: Color::Rgb(80, 100, 140),
411 md_blockquote_text: Color::Rgb(150, 160, 180),
412 md_rule: Color::Rgb(70, 75, 90),
413
414 code_border: Color::Rgb(80, 90, 110),
416 code_bg: Color::Rgb(30, 30, 42),
417 code_default: Color::Rgb(171, 178, 191),
418 code_keyword: Color::Rgb(198, 120, 221),
419 code_string: Color::Rgb(152, 195, 121),
420 code_comment: Color::Rgb(92, 99, 112),
421 code_number: Color::Rgb(209, 154, 102),
422 code_type: Color::Rgb(229, 192, 123),
423 code_primitive: Color::Rgb(86, 182, 194),
424 code_macro: Color::Rgb(97, 175, 239),
425 code_attribute: Color::Rgb(86, 182, 194),
426 code_lifetime: Color::Rgb(229, 192, 123),
427 code_shell_var: Color::Rgb(86, 182, 194),
428
429 table_border: Color::Rgb(60, 70, 100),
431 table_header: Color::Rgb(120, 180, 255),
432 table_body: Color::Rgb(180, 180, 200),
433
434 help_title: Color::Rgb(120, 180, 255),
436 help_key: Color::Rgb(230, 210, 120),
437 help_desc: Color::Rgb(200, 200, 220),
438 help_path: Color::Rgb(100, 100, 130),
439 help_bg: Color::Rgb(24, 24, 34),
440 }
441 }
442
443 pub fn dark() -> Self {
445 Self {
446 bg_primary: Color::Rgb(30, 30, 30),
448 bg_title: Color::Rgb(37, 37, 38),
449 bg_input: Color::Rgb(37, 37, 38),
450 bg_panel: Color::Rgb(37, 37, 38),
451
452 border_title: Color::Rgb(70, 70, 70),
454 border_message: Color::Rgb(55, 55, 55),
455 border_input: Color::Rgb(55, 80, 55),
456 border_input_loading: Color::Rgb(120, 100, 50),
457 border_config: Color::Rgb(70, 70, 70),
458 separator: Color::Rgb(55, 55, 55),
459
460 bubble_ai: Color::Rgb(40, 40, 40),
462 bubble_ai_selected: Color::Rgb(50, 50, 55),
463 bubble_user: Color::Rgb(38, 65, 110),
464 bubble_user_selected: Color::Rgb(50, 80, 130),
465
466 label_ai: Color::Rgb(80, 200, 120),
468 label_user: Color::Rgb(80, 150, 240),
469 label_selected: Color::Rgb(255, 200, 80),
470
471 text_normal: Color::Rgb(212, 212, 212),
473 text_bold: Color::Rgb(230, 200, 160),
474 text_dim: Color::Rgb(128, 128, 128),
475 text_very_dim: Color::Rgb(80, 80, 80),
476 text_white: Color::White,
477 text_system: Color::Rgb(100, 100, 100),
478
479 title_icon: Color::Rgb(100, 160, 240),
481 title_separator: Color::Rgb(60, 60, 60),
482 title_model: Color::Rgb(140, 200, 140),
483 title_count: Color::Rgb(170, 170, 170),
484 title_loading: Color::Rgb(255, 200, 80),
485
486 input_prompt: Color::Rgb(80, 180, 100),
488 input_prompt_loading: Color::Rgb(255, 200, 80),
489 cursor_fg: Color::Rgb(30, 30, 30),
490 cursor_bg: Color::Rgb(200, 200, 200),
491
492 hint_key_fg: Color::Rgb(30, 30, 30),
494 hint_key_bg: Color::Rgb(100, 100, 100),
495 hint_desc: Color::Rgb(128, 128, 128),
496 hint_separator: Color::Rgb(50, 50, 50),
497
498 toast_success_border: Color::Rgb(60, 160, 80),
500 toast_success_bg: Color::Rgb(20, 40, 25),
501 toast_success_text: Color::Rgb(140, 230, 160),
502 toast_error_border: Color::Rgb(200, 70, 70),
503 toast_error_bg: Color::Rgb(50, 20, 20),
504 toast_error_text: Color::Rgb(255, 130, 130),
505
506 welcome_border: Color::Rgb(60, 60, 60),
508 welcome_text: Color::Rgb(120, 140, 180),
509 welcome_hint: Color::Rgb(80, 80, 80),
510
511 model_sel_border: Color::Rgb(180, 160, 80),
513 model_sel_title: Color::Rgb(230, 210, 120),
514 model_sel_active: Color::Rgb(80, 200, 120),
515 model_sel_inactive: Color::Rgb(170, 170, 170),
516 model_sel_highlight_bg: Color::Rgb(50, 50, 60),
517
518 config_title: Color::Rgb(100, 160, 240),
520 config_section: Color::Rgb(140, 200, 140),
521 config_pointer: Color::Rgb(255, 200, 80),
522 config_label_selected: Color::Rgb(230, 210, 120),
523 config_label: Color::Rgb(128, 128, 128),
524 config_value: Color::Rgb(170, 170, 170),
525 config_edit_bg: Color::Rgb(50, 50, 60),
526 config_tab_active_bg: Color::Rgb(100, 160, 240),
527 config_tab_active_fg: Color::Rgb(30, 30, 30),
528 config_tab_inactive: Color::Rgb(140, 140, 140),
529 config_hint_key: Color::Rgb(230, 210, 120),
530 config_hint_desc: Color::Rgb(128, 128, 128),
531 config_toggle_on: Color::Rgb(80, 200, 120),
532 config_toggle_off: Color::Rgb(200, 100, 100),
533 config_dim: Color::Rgb(80, 80, 80),
534 config_api_key: Color::Rgb(100, 100, 100),
535
536 md_h1: Color::Rgb(80, 160, 240),
538 md_h2: Color::Rgb(100, 170, 240),
539 md_h3: Color::Rgb(120, 180, 240),
540 md_h4: Color::Rgb(140, 190, 240),
541 md_heading_sep: Color::Rgb(60, 60, 80),
542 md_inline_code_fg: Color::Rgb(220, 180, 110),
543 md_inline_code_bg: Color::Rgb(50, 50, 60),
544 md_list_bullet: Color::Rgb(80, 150, 240),
545 md_blockquote_bar: Color::Rgb(70, 90, 130),
546 md_blockquote_text: Color::Rgb(150, 150, 170),
547 md_rule: Color::Rgb(70, 70, 80),
548
549 code_border: Color::Rgb(70, 70, 80),
551 code_bg: Color::Rgb(35, 35, 38),
552 code_default: Color::Rgb(212, 212, 212),
553 code_keyword: Color::Rgb(198, 120, 221),
554 code_string: Color::Rgb(152, 195, 121),
555 code_comment: Color::Rgb(106, 115, 125),
556 code_number: Color::Rgb(209, 154, 102),
557 code_type: Color::Rgb(229, 192, 123),
558 code_primitive: Color::Rgb(86, 182, 194),
559 code_macro: Color::Rgb(97, 175, 239),
560 code_attribute: Color::Rgb(86, 182, 194),
561 code_lifetime: Color::Rgb(229, 192, 123),
562 code_shell_var: Color::Rgb(86, 182, 194),
563
564 table_border: Color::Rgb(60, 60, 80),
566 table_header: Color::Rgb(80, 160, 240),
567 table_body: Color::Rgb(170, 170, 170),
568
569 help_title: Color::Rgb(100, 160, 240),
571 help_key: Color::Rgb(230, 210, 120),
572 help_desc: Color::Rgb(200, 200, 200),
573 help_path: Color::Rgb(100, 100, 100),
574 help_bg: Color::Rgb(37, 37, 38),
575 }
576 }
577
578 pub fn light() -> Self {
580 Self {
581 bg_primary: Color::Rgb(255, 255, 255),
583 bg_title: Color::Rgb(243, 243, 243),
584 bg_input: Color::Rgb(248, 248, 248),
585 bg_panel: Color::Rgb(248, 248, 248),
586
587 border_title: Color::Rgb(190, 190, 200),
589 border_message: Color::Rgb(210, 210, 220),
590 border_input: Color::Rgb(160, 200, 160),
591 border_input_loading: Color::Rgb(180, 150, 50),
592 border_config: Color::Rgb(190, 190, 200),
593 separator: Color::Rgb(210, 210, 220),
594
595 bubble_ai: Color::Rgb(240, 240, 245),
597 bubble_ai_selected: Color::Rgb(225, 230, 240),
598 bubble_user: Color::Rgb(210, 230, 255),
599 bubble_user_selected: Color::Rgb(190, 215, 250),
600
601 label_ai: Color::Rgb(40, 140, 80),
603 label_user: Color::Rgb(30, 100, 200),
604 label_selected: Color::Rgb(180, 130, 20),
605
606 text_normal: Color::Rgb(40, 40, 50),
608 text_bold: Color::Rgb(150, 90, 30),
609 text_dim: Color::Rgb(120, 120, 140),
610 text_very_dim: Color::Rgb(170, 170, 180),
611 text_white: Color::Rgb(40, 40, 50),
612 text_system: Color::Rgb(140, 140, 160),
613
614 title_icon: Color::Rgb(40, 100, 200),
616 title_separator: Color::Rgb(200, 200, 210),
617 title_model: Color::Rgb(40, 140, 80),
618 title_count: Color::Rgb(100, 100, 120),
619 title_loading: Color::Rgb(180, 130, 20),
620
621 input_prompt: Color::Rgb(40, 140, 80),
623 input_prompt_loading: Color::Rgb(180, 130, 20),
624 cursor_fg: Color::Rgb(255, 255, 255),
625 cursor_bg: Color::Rgb(50, 100, 200),
626
627 hint_key_fg: Color::Rgb(255, 255, 255),
629 hint_key_bg: Color::Rgb(100, 110, 130),
630 hint_desc: Color::Rgb(120, 120, 140),
631 hint_separator: Color::Rgb(210, 210, 220),
632
633 toast_success_border: Color::Rgb(60, 160, 80),
635 toast_success_bg: Color::Rgb(230, 250, 235),
636 toast_success_text: Color::Rgb(30, 100, 50),
637 toast_error_border: Color::Rgb(200, 70, 70),
638 toast_error_bg: Color::Rgb(255, 235, 235),
639 toast_error_text: Color::Rgb(160, 30, 30),
640
641 welcome_border: Color::Rgb(180, 190, 210),
643 welcome_text: Color::Rgb(60, 80, 130),
644 welcome_hint: Color::Rgb(140, 150, 170),
645
646 model_sel_border: Color::Rgb(180, 160, 80),
648 model_sel_title: Color::Rgb(140, 110, 30),
649 model_sel_active: Color::Rgb(40, 140, 80),
650 model_sel_inactive: Color::Rgb(100, 100, 120),
651 model_sel_highlight_bg: Color::Rgb(225, 230, 245),
652
653 config_title: Color::Rgb(40, 100, 200),
655 config_section: Color::Rgb(40, 140, 80),
656 config_pointer: Color::Rgb(180, 130, 20),
657 config_label_selected: Color::Rgb(140, 110, 30),
658 config_label: Color::Rgb(120, 120, 140),
659 config_value: Color::Rgb(60, 60, 80),
660 config_edit_bg: Color::Rgb(225, 230, 245),
661 config_tab_active_bg: Color::Rgb(40, 100, 200),
662 config_tab_active_fg: Color::Rgb(255, 255, 255),
663 config_tab_inactive: Color::Rgb(120, 120, 140),
664 config_hint_key: Color::Rgb(140, 110, 30),
665 config_hint_desc: Color::Rgb(120, 120, 140),
666 config_toggle_on: Color::Rgb(40, 140, 80),
667 config_toggle_off: Color::Rgb(200, 80, 80),
668 config_dim: Color::Rgb(170, 170, 180),
669 config_api_key: Color::Rgb(160, 160, 170),
670
671 md_h1: Color::Rgb(30, 80, 180),
673 md_h2: Color::Rgb(40, 100, 200),
674 md_h3: Color::Rgb(50, 110, 210),
675 md_h4: Color::Rgb(60, 120, 220),
676 md_heading_sep: Color::Rgb(180, 190, 210),
677 md_inline_code_fg: Color::Rgb(160, 80, 30),
678 md_inline_code_bg: Color::Rgb(240, 235, 225),
679 md_list_bullet: Color::Rgb(30, 100, 200),
680 md_blockquote_bar: Color::Rgb(100, 130, 180),
681 md_blockquote_text: Color::Rgb(80, 90, 110),
682 md_rule: Color::Rgb(190, 195, 210),
683
684 code_border: Color::Rgb(190, 195, 210),
686 code_bg: Color::Rgb(245, 245, 248),
687 code_default: Color::Rgb(40, 40, 50),
688 code_keyword: Color::Rgb(175, 0, 219),
689 code_string: Color::Rgb(163, 21, 21),
690 code_comment: Color::Rgb(0, 128, 0),
691 code_number: Color::Rgb(9, 134, 88),
692 code_type: Color::Rgb(38, 127, 153),
693 code_primitive: Color::Rgb(0, 112, 193),
694 code_macro: Color::Rgb(121, 94, 38),
695 code_attribute: Color::Rgb(0, 112, 193),
696 code_lifetime: Color::Rgb(38, 127, 153),
697 code_shell_var: Color::Rgb(0, 112, 193),
698
699 table_border: Color::Rgb(180, 190, 210),
701 table_header: Color::Rgb(30, 80, 180),
702 table_body: Color::Rgb(60, 60, 80),
703
704 help_title: Color::Rgb(40, 100, 200),
706 help_key: Color::Rgb(140, 110, 30),
707 help_desc: Color::Rgb(50, 50, 60),
708 help_path: Color::Rgb(120, 120, 140),
709 help_bg: Color::Rgb(248, 248, 248),
710 }
711 }
712}