|
@@ -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()
|