Browse Source

#826 code review

Falko Schindler 2 years ago
parent
commit
a1216e6ad6
4 changed files with 43 additions and 62 deletions
  1. 9 28
      examples/chat_app/main.py
  2. 11 13
      nicegui/elements/chat_message.js
  3. 22 20
      nicegui/elements/chat_message.py
  4. 1 1
      nicegui/ui.py

+ 9 - 28
examples/chat_app/main.py

@@ -1,41 +1,22 @@
 #!/usr/bin/env python3
 #!/usr/bin/env python3
 import asyncio
 import asyncio
-
 from datetime import datetime
 from datetime import datetime
 from typing import List, Tuple
 from typing import List, Tuple
 
 
 from nicegui import Client, ui
 from nicegui import Client, ui
 
 
 messages: List[Tuple[str, str]] = []
 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()
     content.clear()
     with content:  # use the context of each client to update their ui
     with content:  # use the context of each client to update their ui
         for name, text in messages:
         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)
         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:
     async def send() -> None:
         messages.append((name.value, text.value))
         messages.append((name.value, text.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}'
     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>')
     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')
             .classes('text-xs self-end mr-8 m-[-1em] text-primary')
 
 
     await client.connected()  # update(...) uses run_javascript which is only possible after connecting
     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()
 ui.run()

+ 11 - 13
nicegui/elements/chat_message.js

@@ -1,22 +1,20 @@
 export default {
 export default {
   template: `
   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: {
   props: {
-    sent: Boolean,
     text: String,
     text: String,
-    stamp: String,
     name: String,
     name: String,
-    avatar: String,
     label: 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 typing import Optional
 
 
 from ..dependencies import register_component
 from ..dependencies import register_component
-from .mixins.disableable_element import DisableableElement
+from ..element import Element
 
 
 register_component('chat_message', __file__, 'chat_message.js')
 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,
                  stamp: Optional[str] = None,
                  avatar: Optional[str] = None,
                  avatar: Optional[str] = None,
+                 sent: bool = False,
                  ) -> None:
                  ) -> None:
         """Chat Message
         """Chat Message
 
 
         Based on Quasar's `Chat Message <https://quasar.dev/vue-components/chat/`_ component.
         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['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
             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 CardActions as card_actions
 from .elements.card import CardSection as card_section
 from .elements.card import CardSection as card_section
 from .elements.chart import Chart as chart
 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.checkbox import Checkbox as checkbox
 from .elements.color_input import ColorInput as color_input
 from .elements.color_input import ColorInput as color_input
 from .elements.color_picker import ColorPicker as color_picker
 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.tree import Tree as tree
 from .elements.upload import Upload as upload
 from .elements.upload import Upload as upload
 from .elements.video import Video as video
 from .elements.video import Video as video
-from .elements.chat_message import ChatMessage as chat_message
 from .functions.download import download
 from .functions.download import download
 from .functions.html import add_body_html, add_head_html
 from .functions.html import add_body_html, add_head_html
 from .functions.javascript import run_javascript
 from .functions.javascript import run_javascript