Initial MCM project: FastAPI + Textual TUI unified messenger
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.
This commit is contained in:
50
tui/screens/compose_screen.py
Normal file
50
tui/screens/compose_screen.py
Normal file
@@ -0,0 +1,50 @@
|
||||
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})
|
||||
Reference in New Issue
Block a user