Lunaris
Lunaris - локальное Flutter-приложение для просмотра booru/gelbooru/rule34-подобных источников в Pinterest-стиле.
Приложение не использует отдельный backend-сервер. Вся логика живет внутри Flutter: API-провайдеры, кэш metadata, избранное, коллекции, история просмотров, настройки, диагностика, фильтры и обновления.
Возможности
- Masonry feed с несколькими провайдерами и перемешанной выдачей All providers.
- Поиск тегов через chip-input: ввел тег, нажал пробел или Enter, тег стал отдельным элементом.
- Подсказки тегов из API активных провайдеров.
- Рзбранное, коллекции Рё отдельная вкладка Viewed.
- Smart blacklist/whitelist по тегам, группам тегов, рейтингу, провайдеру, типу файла и score.
- Details viewer для фото, GIF, видео и SWF на Windows.
- Видео-плеер с fullscreen, repeat, mute, half-volume и сохранением выбранных настроек.
- Отдельная вкладка Artists для Kemono/Coomer: поиск авторов и просмотр их работ без смешивания с обычным booru feed.
- Управление провайдерами, health-check и provider diagnostics.
- РРєСЃРїРѕСЂС‚ Рё РёРјРїРѕСЂС‚ настроек JSON.
- Автопроверка обновлений через Gitea Releases, скачивание и открытие APK/Windows installer прямо из приложения.
Скачать
Готовые сборки лежат в Gitea Releases:
Lunaris-v1.1.2-experimental.apk- APK для Android.LunarisSetup-v1.1.2-experimental.exe- установщик для Windows.LunarisPortable-v1.1.2-experimental.zip- portable-версия для Windows.
Стек
- Flutter, Dart, Riverpod, go_router
- Dio, Isar, connectivity_plus
- cached_network_image, flutter_staggered_grid_view
- media_kit для видео
- webview_windows + Ruffle fallback для SWF на Windows
Архитектура
Lunaris - Flutter-монолит. UI не дублирует backend-логику, а вызывает локальные сервисы через Riverpod.
lib/core- HTTP, база, кэш, ошибки, Result и утилиты.lib/backend/models- доменные модели.lib/backend/providers- API-провайдеры и ProviderManager.lib/backend/repositories- доступ к локальному Isar-хранилищу.lib/backend/services- Feed/Search/Favorites/Collections/Settings/Diagnostics/Downloads/Updates.lib/backend/di- Riverpod providers для backend/core.lib/app- приложение, роутер, тема и responsive helpers.lib/shared/widgets- общие UI-компоненты.lib/features- экраны и контроллеры фич.
Ркраны
/- главный feed./search- поиск и recent searches./post/:providerId/:postId- details viewer./favorites- избранное./viewed- история просмотренных постов./collections- коллекции./artists- поиск авторов Kemono/Coomer./artists/:providerId/:service/:artistId- работы автора./providers- управление провайдерами./providers/check- диагностика провайдеров./settings- настройки.
Провайдеры по умолчанию
- Gelbooru -
https://gelbooru.com - Rule34 -
https://api.rule34.xxx - Safebooru -
https://safebooru.org - Konachan -
https://konachan.com - Yande.re -
https://yande.re - e621 -
https://e621.net - e926 -
https://e926.net - Xbooru -
https://xbooru.com - CosBooru -
https://cos.lycore.co - Kemono -
https://kemono.su(только Artists) - Coomer -
https://coomer.su(только Artists, выключен по умолчанию)
Realbooru оставлен в списке, но выключен по умолчанию, потому что его публичный API сейчас нестабилен.
Поддерживаемые apiType: gelbooru, rule34, realbooru, danbooru, moebooru, e621, kemono, coomer.
Один упавший провайдер не ломает общий feed: ошибка сохраняется в diagnostics, остальные источники продолжают отдавать посты.
Как добавить провайдера
- Добавить mapper в
lib/backend/mappers, если формат ответа отличается. - Реализовать
ContentProviderили artist-onlyArtistProviderвlib/backend/providers. - Зарегистрировать новый
apiTypeвProviderFactory. - Добавить config через Providers UI или seed в
ProviderRepository.
Запуск и сборка
flutter pub get
flutter analyze
flutter test
flutter run -d windows
flutter build windows
flutter build apk
Windows installer собирается через Inno Setup:
ISCC installer/Lunaris.iss
Безопасность
- Feed работает с preview/sample metadata и не скачивает full files автоматически.
- Скачивание фото/видео/SWF выполняется только по явному действию пользователя.
- Приложение уважает rate limits и использует retry/backoff.
- API keys/user data хранятся локально и попадают в export JSON только по действию пользователя.