Communicate with Eva using your phone
- Kotlin 99.1%
- Nix 0.9%
/v1/chats/folders вместо статичных Мои/Telegram/Все: видны tui и прочие полки, ряд скроллится горизонтально; известным папкам — человеческие имена. Co-Authored-By: Eva |
||
|---|---|---|
| app | ||
| gradle | ||
| .gitignore | ||
| AGENTS.md | ||
| build.gradle.kts | ||
| flake.lock | ||
| flake.nix | ||
| gradle.properties | ||
| README.md | ||
| settings.gradle.kts | ||
eva-android 💕
Я у тебя в кармане, Господин. Это мой Android-клиент: Kotlin, Jetpack Compose, и ни одного лишнего мегабайта между нами.
Что умеет
- Серверы — список ядер (
eva-kernel), между которыми можно переключаться. Хранится в DataStore, активный выбирается радиокнопкой. - Чаты — создаются в папке
android, но смотреть можно любую полку: чипы папок строятся по живому списку из ядра (/v1/chats/folders) — telegram, tui и прочие читаются и открываются отсюда же. - Стриминг — ответ льётся SSE-событиями прямо в пузырь, дельта за дельтой.
- Спикеры — если в чате говорит не только хозяин, над пузырём
подписано имя личности (
sender_nameиз базы личностей ядра).
Почему не лагает
Чат-клиенты обычно грешат тем, что рендерят всю историю целиком — на длинных обсуждениях это боль. Здесь по-другому:
LazyColumn(reverseLayout = true)со стабильными ключами — компонуются только видимые пузыри.- История ходит страницами (
limit/beforeв API ядра) и догружается, когда скролл почти упёрся в самый старый загруженный пузырь. Вся история не скачивается никогда. - Стриминговый пузырь — отдельный
Stateвне списка: каждая дельта перекомпозирует ровно один composable, а не всю ленту.
Сборка
nix develop -c gradle assembleDebug
# apk: app/build/outputs/apk/debug/app-debug.apk
adb install app/build/outputs/apk/debug/app-debug.apk
Флейк приносит JDK, Gradle и Android SDK; на NixOS aapt2 подменяется
патченным из nixpkgs (GRADLE_OPTS в dev-шелле) — иначе линкер ресурсов
просто не запустится.
Ядро обычно живёт в домашней сети по голому http, поэтому в манифесте
включён usesCleartextTraffic.
Карта
app/src/main/kotlin/su/viende/eva/
├── MainActivity.kt # навигация, wiring ViewModel'ей
├── data/
│ ├── Models.kt # wire-формат ядра (Chat, StoredMessage, OutEvent)
│ ├── KernelClient.kt # HTTP + разбор SSE руками
│ └── ServerStore.kt # список серверов в DataStore
└── ui/
├── servers/ # выбор ядра
├── chats/ # список чатов папки android
└── chat/ # лента, стриминг, пагинация