155 lines
6 KiB
Python
155 lines
6 KiB
Python
from __future__ import annotations
|
||
|
||
import flet as ft
|
||
import flet_webview as fwv
|
||
|
||
from app.models import FreeTurnProfile
|
||
from app.screens.components import connection_card, section_title
|
||
from app.services.controller import RuntimeController
|
||
from app.services.settings_registry import SettingsRegistry
|
||
from app.theme import card
|
||
|
||
PRESET_TEXT = {
|
||
1: "4/4 · для сообщений",
|
||
2: "8/4 · для простого интернет-сёрфинга",
|
||
3: "12/6 · для видео в невысоком качестве",
|
||
4: "24/6 · для всего · ультра скорость, повышенная нагрузка",
|
||
}
|
||
CAPTCHA_ENTRY_URL = "https://vk.com"
|
||
|
||
|
||
def build_white_lists_screen(
|
||
page: ft.Page,
|
||
controller: RuntimeController,
|
||
registry: SettingsRegistry,
|
||
on_theme: callable,
|
||
) -> ft.Control:
|
||
content = ft.Column(expand=True, scroll=ft.ScrollMode.AUTO, spacing=14)
|
||
|
||
async def slide(event: ft.ControlEvent) -> None:
|
||
if float(event.control.value or 0) < 0.8:
|
||
return
|
||
try:
|
||
controller.select_freeturn()
|
||
await controller.connect()
|
||
except Exception as exc:
|
||
controller.snapshot = controller.snapshot.model_copy(
|
||
update={"state": "error", "message": controller.error_text(exc)}
|
||
)
|
||
render()
|
||
|
||
async def stop(_: ft.ControlEvent) -> None:
|
||
await controller.stop()
|
||
render()
|
||
|
||
def preset_change(event: ft.ControlEvent) -> None:
|
||
controller.freeturn.preset = int(round(float(event.control.value)))
|
||
render()
|
||
|
||
def stability_change(event: ft.ControlEvent) -> None:
|
||
controller.freeturn.stability_over_load = bool(event.control.value)
|
||
render()
|
||
|
||
def captcha_settings() -> ft.Control:
|
||
captcha_url = controller.snapshot.captcha_url or CAPTCHA_ENTRY_URL
|
||
|
||
def open_captcha(_: ft.ControlEvent, in_browser: bool = False) -> None:
|
||
if in_browser or controller.freeturn.captcha_always_browser:
|
||
page.launch_url(captcha_url)
|
||
return
|
||
dialog = ft.AlertDialog(
|
||
modal=True,
|
||
title=ft.Text("CAPTCHA"),
|
||
content=ft.Container(
|
||
fwv.WebView(url=captcha_url, expand=True),
|
||
width=520,
|
||
height=620,
|
||
),
|
||
actions=[
|
||
ft.TextButton(
|
||
"Открыть в браузере",
|
||
on_click=lambda _: page.launch_url(captcha_url),
|
||
),
|
||
ft.TextButton("Закрыть", on_click=lambda _: page.close(dialog)),
|
||
],
|
||
)
|
||
page.open(dialog)
|
||
|
||
return card(
|
||
ft.Column(
|
||
[
|
||
ft.Text("CAPTCHA", weight=ft.FontWeight.W_600),
|
||
ft.Text(
|
||
"Встроенное окно доступно на Android. На desktop используйте браузер.",
|
||
color=ft.Colors.OUTLINE,
|
||
),
|
||
ft.Switch(
|
||
label="Всегда открывать CAPTCHA в браузере",
|
||
value=controller.freeturn.captcha_always_browser,
|
||
on_change=lambda e: setattr(
|
||
controller.freeturn, "captcha_always_browser", bool(e.control.value)
|
||
),
|
||
),
|
||
ft.Row(
|
||
[
|
||
ft.FilledButton(
|
||
"Открыть внутри приложения",
|
||
on_click=open_captcha,
|
||
),
|
||
ft.OutlinedButton(
|
||
"Открыть в браузере",
|
||
on_click=lambda e: open_captcha(e, True),
|
||
),
|
||
]
|
||
),
|
||
],
|
||
spacing=8,
|
||
)
|
||
)
|
||
|
||
def render() -> None:
|
||
profile: FreeTurnProfile = controller.freeturn
|
||
threads, per_credential = profile.stream_settings
|
||
content.controls = [
|
||
section_title("Белые списки", "FreeTurn · отдельный runtime"),
|
||
connection_card(controller.snapshot.state, controller.mode, "FreeTurn", slide),
|
||
card(
|
||
ft.Column(
|
||
[
|
||
ft.Text("Скорость", weight=ft.FontWeight.W_600),
|
||
ft.Text(
|
||
PRESET_TEXT[profile.preset],
|
||
color=ft.Colors.ERROR if profile.preset == 4 else None,
|
||
),
|
||
ft.Slider(
|
||
min=1,
|
||
max=4,
|
||
divisions=3,
|
||
value=profile.preset,
|
||
label="Уровень {value}",
|
||
on_change=preset_change,
|
||
),
|
||
ft.Text(f"Потоки: {threads}/{per_credential}", color=ft.Colors.OUTLINE),
|
||
ft.Switch(
|
||
label="Повысить стабильность ценой нагрузки",
|
||
value=profile.stability_over_load,
|
||
disabled=profile.preset < 3,
|
||
on_change=stability_change,
|
||
),
|
||
],
|
||
spacing=8,
|
||
)
|
||
),
|
||
captcha_settings(),
|
||
ft.OutlinedButton("Остановить", icon=ft.Icons.STOP, on_click=stop),
|
||
ft.Text(
|
||
controller.snapshot.message or "",
|
||
color=ft.Colors.ERROR if controller.snapshot.message else None,
|
||
),
|
||
]
|
||
page.update()
|
||
|
||
registry.register("white-lists", "Белые списки", lambda: content)
|
||
controller.add_listener(render)
|
||
render()
|
||
return content
|