- Dart 74.4%
- C++ 9.8%
- CMake 7.8%
- Shell 3.3%
- Kotlin 2.8%
- Other 1.9%
- Bump to 3.0.1+4 - Point version.json at nyra.apk for v3.0.1 - Document the shared_preferences_android 2.5.2+ requirement |
||
|---|---|---|
| .agents/skills | ||
| android | ||
| assets/fonts | ||
| docs/releases | ||
| ios | ||
| lib | ||
| linux | ||
| macos | ||
| test | ||
| tool | ||
| web | ||
| windows | ||
| .gitignore | ||
| .metadata | ||
| analysis_options.yaml | ||
| DEVELOPER_GUIDE.md | ||
| devtools_options.yaml | ||
| pubspec.lock | ||
| pubspec.yaml | ||
| README.md | ||
| skills-lock.json | ||
| version.json | ||
Nyra
Nyra is a personal Flutter shopping list app by Keyworks Technology for keeping track of products, quantities, prices, tax, and totals.
The app is designed for personal sideloaded Android use and includes a lightweight in-app update check that can download a newer APK and open Android's installer.
Features
- Create and switch between multiple shopping lists
- Add products with:
- Product name
- Quantity selector
- Price
- Edit existing products
- Mark products as purchased
- Swipe products to delete them with undo support
- Search and sort products
- Clear the current list with confirmation
- Calculate subtotal, purchased subtotal, tax, and final total automatically
- Enter IVU/tax percentage
- Set an optional budget and see remaining/over-budget status
- Save lists, products, tax, budget, and theme preference locally
- Responsive layout for phone, tablet, and desktop-sized windows
- Settings/About screen with manual update check
- Light, dark, and system theme modes (shared Slate + Sage palette)
- Android sideload update flow:
- Checks
version.jsonon startup - Prompts when a newer version is available
- Downloads the APK directly
- Verifies the APK's detached
.sigsignature before installing - Opens Android's package installer
- Checks
- One-time “App Updated” message after a successful version upgrade
- Tap the version in Settings → About to view the latest release notes
Tech Stack
- Flutter / Dart
- Provider for app state
- Shared Slate + Sage design system (
lib/ui/theme/) with a bundled Inter font flutter_slidablefor swipe-to-delete actionshttpfor update/version checkspackage_info_plusfor reading the installed app versionpath_providerfor temporarily storing downloaded APKsshared_preferencesfor local app persistence and theme settings- Android platform channel for launching the APK installer
Getting Started
Prerequisites
Install Flutter and confirm your environment is ready:
flutter doctor
Install dependencies
flutter pub get
Run the app
flutter run
Build an Android APK
# Release builds are a single arm64-v8a APK (~20 MB); the universal APK ships
# all three ABIs (~57 MB). tool/release.sh builds arm64-only by default.
flutter build apk --release --target-platform android-arm64
The APK is generated at:
build/app/outputs/flutter-apk/app-release.apk
Update System
This app is not distributed through Google Play. Instead, it uses a custom version.json file hosted in this repository on the self-hosted Forgejo instance:
https://forgejo.sladertech.cloud/admslader/nyra/raw/branch/main/version.json
Example version.json:
{
"version": "1.1.4",
"download_url": "https://forgejo.sladertech.cloud/admslader/nyra/releases/download/v1.1.4/nyra.apk",
"release_notes": "Describe what changed"
}
When the app opens, it compares the installed version from pubspec.yaml with the remote version.json. If the remote version is newer, it shows an update dialog.
On Android, tapping Update Now downloads the APK into the app cache, verifies its detached .sig signature against the key embedded in the app, and opens Android's installer. Android still requires the user to confirm installation manually. An update whose signature is missing or invalid is refused.
The Settings screen also includes a Check for updates action for manually checking the hosted version.json.
After a user installs an update and opens the app again, the app shows a one-time message confirming the installed version, for example:
Nyra has been updated to version 1.0.3.
Android install permission
Because this is a sideloaded app, Android may ask the user to allow this app to install unknown apps:
Settings → Install unknown apps → Nyra → Allow from this source
The app will open that settings screen automatically if permission is missing.
Release Workflow
Releases are driven from Orbita (the sibling orbita repo),
which builds, signs, and publishes every app. The developer/agent only does the
git work — never build or publish by hand.
-
Bump the version in
pubspec.yamland updateversion.jsonto match:pubspec.yaml:version: X.Y.Zversion.json:version: sameX.Y.Zdownload_url:https://forgejo.sladertech.cloud/admslader/nyra/releases/download/vX.Y.Z/nyra.apkrelease_notes: a short single-paragraph summary (shown in the in-app patch-notes screen)
-
Draft
docs/releases/vX.Y.Z.md— a title line, a one-line intro, then emoji-prefixed sections of one-line bullets (see the Developer Guide §12 for the style). Orbita uses this file as the Forgejo release body. -
Commit as
Release X.Y.Z: <short title>, tagvX.Y.Z, and pushmainand the tag. -
Publish from Orbita — it builds the release APK, signs it, creates the Forgejo release for
vX.Y.Z, and uploads the APK plus its signature:cd ../orbita dart run tool/release.dart status # local vs. published version dart run tool/release.dart publish nyraFORGEJO_TOKENis required. Each app keeps its own signing key; Command Center never touches it.nyraexposestool/release.sh(build/sign/publish/all) and keeps its signing key in the gitignoredtool/keys/release_private.json.
Nothing is live until Orbita publishes. You may move the tag while the release is unpublished; once published, its tag is frozen — cut a new version instead.
Users with an older installed version will be prompted to update the next time they open the app.
Important Notes
- Silent self-updates are not allowed for normal Android apps. The app can download the APK, but Android requires the user to approve installation.
- Future APKs must use the same Android package name:
cloud.keyworks.nyra. - The package name changed from
cloud.sladertech.shopping_listduring the Nyra rename, so the first release under the new name must be installed fresh (export a backup, uninstall, install, import the backup). Later releases update in place normally. - Releases must be signed with the app's own release keystore (see the Developer Guide §12) — never the shared debug key.
- Changing the package name or the signing key makes Android treat the build as a different app; existing installs must be uninstalled and reinstalled once.
- The version in
version.jsonmust be higher than the installed app version for the update prompt to appear.
Repository
Forgejo: admslader/nyra