This project is under active development and refactoring. And this is a sandbox for me as well. This is why some parts of code may look as overengineered, bad, strange, etc.
"Wtf is this app about?" - you'll ask.
Imagine your local groceries where sellers at the cash register scan your products and eventually ask you to pay.
Well, this app actually does this. You can choose products, you can sell them, you can scan a product by a barcode.
There is also such a feature as Waybill, this is needed for sellers when some new products are shipped to this grocery and a seller has to add them to the database of products and to their grocery.
I do this because I had an experience with an app of such functionality.
Hilt - A dependency injection library for Android that reduces the boilerplate of doing manual dependency injection in your project.
Pagination - helps you load and display pages of data from a larger dataset from local storage or over network.
ViewModel - is designed to store and manage UI-related data in a lifecycle conscious way.
WorkManager - is an API that makes it easy to schedule reliable, asynchronous tasks that are expected to run even if the app exits or the device restarts.
Room - provides an abstraction layer over SQLite to allow fluent database access while harnessing the full power of SQLite
StateFlow, SharedFlow - StateFlow and SharedFlow are Flow APIs that enable flows to optimally emit state updates and emit values to multiple consumers.
Chucker - A simple in-app HTTP inspector for Android OkHttp clients.
Coil - An image loading library for Android backed by Kotlin Coroutines.
Android Debug Database - A powerful library for debugging databases and shared preferences in Android applications
Cicerone - is a lightweight library that makes the navigation in an Android app easy.
TODOs
Remove excessive emit(Try.Loading) from repos. Check flow use cases
Remove base useCases, otherwise it is problematic to test
Roadmap
Move all UI to compose, (only scanner is left without any changes)
rememberLazyListState() in some compose functions where we have LazyList() and Scaffold's bottomBar. It is done so that list's bottom has been constrained to the top of Scaffold's bottomBar.