- категория connection теперь только жизненный цикл соединения; INIT/PING/keepalive
переклассифицированы в ETCP/SOCKET/KEEPALIVE/REALITY/ROUTING, удалены дубли
- settingsdialog: устранён дубль my_node_name в конфиге (двухпроходная запись + только при изменении)
- storagesettingspage: канонические ключи storage_total_size/storage_unit_size с суффиксом M/G
- audiodevicesettingspage: compressor_max_gain_db min 0→1
- etcp_connections: %s-баг в логе TCP link (addr → sockaddr_storage_to_str)
- docs/sample: [chatserver], актуализированы ключи хранилища
- chatgui: просмотрщик изображений (ImageViewerWindow) с зумом/поворотом
- chatgui: отправка картинок как image с определением разрешения и типа
- chatgui: у видео-пузыря строка info (res·size·bitrate) и бейдж только длительность
- chatgui: контекстное меню медиа (сохранить в файл/скачать)
- chatgui-android: большие emoji-only сообщения, битрейт/разрешение у видео
- chatgui-android: сохранение неактивных интерфейсов как закомментированные секции
- chatgui-android: отправка картинок по расширению (jpg/png/gif/bmp/webp)
- photo_sender: content-type и расширение по типу файла
- C-слой: video_sender (content_type video/mp4, media_video=0 без FFmpeg)
- chat_msg_submit: duration/width/height для метаданных видео в теле сообщения
- JNI: nativeVideoSend + NativeLib/Repository/ViewModel
- VideoRecordScreen: CameraX VideoCapture, 4 пресета качества (разрешение+битрейт),
выбор камеры (селфи/широкая/обычная/макро/теле по фокусу), тумблер подсветки,
запись/пауза/отправить, лимит 60с
- InputBar: единая кнопка — короткий тап переключает voice/video, удержание — запись
- режим камеры/микрофона сохраняется в ViewModel
- main.cpp: на Linux принудительно QT_QPA_PLATFORM=xcb (если не задан) — на Wayland
композитор владеет позицией окна, на XWayland ручной move/resize работает полностью
- videoplayer_window: вернуть ручной move + ручной resize с пропорцией (один путь,
без платформозависимого нативного startSystemMove/Resize)
- окно: startSystemMove/startSystemResize вместо ручного move/setGeometry
(Wayland игнорирует позицию окна) — драг и resize за левый/верхний край работают
- пропорции: снэп к videoAspect после нативного resize (дебаунс 150мс)
- перемотка: backpressure по m_buffered (декод не убегает вперёд и воркер живёт
для seek), seek через av_seek_frame(-1, us), пропуск кадров с AV_NOPTS_VALUE
- SeekSlider: клик по шкале = прыжок к позиции
- крестик закрытия справа вверху; курсор контролов — стрелка
- test_video_engine: проверка seek
- m_render WA_TransparentForMouseEvents — события мыши напрямую в окно (drag работает)
- открытие: видео влезает — натуральный размер по центру; больше экрана — fullscreen
- resize мышью за 4 края и 4 угла, пропорции сохраняются (якорь = противоположный край)
- нижний край доступен через eventFilter на панели контролов (пустые поля пропагируют)
- сброс fullscreen при повторном playFile
- presentTick: кадры всегда по мастер-часам, завершение только когда очередь пуста
- clockMs: по окончании аудио часы в конец (хвостовые кадры не теряются)
- fallback на системные часы, если аудио-устройство недоступно
- tests/test_video_engine: smoke-тест FFmpeg-декодера (opened/frames/seek)
Добавлен 64-битный reset_id (эпоха ресета) в INIT-фреймы и STCP-handshake:
- генерится один раз при создании conn, меняется только при фатальном ресете
(normalizer desync / bad fragment size);
- при приёме чужого id slave принимает эпоху пира и ресетится, master держит свою;
- первый id принимается без ресета (свежие при init);
- «tcp peer clean» реинит гейтится по смене id — нет повторного сброса seq.
Это устраняет коллизию seq=1 (RX dup) из-за двойного реинита нескольких TCP-линков,
из-за которой NODEINFO пира терялся и member не возвращался online.
Также: chat member online теперь из topo_group (без БД/merkle), тест test_etcp_seq_collision.
- ConfigProvider: флаг service_enabled (DataStore), flow/getter/setter
- MainActivity: автозапуск сервиса только при service_enabled; edge-to-edge со светлыми иконками статус-бара
- SettingsScreen: секция Service (start/stop), stop/exit сохраняет состояние; NativeLib.restart гейтится по isReady чтобы ядро не запускалось без сервиса
standby.h/c: duty-cycle ACTIVE/SLEEP, standby_wait() будит в burst сразу,
в SLEEP — до следующего burst; notify_network_activity для раннего пробуждения.
Интеграция (по флагу UTUN_HAVE_STANDBY, десктоп без изменений):
- conn_mgr: bg_ping/candidate_ping в SLEEP defer через standby_wait
- route_connectivity: probe_node откладывается (PROBE_STATUS_DEFERRED)
- topo_group_connect: пауза между попытками — активный режим 1с, фон standby_wait
- jni_bridge/ConfigProvider/NetworkActivityMonitor: set_active + сетевая активность
- chat_setting: standby_active_sec/sleep_sec/min_sleep_sec
+ юнит-тест test_standby (31 проверок)