chat.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import reflex as rx
  2. from ...webui import styles
  3. from ...webui.components import loading_icon
  4. from ...webui.state import QA, State
  5. def message(qa: QA) -> rx.Component:
  6. """A single question/answer message.
  7. Args:
  8. qa: The question/answer pair.
  9. Returns:
  10. A component displaying the question/answer pair.
  11. """
  12. return rx.box(
  13. rx.box(
  14. rx.text(
  15. qa.question,
  16. bg=styles.border_color,
  17. shadow=styles.shadow_light,
  18. **styles.message_style,
  19. ),
  20. text_align="right",
  21. margin_top="1em",
  22. ),
  23. rx.box(
  24. rx.text(
  25. qa.answer,
  26. bg=styles.accent_color,
  27. shadow=styles.shadow_light,
  28. **styles.message_style,
  29. ),
  30. text_align="left",
  31. padding_top="1em",
  32. ),
  33. width="100%",
  34. )
  35. def chat() -> rx.Component:
  36. """List all the messages in a single conversation.
  37. Returns:
  38. A component displaying all the messages in a single conversation.
  39. """
  40. return rx.vstack(
  41. rx.box(rx.foreach(State.chats[State.current_chat], message)),
  42. py="8",
  43. flex="1",
  44. width="100%",
  45. max_w="3xl",
  46. padding_x="4",
  47. align_self="center",
  48. overflow="hidden",
  49. padding_bottom="5em",
  50. **styles.base_style[rx.Vstack],
  51. )
  52. def action_bar() -> rx.Component:
  53. """The action bar to send a new message.
  54. Returns:
  55. The action bar to send a new message.
  56. """
  57. return rx.box(
  58. rx.vstack(
  59. rx.form(
  60. rx.form_control(
  61. rx.hstack(
  62. rx.input(
  63. placeholder="Type something...",
  64. value=State.question,
  65. on_change=State.set_question,
  66. _placeholder={"color": "#fffa"},
  67. _hover={"border_color": styles.accent_color},
  68. style=styles.input_style,
  69. ),
  70. rx.button(
  71. rx.cond(
  72. State.processing,
  73. loading_icon(height="1em"),
  74. rx.text("Send"),
  75. ),
  76. type_="submit",
  77. _hover={"bg": styles.accent_color},
  78. style=styles.input_style,
  79. ),
  80. **styles.base_style[rx.Hstack],
  81. ),
  82. is_disabled=State.processing,
  83. ),
  84. on_submit=State.process_question,
  85. width="100%",
  86. ),
  87. rx.text(
  88. "ReflexGPT may return factually incorrect or misleading responses. Use discretion.",
  89. font_size="xs",
  90. color="#fff6",
  91. text_align="center",
  92. ),
  93. width="100%",
  94. max_w="3xl",
  95. mx="auto",
  96. **styles.base_style[rx.Vstack],
  97. ),
  98. position="sticky",
  99. bottom="0",
  100. left="0",
  101. py="4",
  102. backdrop_filter="auto",
  103. backdrop_blur="lg",
  104. border_top=f"1px solid {styles.border_color}",
  105. align_items="stretch",
  106. width="100%",
  107. )