Covid19Tracker
Covid19 Tracker is a sample Android application focused on displaying statistics using graphs and adding a lot of tests. From a technical point of view, it has an Offline-First approach and uses the Single Source of Truth principle. Also, it has been built making use of a huge database and Flow streams with the aim of achieving the best performance.
Install / Use
/learn @jaimegc/Covid19TrackerREADME
Introduction
Covid19 Tracker is a sample Android application focused on displaying statistics using graphs and adding tests, tests and more tests (<b>> 1.000</b>). From a technical point of view, it has an <b>Offline-First</b> approach and uses the <b>Single Source of Truth (SSOT)</b> principle. Also, it has been built making use of a huge database and <b>Flow</b> streams with the aim of achieving the best performance. However, it is important to point out that certain technical decisions have been made only for me to have an opportunity to practice new Android concepts.
You can download the app here.
Technical summary
- Offline-First: The offline-first apps, while still requiring a connection to the servers, don't need a constant internet connection. The data from servers is downloaded to the user's device and can still be accessed offline.
- Single Source of Truth (SSOT): It is the practice of structuring information models and associated schemata such that every data element is stored exactly once. You can have an offline app and be sure your data always use one source and that is your database.
- Model-View-ViewModel (MVVM): It is a software architectural pattern that facilitates the separation of the development of the graphical user interface (without using DataBinding). Also, there are Screen States to handle the different states in the UI.
- Android Architecture Components: Collection of libraries that help you design robust, testable, and maintainable apps.
- LiveData: Data objects that notify views when the underlying database changes.
- ViewModel: Stores UI-related data that isn't destroyed on UI changes.
- ViewBinding: Generates a binding class for each XML layout file present in that module and allows you to more easily write code that interacts with views.
- Room: The library provides an abstraction layer over SQLite to allow for more robust database access while harnessing the full power of SQLite.
- DatabaseView: This annotation allows you to encapsulate a query into a class. Room refers to these query-backed classes as views, and they behave the same as simple data objects when used in a DAO.
- WorkManager: The WorkManager API makes it easy to schedule deferrable, asynchronous tasks that are expected to run even if the app exits or device restarts.
- Navigation: This component helps you implement navigation.
- Custom classes:
- QueueLiveData: This custom LiveData class will deliver values even when they are posted very quickly one after another. It solves the issue of losing values when several new ones are posted very quickly.
- KeepStateNavigator: This class is to keep state in fragment navigator.
- Flow: A cold asynchronous data stream that sequentially emits values and completes normally or with an exception.
- zip: Zips values from the current flow (this) with other flow using provided transform function applied to each pair of values. The resulting flow completes as soon as one of the flows completes and cancel is called on the remaining flow.
- combine: Returns a Flow whose values are generated with transform function by combining the most recently emitted values by each flow.
- flatMapMerge: Transforms elements emitted by the original flow by applying transform, that returns another flow, and then merging and flattening these flows. This operator calls transform sequentially and then merges the resulting flows with a concurrency limit on the number of concurrently collected flows.
- StateFlow: A SharedFlow that represents a read-only state with a single updatable data value that emits updates to the value to its collectors. A state flow is a hot flow because its active instance exists independently of the presence of collectors.
- Testing: Unit, instrumentation and UI tests have been implemented. There are more than <b>1.000 tests</b> using different frameworks, libraries, patterns, techniques, etc.
- Mockito-Kotlin: A small library that provides helper functions to work with Mockito in Kotlin.
- Mockk: Provides DSL to mock behavior. Built from zero to fit Kotlin language. Supports named parameters, object mocks, coroutines and extension function mocking.
- Espresso: Writing concise, beautiful, and reliable Android UI tests.
- Screen Robot Pattern: This pattern fits with Espresso and allows to create clear and understandable tests.
- Kakao: Nice and simple DSL for Espresso in Kotlin.
- Barista: Barista makes developing UI test faster, easier and more predictable. Built on top of Espresso, it provides a simple and discoverable API, removing most of the boilerplate and verbosity of common Espresso tasks.
- Robolectric: Robolectric lets you run your tests on your workstation, or on your continuous integration environment in a regular JVM, without an emulator. Running tests on an Android emulator or device is slow!
- Kotest: Kotest is a flexible and comprehensive testing tool for Kotlin with <b>multiplatform support</b>.
- Turbine: Turbine is a small testing library for kotlinx.coroutines flow.
- Flow-Test-Observer: Library inspired by TestSubscriber from RxJava. Works with both cold/finite and hot/infinite flow.
- MockWebServer: A scriptable web server for testing HTTP clients.
- Google Truth: Truth makes your test assertions and failure messages more readable.
- Arrow: It is a library for Typed Functional Programming in Kotlin.
- Either: Represents the presence of either a Left value or a Right value. By convention, most functional programming libraries choose Left as the exceptional case and Right as the success value.
- IO: It is used to represent operations that can be executed lazily, and are capable of failing, generally with exceptions. This means that code wrapped inside IO will not throw exceptions until it is run, and those exceptions can be captured inside IO for the user to check. In this project, it has only been used in the UpdateDatabaseWorker worker to build concurrent API calls.
- Koin: Dependency Injection Framework (Kotlin)
- Moshi & Moshi Converter: A modern JSON library for Kotlin and Java. The converter uses Moshi for serialization to and from JSON.
- Detekt: A static code analysis tool for the Kotlin programming language. It operates on the abstract syntax tree provided by the Kotlin compiler.
- Kotlin Gradle DSL: Gradle's Kotlin DSL provides an alternative syntax to the traditional Groovy DSL with an enhanced editing experience in supported IDEs, with superior content assist, refactoring, documentation, and more.
- Remal check dependency update: Plugin that provides task for discovering dependency updates.
- GitHub Actions: Automate, customize, and execute your software development workflows right in your repository. Discover, create, and share actions to perform any job, including CI/CD, and combine actions in a completely customized workflow.
Screens
Country
<b>List</b>
<p align="left"> <img src="./art/country_list1.jpg" width="275"> <img src="./art/country_list2.jpg" width="275"> <img src="./art/countryRelated Skills
gh-issues
349.0kFetch GitHub issues, spawn sub-agents to implement fixes and open PRs, then monitor and address PR review comments. Usage: /gh-issues [owner/repo] [--label bug] [--limit 5] [--milestone v1.0] [--assignee @me] [--fork user/repo] [--watch] [--interval 5] [--reviews-only] [--cron] [--dry-run] [--model glm-5] [--notify-channel -1002381931352]
node-connect
349.0kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
109.4kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
Writing Hookify Rules
109.4kThis skill should be used when the user asks to "create a hookify rule", "write a hook rule", "configure hookify", "add a hookify rule", or needs guidance on hookify rule syntax and patterns.
