Диагноз: диспетчеризация Gitea работает, но host-исполнение act_runner
роняет шаги (No such file / MODULE_NOT_FOUND, задвоение hostexecutor/.cache).
Workflow → workflow_dispatch (не auto-fail на push), раннер остановлен.
Рабочий путь на будущее — Docker-образ с JDK+SDK + gradle-кэш (docs/CI.md).
Сборки/релизы пока вручную (v0.5.123 опубликован).
Новый эффект F7SecureScreen(): пока экран на виду — окно с FLAG_SECURE
(нет в скриншотах/recents/записи экрана), снимается при уходе. Повешен на
LoginScreen (ввод пароля), AppLockUnlockScreen (разблокировка PIN) и
AppLockSetupDialog (создание PIN). Закрывает хвост Этапа 0 п.3.
- Нижняя панель: слева всегда «назад» (кнопки чатов больше нет; в
Конференциях раньше был чат-слот) — единый layout во всех разделах.
- Экран Конференций: убран onRefresh у F7ModuleScreen → нет кнопки ↻
сверху справа (список грузится при открытии и по push).
Фон кнопок всегда нейтральный (0x99FFFFFF); убраны highlight-подложка,
BottomBarHighlightBrush и параметр highlighted слота. Зелёные варианты
иконок чатов/бургера (при открытии) — это иконка, остаются.
У серверных SVG (mail-/deck-/spreed-header-icon) внутренний «воздух»,
поэтому глиф оставался мелким. Отдельный размер BottomBarSectionIconSize=46dp
для Почты/Карточек/Конференций (стрелка/бургер — прежние 34dp).
Раньше он показывался только в debug (в release скрыт), теперь убран
совсем. trustAllCerts остаётся false по умолчанию (безопасно); trust-all
на уровне сети/WebView и так отключён в release (UnsafeSsl).
Накоплено: нижняя навигац.панель + кнопки создания, меню (пол-экрана/
3 колонки/состав по дизайну), нативная панель профиля, нижний inset,
фикс ширины писем.
Панель стала единой навигационной: слева назад (в Конференциях — чаты),
далее ярлыки-разделы Почта · Карточки · Конференции (активный подсвечен),
справа выдвижное меню. Профиль/Уведомления/Настройки/Создать убраны из
панели (Профиль/Уведомления/Настройки — в выдвижном меню; бейдж
уведомлений перенесён на кнопку меню).
Создание раньше вызывалось ТОЛЬКО из панели → чтобы не потерять:
- новый общий компонент F7CreateButton (зелёный круг «+»);
- добавлен в шапку Файлов (→ меню создания) и Контактов (→ добавить контакт).
Задачи/Поддержка уже имели свои кнопки; Почта — «+» в шапке.
F7BottomBarConfig упрощён (единый layout), F7MobileBottomBar получил
слоты SectionMail/SectionCards/SectionConferences + activeTabKey.
Дизайн выдвижного меню — 3 колонки (было 4), иконки-бейджи *-glass.svg
уже совпадают со стилем. Ячейка стала кликабельной целиком (clip+ripple),
подпись использует ширину ячейки (Личный кабинет/Уведомления не дробятся).
«Личный кабинет» открывал внешнюю веб-ссылку → десктопный дропдаун
forbion, криво на мобильном. Теперь пункт открывает нативную панель
(ProfileSheet, bottom-card F7FloatingPanel):
- шапка: аватар-инициал + отображаемое имя (тянется из OCS cloud/user)
+ «Открыть профиль» (deep-link /u/<id>) + кнопка QR-скана браузера;
- пункты: Установить статус / Личные настройки / Учётные записи
(deep-link в веб-настройки), О программе и что нового (нативный
About-диалог с версией), Выйти (нативный logout, красный).
Material-иконки (extended уже в app). Точки входа: пункт меню
«Личный кабинет» + кнопка профиля в нижней панели. Компилируется.
Edge-to-edge (targetSdk 36): контент был full-bleed без нижнего inset →
уезжал под системные 3 кнопки/жест-панель (плавающая нижняя панель свой
navigationBarsPadding имела, а контент — нет). Добавил f7SafeBottomInsets
к контенту в F7AppScaffold (верх уже был через f7SafeTopInsets).
HTML-письма (широкие таблицы Битрикс/рассылок) уезжали за правый край:
WebView без useWideViewPort игнорировал viewport width=device-width и
раскладывал по ~980px. Включил useWideViewPort+loadWithOverviewMode
(вписывает/масштабирует в обзор) + пинч-зум. READER_CSS уже имел
overflow-x:hidden/table-layout:fixed — теперь работает как задумано.
F7AppMenuSheet был fillMaxSize с непрозрачным фоном (закрывал весь экран).
Теперь выезжает снизу и занимает ~пол-экрана: якорь BottomCenter,
fillMaxHeight(0.6f), скруглённый верх 20dp + тень, ручка-хендл, лёгкий
скрим над листом (тап закрывает), зазор под нижнюю панель, сетка иконок
скроллится. Экран под меню виден сверху. Бамп версии 0.5.115→0.5.116.
По «Календарь · Месяц»: дни недели — серые пилюли; сетка безрамочная с
гридлайнами (0.5dp) вместо скруглённых боксов; номер дня сверху-слева;
сегодня — в зелёном круге (Primary, белый текст); событие — зелёная
пилюля PrimaryLight (до 2 + «+N»), было одно превью/точка. Компактная
модель (месяц + список дня снизу) сохранена. Компилируется.
Сняты пипеткой с «Почта · Список сообщений» (Figma):
Работа #DAEDD6/#28A413, Позже #F1EEE0/#C1B464, Личное #EFE4FB/#B574F7.
Раньше были приблизительные зелёный/коричневый/фиолетовый.
Строка письма уже карточная (аватар+имя+дата+тема) — близка к макету. Добавлены
цветные теги-пилюли (Работа/Позже/Личное) под темой (message.tags, MailTagChip).
Верхний бар (поиск+фильтр+compose) уже был. feature:mail компилируется.
- 13 SVG-иконок типов из Figma-набора (PDF/Word/Spreadsheet/Presentation/Image/
Audio/Video/Archive/Code/Text/Certificate/Eml/file) → assets/filetypes/.
- FileIcons переключён на локальные (file:///android_asset, грузятся coil-svg):
офлайн + точно из дизайна. Раньше тянулись с сервера (аудит: офлайн ломался).
- Папка пока с сервера (иконки папки в наборе дизайна нет — TODO из Figma).
feature:files компилируется.
- Имя + расширение инлайн (расширение серым TextSecondary), одна строка —
вместо имени в 2 строки + мета (размер·дата). По мобильному макету.
- Выбранная строка — светло-зелёный фон (F7Colors.PrimaryLight), скругление.
- Иконка типа 28→24dp. На токенах F7Spacing/F7Radius.
- Строка на существующей загрузке иконок с сервера; локальные ico + офлайн — следом.
feature:files компилируется. Визуальная сверка — на устройстве (side-by-side).
- detekt 1.23.8 применён ко всем НАШИМ модулям (vendor-форк исключён),
+formatting-ruleset (обёртка ktlint). Совместим с Kotlin 2.3 (проверено).
- config/detekt/detekt.yml — настройки под наш код (LongMethod 120, MaxLine 140,
MagicNumber off — dp/цвета отдельно, FunctionNaming off — @Composable Заглавные).
- detekt-baseline.xml по модулям: ~403 текущих замечаний зафиксированы →
detekt зелёный, дальше ловит только НОВЫЕ. detekt в CI (ci.yml verify).
Проверено: detektBaseline + detekt BUILD SUCCESSFUL.
Раньше NetworkFactory создавал новый OkHttpClient на КАЖДЫЙ запрос (~32 места):
TLS-handshake + новый пул/диспатчер на запрос + утечка ExecutorService.
Теперь: один базовый клиент (общий ConnectionPool/Dispatcher + диск-кэш 20МБ),
авторизованные варианты через base.newBuilder() (шарят пул/кэш), кэшируются по
кредам+таймаутам. Публичный API НЕ менялся — 32 вызова не тронуты.
Init диск-кэша в F7MobileApp.onCreate.
+3 unit-теста (переиспользование клиента, общий пул). 401→interceptor НЕ делал
(меняет семантику исключений — отдельный шаг).
Проверено: 15 тестов зелёные + assembleRelease BUILD SUCCESSFUL, APK 53 МБ.
ABI задаются побилдтипово: debug включает x86/x86_64 → нативно на эмуляторах
(BlueStacks) и на ARM-девайсах для тестирования; release остаётся arm64+armeabi-v7a
(компактный прод). Проверено: debug-APK содержит все 4 ABI.
- .gitea/workflows/ci.yml: push/PR → testDebugUnitTest+lintRelease+assembleDebug;
тег v* → подписанный assembleRelease + архив исходников в Gitea Release.
Gitea 1.26.1 поддерживает Actions. Self-hosted раннер (метка f7-android),
т.к. проект тяжёлый (WebRTC) и нужен тёплый Gradle-кэш.
- scripts/package-source.sh: GPL corresponding source (§6) — архив всего дерева
вкл. vendor talk-android (GPL), LICENSE, NOTICE. Проверен: 6.7 МБ, 2353 файла.
Закрывает п.4c, работает и вручную до появления раннера.
- docs/CI.md: пайплайн, регистрация раннера, secrets.
НЕ активно до регистрации раннера на инфре B (нужен Gitea-админ для токена).
- org.gradle.parallel=true (быстрее сборка 20 модулей)
- удалены core:data, core:ui (пустые заготовки) и feature:widgets (не в
settings.gradle, не компилировался) + чистка settings.gradle
- nonTransitiveRClass=true и убирание enableJetifier ОТКАЧЕНЫ: vendor-форк
talk-android их не переживает (R транзитивно; legacy android.support.* в
зависимостях типа FlexibleAdapter). Причины — в комментах gradle.properties.
Проверено сборкой: assembleRelease BUILD SUCCESSFUL. Этап 0 закрыт.