1
0
Falko Schindler 2 жил өмнө
parent
commit
a1216e6ad6

+ 9 - 28
examples/chat_app/main.py

@@ -1,41 +1,22 @@
 #!/usr/bin/env python3
 import asyncio
-
 from datetime import datetime
 from typing import List, Tuple
 
 from nicegui import Client, ui
 
 messages: List[Tuple[str, str]] = []
-contents: List[ui.column] = []
-
-
-async def update(content: ui.column) -> None:
-    # Note: Messages should come from a database
+contents: List[Tuple[ui.column, ui.input]] = []
 
-    sent = False
-    # 'sent' should be determined based on the current user
-    # which requires session/user auth - outside of scope
-    # of this example
-    # For now we just alternate for every new message
 
+async def update(content: ui.column, name_input: ui.input) -> None:
     content.clear()
     with content:  # use the context of each client to update their ui
         for name, text in messages:
-            # A simple way to show a message:
-            # ui.markdown(f'**{name or "someone"}:** {text}') \
-            #       .classes('text-lg m-2')
-
-            # A more advanced example is using quasar chat_message:
-            sent = not sent
-            avatar = f'https://robohash.org/{name}'
-            ui.chat_message(text=text,
-                            avatar=avatar,
-                            name=name,
-                            sent=sent,
-                            stamp=datetime.utcnow().isoformat()) \
-                .classes('w-full')
-
+            sent = name == name_input.value
+            avatar = f'https://robohash.org/{name or "anonymous"}'
+            stamp = datetime.utcnow().strftime('%X')
+            ui.chat_message(text=text, name=name, stamp=stamp, avatar=avatar, sent=sent).classes('w-full')
         await ui.run_javascript('window.scrollTo(0, document.body.scrollHeight)', respond=False)
 
 
@@ -44,7 +25,7 @@ async def main(client: Client):
     async def send() -> None:
         messages.append((name.value, text.value))
         text.value = ''
-        await asyncio.gather(*[update(content) for content in contents])  # run updates concurrently
+        await asyncio.gather(*[update(content, name) for content, name in contents])  # run updates concurrently
 
     anchor_style = r'a:link, a:visited {color: inherit !important; text-decoration: none; font-weight: 500}'
     ui.add_head_html(f'<style>{anchor_style}</style>')
@@ -57,8 +38,8 @@ async def main(client: Client):
             .classes('text-xs self-end mr-8 m-[-1em] text-primary')
 
     await client.connected()  # update(...) uses run_javascript which is only possible after connecting
-    contents.append(ui.column().classes('w-full max-w-2xl mx-auto'))  # save ui context for updates
-    await update(contents[-1])  # ensure all messages are shown after connecting
+    contents.append((ui.column().classes('w-full max-w-2xl mx-auto'), name))  # save ui context for updates
+    await update(*contents[-1])  # ensure all messages are shown after connecting
 
 
 ui.run()

+ 11 - 13
nicegui/elements/chat_message.js

@@ -1,22 +1,20 @@
 export default {
   template: `
-    <q-chat-message ref="chat_message"
-        :name="name"
-        :label="label"
-        :avatar="avatar"
-        :text="[text]"
-        :sent=sent
-        :stamp="stamp"
-      />
+    <q-chat-message
+      :text="[text]"
+      :name="name"
+      :label="label"
+      :stamp="stamp"
+      :avatar="avatar"
+      :sent=sent
+    />
   `,
-  methods: {
-  },
   props: {
-    sent: Boolean,
     text: String,
-    stamp: String,
     name: String,
-    avatar: String,
     label: String,
+    stamp: String,
+    avatar: String,
+    sent: Boolean,
   },
 };

+ 22 - 20
nicegui/elements/chat_message.py

@@ -1,38 +1,40 @@
 from typing import Optional
 
 from ..dependencies import register_component
-from .mixins.disableable_element import DisableableElement
+from ..element import Element
 
 register_component('chat_message', __file__, 'chat_message.js')
 
 
-class ChatMessage(DisableableElement):
+class ChatMessage(Element):
 
-    def __init__(self, *,
-                 sent: Optional[bool] = False,
-                 label: Optional[str] = '',
-                 name: Optional[str] = '',
-                 text: Optional[str] = '',
+    def __init__(self,
+                 text: str, *,
+                 name: Optional[str] = None,
+                 label: Optional[str] = None,
                  stamp: Optional[str] = None,
                  avatar: Optional[str] = None,
+                 sent: bool = False,
                  ) -> None:
         """Chat Message
 
         Based on Quasar's `Chat Message <https://quasar.dev/vue-components/chat/`_ component.
 
-        :param sent: Render as a sent message (so from current user) (default: False)
-        :param label: Adding a label adds a tiny headline between messages
-        :param name: The name of the message author
-        :param text: The message body
-        :param stamp: The time stamp of the message. (default: `None`))
-        :param avatar: URL to avatar. (default: `None`))
+        :param text: the message body
+        :param name: the name of the message author
+        :param label: renders a label header/section only
+        :param stamp: timestamp of the message
+        :param avatar: URL to an avatar
+        :param sent: render as a sent message (so from current user) (default: False)
         """
-        super().__init__(tag='chat_message')
-        self._props['sent'] = sent
+        super().__init__('chat_message')
         self._props['text'] = text
-        self._props['stamp'] = stamp
-        self._props['name'] = name
-        if avatar:
-            self._props['avatar'] = avatar
-        if stamp:
+        if name is not None:
+            self._props['name'] = name
+        if label is not None:
+            self._props['label'] = label
+        if stamp is not None:
             self._props['stamp'] = stamp
+        if avatar is not None:
+            self._props['avatar'] = avatar
+        self._props['sent'] = sent

+ 1 - 1
nicegui/ui.py

@@ -11,6 +11,7 @@ from .elements.card import Card as card
 from .elements.card import CardActions as card_actions
 from .elements.card import CardSection as card_section
 from .elements.chart import Chart as chart
+from .elements.chat_message import ChatMessage as chat_message
 from .elements.checkbox import Checkbox as checkbox
 from .elements.color_input import ColorInput as color_input
 from .elements.color_picker import ColorPicker as color_picker
@@ -62,7 +63,6 @@ from .elements.tooltip import Tooltip as tooltip
 from .elements.tree import Tree as tree
 from .elements.upload import Upload as upload
 from .elements.video import Video as video
-from .elements.chat_message import ChatMessage as chat_message
 from .functions.download import download
 from .functions.html import add_body_html, add_head_html
 from .functions.javascript import run_javascript