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

135 lines
3.3 KiB
Python

# -*- coding: utf-8 -*-
"""
会话组件
"""
from reflex import (
Component,
auto_scroll as AutoScroll,
box as Box,
button as Button,
center as Center,
color as Color,
foreach as Foreach,
form as Form,
hstack as HStack,
icon as Icon,
input as Input,
logo as Logo,
markdown as Markdown,
text as Text,
tooltip as Tooltip,
vstack as VStack,
)
from reflex.constants.colors import ColorType
from ..state import State, Turn
def message(text: str, color: ColorType) -> Component:
"""
消息组件
:param text: 文本
:param color: 颜色
:return: Component
"""
return Markdown(
text,
background_color=Color(color=color, shade=4),
color=Color(color=color, shade=12),
display="inline-block",
padding_inline="1em",
border_radius="8px",
)
def turn(turn: Turn) -> Component:
"""
对话组件
:param turn: 对话
:return: Component
"""
return Box(
Box(
message(text=turn.input_message, color="mauve"),
text_align="right",
margin_bottom="8px",
),
Box(
message(text=turn.output_message, color="accent"),
text_align="left",
margin_bottom="8px",
),
max_width="50em",
margin_inline="auto",
)
def session() -> Component:
"""
会话组件
:return: Component
"""
return AutoScroll(
Foreach(State.get_turns, turn),
flex="1",
padding="8px",
overflow_y="auto",
)
def action_bar() -> Component:
"""
输入发送栏组件
"""
return Center(
VStack(
Form(
HStack(
Input(
Input.slot(
Tooltip(
Icon("info", size=18),
content="Enter a question to get a response.",
)
),
placeholder="Type something...",
id="input_message",
flex="1",
),
Button(
"Send",
loading=State.current_session_processing,
disabled=State.current_session_processing,
type="submit",
),
max_width="50em",
margin="0 auto",
align_items="center",
),
reset_on_submit=True, # 提交后清空输入框
on_submit=State.adapt_input_message,
),
Text(
"ReflexGPT may return factually incorrect or misleading responses. Use discretion.",
text_align="center",
font_size=".75em",
color=Color("mauve", 10),
),
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 {Color('mauve', 3)}",
background_color=Color("mauve", 2),
align="stretch",
width="100%",
)