"""Общие UI-хелперы (Flet ≥ 0.80: show_dialog/pop_dialog, SnackBar через show_dialog).""" import asyncio import flet as ft def confirm_dialog(page: ft.Page, title: str, text: str, on_confirm, danger: bool = True): """Модальный диалог подтверждения.""" def close(e=None): page.pop_dialog() def yes(e): page.pop_dialog() on_confirm() dlg = ft.AlertDialog( modal=True, title=ft.Text(title), content=ft.Text(text), actions=[ ft.TextButton("Отмена", on_click=close), ft.FilledButton( "Подтвердить", on_click=yes, style=ft.ButtonStyle(bgcolor=ft.Colors.RED_700 if danger else None), ), ], ) page.show_dialog(dlg) def snack(page: ft.Page, text: str, error: bool = False): page.show_dialog(ft.SnackBar( ft.Text(text), bgcolor=ft.Colors.RED_700 if error else ft.Colors.GREEN_700, open=True, )) def log_view(initial: str = "") -> ft.ListView: """Скроллящаяся панель лога.""" return ft.ListView(expand=True, spacing=2, auto_scroll=True) def append_log(lv: ft.ListView, line: str): lv.controls.append( ft.Text(line, size=12, font_family="Consolas", selectable=True) ) try: lv.update() except Exception: pass def open_dialog(page: ft.Page, dlg: ft.AlertDialog): page.show_dialog(dlg) def close_dialog(page: ft.Page): page.pop_dialog() def fmt_mb(v: float) -> str: if v >= 1024: return f"{v/1024:.1f} ГБ" return f"{v:.0f} МБ"