From 35a7523bfeb94cca00055b563e084ca06de22813 Mon Sep 17 00:00:00 2001 From: Masen Furer Date: Tue, 20 May 2025 10:56:11 -0700 Subject: [PATCH] UX niceities: enter to submit avoid disabling the question input so that it retains focus between messages --- chat/components/chat.py | 4 ++-- chat/components/navbar.py | 28 ++++++++++++++-------------- chat/state.py | 23 +++++++++++++++++------ 3 files changed, 33 insertions(+), 22 deletions(-) diff --git a/chat/components/chat.py b/chat/components/chat.py index bf99bce..bb576cf 100644 --- a/chat/components/chat.py +++ b/chat/components/chat.py @@ -73,7 +73,6 @@ def action_bar() -> rx.Component: ), placeholder="Type something...", id="question", - disabled=State.processing, flex="1", ), rx.button( @@ -86,7 +85,8 @@ def action_bar() -> rx.Component: margin="0 auto", align_items="center", ), - on_submit=[State.process_question, rx.set_value("question", "")], + reset_on_submit=True, + on_submit=State.process_question, ), rx.text( "ReflexGPT may return factually incorrect or misleading responses. Use discretion.", diff --git a/chat/components/navbar.py b/chat/components/navbar.py index 71be5bf..e71f91f 100644 --- a/chat/components/navbar.py +++ b/chat/components/navbar.py @@ -64,25 +64,25 @@ def modal(trigger) -> rx.Component: return rx.dialog.root( rx.dialog.trigger(trigger), rx.dialog.content( - rx.hstack( - rx.input( - placeholder="Chat name", - on_blur=State.set_new_chat_name, - flex="1", - min_width="20ch", - ), - rx.dialog.close( - rx.button( - "Create chat", - on_click=State.create_chat, + rx.form( + rx.hstack( + rx.input( + placeholder="Chat name", + name="new_chat_name", + flex="1", + min_width="20ch", ), + rx.button("Create chat"), + spacing="2", + wrap="wrap", + width="100%", ), - spacing="2", - wrap="wrap", - width="100%", + on_submit=State.create_chat, ), background_color=rx.color("mauve", 1), ), + open=State.is_modal_open, + on_open_change=State.set_is_modal_open, ) diff --git a/chat/state.py b/chat/state.py index 26e9ffd..a7bd678 100644 --- a/chat/state.py +++ b/chat/state.py @@ -30,15 +30,26 @@ class State(rx.State): # Whether we are processing the question. processing: bool = False - # The name of the new chat. - new_chat_name: str = "" + # Whether the new chat modal is open. + is_modal_open: bool = False @rx.event - def create_chat(self): + def create_chat(self, form_data: dict[str, Any]): """Create a new chat.""" # Add the new chat to the list of chats. - self.current_chat = self.new_chat_name - self._chats[self.new_chat_name] = [] + new_chat_name = form_data["new_chat_name"] + self.current_chat = new_chat_name + self._chats[new_chat_name] = [] + self.is_modal_open = False + + @rx.event + def set_is_modal_open(self, is_open: bool): + """Set the new chat modal open state. + + Args: + is_open: Whether the modal is open. + """ + self.is_modal_open = is_open @rx.var def selected_chat(self) -> list[QA]: @@ -97,7 +108,7 @@ async def process_question(self, form_data: dict[str, Any]): question = form_data["question"] # Check if the question is empty - if question == "": + if not question: return async for value in self.openai_process_question(question):