diff --git a/Code/api/__init__.py b/Code/api/__init__.py index e69de29..9553508 100644 --- a/Code/api/__init__.py +++ b/Code/api/__init__.py @@ -0,0 +1,3 @@ +from .chat import ChatClientModule + +__all__ = ["ChatClientModule"] diff --git a/Code/api/chat.py b/Code/api/chat.py new file mode 100644 index 0000000..d72c557 --- /dev/null +++ b/Code/api/chat.py @@ -0,0 +1,127 @@ +from typing import List, Literal, Optional + +import dearpygui.dearpygui as dpg +import dpg_tools +from DMBotNetwork import Client +from systems.loc import Localization as loc + + +class ChatMessageType: + __slots__ = ["_message_type", "message", "sender"] + + def __init__( + self, + message_type: Literal["ooc", "admin", "ic"], + message: str, + sender: Optional[str] = None, + ) -> None: + self._message_type: str = message_type + self.message: str = message + self.sender: Optional[str] = sender + + @property + def message_type(self) -> str: + return self._message_type + + @message_type.setter + def message_type(self, value: Literal["ooc", "admin", "ic"]) -> None: + self._message_type = value + + +class ChatClientModule: + messages: List[ChatMessageType] = [] + filters = {"ooc": True, "admin": True, "ic": True} + + @staticmethod + async def send_chat_message(chat_message_type: ChatMessageType) -> None: + """Отправляет сообщение через сеть.""" + await Client.req_net_func( + "send_message", + message=chat_message_type.message, + message_type=chat_message_type.message_type, + ) + + @staticmethod + async def net_get_chat_message( + message: str, message_type: str, sender: Optional[str] = None + ) -> None: + """Получает сообщение и добавляет его в чат.""" + ChatClientModule.messages.append(ChatMessageType(message_type, message, sender)) # type: ignore Кладём хуй на проверку с сервера) + ChatClientModule.update_chat_display() + + @classmethod + async def _iternal_send_message(cls, sender, app_data, user_data) -> None: + """Асинхронная отправка сообщения через UI.""" + message = dpg_tools.decode_string(dpg.get_value("chat_input")) + message_type = dpg.get_value("message_type_selector") + chat_message = ChatMessageType(message_type, message) + await cls.send_chat_message(chat_message) + + @classmethod + def create_window(cls, sender, app_data, user_data): + """Создание основного окна чата с фильтрацией и отправкой сообщений.""" + if dpg.does_item_exist("chat_window"): + dpg.focus_item("chat_window") + return + + with dpg.window( + label=loc.get_string("chat_window_lable"), + tag="chat_window", + width=400, + height=400, + ): + with dpg.group(horizontal=True): + dpg.add_checkbox( + label="OOC", + default_value=True, + callback=cls.update_filter, + user_data="ooc", + tag="ooc_filter", + ) + + dpg.add_checkbox( + label="Admin", + default_value=True, + callback=cls.update_filter, + user_data="admin", + tag="admin_filter", + ) + + dpg.add_checkbox( + label="IC", + default_value=True, + callback=cls.update_filter, + user_data="ic", + tag="ic_filter", + ) + + dpg.add_child_window( + label="Chat Display", autosize_x=True, height=200, tag="chat_display" + ) + + with dpg.group(horizontal=True): + dpg.add_combo( + items=["ooc", "admin", "ic"], + default_value="ooc", + tag="message_type_selector", + width=70, + ) + dpg.add_input_text(width=300, tag="chat_input") + + dpg.add_button(label="Отправить", callback=cls._iternal_send_message) + + @classmethod + def update_filter(cls, sender, app_data, user_data): + """Обновляет фильтры в зависимости от состояния чекбоксов.""" + cls.filters[user_data] = app_data + cls.update_chat_display() + + @classmethod + def update_chat_display(cls): + """Обновляет отображение сообщений в чате на основе фильтров.""" + dpg.delete_item("chat_display", children_only=True) + + for chat_message in cls.messages: + if cls.filters[chat_message.message_type]: + display_message = f"[{chat_message.message_type}] {chat_message.sender}: {chat_message.message}" + dpg.add_text(display_message, parent="chat_display", wrap=0) diff --git a/Code/gui/dm_client_app.py b/Code/gui/dm_client_app.py index 8a92bb2..2489905 100644 --- a/Code/gui/dm_client_app.py +++ b/Code/gui/dm_client_app.py @@ -14,7 +14,8 @@ from systems.loc import Localization as loc from .fonts_setup import FontManager -from .windows.admin import admin_main_window +from .windows.admin import admin_menu_setup +from .windows.user import user_menu_setup class DMClientApp: @@ -223,7 +224,9 @@ async def setup_start_windows(cls) -> None: # При всём желании, проверка прав проходит на сервере. Даже не пытайтесь. if "full_access" in access: - await admin_main_window() + await admin_menu_setup() + + await user_menu_setup() @classmethod async def download_content_from_server(cls) -> None: diff --git a/Code/gui/windows/admin/__init__.py b/Code/gui/windows/admin/__init__.py index f965484..c9001c4 100644 --- a/Code/gui/windows/admin/__init__.py +++ b/Code/gui/windows/admin/__init__.py @@ -1 +1 @@ -from .main import admin_main_window \ No newline at end of file +from .main import admin_menu_setup \ No newline at end of file diff --git a/Code/gui/windows/admin/main.py b/Code/gui/windows/admin/main.py index 447bb17..a61f3c2 100644 --- a/Code/gui/windows/admin/main.py +++ b/Code/gui/windows/admin/main.py @@ -5,7 +5,7 @@ from .manage_users import user_management -async def admin_main_window(): +async def admin_menu_setup(): dpg.add_menu( label=loc.get_string("admin_control_menu"), tag="admin_control_menu_bar", diff --git a/Code/gui/windows/user/__init__.py b/Code/gui/windows/user/__init__.py new file mode 100644 index 0000000..2bf1b8f --- /dev/null +++ b/Code/gui/windows/user/__init__.py @@ -0,0 +1 @@ +from .main import user_menu_setup \ No newline at end of file diff --git a/Code/gui/windows/user/main.py b/Code/gui/windows/user/main.py new file mode 100644 index 0000000..0c59d3f --- /dev/null +++ b/Code/gui/windows/user/main.py @@ -0,0 +1,17 @@ +import dearpygui.dearpygui as dpg +from api import ChatClientModule +from systems.loc import Localization as loc + + +async def user_menu_setup(): + dpg.add_menu( + label=loc.get_string("user_menu"), + tag="user_menu_bar", + parent="main_bar", + ) + + dpg.add_menu_item( + label=loc.get_string("chat_window_lable"), + parent="user_menu_bar", + callback=ChatClientModule.create_window, + ) diff --git a/Code/main.py b/Code/main.py index d036dc0..90160a6 100644 --- a/Code/main.py +++ b/Code/main.py @@ -2,6 +2,7 @@ import logging from pathlib import Path +from api import ChatClientModule from DMBotNetwork import Client from gui.dm_client_app import DMClientApp from root_path import ROOT_PATH @@ -14,11 +15,14 @@ def format(self, record): record.levelname = f"{record.levelname:<7}" return super().format(record) + def init_classes() -> None: - pass + Client.register_methods_from_class([ChatClientModule]) + def main() -> None: loc.load_translations(Path(ROOT_PATH / "Content" / "Client" / "loc" / "rus")) + init_classes() DiscordRPC() Client() diff --git a/requirements.txt b/requirements.txt index 66298d5..9e1855a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ dearpygui dearpygui-async -DMBotNetwork==0.2.8 +DMBotNetwork==0.3.0 DMBotTools msgpack Pillow