Mr.Comic — Android Reader Architecture Analysis
By Leostrange · Published July 26, 2026
Comprehensive technical audit of Mr.Comic, a modular Android app for reading comics, manga, ebooks (EPUB, PDF, DJVU), audiobooks with OCR, TTS, and LLM features built on Kotlin, Compose, and Jetpack.
- android
- kotlin
- architecture
- ebook-reader
- jetpack-compose
- modular-design
Inside this notebook
# Mr.Comic — Подробный анализ проекта **Репозиторий:** [github.com/Leostrange/Mr.Comic](https://github.com/Leostrange/Mr.Comic) **Дата анализа:** 2026-07-26 **Версия:** v2.1.0 (релиз 2026-06-22) **Лицензия:** Source-available (все права защищены) Mr.Comic — модульное Android-приложение для чтения комиксов, манги, вебтунов, книг (EPUB, FB2, TXT, HTML, Markdown, RTF, MOBI, AZW3, DOCX, ODT), аудиокниг, с OCR-переводами, словарями, TTS и LLM-объяснениями. Проект написан на Kotlin с использованием Jetpack Compose, Hilt DI, Room и Media3. Этот notebook содержит детальный анализ архитектуры, стека технологий, статуса функций, тестовой инфраструктуры, CI/CD и текущего состояния разработки.
import subprocess, os, json
from pathlib import Path
from collections import defaultdict
REPO = Path("/home/user/repos/Mr.Comic")
# ── 1. Kotlin files & LOC per module ──────────────────────────────────
modules = sorted([d.name for d in (REPO / "android").iterdir() if d.is_dir()])
stats = []
for m in modules:
mdir = REPO / "android" / m
kt_files = list(mdir.rglob("*.kt"))
src_files = [f for f in kt_files if "/test/" not in str(f) and "/androidTest/" not in str(f)]
test_files = [f for f in kt_files if "/test/" in str(f) or "/androidTest/" in str(f)]
src_loc = sum(len(f.read_text(errors="ignore").splitlines()) for f in src_files)
test_loc = sum(len(f.read_text(errors="ignore").splitlines()) for f in test_files)
stats.append({
…======================================================================== MR.COMIC — МЕТРИКИ ПРОЕКТА ======================================================================== Всего Kotlin-файлов (src): 412 Всего Kotlin-файлов (test): 165 Всего строк кода (src): 107,013 Всего строк кода (test): 19,623 Итого строк: 126,636 Модулей: 16 Тестов на 1000 строк src: 1.5 ========================================================================…
## 1. Общие сведения | Параметр | Значение | |----------|----------| | **Название** | Mr.Comic | | **Репозиторий** | `https://github.com/Leostrange/Mr.Comic` | | **Платформа** | Android (minSdk 26 / targetSdk 35 / compileSdk 37) | | **Язык** | Kotlin 2.2.21 | | **UI** | Jetpack Compose + Material 3 (BOM 2025.01.01) | | **DI** | Hilt 2.59.2 + KSP 2.2.21-2.0.5 | | **Хранение** | Room 2.7.1, DataStore 1.2.1 | | **Медиа** | Android Media3 1.5.1 (ExoPlayer) | | **EPUB** | Readium 3.1.2 | | **Сеть** | Retrofit 3.0.0, OkHttp 5.4.0 | | **Изображения** | Coil 2.7.0 | | **OCR / ML** | ML Kit (text-recognition, translate, language-id) | | **Сборка** | Gradle + AGP 9.2.1, JDK 17 | | **Статический анализ** | Detekt 1.23.7 | | **CI/CD** | GitHub Actions (2 workflow) | | **Лицензия** | Source-available (© 2026 Leostrange) | | **Текущая версия** | v2.1.0 (2026-06-22) | | **Контрибьюторы** | 1 (Leostrange — 82 коммита) | | **Период разработки** | 2026-04-21 — 2026-07-25 (≈ 3 месяца) |
## 2. Архитектура проекта ### 2.1. Модульная структура Проект состоит из **16 Android-модулей** и **1 KMP-модуля** (`shared/`), организованных по принципу feature-first + layer-first гибрид: ```text Mr.Comic/ ├── android/ │ ├── app/ → Точка входа, навигация, DI-корень │ ├── core-model/ → Общие модели, enum'ы, каталог форматов │ ├── core-data/ → Room, DataStore, репозитории, миграции, словари │ ├── core-domain/ → Доменная логика, use case, перевод, аналитика │ ├── core-ui/ → Тема, дизайн-примитивы, shared UI-компоненты │ ├── engine-api/ → Граничные интерфейсы движков чтения (3 файла) │ ├── engine-epub-readium/ → Интеграция EPUB через Readium │ ├── engine-formats/ → Ридеры форматов: архивы, EPUB, FB2, PDF, DJVU, текст │ ├── engine-llm/ → LLM-интеграция (OpenRouter, llama.cpp, NLLB) │ ├── engine-registry/ → Регистрация и обнаружение движков │ ├── engine-rendering/ → Кэш битмапов, предзагрузка, рендеринг │ ├── feature-library/ → Библиотека, импорт, аудиоплеер, прогресс │ ├── feature-reader/ → Экран чтения, контейнеры, TTS, жесты, пагинация │ ├── feature-settings/ → Настройки и кастомизация │ ├── feature-ocr/ → OCR-модуль (ML Kit) │ └── feature-onboarding/ → Онбординг первого запуска ├── shared/ → KMP-модуль (commonMain + androidMain) ├── docs/ → Документация, рекомендаци…
## 3. Технологический стек ### 3.1. Сборка и инструментарий | Компонент | Версия | Примечание | |-----------|--------|-----------| | Android Gradle Plugin | 9.2.1 | Актуальная линейка AGP | | Kotlin | 2.2.21 | С K2-компилятором | | KSP | 2.2.21-2.0.5 | Замена kapt для Hilt/Room | | JDK | 17 | Обязательно для AGP 9.x | | Gradle | wrapper из репозитория | Parallel + caching включены | | compileSdk | 37 | Android 17 (Baklava) | | minSdk | 26 | Android 8.0 | | targetSdk | 35 | Android 15 | | JVM target | 17 | | | Version catalog | `gradle/libs.versions.toml` | Единый источник версий | | ProGuard/R8 | Включён для release | `isMinifyEnabled = true`, `isShrinkResources = true` | | Core library desugaring | 2.1.5 | Java 8+ API на minSdk 26 | ### 3.2. UI-фреймворк - **Jetpack Compose** (BOM 2025.01.01) — декларативный UI - **Material 3** — дизайн-система - **Navigation Compose** 2.9.8 — навигация - **Accompanist** 0.36.0 — вспомогательные Compose-компоненты - **Lottie** 6.6.2 — анимации - **Coil** 2.7.0 — загрузка и кеширование изображений - **Splash Screen API** 1.2.0 ### 3.3. Данные и хранилище - **Room** 2.7.1 — ORM, миграции, кеш EPUB-манифестов, словари - **DataStore** 1.2.1 — настройки (Preferences) - **Gson** 2.14.0 — сериализация JSON ### 3.4. Сеть и интеграции - **Retrofit** 3.0.0 + **OkHttp** 5.4.0 — HTTP-клиент - **OpenRouter** — LLM-объяснения (через engine-llm) - **Google Drive API** — облачная синхронизация (google-api-services-drive) - **Microsoft Identity (MSAL…
## 4. Статус реализации функций ### 4.1. Реализовано и работает | Функция | Статус | Модуль | |---------|--------|--------| | Чтение растровых комиксов (CBZ, CBR, ZIP, RAR, 7Z, TAR, папки) | ✅ Работает | `engine-formats`, `feature-reader` | | Вертикальный режим (webtoon) для изображений | ✅ Работает | `feature-reader` | | PDF-рендеринг (встроенный PdfRenderer) | ✅ Работает | `engine-formats/pdf` | | DJVU-рендеринг (собственный декодер: BZZ, IW44, ZP) | ✅ Работает | `engine-formats/djvu` (18 файлов) | | Библиотека: импорт, обложки, прогресс | ✅ Работает | `feature-library` | | Аудиокниги (Media3 ExoPlayer) | ✅ Работает | `feature-library`, `app` | | TTS (Text-to-Speech) | ✅ Работает | `feature-reader` | | Настройки: темы, шрифты, пресеты | ✅ Работает | `feature-settings` | | Закладки, цитаты, highlights | ✅ Работает | `core-data` | | Навигация по TOC | ✅ Работает | `feature-reader` | | Онбординг первого запуска | ✅ Работает | `feature-onboarding` | ### 4.2. Работает частично / с известными проблемами | Функция | Статус | Проблема | |---------|--------|----------| | EPUB-чтение (Readium) | ⚠️ Частично | Deadlocks при закрытии, прогресс-калькуляция, base-path ассетов | | FB2, TXT, HTML, Markdown, RTF, DOCX | ⚠️ Частично | Пагинация, переносы, отступы, сложное форматирование | | MOBI / AZW3 | ⚠️ Частично | Базовое извлечение текста | | Сноски (footnotes) | ⚠️ Частично | Marker, peek, expand — есть; длинные сноски и popup — нестабильны | | RTL-навигация | ⚠️ Частично | Базовая…
## 5. Тестовая инфраструктура ### 5.1. Общая статистика | Метрика | Значение | |---------|----------| | Тестовых файлов (unit) | 164 | | Тестовых файлов (instrumented) | 1 | | Строк тестового кода | 19 623 | | Соотношение test/src (по строкам) | 18.3% | | Тестовых файлов на 1000 строк src | 1.5 | ### 5.2. Распределение тестов по модулям | Модуль | Unit-тестов | Instrumented | Покрытие ключевых областей | |--------|:-----------:|:------------:|---------------------------| | `feature-reader` | 49 | 0 | Навигация, пагинация, прогресс, CSS, сноски, webtoon, TTS-политики | | `engine-formats` | 48 | 0 | EPUB (assets, close, chunking, footnotes, CSS), FB2, MOBI, архивы, DJVU, charset, формат-детектор | | `core-domain` | 20 | 0 | Перевод, словари, use case, аналитика, геймификация, Result | | `feature-library` | 16 | 0 | Импорт, обложки, прогресс, фоновая генерация | | `core-model` | 9 | 0 | Формат-каталог, модели, enum'ы | | `app` | 7 | 0 | Навигация, политики открытия, continue-чекпоинты | | `core-data` | 4 | 1 | Миграции Room, формат-детектор, цитаты | | `feature-settings` | 3 | 0 | Настройки | | `feature-ocr` | 3 | 0 | OCR-политики | | `engine-epub-readium` | 3 | 0 | Readium-адаптер | | `engine-rendering` | 2 | 0 | Рендеринг | | `core-ui` | 1 | 0 | UI-компоненты | | `engine-llm` | 0 | 0 | ⚠️ Нет тестов | | `engine-registry` | 0 | 0 | ⚠️ Нет тестов (1 файл исходного кода) | | `feature-onboarding` | 0 | 0 | ⚠️ Нет тестов | | `shared` | 0 | 0 | ⚠️ Нет тестов (KMP-модуль) | ###…
## 6. CI/CD ### 6.1. Workflow: `build-apk.yml` (основной) **Триггеры:** push в `main`, pull request в `main`, ручной запуск (`workflow_dispatch`) | Job | Зависимости | Timeout | Описание | |-----|-------------|---------|----------| | `unit-tests` | — | 30 мин | `testDebugUnitTest` для всех 16 модулей, upload артефактов | | `lint` | — | 20 мин | Detekt + Android Lint (`:app:lintDebug`), upload HTML-отчётов | | `build` | unit-tests, lint | 30 мин | Сборка Debug + Release APK, upload APK + mapping | | `python-scripts` | — | 10 мин | Smoke-тест Python-скриптов сборки словарей | | `instrumented-tests` | unit-tests | 30 мин | Эмулятор API 34 (x86_64, KVM), `connectedDebugAndroidTest` | **Особенности:** - Concurrency group с `cancel-in-progress: true` — отмена устаревших запусков - Gradle setup через `gradle/actions/setup-gradle@v5` с кешированием - JDK 17 (Temurin) - Артефакты: тестовые отчёты, lint-отчёты, Debug/Release APK, ProGuard mapping ### 6.2. Workflow: `release.yml` **Триггер:** push тегов `v*` | Шаг | Описание | |-----|----------| | Checkout | `fetch-depth: 0` для полной истории | | Keystore | Декодирование из `secrets.KEYSTORE_BASE64` (base64) | | Build | Debug APK (всегда) + Release APK (при наличии keystore) | | Changelog | Генерация из `git log` между тегами | | GitHub Release | `softprops/action-gh-release@v2` с APK-файлами | ### 6.3. Оценка CI/CD **Сильные стороны:** - Полный pipeline: тесты → lint → сборка → instrumented-тесты - Автоматический release по т…
## 7. Качество кода и статический анализ ### 7.1. Detekt Detekt 1.23.7 подключён как плагин в корневом `build.gradle.kts` с кастомной конфигурацией `config/detekt/detekt.yml` (70 строк) и baseline-файлом. **Активные правила:** | Категория | Правило | Порог | |-----------|---------|-------| | Complexity | `LargeClass` | 500 строк | | Complexity | `LongMethod` | 80 строк | | Complexity | `LongParameterList` | 10 (функция) / 12 (конструктор) | | Complexity | `TooManyFunctions` | 50 (класс) / 80 (файл) | | Complexity | `CyclomaticComplexMethod` | 15 | | Complexity | `ComplexCondition` | активен | | Style | `MaxLineLength` | 140 символов | | Style | `MagicNumber` | активен (ignore `@Preview`) | | Style | `ReturnCount` | макс. 4 | | Style | `NestedBlockDepth` | 5 | | Naming | `PackageNaming` | `^[a-z]+(\.[a-z][a-z0-9]*)*$` | | Naming | `FunctionNaming` | `[a-z][a-zA-Z0-9]*` (ignore `@Composable`) | | Potential bugs | `UnsafeCallOnNullableType` | активен | | Potential bugs | `UnnecessaryNotNullCheck` | активен | | Potential bugs | `LateinitUsage` | **отключён** | | Empty blocks | — | активны | **Особенности:** - `buildUponDefaultConfig = true` — наследование стандартных правил - Baseline-файл позволяет постепенно уменьшать нарушения - В корневом `build.gradle.kts` принудительно выравниваются версии `kotlin-stdlib` - Запрещены `pdfium-android` (несовместим с AndroidX) и `pdfbox-android` (заменён встроенным PdfRenderer) ### 7.2. Android Lint Запускается через `:app:lintDebug` в…
## 8. Документация и проектные материалы ### 8.1. Структура документации ```text docs/ ├── README.md → Общая документация ├── RECOMMENDATIONS.md → 21 рекомендация по коду (с примерами) ├── KMP_MIGRATION_PLAN.md → План миграции на Kotlin Multiplatform ├── bugs_status_20260523.md → Статус багов ├── reader_test_progress.md → Прогресс тестирования ридера └── active/ → Активные рабочие документы ├── AUDIT_2026-07-07.md ├── AUDIT_2026-07-07_REMAINING.md ├── DJVU_RENDERER_RESEARCH.md ├── EPUB_DJVU_MIGRATION_TASKLIST.md ├── FORMAT_SUPPORT_AUDIT_2026-03-27.md ├── LIBRARY_BACKGROUND_GENERATION_TZ.md ├── LIBRARY_BACKGROUND_PROMPT_PACK.md ├── LOCALIZATION_AUDIT.md ├── QA_REGRESSION_CHECKLIST.md ├── READER_IMPORT_OPEN_PLAN.md ├── READIUM_EPUB_DJVU_MIGRATION_PLAN.md ├── SETTINGS_CAPABILITY_MAP.md ├── THIRD_PARTY_DICTIONARIES.md ├── TRANSLATION_MODULE_TZ.md └── TRANSLATION_TASKLIST.md ``` ### 8.2. Корневые документы | Файл | Назначение | |------|-----------| | `README.md` | Описание проекта, возможности, форматы, стек, сборка, CI | | `RELEASE_NOTES.md` | Заметки релиза v2.1.0 | | `LICENSE` | Source-available лицензия | | `THIRD_PARTY_NOTICES.md` | Сторонние лицензии | | `ACTIVE_REMAINING_TASKS_2026-07-23.md` | Активный список задач (рабочая точка входа) | ### 8.3. Вспомогательные материалы | Каталог | Содержимое | |---------…
## 9. Текущее состояние разработки ### 9.1. Git-активность | Период | Коммитов | Характер работ | |--------|:--------:|----------------| | 2026-04-21 — 2026-04-30 | 13 | Начальный snapshot, рефакторинг формат-ридеров | | 2026-05-14 | 2 | Точечные правки | | 2026-06-10 — 2026-06-23 | 31 | Детект, namespace-рефакторинг, CI, тесты, ISP, декомпозиция ViewModel, KMP-план, релиз v2.1.0 | | 2026-07-20 — 2026-07-25 | 35 | P0/P1 баги, рефакторинг (WebtoonDocumentBuilder, ComicFormatDetector), тесты навигации, прогресс EPUB | **Пик активности:** 20–21 июля 2026 (31 коммит за 2 дня) — массовый рефакторинг и исправление критических багов. **Ветки:** только `main`. Feature-ветки не обнаружены (вероятно, squash-merge или работа в main). ### 9.2. Активные задачи (из ACTIVE_REMAINING_TASKS_2026-07-23.md) **P0 — Reader: корректность чтения:** | ID | Задача | Состояние | |----|--------|-----------| | RDR-01 | PAGE → WEBTOON restoration | Код есть, unit-тесты зелёные, runtime-подтверждение не получено | | RDR-02 | Стабильный API 37 QA-стенд | **Блокер**: эмулятор выдаёт `System UI isn't responding` | | RDR-03 | Регрессия page mode (EPUB, FB2, HTML, TXT, DOCX) | Не выполнена | | RDR-04 | Регрессия vertical mode и сносок | Не выполнена | | RDR-05 | Прогресс и completion | Не выполнена | **P1 — Декомпозиция крупных файлов:** | ID | Задача | Состояние | |----|--------|-----------| | ARC-09b | Archive content scanner → `ComicFormatDetector` | Частично выполнено (коммит ca0fbd1) | | ARC-10 |…
This is a preview. Open the live notebook to see all 15 cells with their charts and full outputs, or fork it into your own Clusy workspace.