Python/产品需求文档AI生成/application/components/chat.py

113 lines
3.1 KiB
Python

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%",
)