MultiCustomerMessenger supporting Telegram (python-telegram-bot), WhatsApp (Green API) and SMS (python-gsmmodem-new). REST API with Bearer-token auth, SQLAlchemy models for MariaDB, APScheduler for background polling, and Textual TUI running in same asyncio event-loop.
51 lines
1.7 KiB
Python
51 lines
1.7 KiB
Python
from __future__ import annotations
|
|
|
|
from textual.app import ComposeResult
|
|
from textual.containers import Horizontal, Vertical
|
|
from textual.screen import ModalScreen
|
|
from textual.widgets import Button, Input, Label, Select, TextArea
|
|
|
|
|
|
CHANNEL_OPTIONS = [
|
|
("Telegram", "telegram"),
|
|
("WhatsApp", "whatsapp"),
|
|
("SMS", "sms"),
|
|
]
|
|
|
|
|
|
class ComposeScreen(ModalScreen[dict | None]):
|
|
"""Modal-Dialog für neue ausgehende Nachricht."""
|
|
|
|
DEFAULT_CSS = ""
|
|
|
|
def compose(self) -> ComposeResult:
|
|
with Vertical(id="compose-dialog"):
|
|
yield Label("Neue Nachricht", id="compose-title")
|
|
yield Label("Kanal:")
|
|
yield Select(
|
|
[(label, value) for label, value in CHANNEL_OPTIONS],
|
|
id="channel-select",
|
|
value="telegram",
|
|
)
|
|
yield Label("Empfänger (Telefon / Telegram-ID):")
|
|
yield Input(placeholder="+49… oder Telegram-Chat-ID", id="recipient-input")
|
|
yield Label("Nachricht:")
|
|
yield TextArea(id="msg-textarea")
|
|
with Horizontal(id="compose-buttons"):
|
|
yield Button("Abbrechen", variant="default", id="btn-cancel")
|
|
yield Button("Senden", variant="primary", id="btn-send")
|
|
|
|
def on_button_pressed(self, event: Button.Pressed) -> None:
|
|
if event.button.id == "btn-cancel":
|
|
self.dismiss(None)
|
|
return
|
|
|
|
channel = self.query_one("#channel-select", Select).value
|
|
recipient = self.query_one("#recipient-input", Input).value.strip()
|
|
text = self.query_one("#msg-textarea", TextArea).text.strip()
|
|
|
|
if not recipient or not text:
|
|
return
|
|
|
|
self.dismiss({"channel": channel, "recipient": recipient, "text": text})
|