feat(tray): добавлен статус прокси в GUI и обновлены настройки
This commit is contained in:
parent
bd5056a64c
commit
a11b634ba7
13
README.md
13
README.md
|
|
@ -39,13 +39,20 @@ Telegram Desktop → SOCKS5 (127.0.0.1:1080) → TG WS Proxy → WSS → Telegra
|
|||
**Меню трея:**
|
||||
|
||||
- **Открыть в Telegram** — автоматически настроить прокси через `tg://socks` ссылку
|
||||
- **Статус и проверка TCP…** — диалог с фазой прокси (запуск / слушает / ошибка), uptime и локальной проверкой TCP до `host:port`
|
||||
- **Перезапустить прокси** — перезапуск без выхода из приложения
|
||||
- **Настройки...** — GUI-редактор конфигурации (в т.ч. версия приложения, опциональная проверка обновлений с GitHub)
|
||||
- **Настройки...** — GUI-редактор конфигурации (см. ниже)
|
||||
- **Открыть логи** — открыть файл логов
|
||||
- **Выход** — остановить прокси и закрыть приложение
|
||||
|
||||
**Иконка в трее:** цветной индикатор на иконке — **зелёный** прокси слушает порт, **красный** — ошибка, **жёлтый** — запуск / остановка / ожидание. Подсказка при наведении: адрес, состояние и при работе — uptime.
|
||||
|
||||
Повторный запуск приложения, пока оно уже работает, блокируется (один экземпляр); при конфликте порта показывается сообщение об ошибке.
|
||||
|
||||
При первом запуске после старта может появиться запрос об открытии страницы релиза, если на GitHub вышла новая версия (отключается в настройках).
|
||||
|
||||
**Окно настроек (Windows / Linux):** секция **«Статус»** — цветной индикатор, текст состояния и uptime (обновляется автоматически). Полная проверка TCP и детали — в меню трея **«Статус и проверка TCP…»**. В блоке **«Обновления»** — время последней проверки GitHub; без интернета имеет смысл отключить **«Проверять обновления при запуске»**.
|
||||
|
||||
### macOS
|
||||
|
||||
Перейдите на [страницу релизов](https://github.com/Flowseal/tg-ws-proxy/releases) и скачайте **`TgWsProxy_macos_universal.dmg`** — универсальная сборка для Apple Silicon и Intel.
|
||||
|
|
@ -54,6 +61,8 @@ Telegram Desktop → SOCKS5 (127.0.0.1:1080) → TG WS Proxy → WSS → Telegra
|
|||
2. Перенести **TG WS Proxy.app** в папку **Applications**
|
||||
3. При первом запуске macOS может попросить подтвердить открытие: **Системные настройки → Конфиденциальность и безопасность → Всё равно открыть**
|
||||
|
||||
В строке меню доступны те же действия, что и в трее Windows/Linux (в т.ч. статус и проверка TCP); иконка в меню обновляется с цветным индикатором состояния. Настройки на macOS задаются через системные диалоги, не через окно CustomTkinter.
|
||||
|
||||
### Linux
|
||||
|
||||
Для Debian/Ubuntu скачайте со [страницы релизов](https://github.com/Flowseal/tg-ws-proxy/releases) пакет **`TgWsProxy_linux_amd64.deb`**.
|
||||
|
|
@ -158,7 +167,7 @@ tg-ws-proxy-tray-linux = "linux:main"
|
|||
|
||||
## Структура исходников (tray)
|
||||
|
||||
Общая логика tray-приложений (пути данных, один экземпляр процесса, конфиг, логирование, поток с прокси, IPv6, фоновая проверка релизов) находится в `utils/tray_*.py`; вспомогательные части UI — в `ui/tray_*.py`. Точки входа по ОС: `windows.py`, `linux.py`, `macos.py`.
|
||||
Общая логика tray-приложений (пути данных, один экземпляр процесса, конфиг, логирование, поток с прокси, состояние для UI, локальная диагностика порта/TCP, IPv6, фоновая проверка релизов) находится в `utils/tray_*.py`; вспомогательные части UI — в `ui/tray_*.py` и `ui/ctk_tray_ui.py`. Точки входа по ОС: `windows.py`, `linux.py`, `macos.py`.
|
||||
|
||||
Для согласованных окончаний строк в репозитории используются `.editorconfig` и `.gitattributes` (LF).
|
||||
|
||||
|
|
|
|||
1
linux.py
1
linux.py
|
|
@ -275,6 +275,7 @@ def _edit_config_dialog():
|
|||
cfg,
|
||||
DEFAULT_CONFIG,
|
||||
show_autostart=False,
|
||||
proxy_state=_proxy_state,
|
||||
)
|
||||
|
||||
def on_save():
|
||||
|
|
|
|||
|
|
@ -50,6 +50,8 @@ class CtkTheme:
|
|||
field_border: str = "#d6d9dc"
|
||||
text_primary: str = "#000000"
|
||||
text_secondary: str = "#707579"
|
||||
status_pill_bg: str = "#f4f6fa"
|
||||
status_pill_border: str = "#e2e6ed"
|
||||
ui_font_family: str = "Sans"
|
||||
mono_font_family: str = "Monospace"
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ from typing import Any, Callable, Dict, List, Optional, Tuple, Union
|
|||
|
||||
import proxy.tg_ws_proxy as tg_ws_proxy
|
||||
from proxy import __version__
|
||||
from ui.tray_icons import badge_rgb_for_phase
|
||||
from utils.tray_proxy_state import format_uptime_short, phase_label_ru
|
||||
from utils.update_check import RELEASES_PAGE_URL, get_status
|
||||
|
||||
from ui.ctk_theme import (
|
||||
|
|
@ -138,6 +140,7 @@ def install_tray_config_form(
|
|||
*,
|
||||
show_autostart: bool = False,
|
||||
autostart_value: bool = False,
|
||||
proxy_state: Optional[Any] = None,
|
||||
) -> TrayConfigFormWidgets:
|
||||
"""Поля настроек прокси внутри уже созданного `frame`."""
|
||||
header = ctk.CTkFrame(frame, fg_color="transparent")
|
||||
|
|
@ -216,6 +219,67 @@ def install_tray_config_form(
|
|||
port_entry.pack(anchor="w")
|
||||
attach_tooltip_to_widgets([port_lbl, port_entry, port_col], _TIP_PORT)
|
||||
|
||||
if proxy_state is not None:
|
||||
stat_inner = _config_section(ctk, frame, theme, "Статус")
|
||||
pill = ctk.CTkFrame(
|
||||
stat_inner,
|
||||
fg_color=theme.status_pill_bg,
|
||||
corner_radius=12,
|
||||
border_width=1,
|
||||
border_color=theme.status_pill_border,
|
||||
)
|
||||
pill.pack(fill="x", pady=(2, 0))
|
||||
row = ctk.CTkFrame(pill, fg_color="transparent")
|
||||
row.pack(fill="x", padx=14, pady=12)
|
||||
dot = ctk.CTkFrame(
|
||||
row,
|
||||
width=12,
|
||||
height=12,
|
||||
corner_radius=6,
|
||||
fg_color="#eab308",
|
||||
)
|
||||
dot.pack(side="left", padx=(0, 12))
|
||||
dot.pack_propagate(False)
|
||||
text_col = ctk.CTkFrame(row, fg_color="transparent")
|
||||
text_col.pack(side="left", fill="x", expand=True)
|
||||
status_main = ctk.CTkLabel(
|
||||
text_col,
|
||||
text="",
|
||||
font=(theme.ui_font_family, 14),
|
||||
text_color=theme.text_primary,
|
||||
anchor="w",
|
||||
)
|
||||
status_main.pack(side="left")
|
||||
status_uptime = ctk.CTkLabel(
|
||||
text_col,
|
||||
text="",
|
||||
font=(theme.ui_font_family, 13),
|
||||
text_color=theme.text_secondary,
|
||||
anchor="w",
|
||||
)
|
||||
status_uptime.pack(side="left")
|
||||
|
||||
def _mini_status_tick() -> None:
|
||||
if not frame.winfo_exists():
|
||||
return
|
||||
try:
|
||||
snap = proxy_state.snapshot()
|
||||
phase = snap["phase"]
|
||||
r, g, b = badge_rgb_for_phase(phase)
|
||||
dot.configure(fg_color=f"#{r:02x}{g:02x}{b:02x}")
|
||||
status_main.configure(text=phase_label_ru(phase))
|
||||
ls = snap.get("listening_since")
|
||||
if phase == "listening" and ls is not None:
|
||||
status_uptime.configure(text=f" · {format_uptime_short(ls)}")
|
||||
else:
|
||||
status_uptime.configure(text="")
|
||||
except Exception:
|
||||
pass
|
||||
if frame.winfo_exists():
|
||||
frame.after(1000, _mini_status_tick)
|
||||
|
||||
_mini_status_tick()
|
||||
|
||||
dc_inner = _config_section(ctk, frame, theme, "Датацентры Telegram (DC → IP)")
|
||||
dc_lbl = ctk.CTkLabel(
|
||||
dc_inner,
|
||||
|
|
@ -591,7 +655,7 @@ def populate_first_run_window(
|
|||
"порт занят — другой процесс или старый экземпляр; смените порт в настройках;",
|
||||
"IPv6 — трафик может идти мимо прокси; см. предупреждение при первом запуске;",
|
||||
"брандмауэр / антивирус — разрешите локальное прослушивание;",
|
||||
"меню трея: «Статус» — без поиска по логам.",
|
||||
"меню трея: «Статус и проверка TCP…» — без поиска по логам.",
|
||||
):
|
||||
ctk.CTkLabel(
|
||||
frame,
|
||||
|
|
|
|||
|
|
@ -6,12 +6,6 @@ from typing import Any, List, Tuple
|
|||
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
|
||||
# Подсказка для tooltip (согласована с цветами бейджа)
|
||||
BADGE_TOOLTIP_HINT = (
|
||||
"Бейдж: зелёный — работает, красный — ошибка, жёлтый — запуск/ожидание/остановка"
|
||||
)
|
||||
|
||||
|
||||
def _resample_lanczos() -> int:
|
||||
try:
|
||||
return Image.Resampling.LANCZOS # type: ignore[attr-defined]
|
||||
|
|
|
|||
|
|
@ -90,8 +90,6 @@ def build_tray_tooltip(
|
|||
port: int,
|
||||
state: ProxyRuntimeState,
|
||||
) -> str:
|
||||
from ui.tray_icons import BADGE_TOOLTIP_HINT
|
||||
|
||||
snap = state.snapshot()
|
||||
phase = snap["phase"]
|
||||
addr = f"{host}:{port}"
|
||||
|
|
@ -99,12 +97,10 @@ def build_tray_tooltip(
|
|||
|
||||
if phase == "listening" and snap["listening_since"] is not None:
|
||||
up = format_uptime_short(snap["listening_since"])
|
||||
base = f"TG WS Proxy | {addr} | {label} | {up}"
|
||||
elif phase == "error" and snap["detail"]:
|
||||
return f"TG WS Proxy | {addr} | {label} | {up}"
|
||||
if phase == "error" and snap["detail"]:
|
||||
short = snap["detail"]
|
||||
if len(short) > 80:
|
||||
short = short[:77] + "…"
|
||||
base = f"TG WS Proxy | {addr} | {label}: {short}"
|
||||
else:
|
||||
base = f"TG WS Proxy | {addr} | {label}"
|
||||
return f"{base}\n{BADGE_TOOLTIP_HINT}"
|
||||
return f"TG WS Proxy | {addr} | {label}: {short}"
|
||||
return f"TG WS Proxy | {addr} | {label}"
|
||||
|
|
|
|||
|
|
@ -394,6 +394,7 @@ def _edit_config_dialog():
|
|||
DEFAULT_CONFIG,
|
||||
show_autostart=_supports_autostart(),
|
||||
autostart_value=cfg.get("autostart", False),
|
||||
proxy_state=_proxy_state,
|
||||
)
|
||||
|
||||
def on_save():
|
||||
|
|
|
|||
Loading…
Reference in New Issue