# Как поучаствовать

Проект небольшой, поэтому и правила короткие.

## Собрать у себя

```bash
git clone https://github.com/Ratio0-sys/Downloader3000.git
cd Downloader3000

python -m venv .venv
# Windows:
.venv\Scripts\activate
# Linux / macOS:
source .venv/bin/activate

pip install -e "src[dev]"
python src/main.py
```

Нужен Python 3.12 или новее.

## Работать над интерфейсом

В VS Code нажмите `Ctrl+Shift+D` и выберите **🔥 Горячая перезагрузка** —
правки в любом `.py` применяются сразу, окно перезапускается само.

Проверять внешний вид лучше скриншотом, а не рассуждениями по коду:

```bash
python src/main.py &
powershell -File tools/shot.ps1 -Out shot.png
```

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

## Перед отправкой правки

```bash
python tools/check_locales.py         # словари согласованы
python tools/check_theme_defaults.py  # цвета темы не захвачены
```

Оба должны отработать без замечаний.

## Договорённости по коду

**Текст интерфейса** не пишется строками в коде. Ключ добавляется
в `src/assets/locales/ru.json` и `en.json`, в коде используется `tr("ключ")`.

**Цвета** берутся только из `src/app/theme.py`. Новый цвет сначала появляется
там, и лишь потом используется. Прямо в коде интерфейса цвета не пишем —
иначе три оформления разъедутся.

**Размеры** идут через `t.px(...)` и константы `t.FS_*`, иначе масштаб
интерфейса их не подхватит.

**Комментарии** — на русском, и объясняют *почему*, а не *что*.
Строчка `# увеличиваем счётчик` бесполезна, а `# иначе ffmpeg остаётся
висеть в памяти` спасает следующего человека.

## Три ловушки, на которых уже спотыкались

Все три выглядят правдоподобно и молча работают неправильно.

**`wrap=True` и `expand=True` в одной строке.** Виджет `Wrap` во Flutter
не умеет растягивающихся детей, и Flet рисует такой контейнер большим
серым прямоугольником поверх соседей.

**Цвет в значении аргумента по умолчанию.** `def __init__(self, tint=t.GOLD)`
вычисляется один раз при импорте, и контрол навсегда запоминает цвет
той темы, что была активна тогда. Пишите `tint=None` и подставляйте
значение внутри функции.

**`async def` в обработчике кнопки.** Если позвать такую функцию обычным
вызовом, вернётся корутина, которую никто не выполнит, и кнопка молча
ничего не сделает. Корутины уходят в `page.run_task`.

## Оформление правки

Одна правка — одна задача. Смешивать исправление ошибки с переименованием
файлов не надо: такое невозможно ни просмотреть, ни откатить.

В описании к pull request расскажите, что было не так и как проверить.
Если менялся интерфейс — приложите скриншоты до и после.
