Zapret | Дорожная карта
2.37K subscribers
28 photos
24 files
3.55K links
Дорожная карта обновлений.

Узнайте что я буду редактировать в Запрет для обхода блокировок Дискорда и Ютуба в первую очередь

И ужаснуться моим техническим непонятным запискам без контекста.
Download Telegram
💥 ВСЕ НАШИ ССЫЛКИ: https://t.me/runetvpnyoutubediscord

🔔 Новый коммит в youtubediscord/zapret

📝 Refactor preset profile architecture cleanup

👤 Автор: loop-uh
📅 Дата: 09.05.2026 21:52:56
🔗 SHA: 1701853

📊 Статистика:
➕ Добавлено: 328 строк
➖ Удалено: 294 строк
📝 Всего изменений: 622

📁 Изменено файлов: 31

✏️ src/donater/subscription_manager.py
+15 -55

Удалилось:
from PyQt6.QtCore import QThread, QObject, pyqtSignal

from donater.subscription_ui_applier import SubscriptionUiApplier

self._ui_applier = SubscriptionUiApplier(app_instance)

"""Асинхронная инициализация и проверка подписки"""

class SubscriptionInitWorker(QObject):

finished = pyqtSignal(object, object, bool)  # donate_checker, activation_info, success

progress = pyqtSignal(str)

def run(self):

try:

self.progress.emit("Инициализация системы подписок...")

... и еще 35 строк

Добавилось:
from PyQt6.QtCore import QThread, QObject

from donater.subscription_ui import (

apply_subscription_info_to_ui,

apply_subscription_init_failed_to_ui,

apply_subscription_ready_to_ui,

)

from donater.subscription_worker import SubscriptionInitWorker

"""Асинхронно запускает первичную проверку подписки."""

"""Обрабатывает результат фоновой проверки подписки."""

apply_subscription_init_failed_to_ui(self.app)

... и еще 5 строк

🆕 src/donater/subscription_ui.py
+40 -0

Добавилось:
from __future__ import annotations

from typing import Any, Dict

from log.log import log

def apply_subscription_info_to_ui(

app,

sub_info: Dict[str, Any],

) -> None:

"""Применяет Premium-статус к состоянию окна и заголовку."""

is_premium = bool(sub_info.get("is_premium"))

days_remaining = sub_info.get("days_remaining")

... и еще 19 строк

🗑️ src/donater/subscription_ui_applier.py
+0 -49

Удалилось:
from __future__ import annotations

from typing import Any, Dict, Optional

from log.log import log

class SubscriptionUiApplier:

"""Применяет Premium-статус к главному окну."""

def __init__(self, app_instance):

self.app = app_instance

