Unofficial Kavita client for mobile and desktop (in progress)
- Motivation
- About
- Template: Getting Started
- Setup
- Testing
- Building from Source (Advanced)
- Architecture
- Libraries
- Contributing
There is a lack of apps for self hosted services like Kavita and Audiobookshelf, this app provides some basic functionality for them.
A preview of the application is deployed to getboolean.github.io/subete_app.
- Supports Kavita 0.8
- Minimal OS Version:
- iOS: 13.0
- Android: 6.0 (SDK 23)
- MacOS: 10.14.6
- Windows 10
- Linux: Any modern distribution
- Made with Flutter
- Template by @getBoolean
- Add Environment Variables: ENVied Environment Variables section for details.
- Change App Icon: flutter_launcher_icons
- Change Splash Screen: flutter_native_splash
- Setup Codecov for the repository, see the Codecov documentation.
- Delete this
Template: Getting Started
section from the README.
- Install puro Flutter Environment Manager
- Install Flutter stable using Puro
- Install Melos globally
- Install Mason CLI
- Run
melos bootstrap
to install dependencies for all packages and generate env files.
- This project uses Mocktail to create mocks and fakes. Follow the instructions in the Mocktail README.
- Tests are located in the
test
root directory and each package. To run all tests, run the following command:
melos run test
-
To run and build this app, you need to have Flutter SDK installed on your system. Check for any problems with the command below.
flutter doctor
-
Create/modify packages/env/local.env.
# required
KAVITA_BASE_URL=https://kavita.example.com
# Either of the following
# Option 1 (remove if unused)
KAVITA_API_KEY=key_here
# Option 2
KAVITA_USERNAME=username_here
KAVITA_PASSWORD=password_here
-
Initialize the Flutter project using melos.
flutter pub get dart pub global activate melos melos bootstrap
-
If you change environment variables after the above step, run these commands to update the code generated environment variables.
melos run env melos run generate:pkg # choose "env" when prompted
-
Then, you can run the app normally with
flutter run
or build the app executables with the following commands.-
iOS IPA
flutter build ios --release --no-codesign --dart-define FLUTTER_APP_FLAVOR=local --no-tree-shake-icons cd build/ios/iphoneos && rm -rf Payload && mkdir Payload && cd Payload && ln -s ../Runner.app && cd .. && zip -r subete-release.ipa Payload && cd ../../..
-
Android APK
flutter build apk --release --dart-define FLUTTER_APP_FLAVOR=local --no-tree-shake-icons cd build/app/outputs/flutter-apk && mv app-release.apk subete-release.apk
-
Windows MSIX
flutter build windows --dart-define FLUTTER_APP_FLAVOR=local dart run msix:create --build-windows false cd build/windows/x64/runner/Release && mv subete.msix subete-release.msix
-
MacOS DMG
git config --global core.longpaths true brew install create-dmg flutter build macos --release --dart-define FLUTTER_APP_FLAVOR=local --no-tree-shake-icons create-dmg --volname subete-release-macos --window-pos 200 120 --window-size 800 450 --icon-size 100 --app-drop-link 600 185 subete-release-macos.dmg build/macos/Build/Products/Release/subete.app
-
Linux AppImage
sudo apt-get update sudo apt-get install webkit2gtk-4.1 clang cmake ninja-build pkg-config libgtk-3-dev mpv libmpv-dev dpkg-dev sudo apt install -y libfuse2 flutter build linux --release --dart-define FLUTTER_APP_FLAVOR=local curl -JOL <https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage> chmod a+x appimagetool-x86_64.AppImage mv appimagetool-x86_64.AppImage appimagetool mv build/linux/x64/release/bundle/{subete,AppRun} cp linux/appimage/*build/linux/x64/release/bundle/ ./appimagetool build/linux/x64/release/bundle/ mv*.AppImage build/subete-release.AppImage
-
Flavors are used to provide different environment variables based on the current flavor. By default,
the app uses the "local" flavor. Run/build the app with --dart-define FLUTTER_APP_FLAVOR=<flavorname>
to change the flavor. The following flavors are supported:
local
- Local development. The text banner changes to "Debug" when in debug mode, "Local" in profile mode, and hidden in release mode.dev
- Development build not intended for release.beta
- Beta build intended for release to testers.staging
- Staging build intended for device integration testing.prod
- Production build intended for release to stores.
This project uses the Riverpod App Architecture in a feature-first manner where each feature is a separate package in the lib/src/features/ folder. Each feature has its own layers, which separate the business logic from the UI.
The repository pattern consists of Repositories, DTOs, and Data Sources. Their jobs are the following:
- isolate domain models (or entities) from the implementation details of the data sources in the data layer.
- convert data transfer objects to validated entities that are understood by the domain layer
- (optionally) perform operations such as data caching.
Repository pattern use cases:
- talking to REST APIs
- talking to local or remote databases (e.g. Sembast, Hive, Firestore, etc.)
- talking to device-specific APIs (e.g. permissions, camera, location, etc.)
Domain Models, which consist of entity and value objects. It should solve domain-related problems.
The domain models can contain logic for mutating them in an immutable manner, but they should not contain any serialization.
- Note: it is a simple data classes that doesn't have access to repositories, services, or other objects that belong outside the domain layer.
- holds business logic
- manage the widget state
- interact with repositories in the data layer
Implements application-specific logic by accessing the relevant repositories as needed. The service classes are not concerned about:
- managing and updating the widget state (that's the job of the controller)
- data parsing and serialization (that's the job of the repositories)
This project uses Melos to manage the monorepo.
flutter pub get
# Install melos globally
dart pub global activate melos
# Setup local dependency overrides for packages in the monorepo
melos bootstrap
# Or if dart executables are not on your path
dart pub global run melos bootstrap
Pub:
melos run pub
- Runpub get
in all packages.melos run dart:pkg
- Rundart pub get
in the selected dart package.melos run flutter:pkg
- Runflutter pub get
in the selected flutter package.melos run upgrade
- Runpub upgrade
in all packages.melos run upgrade:pkg
- Runpub upgrade
in the selected package.
Code Generation:
dart run build_runner watch -d
- Watch and generate code for the app, does not work with subpackagesmelos run generate
- Runbuild_runner build
in all packages that depend onbuild_runner
.melos run generate:pkg
- Runbuild_runner build
for a specific package (exceptenvied
packages).melos run watch:pkg
- Runbuild_runner watch
for a specific package (exceptenvied
packages). It will not work if you choose "all" in the package selection prompt.melos run assets
- Runassets_gen build
in all packages that depend onassets_gen
.melos run assets:pkg
- Runassets_gen build
for a specific package.melos run env
- Runbuild_runner
in all packages that depends onenvied
.melos run env:pkg
- Runbuild_runner
in a specific package that depends onenvied
.melos run loc
- Runflutter gen-l10n
in the localization package to generate the localized strings from the arb files.
Tests:
melos run lint
- Run dart analyzer and custom lints in all packages.melos run analyze
- Rundart analyze
in all packages.melos run custom_lint
- Rundart run custom_lint
in all packages.melos run test
- Run all Flutter tests.melos run format
- Rundart format
in all packages.melos run fix
- Rundart fix --apply
in all packages.melos run test
- Run all tests in the project.melos run flutter_test
- Run all Flutter tests in the project.melos run dart_test
- Run all Dart tests in the project.melos run flutter_test:pkg
- Run Flutter tests for a specific package.melos run dart_test:pkg
- Run Dart tests for a specific (Dart only) package.
Environment variables are setup using ENVied in the env package. Environment variables need to be defined for debug, profile, and release modes.
- Copy the
*.env.example
files and remove the.example
extension from them. - Add the values for the environment variables in the respective
.env*
file.- Each key must be added to each
.env*
file, unless a non null default value is added to the@EnviedField
annotation. - It is recommended to use an empty string for the default and use
Env
's getter to access the value.
- Each key must be added to each
- Update src/env/app_env_fields.dart
with the new environment variables for
AppEnvFieldsGenerated
andAppEnvFieldsNullable
. - Add the new environment variables to the implementing
*Env
classes in the src/env directory.- It must be done for all even if only one
.env
file is planned to be used
- It must be done for all even if only one
- Optionally, add a
@EnviedField
defaultValue
or enableoptional
on the annotation for keys which are not required in all modes.
- Fork it https://github.com/getBoolean/subete_app/fork
- Create your feature branch (git checkout -b feature/fooBar)
- Commit your changes (git commit -am 'Add some fooBar')
- Push to the branch (git push origin feature/fooBar)
- Create a new Pull Request