from nicegui import ui import time from uuid import uuid4 from api.message import Message from api.node import MeshNode chat_content = None fake = MeshNode(None) fake.name = "Some Guy" me = MeshNode(None) me.name = "SpookyDervish (You)" messages = { "Cool Guy": [ Message("hi", me), Message("hey", fake), Message("hru?", fake), Message("Good!", me), Message("hbu?", me), ], } groups = { "Cool Group": [ Message("Welcome to the group chat!", fake), Message("This is a message in the group chat.", fake), Message("This is another message in the group chat.", me), ] } def open_chat(channel: dict, channel_name: str, is_group=False): chat_content.clear() with chat_content: # back btn with ui.row(): ui.button("Back", icon="arrow_back", on_click=show_contacts).props("flat") ui.label(channel_name).classes('text-h5') ui.icon("people" if is_group else "person").classes('text-h5 h-full') ui.separator() with ui.row().classes('w-full h-full'): # message history with ui.column().classes('flex-grow h-full overflow-auto'): current_messages = [] for i, msg in enumerate(channel): current_messages.append(msg.content) if i == len(channel)-1 or channel[i + 1].sender != msg.sender: ui.chat_message(current_messages, name=msg.sender.name, stamp=msg.timestamp, sent=msg.sender != me) current_messages = [] # users column on the right with ui.column().classes('w-50 border-l h-full'): ui.label("Users").classes('pl-4 text-h5') ui.separator() for user in set(msg.sender.name for msg in channel): with ui.item(): with ui.item_section().props("avatar"): ui.icon("person") with ui.item_section(): ui.item_label(user) def show_contacts(): chat_content.clear() with chat_content: ui.label('Channels').classes('text-h4') with ui.row().classes("w-250 gap-2"): with ui.column().classes('w-1/2'): with ui.list().props("bordered inset rounded").classes("w-full"): ui.item_label("Contacts").props("header") ui.separator() for user in messages.keys(): with ui.item(on_click=lambda u=user: open_chat(messages[u], u, False)): with ui.item_section().props("avatar"): ui.icon("person") with ui.item_section(): ui.item_label(user) ui.item_label(str(uuid4())).props("caption") with ui.item_section().props('side'): ui.icon('chat') with ui.column().classes('flex-grow'): with ui.list().props("bordered inset rounded").classes("w-full"): ui.item_label("Group Chats").props("header") ui.separator() for group in groups.keys(): with ui.item(on_click=lambda g=group: open_chat(groups[g], g, True)): with ui.item_section().props("avatar"): ui.icon("people") with ui.item_section(): ui.item_label(group) ui.item_label(str(uuid4())).props("caption") with ui.item_section().props('side'): ui.icon('chat') @ui.page("/") async def main(): global chat_content with ui.header(): ui.label("mesh").classes('text-h5') with ui.splitter(value=10).classes('w-full h-full') as splitter: with splitter.before: with ui.tabs().props('vertical').classes('w-full') as tabs: home = ui.tab('Home', icon='home') channels = ui.tab('Channels', icon='radio') settings = ui.tab('Settings', icon='settings') with splitter.after: with ui.tab_panels(tabs, value=channels) \ .props('vertical').classes('size-full'): with ui.tab_panel(home): ui.label('Summary').classes('text-h4') with ui.tab_panel(channels): chat_content = ui.column().classes('w-full h-full gap-2') show_contacts() with ui.tab_panel(settings): ui.label('Settings').classes('text-h4') if __name__ in {"__main__", "__mp_main__"}: ui.run(dark=True)