135 lines
3.3 KiB
Python
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%",
|
|
)
|