import reflex as rx from application.state import Turn, State from reflex.constants.colors import ColorType def message_content(text: str, color: ColorType) -> rx.Component: """Create a message content component. Args: text: The text to display. color: The color of the message. Returns: A component displaying the message. """ return rx.markdown( text, background_color=rx.color(color, 4), color=rx.color(color, 12), display="inline-block", padding_inline="1em", border_radius="8px", ) def message(turn: Turn) -> rx.Component: """A single question/answer message. Args: turn: The question/answer pair. Returns: A component displaying the question/answer pair. """ return rx.box( rx.box( message_content(turn["question"], "mauve"), text_align="right", margin_bottom="8px", ), rx.box( message_content(turn["answer"], "accent"), text_align="left", margin_bottom="8px", ), max_width="50em", margin_inline="auto", ) def chat() -> rx.Component: """List all the messages in a single conversation.""" return rx.auto_scroll( rx.foreach(State.selected_chat, message), flex="1", padding="8px", ) def action_bar() -> rx.Component: """The action bar to send a new message.""" return rx.center( rx.vstack( rx.form( rx.hstack( rx.input( rx.input.slot( rx.tooltip( rx.icon("info", size=18), content="Enter a question to get a response.", ) ), placeholder="Type something...", id="question", flex="1", ), rx.button( "Send", loading=State.processing, disabled=State.processing, type="submit", ), max_width="50em", margin="0 auto", align_items="center", ), reset_on_submit=True, on_submit=State.process_question, ), rx.text( "ReflexGPT may return factually incorrect or misleading responses. Use discretion.", text_align="center", font_size=".75em", color=rx.color("mauve", 10), ), rx.logo(margin_block="-1em"), width="100%", padding_x="16px", align="stretch", ), position="sticky", bottom="0", left="0", padding_y="16px", backdrop_filter="auto", backdrop_blur="lg", border_top=f"1px solid {rx.color('mauve', 3)}", background_color=rx.color("mauve", 2), align="stretch", width="100%", )