def apply_subscription_info(

self,

sub_info: Dict[str, Any],

... и еще 27 строк

🆕 src/donater/subscription_worker.py
+34 -0

Добавилось:
from __future__ import annotations

import traceback

from PyQt6.QtCore import QObject, pyqtSignal

from log.log import log

class SubscriptionInitWorker(QObject):

"""Фоновый worker для первичной проверки Premium-статуса."""

finished = pyqtSignal(object, object, bool)  # donate_checker, activation_info, success

progress = pyqtSignal(str)

def run(self) -> None:

try:

... и еще 13 строк

✏️ src/main/post_startup_checks.py
+2 -2

Удалилось:
window.log_startup_metric("StartupChecksFinished", f"{duration_ms}ms")

window.log_startup_metric("StartupChecksStarted", "startup_checks_worker")


Добавилось:
window.log_startup_metric("StartupPostInitChecksFinished", f"{duration_ms}ms")

window.log_startup_metric("StartupPostInitChecksStarted", "startup_checks_worker")


... и еще 26 файлов

... и еще 21 файлов

🔗 Открыть на GitHub
💥 ВСЕ НАШИ ССЫЛКИ: https://t.me/runetvpnyoutubediscord

🔔 Новый коммит в youtubediscord/zapret

📝 удаление

👤 Автор: loop-uh
📅 Дата: 09.05.2026 22:05:23
🔗 SHA: 92d08ae

📊 Статистика:
➕ Добавлено: 124 строк
➖ Удалено: 136 строк
📝 Всего изменений: 260

📁 Изменено файлов: 4

🗑️ docs/gui_architecture_contract.md
+0 -73

Удалилось:
# GUI Architecture Contract

Дата фиксации: 2026-04-10

Этот документ описывает не пожелания, а архитектурный контракт GUI, который надо поддерживать при...

## Direct preset flow

- `direct_zapret1` использует выбранный source preset как единственный источник истины.

- `direct_zapret2` использует выбранный source preset как единственный источник истины.

- Канонический путь выбора direct-пресета: `PresetSelectionService` -> `DirectFlowCoordinator` ->...

- Канонический корень пресетов: `presets/` рядом с программой.

- Пользовательские direct-пресеты лежат только в `presets/presets_v1` и `presets/presets_v2`.

- Встроенные direct-пресеты лежат только в `presets/presets_v1_builtin` и `presets/presets_v2_bui...

... и еще 47 строк

✏️ src/donater/subscription_ui.py
+4 -8

Удалилось:
"""Применяет Premium-статус к состоянию окна и заголовку."""

app.update_title_with_subscription_status(

is_premium,

app.theme_manager.current_theme,

days_remaining,

)

log(f"Обновлён заголовок подписки: premium={is_premium}", "DEBUG")

app.update_title_with_subscription_status(False, None, 0)


Добавилось:
"""Применяет Premium-статус к состоянию окна и верхней метке."""

app.update_subscription_title_badge(is_premium)

log(f"Обновлена Premium-метка: premium={is_premium}", "DEBUG")

app.update_subscription_title_badge(False, source="subscription_init_failed")


🆕 src/main/startup_contract.md
+46 -0

Добавилось:
# Контракт Запуска

Этот документ фиксирует текущий контракт запуска GUI после разгрузки первого старта.

## Основные Роли

`window_bootstrap_for(...)` создаёт `AppContext`, главное окно и регистрирует окно как активное.

`WindowStartupMixin` отвечает за жизненный цикл окна во время старта:

- показать окно как можно раньше;

- собрать основной UI после первого показа;

- создать стартовые объекты через `startup_bootstrap_for(...)`;

- запустить `StartupCoordinator`;

- отметить метрики `StartupInteractive`, `StartupCoreReady`, `StartupPostInit`.

... и еще 21 строк

✏️ src/ui/theme_subscription_manager.py
+74 -55

Удалилось:
"""

Менеджер для работы с темами и подписками.

Содержит всю логику обновления UI в зависимости от статуса подписки и текущей темы.

"""

from typing import Optional

from PyQt6.QtWidgets import QWidget

from config.build_info import APP_VERSION

Миксин-класс для управления темами и отображением статуса подписки.

Должен использоваться вместе с основным классом окна.

def update_title_with_subscription_status(self: QWidget, is_premium: bool = False,

... и еще 41 строк

Добавилось:
from PyQt6.QtCore import Qt

from PyQt6.QtWidgets import QLabel, QSizePolicy, QWidget

PREMIUM_TITLE_BADGE_TEXT = "Premium"

Миксин для отображения Premium-статуса в верхней панели окна.

Базовый системный заголовок окна ставит ZapretFluentWindow при создании.

Этот миксин не пересобирает заголовок целиком, а обновляет только отдельную

Premium-метку, чтобы основной текст окна не прыгал при получении подписки.

def update_subscription_title_badge(

self: QWidget,

is_premium: bool = False,

... и еще 53 строк
... и еще 0 файлов

🔗 Открыть на GitHub
💥 ВСЕ НАШИ ССЫЛКИ: https://t.me/runetvpnyoutubediscord

🔔 Новый коммит в youtubediscord/zapret

📝 Update theme_subscription_manager.py

👤 Автор: loop-uh
📅 Дата: 09.05.2026 22:06:38
🔗 SHA: ac85df2

📊 Статистика:
➕ Добавлено: 8 строк
➖ Удалено: 5 строк
📝 Всего изменений: 13

📁 Изменено файлов: 1

✏️ src/ui/theme_subscription_manager.py
+8 -5

Удалилось:
badge = self._ensure_subscription_title_badge()

if badge is None:

log(f"Premium-метка не обновлена: titleBar недоступен (source: {source})", "WARNING")

return


Добавилось:
badge = getattr(self, "_subscription_title_badge", None)

if badge is None:

return

badge = self._ensure_subscription_title_badge()

if badge is None:

log(f"Premium-метка не обновлена: titleBar недоступен (source: {source})", "WARNING")

return


🔗 Открыть на GitHub
💥 ВСЕ НАШИ ССЫЛКИ: https://t.me/runetvpnyoutubediscord

🔔 Новый коммит в youtubediscord/zapret

📝 Add feature public APIs and DNS layer

👤 Автор: loop-uh
📅 Дата: 10.05.2026 11:31:03
🔗 SHA: 68161f4

📊 Статистика:
➕ Добавлено: 3033 строк
➖ Удалено: 1066 строк
📝 Всего изменений: 4099

📁 Изменено файлов: 98

🆕 src/app/ARCHITECTURE.md
+249 -0

Добавилось:
# Архитектурный контракт GUI

Дата фиксации: 2026-05-10

Этот документ фиксирует текущие границы проекта. Он нужен не для описания всех деталей,

а чтобы новые правки не возвращали старую схему, где главное окно знает обо всём.

## Главное окно

`MainWindow` — это UI-оболочка.

Разрешено:

- держать виджеты окна;

- держать `WindowUiSession`;

- держать контроллер уведомлений;

... и еще 165 строк

🆕 src/app/ARCHITECTURE_DEBT.md
+157 -0

Добавилось:
# Архитектурный долг

Дата фиксации: 2026-05-10

Это список оставшихся прямых связей. Он нужен, чтобы не забыть, где проект ещё не дошёл

до чистой схемы `UI -> feature.public -> feature internals`.

## Контрольные поиски

Эти команды нужны, чтобы запрещённые связи были видимыми, а не держались в памяти:

```bash

rg -n "from winws_runtime\.(runtime|flow|runners)\.|import winws_runtime\.(runtime|flow|runners)\...

rg -n "from donater\.(service|subscription_manager|worker|device_store|api|.*_service)\.|import d...

rg -n "window\.launch_controller|host\.launch_controller|getattr\([^\\n]*(window|host)[^\\n]*laun...

... и еще 105 строк

✏️ src/app_context.py
+2 -10

Удалилось:
from presets.file_store import PresetFileStore

from presets.ui_store import PresetUiStore

from presets.selection_service import PresetSelectionService

from core.runtime.preset_runtime_coordinator import PresetRuntimeCoordinator

preset_runtime_coordinator_factory: Callable[..., PresetRuntimeCoordinator]

from presets.file_store import PresetFileStore

from presets.ui_store import PresetUiStore

from presets.selection_service import PresetSelectionService

from core.runtime.preset_runtime_coordinator import PresetRuntimeCoordinator

preset_runtime_coordinator_factory=lambda *args, **kwargs: PresetRuntimeCoordinator(*args, **kwar...


Добавилось:
from presets.public import PresetFileStore, PresetSelectionService, PresetUiStore

from presets.public import PresetFileStore, PresetSelectionService, PresetUiStore


✏️ src/blockcheck/strategy_scan_page_controller.py
+7 -4

Удалилось:
manifest = app_context.preset_mode_coordinator.get_selected_source_manifest(ZAPRET2_MODE)

from presets.file_service import PresetFileService

PresetFileService.from_launch_method(

).save_source_text_by_file_name(selected_file_name, updated_text)


Добавилось:
from presets.public import get_selected_source_preset_manifest

manifest = get_selected_source_preset_manifest(ZAPRET2_MODE, app_context=app_context)

from presets.public import save_preset_source_by_file_name

save_preset_source_by_file_name(

selected_file_name,

updated_text,

)


... и еще 94 файлов

... и еще 88 файлов

🔗 Открыть на GitHub
💥 ВСЕ НАШИ ССЫЛКИ: https://t.me/runetvpnyoutubediscord

🔔 Новый коммит в youtubediscord/zapret

📝 окно больше не центр вселенной

👤 Автор: loop-uh
📅 Дата: 15.05.2026 15:08:49
🔗 SHA: e67792c

📊 Статистика:
➕ Добавлено: 20198 строк
➖ Удалено: 19407 строк
📝 Всего изменений: 39605

📁 Изменено файлов: 374

🗑️ docs/gui_controller_rename_plan.md
+0 -352

Удалилось:
# GUI Controller Rename Plan

Дата фиксации: 2026-04-11

Этот документ описывает не конечный архитектурный контракт, а безопасный план миграции для слоя `...

Обновление состояния: 2026-04-12

На дату обновления план остаётся актуальным по стратегии, но уже не полностью совпадает со старой...

- naming-first стратегия остаётся канонической;

- часть folder-move этапа уже фактически произошла;

- дальше нельзя опираться на старую картину `src/ui/pages/...` как на единственный живой UI-слой;

- план нужно читать как живой маршрут миграции, а не как замороженный список старых путей.

## Зачем нужен план

... и еще 224 строк

🗑️ docs/gui_fluent_cutover_plan.md
+0 -1206

Удалилось:
# GUI Fluent Cutover Plan

Дата фиксации: 2026-04-12

Этот документ описывает не абстрактные идеи, а целевой план полной замены текущего `main_window*`...

Документ нужен как передаваемый контекст для следующего ИИ или следующей сессии. Его задача:

- зафиксировать, что именно мы считаем проблемой;

- зафиксировать, что именно мы сохраняем;

- зафиксировать, что именно подлежит полному удалению;

- дать один непротиворечивый план cutover без fallback и без второго источника истины.

## 1. Зачем вообще нужен этот cutover

Проблема проекта не в том, что GUI "не на Fluent". Наоборот, проект уже глубоко использует `qflue...

... и еще 784 строк

🆕 src/about/__init__.py
+1 -0

Добавилось:
"""Функции и планы страниц About/Support."""


🆕 src/about/plans.py
+132 -0

Добавилось:
from __future__ import annotations

import os

import subprocess

import webbrowser

from dataclasses import dataclass

from log.log import log

@dataclass(slots=True)

class AboutActionResult:

ok: bool

message: str

... и еще 99 строк

✏️ src/app/ARCHITECTURE.md
+1053 -46

Удалилось:
- держать контроллер уведомлений;

- обращаться из UI к `launch_controller` напрямую;

window.app_context -> сервисы приложения и общие store-объекты

UI вызывает DPI runtime только через публичный вход:

import winws_runtime.public as runtime_commands

или:

from winws_runtime.public import start_dpi_async

Исключение на текущем этапе:

- startup-код может создавать runtime-контроллер;

- аварийное закрытие может использовать sync shutdown;

... и еще 36 строк

Добавилось:
Быстрая проверка границ:

```bash

python src/app/architecture_checks.py

```

## Итоговая карта владения

Целевая схема проекта:

```txt

AppRuntime

-> собирает ядро приложения: AppPaths, State, Feature-слои

Feature-слои

... и еще 804 строк

... и еще 369 файлов

... и еще 364 файлов

🔗 Открыть на GitHub
💥 ВСЕ НАШИ ССЫЛКИ: https://t.me/runetvpnyoutubediscord

🔔 Новый коммит в youtubediscord/zapret

📝 Update README.md

👤 Автор: loop-uh
📅 Дата: 15.05.2026 15:27:13
🔗 SHA: 6b5c203

📊 Статистика:
➕ Добавлено: 1 строк
➖ Удалено: 1 строк
📝 Всего изменений: 2

📁 Изменено файлов: 1

✏️ docs/README.md
+1 -1

Удалилось:
### Документация доступна здесь https://publish.obsidian.md/zapret


Добавилось:
### Документация доступна здесь https://publish.obsidian.md/zapret/Privacy/Zapret2/Zapret2


🔗 Открыть на GitHub
💥 ВСЕ НАШИ ССЫЛКИ: https://t.me/runetvpnyoutubediscord

🔔 Новый коммит в youtubediscord/zapret

📝 окно точно не центр вселенной

👤 Автор: loop-uh
📅 Дата: 17.05.2026 13:45:34
🔗 SHA: a237480

📊 Статистика:
➕ Добавлено: 9615 строк
➖ Удалено: 8331 строк
📝 Всего изменений: 17946

📁 Изменено файлов: 222

✏️ .gitignore
+1 -0

Добавилось:
/logs


🆕 settings/settings.json
+158 -0

Добавилось:
{

"version": 1,

"program": {

"dpi_autostart": true,

"gui_autostart_enabled": false,

"strategy_launch_method": "zapret2_mode",

"profile_ui_mode": "basic",

"selected_source_preset_file_name_winws1": "",

"selected_source_preset_file_name_winws2": "",

"auto_update_enabled": true,

... и еще 148 строк

✏️ src/app/ARCHITECTURE.md
+183 -1167

Удалилось:
Дата фиксации: 2026-05-10

Этот документ фиксирует текущие границы проекта. Он нужен не для описания всех деталей,

а чтобы новые правки не возвращали старую схему, где главное окно знает обо всём.

Быстрая проверка границ:

```bash

python src/app/architecture_checks.py

```

## Итоговая карта владения

Целевая схема проекта:

```txt

... и еще 920 строк

Добавилось:
Дата фиксации: 2026-05-15.

Этот документ описывает текущее состояние кода. Главное правило простое:

окно показывает интерфейс, но не собирает приложение и не является общим

контейнером сервисов.

## Запуск

Каноническая цепочка запуска:

```text

src/main/entry.py

-> создаёт QApplication

-> создаёт ApplicationController

... и еще 171 строк

🆕 src/app/STATE_OWNERSHIP.md
+139 -0

Добавилось:
# State ownership

Этот документ фиксирует владение состоянием после чистки слоёв окна.

Главное правило:

```text

feature state хранит данные feature;

MainWindowStateStore хранит только короткое состояние, нужное общему UI.

```

`MainWindowStateStore` живёт в:

```text

src/app/state_store.py

... и еще 93 строк

✏️ src/app/__init__.py
+2 -1

Удалилось:
from app.features import AppFeatures, DnsFeature, build_app_features


Добавилось:
from app.feature_assembly import build_app_features

from app.features import AppFeatures, DnsFeature


✏️ src/app/architecture_checks.py
+613 -3

Удалилось:
re.compile(r"\b(?:premium|dns|hosts|presets|preset_)\b", re.IGNORECASE),

re.compile(r"\b(?:app_runtime\.features|features\.|get_premium_state|subscription_manager)\b"),

r"(?:app_context|ui_state_store|app_runtime_state|launch_controller|"


Добавилось:
def check_no_app_runtime_context(files: list[Path]) -> list[Problem]:

return _scan_lines(

files,

re.compile(r"\b(?:app_runtime|AppRuntime|window\.app_runtime|page\.window\(\)\.app_runtime)\.cont...

"AppRuntime.context нельзя добавлять как новый общий app_context",

)

def check_app_features_is_registry_only() -> list[Problem]:

path = SRC_ROOT / "app" / "features.py"

if not path.exists():

return [Problem(path, 1, "app/features.py не найден")]

... и еще 537 строк

... и еще 216 файлов

... и еще 212 файлов

🔗 Открыть на GitHub
💥 ВСЕ НАШИ ССЫЛКИ: https://t.me/runetvpnyoutubediscord

🔔 Новый коммит в youtubediscord/zapret

📝 234

👤 Автор: loop-uh
📅 Дата: 17.05.2026 13:50:17
🔗 SHA: 2855353

📊 Статистика:
➕ Добавлено: 3 строк
➖ Удалено: 158 строк
📝 Всего изменений: 161

📁 Изменено файлов: 2

✏️ .gitignore
+3 -0

Добавилось:
# Runtime user state

/settings/


🗑️ settings/settings.json
+0 -158

Удалилось:
{

"version": 1,

"program": {

"dpi_autostart": true,

"gui_autostart_enabled": false,

"strategy_launch_method": "zapret2_mode",

"profile_ui_mode": "basic",

"selected_source_preset_file_name_winws1": "",

"selected_source_preset_file_name_winws2": "",

"auto_update_enabled": true,

... и еще 148 строк

🔗 Открыть на GitHub
💥 ВСЕ НАШИ ССЫЛКИ: https://t.me/runetvpnyoutubediscord

🔔 Новый коммит в youtubediscord/zapret

📝 Merge pull request #473 from youtubediscord/codex/remove-template-origin-preset-legacy

👤 Автор: loop-uh
📅 Дата: 17.05.2026 13:50:39
🔗 SHA: 6b0bf34

📊 Статистика:
➕ Добавлено: 34930 строк
➖ Удалено: 32732 строк
📝 Всего изменений: 67662

📁 Изменено файлов: 769

✏️ .gitignore
+4 -0

Добавилось:
# Runtime user state

/settings/

/logs


🗑️ docs/gui_architecture_contract.md
+0 -73

Удалилось:
# GUI Architecture Contract

Дата фиксации: 2026-04-10

Этот документ описывает не пожелания, а архитектурный контракт GUI, который надо поддерживать при...

## Direct preset flow

- `direct_zapret1` использует выбранный source preset как единственный источник истины.

- `direct_zapret2` использует выбранный source preset как единственный источник истины.

- Канонический путь выбора direct-пресета: `PresetSelectionService` -> `DirectFlowCoordinator` ->...

- Канонический корень пресетов: `presets/` рядом с программой.

- Пользовательские direct-пресеты лежат только в `presets/presets_v1` и `presets/presets_v2`.

- Встроенные direct-пресеты лежат только в `presets/presets_v1_builtin` и `presets/presets_v2_bui...

... и еще 47 строк

🗑️ docs/gui_controller_rename_plan.md
+0 -352

Удалилось:
# GUI Controller Rename Plan

Дата фиксации: 2026-04-11

Этот документ описывает не конечный архитектурный контракт, а безопасный план миграции для слоя `...

Обновление состояния: 2026-04-12

На дату обновления план остаётся актуальным по стратегии, но уже не полностью совпадает со старой...

- naming-first стратегия остаётся канонической;

- часть folder-move этапа уже фактически произошла;

- дальше нельзя опираться на старую картину `src/ui/pages/...` как на единственный живой UI-слой;

- план нужно читать как живой маршрут миграции, а не как замороженный список старых путей.

## Зачем нужен план

... и еще 224 строк

🗑️ docs/gui_fluent_cutover_plan.md
+0 -1206

Удалилось:
# GUI Fluent Cutover Plan

Дата фиксации: 2026-04-12

Этот документ описывает не абстрактные идеи, а целевой план полной замены текущего `main_window*`...

Документ нужен как передаваемый контекст для следующего ИИ или следующей сессии. Его задача:

- зафиксировать, что именно мы считаем проблемой;

- зафиксировать, что именно мы сохраняем;

- зафиксировать, что именно подлежит полному удалению;

- дать один непротиворечивый план cutover без fallback и без второго источника истины.

## 1. Зачем вообще нужен этот cutover

Проблема проекта не в том, что GUI "не на Fluent". Наоборот, проект уже глубоко использует `qflue...

... и еще 784 строк

🆕 src/about/__init__.py
+1 -0

Добавилось:
"""Функции и планы страниц About/Support."""


🆕 src/about/plans.py
+132 -0

Добавилось:
from __future__ import annotations

import os

import subprocess

import webbrowser

from dataclasses import dataclass

from log.log import log

@dataclass(slots=True)

class AboutActionResult:

ok: bool

message: str

... и еще 99 строк

... и еще 763 файлов

... и еще 759 файлов

🔗 Открыть на GitHub
💥 ВСЕ НАШИ ССЫЛКИ: https://t.me/runetvpnyoutubediscord

🔔 Новый коммит в youtubediscord/zapret

📝 Сделал. Ветка осталась `main`, чужие уже существовавшие изменения не трогал. Что изменил: - Добавил общий ограничитель строк: [src/ui/log_limits.py](/mnt/g/Privacy/zapretgui/public_zapretgui/src/ui/log_limits.py:7). - Поставил лимиты на поля логов: обычные логи, ошибки, вывод `winws`, диагностика, BlockCheck, Telegram Proxy, Orchestra. - Ограничил очередь логов Telegram Proxy: [proxy_logger.py](/mnt/g/Privacy/zapretgui/public_zapretgui/src/telegram_proxy/proxy_logger.py:81). - Ограничил очередь логов Orchestra до обработки интерфейсом: [page.py](/mnt/g/Privacy/zapretgui/public_zapretgui/src/orchestra/ui/page.py:414). - Добавил тесты: [test_ui_log_limits.py](/mnt/g/Privacy/zapretgui/public_zapretgui/tests/test_ui_log_limits.py:1). Проверил: - `PYTHONPATH=src python -m unittest discover -s tests` — 28 тестов прошли. - `PYTHONPATH=src python -m app.architecture_checks` — проверка архитектуры прошла. - `py_compile` по изменённым файлам — без ошибок. Теперь старые строки в логовых окнах будут автоматически выкидываться, а в памяти останется только последний ограниченный хвост.

👤 Автор: loop-uh
📅 Дата: 17.05.2026 14:35:03
🔗 SHA: b05e720

📊 Статистика:
➕ Добавлено: 857 строк
➖ Удалено: 152 строк
📝 Всего изменений: 1009

📁 Изменено файлов: 33

✏️ src/app/ARCHITECTURE.md
+5 -1

Удалилось:
-> ApplicationController создаёт AppRuntime


Добавилось:
-> ApplicationController создаёт AppRuntime

WindowPageActions создаётся только после `window_notifications_setup.py`.

Причина простая: действия страниц используют `window_notification_center.notify`,

а центр уведомлений появляется именно на этапе `window_notifications_setup.py`.


✏️ src/app/architecture_checks.py
+2 -1

Удалилось:
r"removed_placeholder_profiles|_OUT_RANGE_UNSIGNED_SIMPLE_RE)\b"


Добавилось:
r"removed_placeholder_profiles|_OUT_RANGE_UNSIGNED_SIMPLE_RE|"

r"sanitize_presets_before_launch|_ensure_lua_init_lines|strip_strategy_tags)\b"


✏️ src/blockcheck/ui/log_build.py
+2 -0

Добавилось:
from ui.log_limits import BLOCKCHECK_LOG_VIEW_MAX_LINES, apply_text_line_limit

apply_text_line_limit(log_edit, BLOCKCHECK_LOG_VIEW_MAX_LINES)


✏️ src/blockcheck/ui/strategy_scan_page_build.py
+2 -0

Добавилось:
from ui.log_limits import BLOCKCHECK_LOG_VIEW_MAX_LINES, apply_text_line_limit

apply_text_line_limit(log_edit, BLOCKCHECK_LOG_VIEW_MAX_LINES)


✏️ src/diagnostics/ui/build.py
+2 -0

Добавилось:
from ui.log_limits import DIAGNOSTICS_LOG_VIEW_MAX_LINES, apply_text_line_limit

apply_text_line_limit(result_text, DIAGNOSTICS_LOG_VIEW_MAX_LINES)


✏️ src/log/log.py
+2 -0

Добавилось:
from ui.log_limits import MAIN_LOG_VIEW_MAX_LINES, apply_text_line_limit

apply_text_line_limit(self.log_text, MAIN_LOG_VIEW_MAX_LINES)


✏️ src/log/ui/logs_build.py
+9 -0

Добавилось:
from ui.log_limits import (

ERROR_LOG_VIEW_MAX_LINES,

MAIN_LOG_VIEW_MAX_LINES,

WINWS_OUTPUT_MAX_LINES,

apply_text_line_limit,

)

apply_text_line_limit(log_text, MAIN_LOG_VIEW_MAX_LINES)

apply_text_line_limit(errors_text, ERROR_LOG_VIEW_MAX_LINES)

apply_text_line_limit(winws_text, WINWS_OUTPUT_MAX_LINES)


... и еще 26 файлов

... и еще 23 файлов

🔗 Открыть на GitHub
💥 ВСЕ НАШИ ССЫЛКИ: https://t.me/runetvpnyoutubediscord

🔔 Новый коммит в youtubediscord/zapret

📝 Причина: post-startup слой после запуска вызывает DNS-задачу через: application_post_startup.py (line 20) python features.dns.apply_dns_on_startup_async Но в DnsFeature такого поля не было. Сам DNS-метод уже существовал в dns.public, просто фасад DNS его не отдавал наружу. Поэтому exe падал с: text AttributeError: 'DnsFeature' object has no attribute 'apply_dns_on_startup_async' Исправил в dns.py (line 8): добавил apply_dns_on_startup_async в DnsFeature и связал его с dns_public.apply_dns_on_startup_async.

👤 Автор: loop-uh
📅 Дата: 17.05.2026 14:40:51
🔗 SHA: dc35db1

📊 Статистика:
➕ Добавлено: 9 строк
➖ Удалено: 0 строк
📝 Всего изменений: 9

📁 Изменено файлов: 2

✏️ src/app/feature_facades/dns.py
+2 -0

Добавилось:
apply_dns_on_startup_async: Callable

apply_dns_on_startup_async=dns_public.apply_dns_on_startup_async,


✏️ tests/test_main_startup_contract.py
+7 -0

Добавилось:
def test_dns_feature_exposes_startup_dns_entrypoint(self) -> None:

from app.feature_facades.dns import build_dns_feature

dns_feature = build_dns_feature()

self.assertTrue(callable(dns_feature.apply_dns_on_startup_async))


🔗 Открыть на GitHub
💥 ВСЕ НАШИ ССЫЛКИ: https://t.me/runetvpnyoutubediscord

🔔 Новый коммит в youtubediscord/zapret

📝 Причина: post-startup слой после запуска вызывает DNS-задачу через: application_post_startup.py (line 20) python features.dns.apply_dns_on_startup_async Но в DnsFeature такого поля не было. Сам DNS-метод уже существовал в dns.public, просто фасад DNS его не отдавал наружу. Поэтому exe падал с: text AttributeError: 'DnsFeature' object has no attribute 'apply_dns_on_startup_async' Исправил в dns.py (line 8): добавил apply_dns_on_startup_async в DnsFeature и связал его с dns_public.apply_dns_on_startup_async.

👤 Автор: loop-uh
🔗 SHA: dc35db1

📊 Статистика: 2 files changed, 9 insertions(+)

📁 Изменённые файлы:
✏️ src/app/feature_facades/dns.py
✏️ tests/test_main_startup_contract.py

🔗 Открыть на GitHub
💥 ВСЕ НАШИ ССЫЛКИ: https://t.me/runetvpnyoutubediscord

🔔 Новый коммит в youtubediscord/zapret

📝 В profile_setup_page.py (line 44) теперь главное место экрана — большой список готовых стратегий. Выпадающий список убран. Большие блоки “выбранная стратегия” и “что записано в профиль” убраны с главного экрана. Как теперь устроено: в главном окне profile сверху только компактные настройки; ниже вкладка Готовые стратегии с большим списком; активная стратегия выделяется строкой как в “Мои пресеты”: мягкая акцентная подложка + маркер слева; при наведении строка подсвечивается; жирного текста нет; границ между строками нет; строки компактные, высота 34px; при клике по уже активной стратегии открывается её подстраница; внутри подстраницы стратегии есть “Оценка стратегии”; “Что записано в профиль” и аргументы стратегии теперь живут на подстранице стратегии, а не в главном окне.

👤 Автор: loop-uh
🔗 SHA: 4921bc0

📊 Статистика: 10 files changed, 560 insertions(+), 50 deletions(-)

📁 Изменённые файлы:
✏️ src/main/window_notifications_setup.py
✏️ src/main/window_page_actions.py
✏️ src/main/window_startup.py
✏️ src/main/window_startup_setup.py
✏️ src/presets/builtin/winws2/Default v1 (game filter).txt
✏️ src/profile/service.py
✏️ src/profile/state.py
✏️ src/profile/ui/profile_setup_page.py
✏️ src/ui/widgets/win11_controls.py
✏️ tests/test_main_startup_contract.py

🔗 Открыть на GitHub
💥 ВСЕ НАШИ ССЫЛКИ: https://t.me/runetvpnyoutubediscord

🔔 Новый коммит в youtubediscord/zapret

📝 профиль

👤 Автор: loop-uh
🔗 SHA: 90d0260

📊 Статистика: 15 files changed, 635 insertions(+), 557 deletions(-)

📁 Изменённые файлы:
✏️ src/app/feature_facades/profile.py
✏️ src/profile/commands.py
✏️ src/profile/models.py
✏️ src/profile/service.py
✏️ src/profile/state.py
🗑️ src/profile/templates/all_profiles.txt
✏️ src/profile/ui/preset_setup_page.py
🆕 src/profile/ui/profile_display_items.py
✏️ src/profile/ui/profile_item.py
✏️ src/profile/ui/profiles_list.py
🆕 tests/test_build_resource_layout.py
🆕 tests/test_profile_display_items.py
🆕 tests/test_profile_filter_kind_switch.py
🆕 tests/test_profile_list_payload.py
🆕 tests/test_profile_strategy_resolution.py

🔗 Открыть на GitHub
💥 ВСЕ НАШИ ССЫЛКИ: https://t.me/runetvpnyoutubediscord

🔔 Новый коммит в youtubediscord/zapret

📝 Сделал большую проверку и поправил основное. Причина “всё выключено” была не одна: в живой установке выбран preset , там реально есть только 2 общих profile, а YouTube/Discord строки идут из каталога возможных profile и поэтому показывались выключенными. Плюс эти реальные profile попадали в группу «Прочее» внизу, поэтому сверху казалось, что выключено вообще всё. Что поправил: - добавил верхнюю группу , туда теперь попадают реальные profile выбранного preset; - открытие страницы profile больше не строит весь список заново; - оценки готовых стратегий теперь читаются из одним проходом, а не сотни раз; - убрал лишнюю передачу , она нигде не использовалась; - добавил тесты на первый запуск: пустые настройки и битый выбранный preset оба выбирают настроенный default preset. Основные файлы: - [service.py](/mnt/g/Privacy/zapretgui/public_zapretgui/src/profile/service.py) - [strategy_state.py](/mnt/g/Privacy/zapretgui/public_zapretgui/src/profile/strategy_state.py) - [profile_display_items.py](/mnt/g/Privacy/zapretgui/public_zapretgui/src/profile/ui/profile_display_items.py) - [profiles_list.py](/mnt/g/Privacy/zapretgui/public_zapretgui/src/profile/ui/profiles_list.py) - [test_preset_selection_defaults.py](/mnt/g/Privacy/zapretgui/public_zapretgui/tests/test_preset_selection_defaults.py) Проверил: - теста прошли; - прошёл; - прошёл; - прошёл; - на живом сборка detail-данных для profile с стратегиями заняла примерно . В On branch main

👤 Автор: loop-uh
🔗 SHA: 1c62a68

📊 Статистика: 16 files changed, 613 insertions(+), 58 deletions(-)

📁 Изменённые файлы:
✏️ src/hosts/page_controller.py
✏️ src/main/startup_coordinator.py
🆕 src/profile/list_interpreter.py
✏️ src/profile/models.py
✏️ src/profile/service.py
✏️ src/profile/state.py
✏️ src/profile/strategy_state.py
✏️ src/profile/ui/profile_display_items.py
✏️ src/profile/ui/profiles_list.py
✏️ src/winws_runtime/runtime/autostart.py
🆕 tests/test_hosts_page_runtime.py
✏️ tests/test_main_startup_contract.py
🆕 tests/test_preset_selection_defaults.py
✏️ tests/test_profile_display_items.py
✏️ tests/test_profile_list_payload.py
🆕 tests/test_startup_autostart.py

🔗 Открыть на GitHub
🐳1
💥 ВСЕ НАШИ ССЫЛКИ: https://t.me/runetvpnyoutubediscord

🔔 Новый коммит в youtubediscord/zapret

📝 иконки

👤 Автор: loop-uh
🔗 SHA: 2c19204

📊 Статистика: 19 files changed, 250 insertions(+), 67 deletions(-)

📁 Изменённые файлы:
✏️ requirements.txt
✏️ src/blockcheck/ui/domains_build.py
✏️ src/blockcheck/ui/log_build.py
✏️ src/blockcheck/ui/sections_build.py
✏️ src/blockcheck/ui/strategy_scan_page_build.py
✏️ src/blockcheck/ui/strategy_scan_page_results_workflow.py
✏️ src/diagnostics/ui/build.py
✏️ src/donater/ui/build.py
✏️ src/hosts/ui/sections_build.py
✏️ src/log/commands.py
✏️ src/profile/icons.py
✏️ src/profile/ui/profile_icon.py
✏️ src/profile/ui/profile_setup_page.py
✏️ src/profile/ui/shell.py
✏️ src/telegram_proxy/ui/proxy_runtime_workflow.py
✏️ src/telegram_proxy/ui/settings_build.py
✏️ src/ui/fluent_widgets.py
🆕 tests/test_log_page_runtime.py
✏️ tests/test_profile_icons.py

🔗 Открыть на GitHub
💥 ВСЕ НАШИ ССЫЛКИ: https://t.me/runetvpnyoutubediscord

🔔 Новый коммит в youtubediscord/zapret

📝 Keep interactive readiness outside startup coordinator

👤 Автор: loop-uh
🔗 SHA: 4481a91

📊 Статистика: 4 files changed, 3 insertions(+), 16 deletions(-)

📁 Изменённые файлы:
✏️ src/main/startup_contract.md
✏️ src/main/startup_coordinator.py
✏️ src/main/window_startup_setup.py
✏️ tests/test_main_startup_contract.py

🔗 Открыть на GitHub
💥 ВСЕ НАШИ ССЫЛКИ: https://t.me/runetvpnyoutubediscord

🔔 Новый коммит в youtubediscord/zapret

📝 Keep hidden mode sidebar items cached

👤 Автор: loop-uh
🔗 SHA: 8ebb949

📊 Статистика: 3 files changed, 59 insertions(+), 14 deletions(-)

📁 Изменённые файлы:
✏️ src/ui/navigation/layout_plan.py
✏️ src/ui/navigation/schema.py
✏️ tests/test_preset_sidebar_navigation.py

🔗 Открыть на GitHub
💥 ВСЕ НАШИ ССЫЛКИ: https://t.me/runetvpnyoutubediscord

🔔 Новый коммит в youtubediscord/zapret

📝 Improve profile icon resolution

👤 Автор: loop-uh
🔗 SHA: 4ae8332

📊 Статистика: 2 files changed, 155 insertions(+), 28 deletions(-)

📁 Изменённые файлы:
✏️ src/profile/icons.py
✏️ tests/test_profile_icons.py

🔗 Открыть на GitHub