Repository: PatilShreyas/Covid19-Notifier-IN
Branch: master
Commit: 3935d87a84af
Files: 71
Total size: 150.7 KB
Directory structure:
gitextract_cjuovg5p/
├── .github/
│ ├── CODEOWNERS
│ ├── FUNDING.yml
│ ├── dependabot.yml
│ └── workflows/
│ └── Build.yml
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── app/
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src/
│ ├── androidTest/
│ │ └── java/
│ │ └── dev/
│ │ └── shreyaspatil/
│ │ └── covid19notify/
│ │ └── ExampleInstrumentedTest.kt
│ ├── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── dev/
│ │ │ └── shreyaspatil/
│ │ │ └── covid19notify/
│ │ │ ├── CovidNotifyApp.kt
│ │ │ ├── api/
│ │ │ │ └── Covid19IndiaApiService.kt
│ │ │ ├── di/
│ │ │ │ ├── NetworkModule.kt
│ │ │ │ └── ViewModelModule.kt
│ │ │ ├── model/
│ │ │ │ ├── Details.kt
│ │ │ │ ├── StateDetails.kt
│ │ │ │ └── StateResponse.kt
│ │ │ ├── repository/
│ │ │ │ ├── CovidIndiaRepository.kt
│ │ │ │ └── NetworkBoundRepository.kt
│ │ │ ├── ui/
│ │ │ │ ├── adapter/
│ │ │ │ │ └── TotalAdapter.kt
│ │ │ │ ├── details/
│ │ │ │ │ ├── StateDetailsActivity.kt
│ │ │ │ │ ├── StateDetailsViewModel.kt
│ │ │ │ │ └── adapter/
│ │ │ │ │ └── DistrictsAdapter.kt
│ │ │ │ └── main/
│ │ │ │ ├── MainActivity.kt
│ │ │ │ ├── MainViewModel.kt
│ │ │ │ └── adapter/
│ │ │ │ └── ItemAdapter.kt
│ │ │ ├── utils/
│ │ │ │ ├── NetworkUtils.kt
│ │ │ │ ├── State.kt
│ │ │ │ ├── ThemeUtils.kt
│ │ │ │ └── TimeUtils.kt
│ │ │ └── worker/
│ │ │ └── NotificationWorker.kt
│ │ └── res/
│ │ ├── drawable/
│ │ │ ├── ic_death.xml
│ │ │ ├── ic_heart.xml
│ │ │ ├── ic_info.xml
│ │ │ ├── ic_launcher_foreground.xml
│ │ │ ├── ic_lightbulb.xml
│ │ │ ├── ic_patient.xml
│ │ │ ├── ic_settings.xml
│ │ │ ├── ic_trending_up.xml
│ │ │ └── ic_virus.xml
│ │ ├── drawable-anydpi-v24/
│ │ │ └── ic_stat_notification_icon.xml
│ │ ├── layout/
│ │ │ ├── activity_main.xml
│ │ │ ├── activity_state_details.xml
│ │ │ ├── appbar_layout.xml
│ │ │ ├── item_district.xml
│ │ │ ├── item_state.xml
│ │ │ └── item_total.xml
│ │ ├── menu/
│ │ │ └── toolbar_menu.xml
│ │ ├── mipmap-anydpi-v26/
│ │ │ ├── ic_launcher.xml
│ │ │ └── ic_launcher_round.xml
│ │ ├── values/
│ │ │ ├── bool.xml
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── ic_launcher_background.xml
│ │ │ ├── strings.xml
│ │ │ ├── styles.xml
│ │ │ └── theme.xml
│ │ └── values-night/
│ │ ├── bool.xml
│ │ └── colors.xml
│ └── test/
│ └── java/
│ └── dev/
│ └── shreyaspatil/
│ └── covid19notify/
│ └── ExampleUnitTest.kt
├── build.gradle
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/CODEOWNERS
================================================
* @PatilShreyas
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
github: #
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: PatilShreyas
otechie: # Replace with a single Otechie username
custom: ['https://www.paypal.me/PatilShreyas99/']
================================================
FILE: .github/dependabot.yml
================================================
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "gradle"
directory: "/"
schedule:
interval: "daily"
================================================
FILE: .github/workflows/Build.yml
================================================
name: Build
on: [push, pull_request]
jobs:
test:
name: Run Unit Tests
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v1
- name: set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Grant Permission to Execute
run: chmod +x gradlew
- name: Unit tests
run: bash ./gradlew test --stacktrace
apk:
name: Generate APK
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v1
- name: set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Grant Permission to Execute
run: chmod +x gradlew
- name: Build debug APK
run: bash ./gradlew assembleDebug --stacktrace
- name: Upload APK
uses: actions/upload-artifact@v1
with:
name: app
path: app/build/outputs/apk/debug/app-debug.apk
================================================
FILE: .gitignore
================================================
#built application files
*.apk
*.ap_
# files for the dex VM
*.dex
# Java class files
*.class
# generated files
bin/
gen/
# Local configuration file (sdk path, etc)
local.properties
# Windows thumbnail db
Thumbs.db
# OSX files
.DS_Store
# Android Studio
*.iml
.idea
#.idea/workspace.xml - remove # and delete .idea if it better suit your needs.
.gradle
build/
.navigation
captures/
output.json
#NDK
obj/
.externalNativeBuild
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at shreyaspatilg@gmail.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq
================================================
FILE: CONTRIBUTING.md
================================================
## Feeling Awesome! Thanks for thinking about this.
You can contribute us by filing issues, bugs and PRs.
### Contributing:
- Open issue regarding proposed change.
- Repo owner will contact you there.
- If your proposed change is approved, Fork this repo and do changes.
- Open PR against latest `dev` branch. Add nice description in PR.
- You're done!
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2020 Shreyas Patil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
<p align="center">
<img src="app/src/main/ic_launcher-playstore.png" height="200"/>
</p>
# COVID19 Notifier - India 🇮🇳

[](LICENSE)





**Covid19 Notifier India** is a sample Android application 📱 built to demonstrate use of *Modern Android development* tools. Dedicated to all Android Developers with ❤️.
***You can Install and test latest Covid19 Notifier app from below 👇***
[](https://github.com/patilshreyas/covid19-notifier-in/releases/latest/download/app-debug.apk)
<table style="width:100%">
<tr>
<th>Main Screen (Total Report)</th>
<th>Main Screen (State Report List)</th>
<th>Main Screen (Dark Mode 🌗)</th>
<th>Notification in the System Tray</th>
</tr>
<tr>
<td><img src="art/HomeScreen.jpg"/></td>
<td><img src="art/HomeScreen-States.jpg"/></td>
<td><img src="art/HomeScreen-Dark.jpg"/></td>
<td><img src="art/notification.jpg"/></td>
</tr>
</table>
## About
- It simply loads **Total COVID19 cases in India** from [API](https://github.com/covid19india/api).
- It notifies total cases of COVID19 in India after every 1 hours.
- It shows the total cases of the District from every State.
- Dark mode too 🌗.
- It is offline capable (Using Cache) 😃.
*It uses `PeriodicWorkManager` which is scheduled at the first run of an app. After that, `Worker` will execute after every one hour of interval and will show notification on Android's system tray.*
## Built With 🛠
- [Kotlin](https://kotlinlang.org/) - First class and official programming language for Android development.
- [Coroutines](https://kotlinlang.org/docs/reference/coroutines-overview.html) - For asynchronous and more..
- [Flow](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/) - A cold asynchronous data stream that sequentially emits values and completes normally or with an exception.
- [Android Architecture Components](https://developer.android.com/topic/libraries/architecture) - Collection of libraries that help you design robust, testable, and maintainable apps.
- [LiveData](https://developer.android.com/topic/libraries/architecture/livedata) - Data objects that notify views when the underlying database changes.
- [ViewModel](https://developer.android.com/topic/libraries/architecture/viewmodel) - Stores UI-related data that isn't destroyed on UI changes.
- [ViewBinding](https://developer.android.com/topic/libraries/view-binding) - 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.
- [Koin](https://start.insert-koin.io/) - Dependency Injection Framework (Kotlin)
- [Retrofit](https://square.github.io/retrofit/) - A type-safe HTTP client for Android and Java.
- [Moshi](https://github.com/square/moshi) - A modern JSON library for Kotlin and Java.
- [Moshi Converter](https://github.com/square/retrofit/tree/master/retrofit-converters/moshi) - A Converter which uses Moshi for serialization to and from JSON.
- [WorkManager](https://developer.android.com/topic/libraries/architecture/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.
- [Material Components for Android](https://github.com/material-components/material-components-android) - Modular and customizable Material Design UI components for Android
# Package Structure
dev.shreyaspatil.covid19notify # Root Package
.
├── api # For API Service.
├── model # Model classes
├── repository # Repository to handle data from network using API.
├── di # Dependency Injection
|
├── ui # Activity/View layer
│ └── main # Main Screen Activity, ViewModel and RecyclerView Adapters.
|
├── utils # Utility Classes / Kotlin extensions
└── worker # Worker class.
## Contribute
If you want to contribute to this project, you're always welcome!
See [Contributing Guidelines](CONTRIBUTING.md).
## Credits
Thanks to [COVID19India.org](https://github.com/covid19india/api) for open-source API.
## Contact
If you need any help, you can connect with me.
Visit:- [shreyaspatil.dev](https://shreyaspatil.dev)
## Contributed By:
- [Shreyas Patil](https://shreyaspatil.dev) (Maintainer)
- [Rohan Singh](https://twitter.com/zaraki596) (Contributer)
## License
```
MIT License
Copyright (c) 2020 Shreyas Patil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
================================================
FILE: app/.gitignore
================================================
/build
================================================
FILE: app/build.gradle
================================================
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 30
buildToolsVersion "30.0.0"
defaultConfig {
applicationId "dev.shreyaspatil.covid19notify"
minSdkVersion 21
targetSdkVersion 30
versionCode 4
versionName "3.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
viewBinding {
enabled = true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
kotlinOptions {
jvmTarget = "1.8"
}
}
dependencies {
def coroutines_version = '1.3.8'
def appcompat_version = '1.2.0'
def preference_version = '1.1.1'
def core_ktx_version = '1.3.2'
def constraintlayout_version = '2.0.4'
def swiperefreshlayout_version = '1.1.0'
def recyclerview_version = "1.2.0-alpha03"
def lifecycle_version = '2.2.0'
def material_design_version = '1.2.1'
def retrofit_version = '2.9.0'
def moshi_version = '1.11.0'
def workmanager_version = '2.4.0'
def koin_version = '2.1.6'
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
// Coroutines
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
// Android
implementation "androidx.appcompat:appcompat:$appcompat_version"
implementation "androidx.core:core-ktx:$core_ktx_version"
implementation "androidx.constraintlayout:constraintlayout:$constraintlayout_version"
implementation "androidx.swiperefreshlayout:swiperefreshlayout:$swiperefreshlayout_version"
implementation "androidx.recyclerview:recyclerview:$recyclerview_version"
implementation "androidx.preference:preference:$preference_version"
// Architecture Components
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
// Material Design
implementation "com.google.android.material:material:$material_design_version"
// Retrofit
implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
// Moshi
implementation "com.squareup.moshi:moshi-kotlin:$moshi_version"
implementation "com.squareup.retrofit2:converter-moshi:$retrofit_version"
kapt "com.squareup.moshi:moshi-kotlin-codegen:$moshi_version"
// WorkManager
implementation "androidx.work:work-runtime-ktx:$workmanager_version"
// Koin DI
implementation "org.koin:koin-core:$koin_version"
implementation "org.koin:koin-android:$koin_version"
implementation "org.koin:koin-android-scope:$koin_version"
implementation "org.koin:koin-android-viewmodel:$koin_version"
// Testing
testImplementation 'junit:junit:4.13'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
================================================
FILE: app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
================================================
FILE: app/src/androidTest/java/dev/shreyaspatil/covid19notify/ExampleInstrumentedTest.kt
================================================
package dev.shreyaspatil.covid19notify
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("dev.shreyaspatil.covid19notify", appContext.packageName)
}
}
================================================
FILE: app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="dev.shreyaspatil.covid19notify">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".CovidNotifyApp"
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".ui.details.StateDetailsActivity"
android:parentActivityName=".ui.main.MainActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar"
tools:ignore="LockedOrientationActivity" />
<activity
android:name=".ui.main.MainActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar"
tools:ignore="LockedOrientationActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
================================================
FILE: app/src/main/java/dev/shreyaspatil/covid19notify/CovidNotifyApp.kt
================================================
package dev.shreyaspatil.covid19notify
import android.app.Application
import dev.shreyaspatil.covid19notify.di.networkModule
import dev.shreyaspatil.covid19notify.di.viewModelModule
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.InternalCoroutinesApi
import org.koin.android.ext.koin.androidContext
import org.koin.core.context.startKoin
@FlowPreview
@ExperimentalCoroutinesApi
@InternalCoroutinesApi
class CovidNotifyApp : Application() {
override fun onCreate() {
super.onCreate()
initKoin()
}
private fun initKoin() {
startKoin {
androidContext(applicationContext)
modules(networkModule, viewModelModule)
}
}
}
================================================
FILE: app/src/main/java/dev/shreyaspatil/covid19notify/api/Covid19IndiaApiService.kt
================================================
package dev.shreyaspatil.covid19notify.api
import dev.shreyaspatil.covid19notify.model.StateDetailsResponse
import dev.shreyaspatil.covid19notify.model.StateResponse
import retrofit2.Response
import retrofit2.http.GET
interface Covid19IndiaApiService {
@GET("data.json")
suspend fun getData(): Response<StateResponse>
@GET("v2/state_district_wise.json")
suspend fun getStateDistrictData(): Response<List<StateDetailsResponse>>
companion object {
const val BASE_URL = "https://api.covid19india.org/"
}
}
================================================
FILE: app/src/main/java/dev/shreyaspatil/covid19notify/di/NetworkModule.kt
================================================
package dev.shreyaspatil.covid19notify.di
import android.content.Context
import com.squareup.moshi.Moshi
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import dev.shreyaspatil.covid19notify.api.Covid19IndiaApiService
import dev.shreyaspatil.covid19notify.repository.CovidIndiaRepository
import dev.shreyaspatil.covid19notify.utils.isNetworkAvailable
import kotlinx.coroutines.ExperimentalCoroutinesApi
import okhttp3.Cache
import okhttp3.OkHttpClient
import org.koin.android.ext.koin.androidContext
import org.koin.dsl.module
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
@ExperimentalCoroutinesApi
val networkModule = module {
single {
Retrofit.Builder()
.baseUrl(Covid19IndiaApiService.BASE_URL)
.addConverterFactory(
MoshiConverterFactory.create(
Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
)
)
.client(getOkHttpClient(androidContext()))
.build()
.create(Covid19IndiaApiService::class.java)
}
single {
CovidIndiaRepository(get())
}
}
fun getOkHttpClient(context: Context): OkHttpClient {
val cacheSize = (5 * 1024 * 1024).toLong()
val myCache = Cache(context.cacheDir, cacheSize)
return OkHttpClient.Builder()
.cache(myCache)
.addInterceptor { chain ->
var request = chain.request()
request = if (isNetworkAvailable(context)!!)
request.newBuilder().header("Cache-Control", "public, max-age=" + 5).build()
else
request.newBuilder().header(
"Cache-Control",
"public, only-if-cached, max-stale=" + 60 * 60 * 24 * 7
).build()
chain.proceed(request)
}
.build()
}
================================================
FILE: app/src/main/java/dev/shreyaspatil/covid19notify/di/ViewModelModule.kt
================================================
package dev.shreyaspatil.covid19notify.di
import dev.shreyaspatil.covid19notify.ui.details.StateDetailsViewModel
import dev.shreyaspatil.covid19notify.ui.main.MainViewModel
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.InternalCoroutinesApi
import org.koin.android.viewmodel.dsl.viewModel
import org.koin.dsl.module
@FlowPreview
@ExperimentalCoroutinesApi
@InternalCoroutinesApi
val viewModelModule = module {
viewModel { MainViewModel(get()) }
viewModel { StateDetailsViewModel(get()) }
}
================================================
FILE: app/src/main/java/dev/shreyaspatil/covid19notify/model/Details.kt
================================================
package dev.shreyaspatil.covid19notify.model
import android.os.Parcelable
import com.squareup.moshi.Json
import kotlinx.android.parcel.Parcelize
@Parcelize
data class Details(
val active: String = "0",
val confirmed: String = "0",
val recovered: String = "0",
val deaths: String = "0",
val state: String = "",
@Json(name = "statenotes")
val stateNotes: String = "",
@Json(name = "deltaconfirmed")
val deltaConfirmed: String = "0",
@Json(name = "deltarecovered")
val deltaRecovered: String = "0",
@Json(name = "deltadeaths")
val deltaDeaths: String = "0",
@Json(name = "lastupdatedtime")
val lastUpdatedTime: String = ""
) : Parcelable
================================================
FILE: app/src/main/java/dev/shreyaspatil/covid19notify/model/StateDetails.kt
================================================
package dev.shreyaspatil.covid19notify.model
import android.os.Parcelable
import com.squareup.moshi.JsonClass
import kotlinx.android.parcel.Parcelize
@Parcelize
@JsonClass(generateAdapter = true)
data class StateDetailsResponse(
val districtData: List<DistrictData>,
val state: String
) : Parcelable
@Parcelize
@JsonClass(generateAdapter = true)
data class DistrictData(
val confirmed: Int = 0,
val active: Int = 0,
val deceased: Int = 0,
val recovered: Int = 0,
val delta: Delta,
val notes: String = "",
val district: String = ""
) : Parcelable
@Parcelize
@JsonClass(generateAdapter = true)
data class Delta(
val confirmed: Int = 0,
val active: Int = 0,
val deceased: Int = 0,
val recovered: Int = 0
) : Parcelable
================================================
FILE: app/src/main/java/dev/shreyaspatil/covid19notify/model/StateResponse.kt
================================================
package dev.shreyaspatil.covid19notify.model
import android.os.Parcelable
import com.squareup.moshi.Json
import kotlinx.android.parcel.Parcelize
@Parcelize
data class StateResponse(
@Json(name = "statewise")
val stateWiseDetails: List<Details>
) : Parcelable
================================================
FILE: app/src/main/java/dev/shreyaspatil/covid19notify/repository/CovidIndiaRepository.kt
================================================
package dev.shreyaspatil.covid19notify.repository
import dev.shreyaspatil.covid19notify.api.Covid19IndiaApiService
import dev.shreyaspatil.covid19notify.model.StateDetailsResponse
import dev.shreyaspatil.covid19notify.model.StateResponse
import dev.shreyaspatil.covid19notify.utils.State
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import retrofit2.Response
@FlowPreview
@ExperimentalCoroutinesApi
class CovidIndiaRepository(private val apiService: Covid19IndiaApiService) {
fun getData(): Flow<State<StateResponse>> {
return object : NetworkBoundRepository<StateResponse>() {
override suspend fun fetchFromRemote(): Response<StateResponse> = apiService.getData()
}.asFlow().flowOn(Dispatchers.IO)
}
fun getStateDetailsData(stateName: String): Flow<State<StateDetailsResponse>> {
return object : NetworkBoundRepository<List<StateDetailsResponse>>() {
override suspend fun fetchFromRemote(): Response<List<StateDetailsResponse>> =
apiService.getStateDistrictData()
}.asFlow().flowOn(Dispatchers.IO).map { state ->
when (state) {
is State.Loading -> State.loading()
is State.Success -> {
val data = state.data.find { it.state == stateName }
if (data != null) {
State.success<StateDetailsResponse>(data)
} else {
State.error<StateDetailsResponse>("No data found of state '$stateName'")
}
}
is State.Error -> {
State.error<StateDetailsResponse>(state.message)
}
}
}
}
}
================================================
FILE: app/src/main/java/dev/shreyaspatil/covid19notify/repository/NetworkBoundRepository.kt
================================================
package dev.shreyaspatil.covid19notify.repository
import androidx.annotation.MainThread
import dev.shreyaspatil.covid19notify.utils.State
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.flow
import retrofit2.Response
@ExperimentalCoroutinesApi
abstract class NetworkBoundRepository<T> {
fun asFlow() = flow<State<T>> {
// Emit Loading State
emit(State.loading())
try {
// Fetch latest data from remote
val apiResponse = fetchFromRemote()
// Parse body
val remotePosts = apiResponse.body()
// Check for response validation
if (apiResponse.isSuccessful && remotePosts != null) {
emit(State.success(remotePosts))
} else {
// Something went wrong! Emit Error state.
emit(State.error(apiResponse.message()))
}
} catch (e: Exception) {
// Exception occurred! Emit error
emit(State.error("Network error! Can't get latest data."))
e.printStackTrace()
}
}
@MainThread
protected abstract suspend fun fetchFromRemote(): Response<T>
}
================================================
FILE: app/src/main/java/dev/shreyaspatil/covid19notify/ui/adapter/TotalAdapter.kt
================================================
package dev.shreyaspatil.covid19notify.ui.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import dev.shreyaspatil.covid19notify.databinding.ItemTotalBinding
import dev.shreyaspatil.covid19notify.model.Details
class TotalAdapter : ListAdapter<Details, TotalAdapter.TotalViewHolder>(DIFF_CALLBACK) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
TotalViewHolder(
ItemTotalBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
override fun onBindViewHolder(holder: TotalViewHolder, position: Int) =
holder.bind(getItem(position))
class TotalViewHolder(private val binding: ItemTotalBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(details: Details) {
binding.textConfirmed.text = details.confirmed
binding.textActive.text = details.active
binding.textRecovered.text = details.recovered
binding.textDeceased.text = details.deaths
// New Confirmed
details.deltaConfirmed.let {
if (it == "0") {
binding.groupNewConfirmed.visibility = View.GONE
} else {
binding.groupNewConfirmed.visibility = View.VISIBLE
binding.textNewConfirmed.text = details.deltaConfirmed
}
}
// New Recovered
details.deltaRecovered.let {
if (it == "0") {
binding.groupNewRecovered.visibility = View.GONE
} else {
binding.groupNewRecovered.visibility = View.VISIBLE
binding.textNewRecovered.text = details.deltaRecovered
}
}
// New Deaths
details.deltaDeaths.let {
if (it == "0") {
binding.groupNewDeaths.visibility = View.GONE
} else {
binding.groupNewDeaths.visibility = View.VISIBLE
binding.textNewDeaths.text = details.deltaDeaths
}
}
}
}
companion object {
private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Details>() {
override fun areItemsTheSame(oldItem: Details, newItem: Details): Boolean =
oldItem.state == newItem.state
override fun areContentsTheSame(oldItem: Details, newItem: Details): Boolean =
oldItem == newItem
}
}
}
================================================
FILE: app/src/main/java/dev/shreyaspatil/covid19notify/ui/details/StateDetailsActivity.kt
================================================
package dev.shreyaspatil.covid19notify.ui.details
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.MergeAdapter
import dev.shreyaspatil.covid19notify.R
import dev.shreyaspatil.covid19notify.databinding.ActivityStateDetailsBinding
import dev.shreyaspatil.covid19notify.model.Details
import dev.shreyaspatil.covid19notify.ui.adapter.TotalAdapter
import dev.shreyaspatil.covid19notify.ui.details.adapter.DistrictsAdapter
import dev.shreyaspatil.covid19notify.utils.State
import dev.shreyaspatil.covid19notify.utils.getPeriod
import dev.shreyaspatil.covid19notify.utils.toDateFormat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.InternalCoroutinesApi
import org.koin.android.viewmodel.ext.android.viewModel
@FlowPreview
@ExperimentalCoroutinesApi
@InternalCoroutinesApi
class StateDetailsActivity : AppCompatActivity() {
private lateinit var binding: ActivityStateDetailsBinding
private val mStateTotalAdapter = TotalAdapter()
private val mDistrictAdapter = DistrictsAdapter()
private val adapter = MergeAdapter(mStateTotalAdapter, mDistrictAdapter)
private val viewModel: StateDetailsViewModel by viewModel()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityStateDetailsBinding.inflate(layoutInflater)
setContentView(binding.root)
initViews()
initData()
}
private fun getStateDetails(): Details? = intent.getParcelableExtra(KEY_STATE_DETAILS)
private fun initViews() {
setSupportActionBar(binding.appBarlayout.toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
binding.recyclerState.adapter = adapter
val details: Details? = getStateDetails()
details?.let {
mStateTotalAdapter.submitList(listOf(it))
supportActionBar?.title = it.state
supportActionBar?.subtitle = getString(
R.string.text_last_updated,
getPeriod(
it.lastUpdatedTime.toDateFormat()
)
)
}
binding.swipeRefreshLayout.setOnRefreshListener {
loadData(getStateDetails())
}
}
private fun initData() {
viewModel.stateCovidLiveDataDetails.observe(this, Observer { state ->
when (state) {
is State.Loading -> {
binding.swipeRefreshLayout.isRefreshing = true
}
is State.Success -> {
val list = state.data.districtData
list.sortedByDescending { it.confirmed }.let { districtList ->
mDistrictAdapter.submitList(districtList)
}
binding.swipeRefreshLayout.isRefreshing = false
}
is State.Error -> {
binding.swipeRefreshLayout.isRefreshing = false
Toast.makeText(applicationContext, state.message, Toast.LENGTH_LONG).show()
}
}
})
if (viewModel.stateCovidLiveDataDetails.value !is State.Success) {
loadData(getStateDetails())
}
}
private fun loadData(details: Details?) {
details?.state?.let {
viewModel.getDistrictData(it)
}
}
companion object {
const val KEY_STATE_DETAILS = "key_state_details"
}
}
================================================
FILE: app/src/main/java/dev/shreyaspatil/covid19notify/ui/details/StateDetailsViewModel.kt
================================================
package dev.shreyaspatil.covid19notify.ui.details
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dev.shreyaspatil.covid19notify.model.StateDetailsResponse
import dev.shreyaspatil.covid19notify.repository.CovidIndiaRepository
import dev.shreyaspatil.covid19notify.utils.State
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.InternalCoroutinesApi
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
@FlowPreview
@ExperimentalCoroutinesApi
@InternalCoroutinesApi
class StateDetailsViewModel(private val covidIndiaRepository: CovidIndiaRepository) : ViewModel() {
private val _stateCovidLiveData = MutableLiveData<State<StateDetailsResponse>>()
val stateCovidLiveDataDetails: LiveData<State<StateDetailsResponse>> = _stateCovidLiveData
fun getDistrictData(state: String) {
viewModelScope.launch {
covidIndiaRepository.getStateDetailsData(state).collect {
_stateCovidLiveData.value = it
}
}
}
}
================================================
FILE: app/src/main/java/dev/shreyaspatil/covid19notify/ui/details/adapter/DistrictsAdapter.kt
================================================
package dev.shreyaspatil.covid19notify.ui.details.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import dev.shreyaspatil.covid19notify.databinding.ItemDistrictBinding
import dev.shreyaspatil.covid19notify.model.DistrictData
class DistrictsAdapter :
ListAdapter<DistrictData, DistrictsAdapter.TotalViewHolder>(DIFF_CALLBACK) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = TotalViewHolder(
ItemDistrictBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
override fun onBindViewHolder(holder: TotalViewHolder, position: Int) =
holder.bind(getItem(position))
class TotalViewHolder(private val binding: ItemDistrictBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(details: DistrictData) {
binding.textDistrictName.text = details.district
binding.textConfirmed.text = details.confirmed.toString()
binding.textActive.text = details.active.toString()
binding.textDeath.text = details.deceased.toString()
binding.textRecovered.text = details.recovered.toString()
// New Confirmed
details.delta.confirmed.let {
if (it == 0) {
binding.groupStateNewConfirm.visibility = View.GONE
} else {
binding.groupStateNewConfirm.visibility = View.VISIBLE
binding.textDistrictNewConfirm.text = details.delta.confirmed.toString()
}
}
// New Recovered
details.delta.recovered.let {
if (it == 0) {
binding.groupStateNewRecover.visibility = View.GONE
} else {
binding.groupStateNewRecover.visibility = View.VISIBLE
binding.textDistrictNewRecover.text = details.delta.recovered.toString()
}
}
// New Deaths
details.delta.deceased.let {
if (it == 0) {
binding.groupStateNewDeaths.visibility = View.GONE
} else {
binding.groupStateNewDeaths.visibility = View.VISIBLE
binding.textDistrictNewDeath.text = details.delta.deceased.toString()
}
}
// Handling cases with notes
details.notes.let {
if (it.isBlank()) {
binding.textNotes.visibility = View.GONE
} else {
binding.textNotes.visibility = View.VISIBLE
binding.textNotes.text = details.notes
}
}
}
}
companion object {
private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<DistrictData>() {
override fun areItemsTheSame(oldItem: DistrictData, newItem: DistrictData): Boolean =
oldItem.district == newItem.district
override fun areContentsTheSame(oldItem: DistrictData, newItem: DistrictData): Boolean =
oldItem == newItem
}
}
}
================================================
FILE: app/src/main/java/dev/shreyaspatil/covid19notify/ui/main/MainActivity.kt
================================================
package dev.shreyaspatil.covid19notify.ui.main
import android.content.Intent
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.MergeAdapter
import androidx.work.*
import com.google.android.material.snackbar.Snackbar
import dev.shreyaspatil.covid19notify.R
import dev.shreyaspatil.covid19notify.databinding.ActivityMainBinding
import dev.shreyaspatil.covid19notify.model.Details
import dev.shreyaspatil.covid19notify.ui.adapter.TotalAdapter
import dev.shreyaspatil.covid19notify.ui.details.StateDetailsActivity
import dev.shreyaspatil.covid19notify.ui.main.adapter.ItemAdapter
import dev.shreyaspatil.covid19notify.utils.*
import dev.shreyaspatil.covid19notify.worker.NotificationWorker
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.InternalCoroutinesApi
import org.koin.android.viewmodel.ext.android.viewModel
import java.util.concurrent.TimeUnit
@FlowPreview
@ExperimentalCoroutinesApi
@InternalCoroutinesApi
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private val viewModel: MainViewModel by viewModel()
private val mTotalAdapter = TotalAdapter()
private val mStateAdapter = ItemAdapter(this::navigateToStateDetailsActivity)
private val adapter = MergeAdapter(mTotalAdapter, mStateAdapter)
// Useful when back navigation is pressed.
private var backPressedTime = 0L
private val backSnackbar by lazy {
Snackbar.make(binding.root, BACK_PRESSED_MESSAGE, Snackbar.LENGTH_SHORT)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
initViews()
initData()
initWorker()
}
private fun initViews() {
setSupportActionBar(binding.appBarlayout.toolbar)
binding.recycler.adapter = adapter
binding.swipeRefreshLayout.setOnRefreshListener {
loadData()
}
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.toolbar_menu, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.menu_uimode -> {
val uiMode = if (isDarkTheme()) {
AppCompatDelegate.MODE_NIGHT_NO
} else {
AppCompatDelegate.MODE_NIGHT_YES
}
applyTheme(uiMode)
true
}
else -> super.onOptionsItemSelected(item)
}
}
private fun initData() {
viewModel.covidLiveData.observe(this, Observer { state ->
when (state) {
is State.Loading -> binding.swipeRefreshLayout.isRefreshing = true
is State.Error -> {
binding.swipeRefreshLayout.isRefreshing = false
Toast.makeText(applicationContext, state.message, Toast.LENGTH_LONG).show()
}
is State.Success -> {
binding.swipeRefreshLayout.isRefreshing = false
val list = state.data.stateWiseDetails
mTotalAdapter.submitList(list.subList(0, 1))
mStateAdapter.submitList(list.subList(1, list.size - 1))
// Set Last Updated Time
supportActionBar?.subtitle = getString(
R.string.text_last_updated,
getPeriod(
list[0].lastUpdatedTime.toDateFormat()
)
)
}
}
})
if (viewModel.covidLiveData.value !is State.Success) {
loadData()
}
}
private fun loadData() {
viewModel.getData()
}
private fun navigateToStateDetailsActivity(details: Details) {
startActivity(Intent(this, StateDetailsActivity::class.java).apply {
putExtra(StateDetailsActivity.KEY_STATE_DETAILS, details)
})
}
private fun initWorker() {
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
val notificationWorkRequest =
PeriodicWorkRequestBuilder<NotificationWorker>(1, TimeUnit.HOURS)
.setConstraints(constraints)
.build()
WorkManager.getInstance(applicationContext).enqueueUniquePeriodicWork(
JOB_TAG,
ExistingPeriodicWorkPolicy.KEEP,
notificationWorkRequest
)
}
override fun onBackPressed() {
if (backPressedTime + 2000 > System.currentTimeMillis()) {
backSnackbar.dismiss()
super.onBackPressed()
return
} else {
backSnackbar.show()
}
backPressedTime = System.currentTimeMillis()
}
companion object {
const val JOB_TAG = "notificationWorkTag"
const val BACK_PRESSED_MESSAGE = "Press back again to exit"
}
}
================================================
FILE: app/src/main/java/dev/shreyaspatil/covid19notify/ui/main/MainViewModel.kt
================================================
package dev.shreyaspatil.covid19notify.ui.main
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dev.shreyaspatil.covid19notify.model.StateResponse
import dev.shreyaspatil.covid19notify.repository.CovidIndiaRepository
import dev.shreyaspatil.covid19notify.utils.State
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.InternalCoroutinesApi
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
@FlowPreview
@ExperimentalCoroutinesApi
@InternalCoroutinesApi
class MainViewModel(private val repository: CovidIndiaRepository) : ViewModel() {
private val _covidLiveData = MutableLiveData<State<StateResponse>>()
val covidLiveData: LiveData<State<StateResponse>> = _covidLiveData
fun getData() {
viewModelScope.launch {
repository.getData().collect {
_covidLiveData.value = it
}
}
}
}
================================================
FILE: app/src/main/java/dev/shreyaspatil/covid19notify/ui/main/adapter/ItemAdapter.kt
================================================
package dev.shreyaspatil.covid19notify.ui.main.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import dev.shreyaspatil.covid19notify.R
import dev.shreyaspatil.covid19notify.databinding.ItemStateBinding
import dev.shreyaspatil.covid19notify.model.Details
import dev.shreyaspatil.covid19notify.utils.getPeriod
import dev.shreyaspatil.covid19notify.utils.toDateFormat
class ItemAdapter(val clickListener: (stateDetails: Details) -> Unit = {}) :
ListAdapter<Details, ItemAdapter.StateViewHolder>(DIFF_CALLBACK) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = StateViewHolder(
ItemStateBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
override fun onBindViewHolder(holder: StateViewHolder, position: Int) =
holder.bind(getItem(position))
inner class StateViewHolder(private val binding: ItemStateBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(details: Details) {
binding.textState.text = details.state
binding.textLastUpdatedView.text = itemView.context.getString(
R.string.text_last_updated,
getPeriod(
details.lastUpdatedTime.toDateFormat()
)
)
binding.textConfirmed.text = details.confirmed
binding.textActive.text = details.active
binding.textRecovered.text = details.recovered
binding.textDeath.text = details.deaths
// New Confirmed
details.deltaConfirmed.let {
if (it == "0") {
binding.groupStateNewConfirm.visibility = View.GONE
} else {
binding.groupStateNewConfirm.visibility = View.VISIBLE
binding.textStateNewConfirm.text = it
}
}
// New Recovered
details.deltaRecovered.let {
if (it == "0") {
binding.groupStateNewRecover.visibility = View.GONE
} else {
binding.groupStateNewRecover.visibility = View.VISIBLE
binding.textStateNewRecover.text = it
}
}
// New Deaths
details.deltaDeaths.let {
if (it == "0") {
binding.groupStateNewDeaths.visibility = View.GONE
} else {
binding.groupStateNewDeaths.visibility = View.VISIBLE
binding.textStateNewDeath.text = it
}
}
// Set Click Listener
binding.root.setOnClickListener {
if (bindingAdapterPosition == RecyclerView.NO_POSITION) {
return@setOnClickListener
}
val item = getItem(bindingAdapterPosition)
item.let {
clickListener.invoke(it)
}
}
}
}
companion object {
private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Details>() {
override fun areItemsTheSame(oldItem: Details, newItem: Details): Boolean =
oldItem.state == newItem.state
override fun areContentsTheSame(oldItem: Details, newItem: Details): Boolean =
oldItem == newItem
}
}
}
================================================
FILE: app/src/main/java/dev/shreyaspatil/covid19notify/utils/NetworkUtils.kt
================================================
package dev.shreyaspatil.covid19notify.utils
import android.content.Context
import android.net.ConnectivityManager
import android.net.NetworkInfo
fun isNetworkAvailable(context: Context): Boolean? {
var isConnected: Boolean? = false // Initial Value
val connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val activeNetwork: NetworkInfo? = connectivityManager.activeNetworkInfo
if (activeNetwork != null && activeNetwork.isConnected)
isConnected = true
return isConnected
}
================================================
FILE: app/src/main/java/dev/shreyaspatil/covid19notify/utils/State.kt
================================================
package dev.shreyaspatil.covid19notify.utils
sealed class State<T> {
class Loading<T> : State<T>()
data class Success<T>(val data: T) : State<T>()
data class Error<T>(val message: String) : State<T>()
companion object {
fun <T> loading() = Loading<T>()
fun <T> success(data: T) = Success(data)
fun <T> error(message: String) = Error<T>(message)
}
}
================================================
FILE: app/src/main/java/dev/shreyaspatil/covid19notify/utils/ThemeUtils.kt
================================================
package dev.shreyaspatil.covid19notify.utils
import android.content.res.Configuration
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import java.util.*
fun applyTheme(theme: Int) {
AppCompatDelegate.setDefaultNightMode(theme)
}
/**
* Returns if currently dark theme is active or not.
*/
fun AppCompatActivity.isDarkTheme(): Boolean {
return (resources.configuration.uiMode and
Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES)
}
/**
* Returns [Boolean] based on current time.
* Returns true if hours are between 06:00 pm - 07:00 am
*/
fun isNight(): Boolean {
val currentHour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY)
return (currentHour <= 7 || currentHour >= 18)
}
================================================
FILE: app/src/main/java/dev/shreyaspatil/covid19notify/utils/TimeUtils.kt
================================================
package dev.shreyaspatil.covid19notify.utils
import android.annotation.SuppressLint
import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.TimeUnit
/**
* Represents past time in text.
* For e.g. 1 Minutes ago, 1 hour 0 minutes ago.
*/
@SuppressLint("SimpleDateFormat")
fun getPeriod(past: Date): String {
val now = Date()
val seconds = TimeUnit.MILLISECONDS.toSeconds(now.time - past.time)
val minutes = TimeUnit.MILLISECONDS.toMinutes(now.time - past.time)
val hours = TimeUnit.MILLISECONDS.toHours(now.time - past.time)
return when {
seconds < 60 -> {
"Few seconds ago"
}
minutes < 60 -> {
"$minutes minutes ago"
}
hours < 24 -> {
"$hours hour ${minutes % 60} min ago"
}
else -> {
SimpleDateFormat("dd/MM/yy, hh:mm a").format(past).toString()
}
}
}
/**
* Parses String to "dd/MM/yyyy HH:mm:ss" date and time format.
*/
@SuppressLint("SimpleDateFormat")
fun String.toDateFormat(): Date {
return SimpleDateFormat("dd/MM/yyyy HH:mm:ss")
.parse(this)
}
================================================
FILE: app/src/main/java/dev/shreyaspatil/covid19notify/worker/NotificationWorker.kt
================================================
package dev.shreyaspatil.covid19notify.worker
import android.annotation.SuppressLint
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.media.RingtoneManager
import android.os.Build
import android.util.Log
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import dev.shreyaspatil.covid19notify.R
import dev.shreyaspatil.covid19notify.model.StateResponse
import dev.shreyaspatil.covid19notify.repository.CovidIndiaRepository
import dev.shreyaspatil.covid19notify.ui.main.MainActivity
import dev.shreyaspatil.covid19notify.utils.State
import dev.shreyaspatil.covid19notify.utils.getPeriod
import dev.shreyaspatil.covid19notify.utils.toDateFormat
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.toList
import org.koin.core.KoinComponent
import org.koin.core.get
@FlowPreview
@ExperimentalCoroutinesApi
@InternalCoroutinesApi
class NotificationWorker(
private val context: Context,
params: WorkerParameters
) : CoroutineWorker(context, params), KoinComponent {
@SuppressLint("StringFormatInvalid")
private fun showNotification(totalCount: String, time: String) {
val intent = Intent(context, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val pendingIntent = PendingIntent.getActivity(
context, 0, intent,
PendingIntent.FLAG_ONE_SHOT
)
val channelId = context.getString(R.string.default_notification_channel_id)
val channelName = context.getString(R.string.default_notification_channel_name)
val defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val notificationBuilder = NotificationCompat.Builder(context, channelId)
.setColor(ContextCompat.getColor(context, R.color.color_confirmed))
.setSmallIcon(R.drawable.ic_stat_notification_icon)
.setContentTitle(context.getString(R.string.text_confirmed_cases, totalCount))
.setContentText(context.getString(R.string.text_last_updated, time))
.setAutoCancel(true)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent)
val notificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
// Since android Oreo notification channel is needed.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
channelId,
channelName,
NotificationManager.IMPORTANCE_HIGH
)
notificationManager.createNotificationChannel(channel)
}
notificationManager.notify(0, notificationBuilder.build())
}
override suspend fun doWork(): Result = coroutineScope {
Log.d(javaClass.simpleName, "Worker Started!")
val repository: CovidIndiaRepository = get()
val result = withContext(Dispatchers.Default) {
repository.getData().toList()
}.filterIsInstance<State.Success<StateResponse>>()
if (result.isNullOrEmpty()) {
Log.d(javaClass.simpleName, "Work Failed. Retrying...")
Result.retry()
} else {
val totalDetails = result[0].data.stateWiseDetails[0]
showNotification(
totalDetails.confirmed,
getPeriod(
totalDetails.lastUpdatedTime.toDateFormat()
)
)
Log.d(javaClass.simpleName, "Notification Displayed!")
Log.d(javaClass.simpleName, "Work Succeed...")
Result.success()
}
}
}
================================================
FILE: app/src/main/res/drawable/ic_death.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="511.971"
android:viewportHeight="511.971">
<path
android:fillColor="#FF000000"
android:pathData="m509.415,353.795c-1.465,-3.875 -5.795,-5.827 -9.668,-4.363 -3.874,1.465 -5.828,5.793 -4.363,9.668 2.813,7.441 1.854,15.824 -2.565,22.423 -4.837,7.223 -12.912,11.287 -21.62,10.889 -2.639,-0.136 -5.118,1.136 -6.58,3.318 -1.461,2.182 -1.675,4.969 -0.564,7.348 3.686,7.891 2.997,16.914 -1.841,24.137 -3.658,5.461 -9.224,9.171 -15.672,10.446 -6.448,1.276 -13.007,-0.037 -18.468,-3.695 -11.273,-7.551 -14.302,-22.866 -6.75,-34.141 0.626,-0.935 1.335,-1.847 2.107,-2.713 1.444,-1.619 2.117,-3.784 1.845,-5.936s-1.464,-4.082 -3.267,-5.289l-60.294,-40.387c7.083,-7.648 13.33,-15.998 18.639,-24.908l58.944,39.481c1.247,0.835 2.702,1.269 4.174,1.269 0.655,0 1.315,-0.086 1.959,-0.26 2.094,-0.567 3.84,-2.012 4.787,-3.963 0.509,-1.047 1.084,-2.051 1.71,-2.985 5.701,-8.511 16.22,-12.628 26.179,-10.245 4.028,0.965 8.076,-1.52 9.04,-5.548s-1.52,-8.076 -5.548,-9.04c-15.038,-3.597 -30.872,2.01 -40.347,14.028l-53.851,-36.07c8.96,-19.231 13.848,-40.439 13.848,-62.281 0,-15.463 -2.372,-30.567 -6.925,-44.902l46.926,-31.431c12.661,16.106 35.867,19.992 53.165,8.408 18.146,-12.154 23.02,-36.805 10.866,-54.95 -5.832,-8.707 -14.588,-14.568 -24.497,-16.688 1.811,-9.969 -0.275,-20.298 -6.107,-29.004 -5.888,-8.79 -14.846,-14.761 -25.225,-16.814 -10.378,-2.053 -20.935,0.06 -29.726,5.948 -8.79,5.888 -14.762,14.846 -16.814,25.225 -1.854,9.379 -0.308,18.905 4.353,27.14l-43.269,28.981c-1.83,-2.057 -3.716,-4.075 -5.67,-6.043 -27.665,-27.855 -64.512,-43.354 -103.754,-43.64 -0.37,-0.002 -0.738,-0.004 -1.107,-0.004 -21.239,0 -41.776,4.467 -61.056,13.282 -3.767,1.723 -5.424,6.172 -3.701,9.939 1.722,3.767 6.171,5.425 9.939,3.702 17.309,-7.915 35.745,-11.924 54.821,-11.924 0.33,0 0.663,0.002 0.994,0.004 35.257,0.257 68.363,14.182 93.221,39.21 24.869,25.04 38.565,58.268 38.565,93.562 0,47.471 -25.615,91.643 -66.851,115.278 -2.332,1.336 -3.77,3.819 -3.77,6.507v34.247c0,7.99 -6.5,14.491 -14.49,14.491h-5.756v-22.212c0,-4.142 -3.357,-7.5 -7.5,-7.5s-7.5,3.358 -7.5,7.5v22.212h-19.409v-22.212c0,-4.142 -3.357,-7.5 -7.5,-7.5s-7.5,3.358 -7.5,7.5v22.212h-19.409v-22.212c0,-4.142 -3.357,-7.5 -7.5,-7.5s-7.5,3.358 -7.5,7.5v22.212h-5.756c-7.99,0 -14.49,-6.5 -14.49,-14.491v-34.247c0,-2.688 -1.439,-5.171 -3.771,-6.507 -41.235,-23.635 -66.851,-67.807 -66.851,-115.277 0,-41.736 20.179,-81.619 53.978,-106.686 3.327,-2.467 4.023,-7.165 1.557,-10.492 -2.468,-3.327 -7.165,-4.023 -10.492,-1.556 -7.541,5.593 -14.461,11.859 -20.724,18.664l-40.312,-27c4.661,-8.235 6.207,-17.76 4.353,-27.14 -2.052,-10.379 -8.023,-19.337 -16.813,-25.225 -8.79,-5.887 -19.349,-7.998 -29.726,-5.948 -10.378,2.052 -19.336,8.023 -25.224,16.813 -5.832,8.707 -7.918,19.036 -6.107,29.004 -9.908,2.12 -18.665,7.981 -24.497,16.688 -12.153,18.145 -7.279,42.796 10.866,54.95 17.298,11.585 40.506,7.698 53.165,-8.408l42.975,28.785c-5.219,15.178 -7.998,31.234 -7.998,47.549 0,22.813 5.326,44.935 15.061,64.833l-50.039,33.516c-12.66,-16.105 -35.866,-19.992 -53.165,-8.408 -18.146,12.154 -23.02,36.805 -10.866,54.951 5.832,8.707 14.588,14.567 24.497,16.687 -1.81,9.969 0.275,20.298 6.107,29.004 5.888,8.79 14.846,14.761 25.225,16.814 2.588,0.512 5.186,0.764 7.766,0.764 7.767,0 15.361,-2.292 21.96,-6.712 17.297,-11.585 22.535,-34.527 12.46,-52.363l53.714,-35.978c5.599,4.719 11.568,9.061 17.901,12.946v29.977c0,16.261 13.229,29.491 29.49,29.491h95.33c16.261,0 29.49,-13.229 29.49,-29.491v-29.977c7.17,-4.399 13.88,-9.376 20.103,-14.835l56.535,37.868c-10.075,17.837 -4.837,40.778 12.46,52.363 6.599,4.42 14.192,6.712 21.96,6.712 2.579,0 5.179,-0.253 7.766,-0.764 10.379,-2.053 19.337,-8.024 25.225,-16.814 5.832,-8.707 7.918,-19.036 6.107,-29.004 9.908,-2.12 18.665,-7.981 24.497,-16.688 7.115,-10.62 8.66,-24.106 4.135,-36.075zM72.671,151.898c-1.802,-1.208 -4.041,-1.574 -6.133,-1.008 -2.094,0.567 -3.84,2.012 -4.787,3.963 -0.509,1.047 -1.084,2.051 -1.71,2.985 -7.551,11.273 -22.865,14.302 -34.14,6.751 -11.273,-7.551 -14.302,-22.866 -6.751,-34.14 4.838,-7.223 12.916,-11.29 21.62,-10.889 2.637,0.135 5.118,-1.136 6.58,-3.318 1.461,-2.182 1.675,-4.969 0.564,-7.348 -3.686,-7.891 -2.997,-16.914 1.841,-24.137 3.658,-5.461 9.224,-9.171 15.672,-10.446 6.447,-1.276 13.007,0.037 18.468,3.695s9.171,9.223 10.446,15.671 -0.037,13.007 -3.696,18.47c-0.626,0.935 -1.335,1.847 -2.107,2.713 -1.444,1.619 -2.117,3.784 -1.845,5.937 0.272,2.152 1.464,4.082 3.267,5.289l45.409,30.414c-6.244,8.338 -11.587,17.298 -15.951,26.708zM89.959,385.886c-1.803,1.207 -2.994,3.137 -3.267,5.289 -0.272,2.153 0.4,4.318 1.845,5.936 0.772,0.866 1.481,1.778 2.108,2.714 3.658,5.462 4.971,12.02 3.695,18.468 -1.275,6.448 -4.985,12.014 -10.446,15.671 -5.461,3.658 -12.024,4.97 -18.468,3.695 -6.448,-1.275 -12.014,-4.985 -15.672,-10.446 -4.838,-7.223 -5.526,-16.246 -1.841,-24.137 1.111,-2.379 0.897,-5.166 -0.564,-7.348s-3.978,-3.457 -6.58,-3.318c-8.702,0.398 -16.782,-3.666 -21.62,-10.889 -7.551,-11.274 -4.522,-26.589 6.751,-34.14s26.588,-4.523 34.141,6.752c0.625,0.934 1.2,1.938 1.709,2.984 0.947,1.951 2.693,3.396 4.787,3.963 2.091,0.565 4.33,0.198 6.133,-1.008l55.382,-37.095c5.48,8.814 11.874,17.067 19.113,24.59zM422.01,126.086c1.803,-1.207 2.994,-3.137 3.267,-5.289 0.273,-2.153 -0.4,-4.318 -1.845,-5.937 -0.772,-0.866 -1.482,-1.778 -2.108,-2.714 -3.658,-5.461 -4.971,-12.02 -3.695,-18.468 1.275,-6.448 4.985,-12.014 10.446,-15.671 5.461,-3.658 12.023,-4.971 18.468,-3.695 6.448,1.275 12.014,4.985 15.672,10.446 4.838,7.223 5.526,16.246 1.841,24.137 -1.111,2.379 -0.897,5.166 0.564,7.348 1.461,2.181 3.956,3.446 6.58,3.318 8.701,-0.391 16.782,3.666 21.62,10.889 7.551,11.273 4.522,26.588 -6.751,34.14 -11.274,7.551 -26.588,4.522 -34.141,-6.752 -0.625,-0.934 -1.2,-1.938 -1.709,-2.984 -0.947,-1.951 -2.693,-3.396 -4.787,-3.963 -2.094,-0.566 -4.331,-0.199 -6.133,1.008l-50.4,33.758c-4.16,-9.491 -9.341,-18.542 -15.475,-27.026z" />
<path
android:fillColor="#FF000000"
android:pathData="m195.53,227.435c-24.682,0 -44.762,20.08 -44.762,44.762s20.08,44.762 44.762,44.762 44.762,-20.08 44.762,-44.762 -20.08,-44.762 -44.762,-44.762zM195.53,301.959c-16.411,0 -29.762,-13.351 -29.762,-29.762s13.351,-29.762 29.762,-29.762 29.762,13.351 29.762,29.762 -13.351,29.762 -29.762,29.762z" />
<path
android:fillColor="#FF000000"
android:pathData="m310.348,316.959c24.682,0 44.762,-20.08 44.762,-44.762s-20.08,-44.762 -44.762,-44.762 -44.762,20.08 -44.762,44.762 20.08,44.762 44.762,44.762zM310.348,242.435c16.411,0 29.762,13.351 29.762,29.762s-13.351,29.762 -29.762,29.762 -29.762,-13.351 -29.762,-29.762 13.351,-29.762 29.762,-29.762z" />
<path
android:fillColor="#FF000000"
android:pathData="m253.605,311.749c-0.011,0 -0.022,0 -0.033,0 -1.988,0 -3.896,0.79 -5.303,2.197l-11.108,11.108c-2.93,2.929 -2.93,7.677 -0.001,10.606 1.465,1.465 3.384,2.197 5.304,2.197 1.919,0 3.839,-0.732 5.303,-2.197l5.758,-5.757 5.608,5.71c2.905,2.956 7.653,2.996 10.606,0.095 2.955,-2.903 2.997,-7.651 0.095,-10.607l-10.911,-11.108c-1.403,-1.427 -3.317,-2.235 -5.318,-2.244z" />
</vector>
================================================
FILE: app/src/main/res/drawable/ic_heart.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="420.8"
android:viewportHeight="420.8">
<path
android:fillColor="#FF000000"
android:pathData="M413.6,204H378c14.8,-33.6 13.2,-60.8 7.6,-79.2c-9.6,-32.8 -42,-68.4 -90,-68.4c-12.8,0 -25.6,2.4 -38.8,7.2C234,72 218.8,81.2 212,86c-6.8,-4.8 -21.6,-14 -44.8,-22.4c-13.2,-4.8 -26.4,-7.2 -38.8,-7.2c-48,0 -80.4,35.6 -90,68.4c-5.6,19.6 -7.6,49.2 11.2,86.4H6.4c-3.6,0 -6.4,2.8 -6.4,6.4c0,3.6 2.8,6.4 6.4,6.4h50.8c2,3.6 4.4,7.2 7.2,10.8c41.6,60 132,125.2 148.4,129.2v0.4c0,0 0.4,0 0.8,-0.4c0.4,0 0.8,0 1.2,0v-0.4c14,-6.8 100.8,-62.8 146.4,-129.2c4.4,-6 8,-12 11.2,-18h42c3.6,0 6.4,-2.8 6.4,-6.4C420.8,206.4 417.2,204 413.6,204zM349.6,227.6c-42.4,62 -120.4,112 -137.2,122.8c-17.2,-10.8 -94.8,-61.2 -137.6,-122.8c-0.8,-1.2 -1.6,-2.4 -2.4,-3.6h58.8c2.4,0 4.8,-1.2 6,-3.6l26.8,-52.8l42,107.6c0.8,2.4 3.6,4 6,4c0,0 0,0 0.4,0c2.8,0 5.2,-2 6,-4.8l36.8,-126l19.6,63.6c0.8,2.4 2.8,4 5.2,4.4c2.4,0.4 4.8,-0.8 6.4,-2.8l15.6,-22.8l13.2,22.4c1.2,2 3.2,3.2 5.6,3.2h36C354.4,220.4 352,224 349.6,227.6zM364,204h-39.2l-16.4,-28c-1.2,-2 -3.2,-3.2 -5.6,-3.2c-2.4,0 -4.4,0.8 -5.6,2.8l-13.6,20l-22,-71.6c-0.8,-2.8 -3.6,-4.4 -6.4,-4.8c-2.8,0 -5.6,2 -6.4,4.8l-37.2,128.4l-40.4,-103.2c-0.8,-2.4 -3.2,-4 -5.6,-4c-2.8,0 -4.8,1.2 -6,3.6l-31.6,62H64.4c-16,-29.2 -20.4,-57.2 -13.2,-82.4c8.4,-28.4 36,-58.8 77.6,-58.8c11.2,0 22.8,2.4 34.4,6.4c29.2,10.8 44.8,23.2 45.2,23.2c2.4,2 5.6,2 8,0c0,0 15.6,-12.4 45.2,-23.2c11.6,-4.4 23.2,-6.4 34.4,-6.4c41.2,0 69.2,30.4 77.6,58.8C380.4,151.6 376.8,177.2 364,204z" />
</vector>
================================================
FILE: app/src/main/res/drawable/ic_info.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="14dp"
android:height="14dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-6h2v6zM13,9h-2L11,7h2v2z"/>
</vector>
================================================
FILE: app/src/main/res/drawable/ic_launcher_foreground.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="330.02182"
android:viewportHeight="330.02182">
<group
android:translateX="74.43041"
android:translateY="74.254906">
<path
android:fillColor="#933"
android:pathData="M153.428,154.513a3,3 0,0 1,-2.179 -5.061c3.954,-4.181 2.94,-8.512 0.94,-14.641a9.836,9.836 0,0 0,-2.16 -3.016c-1.918,-2.126 -4.544,-5.037 -3.481,-9.607a25.036,25.036 0,0 1,2.379 -5.815,16.448 16.448,0 0,0 2.06,-5.418 5.11,5.11 0,0 1,0.928 -2.279c0.4,-5.449 5.218,-5.819 7.312,-5.979a22.575,22.575 0,0 0,9.38 -2.993c3.758,-2.1 6.259,-5.346 6.529,-8.479 0.307,-3.58 -2.274,-6.473 -4.494,-8.27a18.574,18.574 0,0 0,-11.278 -4.324c-3.111,-0.1 -6.171,-0.864 -7.481,-5.742 -1.04,-3.876 -2.566,-8.807 -5.149,-12.555 -2.849,-4.133 -2.665,-8.212 0.531,-11.8 2.643,-2.962 3.72,-6.614 4.675,-10.409a8.16,8.16 0,0 0,-1.683 -6.742,9.782 9.782,0 0,0 -7.03,-4.094c-4.975,-0.247 -9.676,1.681 -14.352,5.879 -2.732,2.452 -5.985,2.865 -8.7,1.1a44.8,44.8 0,0 0,-10.077 -4.384c-0.647,-0.222 -1.293,-0.443 -1.937,-0.669 -2.712,-0.953 -5.793,-2.674 -5.557,-7.58 0.132,-2.765 -0.81,-5.645 -3.057,-9.336 -2.113,-3.469 -6.6,-8.73 -12.943,-4.98 -4.54,2.685 -7.255,7.178 -8.069,13.355l-0.09,0.685c-0.879,6.758 -2.2,7.873 -9.457,7.948h-0.032a3,3 0,0 1,-0.031 -6c1.18,-0.012 2.487,-0.026 3.172,-0.111 0.135,-0.586 0.273,-1.649 0.4,-2.611l0.091,-0.7c1.053,-7.984 4.844,-14.116 10.964,-17.735 7.638,-4.519 15.733,-1.828 21.122,7.024 1.958,3.217 4.173,7.571 3.925,12.744 -0.049,1.027 -0.051,1.068 1.551,1.63 0.63,0.222 1.263,0.438 1.895,0.655a50.017,50.017 0,0 1,11.4 5.026c0.18,0.117 0.482,0.314 1.427,-0.533 5.911,-5.307 12.017,-7.729 18.652,-7.407a15.688,15.688 0,0 1,11.559 6.514,14.111 14.111,0 0,1 2.681,11.78c-1.1,4.366 -2.47,8.963 -6.015,12.938 -1.186,1.329 -1.5,2.325 -0.07,4.4 3.1,4.5 4.839,10.062 6,14.4a2.8,2.8 0,0 0,0.459 1.125,4.034 4.034,0 0,0 1.42,0.176 24.447,24.447 0,0 1,14.861 5.658c6.067,4.912 6.99,10.024 6.7,13.447 -0.444,5.167 -4.026,10.1 -9.581,13.2a28.445,28.445 0,0 1,-11.846 3.736,12.5 12.5,0 0,0 -1.762,0.219 3.085,3.085 0,0 0,-0.034 0.433,4.808 4.808,0 0,1 -0.954,2.63l-0.037,0.055a22.335,22.335 0,0 1,-2.636 7.1,20.2 20.2,0 0,0 -1.871,4.43c-0.324,1.394 0.281,2.221 2.092,4.229a14.51,14.51 0,0 1,3.409 5.174c1.759,5.392 4.417,13.539 -2.285,20.625A2.994,2.994 0,0 1,153.428 154.513ZM157.963,108.732Z" />
<path
android:fillColor="#933"
android:pathData="M106.515,121.842c-8.431,0 -16.514,-6.048 -17.883,-13.537 -1.719,-9.4 2.991,-17.532 12,-20.728a5.483,5.483 0,0 1,0.657 -0.186,3 3,0 0,1 2.154,-2.1 2.963,2.963 0,0 1,3.623 2.15,4.627 4.627,0 0,1 -0.508,3.837 4.815,4.815 0,0 1,-3.6 1.918,3.768 3.768,0 0,0 -0.377,0.06c-6.115,2.172 -9.22,7.534 -8.042,13.975 0.886,4.845 6.714,8.884 12.5,8.6 3.478,-0.157 6.887,-2.461 8.9,-6.011a10.971,10.971 0,0 0,0.547 -10.616s-2.489,-4.483 -2.238,-7.292a3,3 0,1 1,5.977 0.535c-0.083,0.928 0.336,1.732 1.146,3.19l0.392,0.712c2.66,4.917 2.435,11.058 -0.6,16.425 -3.062,5.414 -8.238,8.8 -13.845,9.052Q106.91,121.841 106.515,121.842ZM101.261,88.961h0Z" />
<path
android:fillColor="#933"
android:pathData="M90.561,181.513a13.509,13.509 0,0 1,-8.284 -3.081,24.191 24.191,0 0,1 -9.743,-18.767 4.306,4.306 0,0 0,-0.192 -1.508h0a3.453,3.453 0,0 0,-1.01 -0.348,49.859 49.859,0 0,1 -12.286,-4.769c-1.987,-1.065 -2.056,-1 -3.218,0.078a24.615,24.615 0,0 1,-18.191 6.923,14.523 14.523,0 0,1 -13.325,-10.755c-2.229,-8.178 1.234,-14.739 4.5,-19.541l0.372,-0.542c1.553,-2.243 1.507,-2.479 1.031,-3.223 -3.211,-5.024 -5.1,-10.576 -6.763,-15.832 -0.4,-1.264 -0.441,-1.4 -2.416,-1.5 -0.34,-0.018 -0.692,-0.025 -1.047,-0.032 -2.577,-0.053 -7.372,-0.151 -9.182,-5.405a3,3 0,1 1,5.673 -1.954c0.367,1.066 0.721,1.3 3.632,1.36 0.419,0.009 0.833,0.018 1.234,0.039 3.033,0.157 6.334,0.955 7.827,5.682 1.54,4.874 3.28,10 6.1,14.409 2.725,4.265 0.3,7.772 -1.153,9.869l-0.345,0.5c-3.827,5.627 -4.925,9.99 -3.672,14.589a8.432,8.432 0,0 0,7.821 6.339,18.494 18.494,0 0,0 13.823,-5.326c4.035,-3.747 7.348,-2.465 10.137,-0.969a43.924,43.924 0,0 0,10.794 4.208c4.958,1.139 5.742,4.422 5.855,7.483a18.36,18.36 0,0 0,7.41 14.237c3.144,2.424 6.1,2.423 9.287,-0.006 5.045,-3.838 7.534,-8.734 7.4,-14.551 -0.113,-4.813 2.809,-6.3 5.681,-7.13a51.269,51.269 0,0 0,12.317 -5.2c4.6,-2.772 8.739,-2.465 12.65,0.939a16.377,16.377 0,0 0,9.4 3.807,3 3,0 0,1 -0.62,5.968 22.162,22.162 0,0 1,-12.718 -5.248c-1.744,-1.517 -2.967,-1.923 -5.616,-0.326a57.31,57.31 0,0 1,-13.758 5.824,5.639 5.639,0 0,0 -1.3,0.483 3.4,3.4 0,0 0,-0.043 0.739c0.181,7.738 -3.194,14.469 -9.761,19.466A13.665,13.665 0,0 1,90.561 181.513Z" />
<path
android:fillColor="#933"
android:pathData="M3.336,97.693a3,3 0,0 1,-2.938 -2.411c-1.31,-6.539 0.619,-12.081 5.735,-16.475a24.129,24.129 0,0 1,15.495 -6.118,4.868 4.868,0 0,0 1.53,-0.217c0.548,-4.076 2.215,-7.56 3.829,-10.931 0.732,-1.53 1.436,-3 2.031,-4.5a27.375,27.375 0,0 1,-7.692 -14.651c-0.961,-5.642 0.55,-10.9 4.146,-14.422s8.824,-4.914 14.383,-3.853c4.179,0.8 9,2.132 13.117,5.954a3.855,3.855 0,0 0,1.132 0.812,4.928 4.928,0 0,0 1.193,-1.545 3,3 0,1 1,5.195 3c-0.577,1 -2.33,4.028 -5.5,4.5 -2.02,0.3 -4.077,-0.5 -6.1,-2.379 -2.991,-2.78 -6.65,-3.784 -10.159,-4.455 -3.651,-0.7 -6.867,0.1 -9.057,2.244s-3.066,5.4 -2.43,9.129a22.088,22.088 0,0 0,7.284 12.645,3 3,0 0,1 0.826,3.143 57.062,57.062 0,0 1,-2.952 6.964c-1.5,3.135 -2.919,6.1 -3.314,9.294 -0.191,1.537 -1.285,5.127 -7.324,5.261a18.288,18.288 0,0 0,-11.719 4.671c-3.489,3 -4.649,6.311 -3.761,10.745a3,3 0,0 1,-2.945 3.59Z" />
<path
android:fillColor="#933"
android:pathData="M84.787,90.657c-7.336,0 -14.743,-6.613 -15.356,-13.806 -0.744,-8.715 3.243,-14.34 12.188,-17.2a2.993,2.993 0,0 1,1.168 -0.132c0.092,-0.008 0.182,-0.01 0.279,-0.01 5.525,0.057 9.761,1.586 12.59,4.544 2.811,2.94 4.141,7.191 3.953,12.637 -0.235,6.843 -7.406,13.757 -14.478,13.958C85.017,90.655 84.902,90.657 84.787,90.657ZM83.012,65.513c-5.955,2.009 -8.094,5.077 -7.6,10.828 0.348,4.081 5.309,8.46 9.552,8.313 3.915,-0.111 8.525,-4.461 8.652,-8.166 0.13,-3.77 -0.642,-6.557 -2.293,-8.284C89.651,66.459 86.861,65.554 83.012,65.513Z" />
<path
android:fillColor="#933"
android:pathData="M69.168,116.919q-0.432,0 -0.879,-0.024a11.373,11.373 0,0 1,-10.856 -12.293c0.332,-6.714 5.81,-9.6 7.61,-10.552a2.964,2.964 0,0 1,1.652 -0.336c0.082,-0.007 0.166,-0.011 0.25,-0.011h0.784c0.584,0 1.169,0 1.753,0a12.567,12.567 0,0 1,9.1 3.935,10.393 10.393,0 0,1 2.846,7.809C81.053,111.072 77.056,116.919 69.168,116.919ZM67.214,99.703c-2.572,1.483 -3.68,3.021 -3.787,5.2a5.381,5.381 0,0 0,5.181 6.006c6.126,0.331 6.768,-4.824 6.837,-5.859a4.427,4.427 0,0 0,-1.258 -3.324,6.628 6.628,0 0,0 -4.751,-2.017c-0.566,0 -1.13,0 -1.695,0Z" />
</group>
</vector>
================================================
FILE: app/src/main/res/drawable/ic_lightbulb.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="@color/color_bulb_icon"
android:pathData="M9,21c0,0.55 0.45,1 1,1h4c0.55,0 1,-0.45 1,-1v-1L9,20v1zM12,2C8.14,2 5,5.14 5,9c0,2.38 1.19,4.47 3,5.74L8,17c0,0.55 0.45,1 1,1h6c0.55,0 1,-0.45 1,-1v-2.26c1.81,-1.27 3,-3.36 3,-5.74 0,-3.86 -3.14,-7 -7,-7zM14.85,13.1l-0.85,0.6L14,16h-4v-2.3l-0.85,-0.6C7.8,12.16 7,10.63 7,9c0,-2.76 2.24,-5 5,-5s5,2.24 5,5c0,1.63 -0.8,3.16 -2.15,4.1z" />
</vector>
================================================
FILE: app/src/main/res/drawable/ic_patient.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="512"
android:viewportHeight="512">
<path
android:fillColor="#FF000000"
android:pathData="M168.514,188.263a9.062,9.062 129.318,1 0,18.035 -1.794a9.062,9.062 129.318,1 0,-18.035 1.794z" />
<path
android:fillColor="#FF000000"
android:pathData="M230.206,188.235a9.062,9.062 129.318,1 0,18.035 -1.794a9.062,9.062 129.318,1 0,-18.035 1.794z" />
<path
android:fillColor="#FF000000"
android:pathData="m220.761,219.565h-27.228c-4.177,0 -7.563,3.386 -7.563,7.563 0,4.178 3.386,7.563 7.563,7.563h27.228c4.177,0 7.563,-3.386 7.563,-7.563s-3.386,-7.563 -7.563,-7.563z" />
<path
android:fillColor="#FF000000"
android:pathData="m497.763,80.897h-22.847v-19.066h29.513c4.177,0 7.563,-3.386 7.563,-7.563s-3.386,-7.563 -7.563,-7.563h-388.735c-4.177,0 -7.563,3.386 -7.563,7.563s3.386,7.563 7.563,7.563h344.096v19.066h-22.846c-7.846,0 -14.229,6.384 -14.229,14.229v65.809c0.172,7.345 1.582,14.977 6.472,23.129 4.08,6.708 9.88,12.258 16.78,16.041l-4.94,7.942c-7.367,11.844 -8.052,26.943 -1.788,39.405l20.542,40.866c4.969,9.886 2.816,22.071 -5.234,29.654l-37.596,34.015v-145.836c0,-11.648 -9.476,-21.124 -21.124,-21.124h-21.862c-0.568,-3.699 -1.414,-7.347 -2.537,-10.92 -0.976,-3.105 -1.129,-6.435 -0.44,-9.629l5.576,-25.866c1.06,-4.918 -0.43,-9.977 -3.987,-13.535 -3.557,-3.557 -8.618,-5.052 -13.537,-3.988 -7.839,1.033 -27.03,7.836 -35.021,4.903 -2.983,-0.99 -6.056,-1.795 -9.132,-2.395 -4.098,-0.792 -8.071,1.88 -8.869,5.98s1.879,8.071 5.979,8.869c2.444,0.476 4.886,1.116 7.258,1.903 5.726,1.9 11.89,2.229 17.827,0.948l24.571,-5.297 -5.452,25.291c-2.836,10.844 3.713,22.529 3.5,35.059v78.225c0,6.091 -0.927,12.097 -2.754,17.853 -0.583,1.835 -0.988,3.715 -1.25,5.613 -17.042,-15.086 -39.432,-24.26 -63.929,-24.26h-32.453v-7.433c10.52,-10.16 18.046,-23.466 21.001,-38.541 10.93,-3.668 20.215,-14.856 23.66,-25.447 5.204,-16.002 -2.142,-32.787 -16.374,-37.416 -0.001,-0.001 -0.001,-0.001 -0.001,-0.001 -1.552,-0.503 -3.596,-0.949 -5.888,-0.916v-36.034c0,-21.964 -17.869,-39.834 -39.834,-39.834h-67.119c-20.008,0 -36.613,14.831 -39.412,34.075h-19.421c-10.698,-1.087 -21.507,5.392 -33.182,4.277l-25.149,-5.423c-4.918,-1.061 -9.979,0.432 -13.535,3.989 -3.557,3.558 -5.047,8.617 -3.987,13.535l5.576,25.867c0.689,3.194 0.537,6.523 -0.44,9.629 -1.123,3.572 -1.969,7.22 -2.537,10.919h-19.191v-106.898c0,-8.986 7.311,-16.298 16.297,-16.298h41.124c4.177,0 7.563,-3.386 7.563,-7.563s-3.386,-7.563 -7.563,-7.563h-41.124c-17.327,0 -31.424,14.097 -31.424,31.424v111.234c-5.066,3.862 -8.355,9.94 -8.355,16.788l0.188,245.917c0,7.293 5.934,13.228 13.227,13.228h390.192c7.294,0 13.227,-5.934 13.227,-13.228l0.116,-79.683 47.798,-43.245c0.033,-0.03 0.066,-0.06 0.098,-0.091 12.941,-12.132 16.415,-31.675 8.449,-47.525l-20.542,-40.866c-3.914,-7.787 -3.486,-17.221 1.117,-24.622l6.819,-10.962c2.175,0.327 4.399,0.499 6.664,0.499s0,0 0,0c16.153,0 30.329,-8.624 38.167,-21.509 2.881,-4.252 6.666,-14.529 6.472,-23.129v-65.808c0.001,-7.846 -6.383,-14.23 -14.229,-14.23zM401.824,206.151v159.52l-8.266,7.479c-1.725,-1.558 -3.474,-3.082 -5.254,-4.56 -0.324,-18.135 -5.671,-35.063 -14.708,-49.453 -1.114,-6.585 -4.48,-14.802 -2.232,-22.133 2.298,-7.237 3.463,-14.784 3.463,-22.43v-74.421h21c3.307,0 5.997,2.691 5.997,5.998zM172.451,277.599c10.65,5.977 22.902,9.374 35.868,9.374 12.967,0 25.218,-3.397 35.868,-9.374v13.734c0,3.422 -2.785,6.207 -6.207,6.207h-59.322c-3.423,0 -6.207,-2.785 -6.207,-6.207zM282.922,179.327c6.301,2.049 9.292,10.283 6.668,18.354 -2.572,7.907 -10.65,15.948 -16.308,16.234 -3.681,0.185 -6.693,2.997 -7.13,6.656 -3.493,29.232 -28.355,51.276 -57.832,51.276s-54.34,-22.044 -57.832,-51.276c-0.437,-3.66 -3.449,-6.471 -7.13,-6.656 -5.659,-0.286 -13.737,-8.326 -16.308,-16.234 -2.625,-8.071 0.367,-16.305 6.667,-18.353 0.317,-0.103 0.566,-0.184 0.802,-0.184 0.493,0 0.929,0.353 1.812,1.591 1.909,2.681 5.329,3.823 8.463,2.818 3.904,-1.111 6.005,-6.617 5.261,-11.873 0,-16.024 13.036,-29.06 29.061,-29.06h58.41c16.024,0 29.061,13.036 29.061,29.06 -0.171,4.026 -0.471,9.402 5.261,11.873 3.134,1.005 6.555,-0.137 8.463,-2.818 1.303,-1.831 1.633,-1.724 2.611,-1.408zM150.053,127.992c0,-13.624 11.084,-24.707 24.707,-24.707h67.118c13.623,0 24.707,11.083 24.707,24.707v10.441c-7.775,-6.804 -17.942,-10.939 -29.061,-10.939h-58.41c-11.119,0 -21.286,4.135 -29.061,10.939zM79.557,141.297c5.936,1.278 12.1,0.95 17.828,-0.949 5.972,-1.982 12.211,-2.988 18.543,-2.988h18.999v26.665c-2.29,-0.034 -4.337,0.412 -5.889,0.918 -14.232,4.629 -21.578,21.413 -16.374,37.416 3.444,10.593 12.728,21.78 23.66,25.447 2.955,15.075 10.481,28.381 21.001,38.541v7.433h-32.453c-24.496,0 -46.887,9.174 -63.929,24.261 -0.262,-1.899 -0.668,-3.779 -1.25,-5.613 -1.827,-5.755 -2.754,-11.763 -2.754,-17.853v-78.225c-0.641,-10.818 6.302,-22.612 3.5,-35.059l-5.452,-25.291zM15.127,206.151c0,-3.307 2.69,-5.997 5.998,-5.997h20.686v74.421c0,7.646 1.165,15.193 3.463,22.43 2.286,4.612 -1.189,17.139 -2.233,22.133 -9.048,14.409 -14.397,31.361 -14.708,49.522 -3.022,2.512 -5.965,5.136 -8.822,7.872 -1.546,1.481 -3.008,3.038 -4.385,4.661v-175.042zM401.708,450.169h-386.393v-28.323c0,-12.932 5.344,-25.466 14.66,-34.391 20.909,-20.028 46.889,-33.552 75.13,-39.113 4.098,-0.807 6.767,-4.783 5.96,-8.881 -0.807,-4.1 -4.785,-6.771 -8.882,-5.96 -20.597,4.054 -40.085,11.977 -57.591,23.257 6.486,-38.457 40.005,-67.852 80.278,-67.852h32.453v2.427c0,11.764 9.57,21.334 21.334,21.334h59.322c11.764,0 21.333,-9.57 21.333,-21.334v-2.427h32.453c40.239,0 73.733,29.344 80.26,67.753 -26.572,-17.104 -57.535,-26.292 -89.775,-26.292h-143.33c-4.177,0 -7.563,3.386 -7.563,7.563 0,4.178 3.386,7.563 7.563,7.563h143.333c34.329,0 67.068,11.455 93.659,32.52 0.07,0.058 0.144,0.112 0.216,0.168 3.799,3.021 7.472,6.238 11.005,9.646 9.264,8.935 14.576,21.44 14.576,34.31v28.032zM496.866,96.024v20.863h-59.025v-20.863zM494.543,172.412c-2.926,8.628 -15.692,18.665 -27.19,18.035 -16.273,0 -29.512,-13.239 -29.512,-29.512v-28.922h59.025v28.922c-0.428,4.049 0.2,4.675 -2.323,11.477z" />
</vector>
================================================
FILE: app/src/main/res/drawable/ic_settings.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M19.1,12.9a2.8,2.8 0,0 0,0.1 -0.9,2.8 2.8,0 0,0 -0.1,-0.9l2.1,-1.6a0.7,0.7 0,0 0,0.1 -0.6L19.4,5.5a0.7,0.7 0,0 0,-0.6 -0.2l-2.4,1a6.5,6.5 0,0 0,-1.6 -0.9l-0.4,-2.6a0.5,0.5 0,0 0,-0.5 -0.4H10.1a0.5,0.5 0,0 0,-0.5 0.4L9.3,5.4a5.6,5.6 0,0 0,-1.7 0.9l-2.4,-1a0.4,0.4 0,0 0,-0.5 0.2l-2,3.4c-0.1,0.2 0,0.4 0.2,0.6l2,1.6a2.8,2.8 0,0 0,-0.1 0.9,2.8 2.8,0 0,0 0.1,0.9L2.8,14.5a0.7,0.7 0,0 0,-0.1 0.6l1.9,3.4a0.7,0.7 0,0 0,0.6 0.2l2.4,-1a6.5,6.5 0,0 0,1.6 0.9l0.4,2.6a0.5,0.5 0,0 0,0.5 0.4h3.8a0.5,0.5 0,0 0,0.5 -0.4l0.3,-2.6a5.6,5.6 0,0 0,1.7 -0.9l2.4,1a0.4,0.4 0,0 0,0.5 -0.2l2,-3.4c0.1,-0.2 0,-0.4 -0.2,-0.6ZM12,15.6A3.6,3.6 0,1 1,15.6 12,3.6 3.6,0 0,1 12,15.6Z"/>
</vector>
================================================
FILE: app/src/main/res/drawable/ic_trending_up.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M16,6l2.29,2.29 -4.88,4.88 -4,-4L2,16.59 3.41,18l6,-6 4,4 6.3,-6.29L22,12V6z"/>
</vector>
================================================
FILE: app/src/main/res/drawable/ic_virus.xml
================================================
<vector android:height="24.0465dp" android:viewportHeight="181.512"
android:viewportWidth="181.161" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#933" android:pathData="M153.428,154.513a3,3 0,0 1,-2.179 -5.061c3.954,-4.181 2.94,-8.512 0.94,-14.641a9.836,9.836 0,0 0,-2.16 -3.016c-1.918,-2.126 -4.544,-5.037 -3.481,-9.607a25.036,25.036 0,0 1,2.379 -5.815,16.448 16.448,0 0,0 2.06,-5.418 5.11,5.11 0,0 1,0.928 -2.279c0.4,-5.449 5.218,-5.819 7.312,-5.979a22.575,22.575 0,0 0,9.38 -2.993c3.758,-2.1 6.259,-5.346 6.529,-8.479 0.307,-3.58 -2.274,-6.473 -4.494,-8.27a18.574,18.574 0,0 0,-11.278 -4.324c-3.111,-0.1 -6.171,-0.864 -7.481,-5.742 -1.04,-3.876 -2.566,-8.807 -5.149,-12.555 -2.849,-4.133 -2.665,-8.212 0.531,-11.8 2.643,-2.962 3.72,-6.614 4.675,-10.409a8.16,8.16 0,0 0,-1.683 -6.742,9.782 9.782,0 0,0 -7.03,-4.094c-4.975,-0.247 -9.676,1.681 -14.352,5.879 -2.732,2.452 -5.985,2.865 -8.7,1.1a44.8,44.8 0,0 0,-10.077 -4.384c-0.647,-0.222 -1.293,-0.443 -1.937,-0.669 -2.712,-0.953 -5.793,-2.674 -5.557,-7.58 0.132,-2.765 -0.81,-5.645 -3.057,-9.336 -2.113,-3.469 -6.6,-8.73 -12.943,-4.98 -4.54,2.685 -7.255,7.178 -8.069,13.355l-0.09,0.685c-0.879,6.758 -2.2,7.873 -9.457,7.948h-0.032a3,3 0,0 1,-0.031 -6c1.18,-0.012 2.487,-0.026 3.172,-0.111 0.135,-0.586 0.273,-1.649 0.4,-2.611l0.091,-0.7c1.053,-7.984 4.844,-14.116 10.964,-17.735 7.638,-4.519 15.733,-1.828 21.122,7.024 1.958,3.217 4.173,7.571 3.925,12.744 -0.049,1.027 -0.051,1.068 1.551,1.63 0.63,0.222 1.263,0.438 1.895,0.655a50.017,50.017 0,0 1,11.4 5.026c0.18,0.117 0.482,0.314 1.427,-0.533 5.911,-5.307 12.017,-7.729 18.652,-7.407a15.688,15.688 0,0 1,11.559 6.514,14.111 14.111,0 0,1 2.681,11.78c-1.1,4.366 -2.47,8.963 -6.015,12.938 -1.186,1.329 -1.5,2.325 -0.07,4.4 3.1,4.5 4.839,10.062 6,14.4a2.8,2.8 0,0 0,0.459 1.125,4.034 4.034,0 0,0 1.42,0.176 24.447,24.447 0,0 1,14.861 5.658c6.067,4.912 6.99,10.024 6.7,13.447 -0.444,5.167 -4.026,10.1 -9.581,13.2a28.445,28.445 0,0 1,-11.846 3.736,12.5 12.5,0 0,0 -1.762,0.219 3.085,3.085 0,0 0,-0.034 0.433,4.808 4.808,0 0,1 -0.954,2.63l-0.037,0.055a22.335,22.335 0,0 1,-2.636 7.1,20.2 20.2,0 0,0 -1.871,4.43c-0.324,1.394 0.281,2.221 2.092,4.229a14.51,14.51 0,0 1,3.409 5.174c1.759,5.392 4.417,13.539 -2.285,20.625A2.994,2.994 0,0 1,153.428 154.513ZM157.963,108.732Z"/>
<path android:fillColor="#933" android:pathData="M106.515,121.842c-8.431,0 -16.514,-6.048 -17.883,-13.537 -1.719,-9.4 2.991,-17.532 12,-20.728a5.483,5.483 0,0 1,0.657 -0.186,3 3,0 0,1 2.154,-2.1 2.963,2.963 0,0 1,3.623 2.15,4.627 4.627,0 0,1 -0.508,3.837 4.815,4.815 0,0 1,-3.6 1.918,3.768 3.768,0 0,0 -0.377,0.06c-6.115,2.172 -9.22,7.534 -8.042,13.975 0.886,4.845 6.714,8.884 12.5,8.6 3.478,-0.157 6.887,-2.461 8.9,-6.011a10.971,10.971 0,0 0,0.547 -10.616s-2.489,-4.483 -2.238,-7.292a3,3 0,1 1,5.977 0.535c-0.083,0.928 0.336,1.732 1.146,3.19l0.392,0.712c2.66,4.917 2.435,11.058 -0.6,16.425 -3.062,5.414 -8.238,8.8 -13.845,9.052Q106.91,121.841 106.515,121.842ZM101.261,88.961h0Z"/>
<path android:fillColor="#933" android:pathData="M90.561,181.513a13.509,13.509 0,0 1,-8.284 -3.081,24.191 24.191,0 0,1 -9.743,-18.767 4.306,4.306 0,0 0,-0.192 -1.508h0a3.453,3.453 0,0 0,-1.01 -0.348,49.859 49.859,0 0,1 -12.286,-4.769c-1.987,-1.065 -2.056,-1 -3.218,0.078a24.615,24.615 0,0 1,-18.191 6.923,14.523 14.523,0 0,1 -13.325,-10.755c-2.229,-8.178 1.234,-14.739 4.5,-19.541l0.372,-0.542c1.553,-2.243 1.507,-2.479 1.031,-3.223 -3.211,-5.024 -5.1,-10.576 -6.763,-15.832 -0.4,-1.264 -0.441,-1.4 -2.416,-1.5 -0.34,-0.018 -0.692,-0.025 -1.047,-0.032 -2.577,-0.053 -7.372,-0.151 -9.182,-5.405a3,3 0,1 1,5.673 -1.954c0.367,1.066 0.721,1.3 3.632,1.36 0.419,0.009 0.833,0.018 1.234,0.039 3.033,0.157 6.334,0.955 7.827,5.682 1.54,4.874 3.28,10 6.1,14.409 2.725,4.265 0.3,7.772 -1.153,9.869l-0.345,0.5c-3.827,5.627 -4.925,9.99 -3.672,14.589a8.432,8.432 0,0 0,7.821 6.339,18.494 18.494,0 0,0 13.823,-5.326c4.035,-3.747 7.348,-2.465 10.137,-0.969a43.924,43.924 0,0 0,10.794 4.208c4.958,1.139 5.742,4.422 5.855,7.483a18.36,18.36 0,0 0,7.41 14.237c3.144,2.424 6.1,2.423 9.287,-0.006 5.045,-3.838 7.534,-8.734 7.4,-14.551 -0.113,-4.813 2.809,-6.3 5.681,-7.13a51.269,51.269 0,0 0,12.317 -5.2c4.6,-2.772 8.739,-2.465 12.65,0.939a16.377,16.377 0,0 0,9.4 3.807,3 3,0 0,1 -0.62,5.968 22.162,22.162 0,0 1,-12.718 -5.248c-1.744,-1.517 -2.967,-1.923 -5.616,-0.326a57.31,57.31 0,0 1,-13.758 5.824,5.639 5.639,0 0,0 -1.3,0.483 3.4,3.4 0,0 0,-0.043 0.739c0.181,7.738 -3.194,14.469 -9.761,19.466A13.665,13.665 0,0 1,90.561 181.513Z"/>
<path android:fillColor="#933" android:pathData="M3.336,97.693a3,3 0,0 1,-2.938 -2.411c-1.31,-6.539 0.619,-12.081 5.735,-16.475a24.129,24.129 0,0 1,15.495 -6.118,4.868 4.868,0 0,0 1.53,-0.217c0.548,-4.076 2.215,-7.56 3.829,-10.931 0.732,-1.53 1.436,-3 2.031,-4.5a27.375,27.375 0,0 1,-7.692 -14.651c-0.961,-5.642 0.55,-10.9 4.146,-14.422s8.824,-4.914 14.383,-3.853c4.179,0.8 9,2.132 13.117,5.954a3.855,3.855 0,0 0,1.132 0.812,4.928 4.928,0 0,0 1.193,-1.545 3,3 0,1 1,5.195 3c-0.577,1 -2.33,4.028 -5.5,4.5 -2.02,0.3 -4.077,-0.5 -6.1,-2.379 -2.991,-2.78 -6.65,-3.784 -10.159,-4.455 -3.651,-0.7 -6.867,0.1 -9.057,2.244s-3.066,5.4 -2.43,9.129a22.088,22.088 0,0 0,7.284 12.645,3 3,0 0,1 0.826,3.143 57.062,57.062 0,0 1,-2.952 6.964c-1.5,3.135 -2.919,6.1 -3.314,9.294 -0.191,1.537 -1.285,5.127 -7.324,5.261a18.288,18.288 0,0 0,-11.719 4.671c-3.489,3 -4.649,6.311 -3.761,10.745a3,3 0,0 1,-2.945 3.59Z"/>
<path android:fillColor="#933" android:pathData="M84.787,90.657c-7.336,0 -14.743,-6.613 -15.356,-13.806 -0.744,-8.715 3.243,-14.34 12.188,-17.2a2.993,2.993 0,0 1,1.168 -0.132c0.092,-0.008 0.182,-0.01 0.279,-0.01 5.525,0.057 9.761,1.586 12.59,4.544 2.811,2.94 4.141,7.191 3.953,12.637 -0.235,6.843 -7.406,13.757 -14.478,13.958C85.017,90.655 84.902,90.657 84.787,90.657ZM83.012,65.513c-5.955,2.009 -8.094,5.077 -7.6,10.828 0.348,4.081 5.309,8.46 9.552,8.313 3.915,-0.111 8.525,-4.461 8.652,-8.166 0.13,-3.77 -0.642,-6.557 -2.293,-8.284C89.651,66.459 86.861,65.554 83.012,65.513Z"/>
<path android:fillColor="#933" android:pathData="M69.168,116.919q-0.432,0 -0.879,-0.024a11.373,11.373 0,0 1,-10.856 -12.293c0.332,-6.714 5.81,-9.6 7.61,-10.552a2.964,2.964 0,0 1,1.652 -0.336c0.082,-0.007 0.166,-0.011 0.25,-0.011h0.784c0.584,0 1.169,0 1.753,0a12.567,12.567 0,0 1,9.1 3.935,10.393 10.393,0 0,1 2.846,7.809C81.053,111.072 77.056,116.919 69.168,116.919ZM67.214,99.703c-2.572,1.483 -3.68,3.021 -3.787,5.2a5.381,5.381 0,0 0,5.181 6.006c6.126,0.331 6.768,-4.824 6.837,-5.859a4.427,4.427 0,0 0,-1.258 -3.324,6.628 6.628,0 0,0 -4.751,-2.017c-0.566,0 -1.13,0 -1.695,0Z"/>
</vector>
================================================
FILE: app/src/main/res/drawable-anydpi-v24/ic_stat_notification_icon.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#FFFFFF"
android:viewportWidth="197.29565"
android:viewportHeight="197.29565">
<group
android:translateX="8.067326"
android:translateY="7.891826">
<path
android:fillColor="#933"
android:pathData="M153.428,154.513a3,3 0,0 1,-2.179 -5.061c3.954,-4.181 2.94,-8.512 0.94,-14.641a9.836,9.836 0,0 0,-2.16 -3.016c-1.918,-2.126 -4.544,-5.037 -3.481,-9.607a25.036,25.036 0,0 1,2.379 -5.815,16.448 16.448,0 0,0 2.06,-5.418 5.11,5.11 0,0 1,0.928 -2.279c0.4,-5.449 5.218,-5.819 7.312,-5.979a22.575,22.575 0,0 0,9.38 -2.993c3.758,-2.1 6.259,-5.346 6.529,-8.479 0.307,-3.58 -2.274,-6.473 -4.494,-8.27a18.574,18.574 0,0 0,-11.278 -4.324c-3.111,-0.1 -6.171,-0.864 -7.481,-5.742 -1.04,-3.876 -2.566,-8.807 -5.149,-12.555 -2.849,-4.133 -2.665,-8.212 0.531,-11.8 2.643,-2.962 3.72,-6.614 4.675,-10.409a8.16,8.16 0,0 0,-1.683 -6.742,9.782 9.782,0 0,0 -7.03,-4.094c-4.975,-0.247 -9.676,1.681 -14.352,5.879 -2.732,2.452 -5.985,2.865 -8.7,1.1a44.8,44.8 0,0 0,-10.077 -4.384c-0.647,-0.222 -1.293,-0.443 -1.937,-0.669 -2.712,-0.953 -5.793,-2.674 -5.557,-7.58 0.132,-2.765 -0.81,-5.645 -3.057,-9.336 -2.113,-3.469 -6.6,-8.73 -12.943,-4.98 -4.54,2.685 -7.255,7.178 -8.069,13.355l-0.09,0.685c-0.879,6.758 -2.2,7.873 -9.457,7.948h-0.032a3,3 0,0 1,-0.031 -6c1.18,-0.012 2.487,-0.026 3.172,-0.111 0.135,-0.586 0.273,-1.649 0.4,-2.611l0.091,-0.7c1.053,-7.984 4.844,-14.116 10.964,-17.735 7.638,-4.519 15.733,-1.828 21.122,7.024 1.958,3.217 4.173,7.571 3.925,12.744 -0.049,1.027 -0.051,1.068 1.551,1.63 0.63,0.222 1.263,0.438 1.895,0.655a50.017,50.017 0,0 1,11.4 5.026c0.18,0.117 0.482,0.314 1.427,-0.533 5.911,-5.307 12.017,-7.729 18.652,-7.407a15.688,15.688 0,0 1,11.559 6.514,14.111 14.111,0 0,1 2.681,11.78c-1.1,4.366 -2.47,8.963 -6.015,12.938 -1.186,1.329 -1.5,2.325 -0.07,4.4 3.1,4.5 4.839,10.062 6,14.4a2.8,2.8 0,0 0,0.459 1.125,4.034 4.034,0 0,0 1.42,0.176 24.447,24.447 0,0 1,14.861 5.658c6.067,4.912 6.99,10.024 6.7,13.447 -0.444,5.167 -4.026,10.1 -9.581,13.2a28.445,28.445 0,0 1,-11.846 3.736,12.5 12.5,0 0,0 -1.762,0.219 3.085,3.085 0,0 0,-0.034 0.433,4.808 4.808,0 0,1 -0.954,2.63l-0.037,0.055a22.335,22.335 0,0 1,-2.636 7.1,20.2 20.2,0 0,0 -1.871,4.43c-0.324,1.394 0.281,2.221 2.092,4.229a14.51,14.51 0,0 1,3.409 5.174c1.759,5.392 4.417,13.539 -2.285,20.625A2.994,2.994 0,0 1,153.428 154.513ZM157.963,108.732Z" />
<path
android:fillColor="#933"
android:pathData="M106.515,121.842c-8.431,0 -16.514,-6.048 -17.883,-13.537 -1.719,-9.4 2.991,-17.532 12,-20.728a5.483,5.483 0,0 1,0.657 -0.186,3 3,0 0,1 2.154,-2.1 2.963,2.963 0,0 1,3.623 2.15,4.627 4.627,0 0,1 -0.508,3.837 4.815,4.815 0,0 1,-3.6 1.918,3.768 3.768,0 0,0 -0.377,0.06c-6.115,2.172 -9.22,7.534 -8.042,13.975 0.886,4.845 6.714,8.884 12.5,8.6 3.478,-0.157 6.887,-2.461 8.9,-6.011a10.971,10.971 0,0 0,0.547 -10.616s-2.489,-4.483 -2.238,-7.292a3,3 0,1 1,5.977 0.535c-0.083,0.928 0.336,1.732 1.146,3.19l0.392,0.712c2.66,4.917 2.435,11.058 -0.6,16.425 -3.062,5.414 -8.238,8.8 -13.845,9.052Q106.91,121.841 106.515,121.842ZM101.261,88.961h0Z" />
<path
android:fillColor="#933"
android:pathData="M90.561,181.513a13.509,13.509 0,0 1,-8.284 -3.081,24.191 24.191,0 0,1 -9.743,-18.767 4.306,4.306 0,0 0,-0.192 -1.508h0a3.453,3.453 0,0 0,-1.01 -0.348,49.859 49.859,0 0,1 -12.286,-4.769c-1.987,-1.065 -2.056,-1 -3.218,0.078a24.615,24.615 0,0 1,-18.191 6.923,14.523 14.523,0 0,1 -13.325,-10.755c-2.229,-8.178 1.234,-14.739 4.5,-19.541l0.372,-0.542c1.553,-2.243 1.507,-2.479 1.031,-3.223 -3.211,-5.024 -5.1,-10.576 -6.763,-15.832 -0.4,-1.264 -0.441,-1.4 -2.416,-1.5 -0.34,-0.018 -0.692,-0.025 -1.047,-0.032 -2.577,-0.053 -7.372,-0.151 -9.182,-5.405a3,3 0,1 1,5.673 -1.954c0.367,1.066 0.721,1.3 3.632,1.36 0.419,0.009 0.833,0.018 1.234,0.039 3.033,0.157 6.334,0.955 7.827,5.682 1.54,4.874 3.28,10 6.1,14.409 2.725,4.265 0.3,7.772 -1.153,9.869l-0.345,0.5c-3.827,5.627 -4.925,9.99 -3.672,14.589a8.432,8.432 0,0 0,7.821 6.339,18.494 18.494,0 0,0 13.823,-5.326c4.035,-3.747 7.348,-2.465 10.137,-0.969a43.924,43.924 0,0 0,10.794 4.208c4.958,1.139 5.742,4.422 5.855,7.483a18.36,18.36 0,0 0,7.41 14.237c3.144,2.424 6.1,2.423 9.287,-0.006 5.045,-3.838 7.534,-8.734 7.4,-14.551 -0.113,-4.813 2.809,-6.3 5.681,-7.13a51.269,51.269 0,0 0,12.317 -5.2c4.6,-2.772 8.739,-2.465 12.65,0.939a16.377,16.377 0,0 0,9.4 3.807,3 3,0 0,1 -0.62,5.968 22.162,22.162 0,0 1,-12.718 -5.248c-1.744,-1.517 -2.967,-1.923 -5.616,-0.326a57.31,57.31 0,0 1,-13.758 5.824,5.639 5.639,0 0,0 -1.3,0.483 3.4,3.4 0,0 0,-0.043 0.739c0.181,7.738 -3.194,14.469 -9.761,19.466A13.665,13.665 0,0 1,90.561 181.513Z" />
<path
android:fillColor="#933"
android:pathData="M3.336,97.693a3,3 0,0 1,-2.938 -2.411c-1.31,-6.539 0.619,-12.081 5.735,-16.475a24.129,24.129 0,0 1,15.495 -6.118,4.868 4.868,0 0,0 1.53,-0.217c0.548,-4.076 2.215,-7.56 3.829,-10.931 0.732,-1.53 1.436,-3 2.031,-4.5a27.375,27.375 0,0 1,-7.692 -14.651c-0.961,-5.642 0.55,-10.9 4.146,-14.422s8.824,-4.914 14.383,-3.853c4.179,0.8 9,2.132 13.117,5.954a3.855,3.855 0,0 0,1.132 0.812,4.928 4.928,0 0,0 1.193,-1.545 3,3 0,1 1,5.195 3c-0.577,1 -2.33,4.028 -5.5,4.5 -2.02,0.3 -4.077,-0.5 -6.1,-2.379 -2.991,-2.78 -6.65,-3.784 -10.159,-4.455 -3.651,-0.7 -6.867,0.1 -9.057,2.244s-3.066,5.4 -2.43,9.129a22.088,22.088 0,0 0,7.284 12.645,3 3,0 0,1 0.826,3.143 57.062,57.062 0,0 1,-2.952 6.964c-1.5,3.135 -2.919,6.1 -3.314,9.294 -0.191,1.537 -1.285,5.127 -7.324,5.261a18.288,18.288 0,0 0,-11.719 4.671c-3.489,3 -4.649,6.311 -3.761,10.745a3,3 0,0 1,-2.945 3.59Z" />
<path
android:fillColor="#933"
android:pathData="M84.787,90.657c-7.336,0 -14.743,-6.613 -15.356,-13.806 -0.744,-8.715 3.243,-14.34 12.188,-17.2a2.993,2.993 0,0 1,1.168 -0.132c0.092,-0.008 0.182,-0.01 0.279,-0.01 5.525,0.057 9.761,1.586 12.59,4.544 2.811,2.94 4.141,7.191 3.953,12.637 -0.235,6.843 -7.406,13.757 -14.478,13.958C85.017,90.655 84.902,90.657 84.787,90.657ZM83.012,65.513c-5.955,2.009 -8.094,5.077 -7.6,10.828 0.348,4.081 5.309,8.46 9.552,8.313 3.915,-0.111 8.525,-4.461 8.652,-8.166 0.13,-3.77 -0.642,-6.557 -2.293,-8.284C89.651,66.459 86.861,65.554 83.012,65.513Z" />
<path
android:fillColor="#933"
android:pathData="M69.168,116.919q-0.432,0 -0.879,-0.024a11.373,11.373 0,0 1,-10.856 -12.293c0.332,-6.714 5.81,-9.6 7.61,-10.552a2.964,2.964 0,0 1,1.652 -0.336c0.082,-0.007 0.166,-0.011 0.25,-0.011h0.784c0.584,0 1.169,0 1.753,0a12.567,12.567 0,0 1,9.1 3.935,10.393 10.393,0 0,1 2.846,7.809C81.053,111.072 77.056,116.919 69.168,116.919ZM67.214,99.703c-2.572,1.483 -3.68,3.021 -3.787,5.2a5.381,5.381 0,0 0,5.181 6.006c6.126,0.331 6.768,-4.824 6.837,-5.859a4.427,4.427 0,0 0,-1.258 -3.324,6.628 6.628,0 0,0 -4.751,-2.017c-0.566,0 -1.13,0 -1.695,0Z" />
</group>
</vector>
================================================
FILE: app/src/main/res/layout/activity_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.main.MainActivity">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="@+id/appBarlayout"
layout="@layout/appbar_layout" />
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingBottom="@dimen/dimen_8"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/item_state" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</LinearLayout>
================================================
FILE: app/src/main/res/layout/activity_state_details.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.details.StateDetailsActivity">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="@+id/appBarlayout"
layout="@layout/appbar_layout" />
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerState"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingBottom="@dimen/dimen_8"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/item_state" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</LinearLayout>
================================================
FILE: app/src/main/res/layout/appbar_layout.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.appbar.AppBarLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/appBarlayout"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
android:background="@color/colorPrimary"
tools:showIn="@layout/activity_main">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|snap|enterAlways"
app:subtitleTextAppearance="@style/ToolBarSubtitle"
app:title="@string/app_name"
app:titleTextColor="@color/color_toolbar_title">
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
================================================
FILE: app/src/main/res/layout/item_district.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen_16"
android:layout_marginTop="@dimen/dimen_8"
android:layout_marginEnd="@dimen/dimen_16"
android:layout_marginBottom="@dimen/dimen_8"
android:padding="@dimen/dimen_8"
app:cardBackgroundColor="@color/colorSurface"
app:cardCornerRadius="@dimen/dimen_16"
app:cardElevation="@dimen/dimen_4">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textNotes"
style="@style/TextLastUpdatedTime"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen_4"
android:paddingStart="@dimen/dimen_16"
android:paddingEnd="@dimen/dimen_16"
android:textAlignment="center"
android:textAllCaps="false"
app:drawableStartCompat="@drawable/ic_info"
app:drawableTint="@color/colorTextLastUpdated"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textDistrictName"
tools:text="@tools:sample/lorem" />
<TextView
android:id="@+id/textDistrictName"
style="@style/TextStateName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen_4"
android:textAlignment="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Maharashtra" />
<ImageView
android:id="@+id/imageView8"
android:layout_width="@dimen/dimen_24"
android:layout_height="@dimen/dimen_24"
android:contentDescription="@string/confirmed"
android:src="@drawable/ic_virus"
android:tint="@color/color_confirmed"
app:layout_constraintBottom_toBottomOf="@+id/imageView9"
app:layout_constraintEnd_toStartOf="@+id/imageView9"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/imageView9" />
<TextView
android:id="@+id/textConfirmed"
style="@style/TextCountSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/color_confirmed"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="@+id/imageView8"
app:layout_constraintStart_toStartOf="@+id/imageView8"
app:layout_constraintTop_toBottomOf="@+id/imageView8"
tools:text="1138" />
<ImageView
android:id="@+id/imageView9"
android:layout_width="@dimen/dimen_24"
android:layout_height="@dimen/dimen_24"
android:contentDescription="@string/active"
android:src="@drawable/ic_patient"
android:tint="@color/color_active"
app:layout_constraintBottom_toBottomOf="@+id/imageView10"
app:layout_constraintEnd_toStartOf="@+id/imageView10"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/imageView8"
app:layout_constraintTop_toTopOf="@+id/imageView10" />
<TextView
android:id="@+id/textActive"
style="@style/TextCountSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/color_active"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="@+id/imageView9"
app:layout_constraintStart_toStartOf="@+id/imageView9"
app:layout_constraintTop_toBottomOf="@+id/imageView9"
tools:text="1138" />
<ImageView
android:id="@+id/imageView10"
android:layout_width="@dimen/dimen_24"
android:layout_height="@dimen/dimen_24"
android:contentDescription="@string/recovered"
android:src="@drawable/ic_heart"
android:tint="@color/color_recovered"
app:layout_constraintBottom_toBottomOf="@+id/imageView11"
app:layout_constraintEnd_toStartOf="@+id/imageView11"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/imageView9"
app:layout_constraintTop_toTopOf="@+id/imageView11" />
<TextView
android:id="@+id/textRecovered"
style="@style/TextCountSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/color_recovered"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="@+id/imageView10"
app:layout_constraintStart_toStartOf="@+id/imageView10"
app:layout_constraintTop_toBottomOf="@+id/imageView10"
tools:text="1138" />
<ImageView
android:id="@+id/imageView11"
android:layout_width="@dimen/dimen_24"
android:layout_height="@dimen/dimen_24"
android:layout_marginTop="@dimen/dimen_8"
android:contentDescription="@string/deaths"
android:src="@drawable/ic_death"
android:tint="@color/color_death"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/imageView10"
app:layout_constraintTop_toBottomOf="@+id/textNotes" />
<TextView
android:id="@+id/textDeath"
style="@style/TextCountSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:textColor="@color/color_death"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/imageView11"
app:layout_constraintStart_toStartOf="@+id/imageView11"
app:layout_constraintTop_toBottomOf="@+id/imageView11"
tools:text="1138" />
<ImageView
android:id="@+id/imageView12"
android:layout_width="@dimen/dimen_16"
android:layout_height="@dimen/dimen_16"
android:layout_marginStart="@dimen/dimen_4"
android:tint="@color/color_confirmed"
app:layout_constraintBottom_toTopOf="@+id/textDistrictNewConfirm"
app:layout_constraintStart_toEndOf="@+id/imageView8"
app:layout_constraintTop_toTopOf="@+id/imageView8"
app:srcCompat="@drawable/ic_trending_up" />
<ImageView
android:id="@+id/imageView13"
android:layout_width="@dimen/dimen_16"
android:layout_height="@dimen/dimen_16"
android:layout_marginStart="@dimen/dimen_4"
android:tint="@color/color_recovered"
app:layout_constraintBottom_toTopOf="@+id/textDistrictNewRecover"
app:layout_constraintStart_toEndOf="@+id/imageView10"
app:layout_constraintTop_toTopOf="@+id/imageView10"
app:srcCompat="@drawable/ic_trending_up" />
<ImageView
android:id="@+id/imageView14"
android:layout_width="@dimen/dimen_16"
android:layout_height="@dimen/dimen_16"
android:layout_marginStart="@dimen/dimen_4"
android:tint="@color/color_death"
app:layout_constraintBottom_toBottomOf="@+id/imageView11"
app:layout_constraintStart_toEndOf="@+id/imageView11"
app:layout_constraintTop_toTopOf="@+id/imageView11"
app:layout_constraintVertical_bias="0.0"
app:srcCompat="@drawable/ic_trending_up" />
<TextView
android:id="@+id/textDistrictNewConfirm"
style="@style/TextCountDelta"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/color_confirmed"
app:layout_constraintEnd_toEndOf="@+id/imageView12"
app:layout_constraintStart_toStartOf="@+id/imageView12"
app:layout_constraintTop_toBottomOf="@+id/imageView12"
tools:text="1338" />
<TextView
android:id="@+id/textDistrictNewRecover"
style="@style/TextCountDelta"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/color_recovered"
app:layout_constraintEnd_toEndOf="@+id/imageView13"
app:layout_constraintStart_toStartOf="@+id/imageView13"
app:layout_constraintTop_toBottomOf="@+id/imageView13"
tools:text="1338" />
<TextView
android:id="@+id/textDistrictNewDeath"
style="@style/TextCountDelta"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/color_death"
app:layout_constraintEnd_toEndOf="@+id/imageView14"
app:layout_constraintStart_toStartOf="@+id/imageView14"
app:layout_constraintTop_toBottomOf="@+id/imageView14"
tools:text="1338" />
<androidx.constraintlayout.widget.Group
android:id="@+id/groupStateNewConfirm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:constraint_referenced_ids="textDistrictNewConfirm,imageView12"
tools:layout_editor_absoluteX="@dimen/dimen_8"
tools:layout_editor_absoluteY="@dimen/dimen_8" />
<androidx.constraintlayout.widget.Group
android:id="@+id/groupStateNewRecover"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:constraint_referenced_ids="textDistrictNewRecover,imageView13"
tools:layout_editor_absoluteX="@dimen/dimen_8"
tools:layout_editor_absoluteY="@dimen/dimen_8" />
<androidx.constraintlayout.widget.Group
android:id="@+id/groupStateNewDeaths"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:constraint_referenced_ids="textDistrictNewDeath,imageView14"
tools:layout_editor_absoluteX="@dimen/dimen_8"
tools:layout_editor_absoluteY="@dimen/dimen_8" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
================================================
FILE: app/src/main/res/layout/item_state.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen_16"
android:layout_marginTop="@dimen/dimen_8"
android:layout_marginEnd="@dimen/dimen_16"
android:layout_marginBottom="@dimen/dimen_8"
android:padding="@dimen/dimen_8"
app:cardBackgroundColor="@color/colorSurface"
app:cardCornerRadius="@dimen/dimen_16"
app:cardElevation="@dimen/dimen_4">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textState"
style="@style/TextStateName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen_4"
android:textAlignment="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Maharashtra" />
<TextView
android:id="@+id/textLastUpdatedView"
style="@style/TextLastUpdatedTime"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimen_4"
android:textAlignment="center"
android:textAllCaps="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textState"
tools:text="Last Updated: 1 minutes ago" />
<ImageView
android:id="@+id/imageView8"
android:layout_width="@dimen/dimen_24"
android:layout_height="@dimen/dimen_24"
android:contentDescription="@string/confirmed"
android:src="@drawable/ic_virus"
android:tint="@color/color_confirmed"
app:layout_constraintBottom_toBottomOf="@+id/imageView9"
app:layout_constraintEnd_toStartOf="@+id/imageView9"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/imageView9" />
<TextView
android:id="@+id/textConfirmed"
style="@style/TextCountSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/color_confirmed"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="@+id/imageView8"
app:layout_constraintStart_toStartOf="@+id/imageView8"
app:layout_constraintTop_toBottomOf="@+id/imageView8"
tools:text="1138" />
<ImageView
android:id="@+id/imageView9"
android:layout_width="@dimen/dimen_24"
android:layout_height="@dimen/dimen_24"
android:contentDescription="@string/active"
android:src="@drawable/ic_patient"
android:tint="@color/color_active"
app:layout_constraintBottom_toBottomOf="@+id/imageView10"
app:layout_constraintEnd_toStartOf="@+id/imageView10"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/imageView8"
app:layout_constraintTop_toTopOf="@+id/imageView10" />
<TextView
android:id="@+id/textActive"
style="@style/TextCountSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/color_active"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="@+id/imageView9"
app:layout_constraintStart_toStartOf="@+id/imageView9"
app:layout_constraintTop_toBottomOf="@+id/imageView9"
tools:text="1138" />
<ImageView
android:id="@+id/imageView10"
android:layout_width="@dimen/dimen_24"
android:layout_height="@dimen/dimen_24"
android:contentDescription="@string/recovered"
android:src="@drawable/ic_heart"
android:tint="@color/color_recovered"
app:layout_constraintBottom_toBottomOf="@+id/imageView11"
app:layout_constraintEnd_toStartOf="@+id/imageView11"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/imageView9"
app:layout_constraintTop_toTopOf="@+id/imageView11" />
<TextView
android:id="@+id/textRecovered"
style="@style/TextCountSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/color_recovered"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="@+id/imageView10"
app:layout_constraintStart_toStartOf="@+id/imageView10"
app:layout_constraintTop_toBottomOf="@+id/imageView10"
tools:text="1138" />
<ImageView
android:id="@+id/imageView11"
android:layout_width="@dimen/dimen_24"
android:layout_height="@dimen/dimen_24"
android:layout_marginTop="@dimen/dimen_8"
android:contentDescription="@string/deaths"
android:src="@drawable/ic_death"
android:tint="@color/color_death"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/imageView10"
app:layout_constraintTop_toBottomOf="@+id/textLastUpdatedView" />
<TextView
android:id="@+id/textDeath"
style="@style/TextCountSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/color_death"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/imageView11"
app:layout_constraintStart_toStartOf="@+id/imageView11"
app:layout_constraintTop_toBottomOf="@+id/imageView11"
tools:text="1138" />
<ImageView
android:id="@+id/imageView12"
android:layout_width="@dimen/dimen_16"
android:layout_height="@dimen/dimen_16"
android:layout_marginStart="@dimen/dimen_4"
android:tint="@color/color_confirmed"
app:layout_constraintBottom_toBottomOf="@+id/imageView8"
app:layout_constraintStart_toEndOf="@+id/imageView8"
app:layout_constraintTop_toTopOf="@+id/imageView8"
app:layout_constraintVertical_bias="0.0"
app:srcCompat="@drawable/ic_trending_up" />
<ImageView
android:id="@+id/imageView13"
android:layout_width="@dimen/dimen_16"
android:layout_height="@dimen/dimen_16"
android:layout_marginStart="@dimen/dimen_4"
android:tint="@color/color_recovered"
app:layout_constraintBottom_toBottomOf="@+id/imageView10"
app:layout_constraintStart_toEndOf="@+id/imageView10"
app:layout_constraintTop_toTopOf="@+id/imageView10"
app:layout_constraintVertical_bias="0.0"
app:srcCompat="@drawable/ic_trending_up" />
<ImageView
android:id="@+id/imageView14"
android:layout_width="@dimen/dimen_16"
android:layout_height="@dimen/dimen_16"
android:layout_marginStart="@dimen/dimen_4"
android:tint="@color/color_death"
app:layout_constraintBottom_toBottomOf="@+id/imageView11"
app:layout_constraintStart_toEndOf="@+id/imageView11"
app:layout_constraintTop_toTopOf="@+id/imageView11"
app:layout_constraintVertical_bias="0.0"
app:srcCompat="@drawable/ic_trending_up" />
<TextView
android:id="@+id/textStateNewConfirm"
style="@style/TextCountDelta"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/color_confirmed"
app:layout_constraintEnd_toEndOf="@+id/imageView12"
app:layout_constraintStart_toStartOf="@+id/imageView12"
app:layout_constraintTop_toBottomOf="@+id/imageView12"
tools:text="1338" />
<TextView
android:id="@+id/textStateNewRecover"
style="@style/TextCountDelta"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/color_recovered"
app:layout_constraintEnd_toEndOf="@+id/imageView13"
app:layout_constraintStart_toStartOf="@+id/imageView13"
app:layout_constraintTop_toBottomOf="@+id/imageView13"
tools:text="1338" />
<TextView
android:id="@+id/textStateNewDeath"
style="@style/TextCountDelta"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/color_death"
app:layout_constraintEnd_toEndOf="@+id/imageView14"
app:layout_constraintStart_toStartOf="@+id/imageView14"
app:layout_constraintTop_toBottomOf="@+id/imageView14"
tools:text="1338" />
<androidx.constraintlayout.widget.Group
android:id="@+id/groupStateNewConfirm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:constraint_referenced_ids="textStateNewConfirm,imageView12"
tools:layout_editor_absoluteX="@dimen/dimen_84"
tools:layout_editor_absoluteY="@dimen/dimen_84" />
<androidx.constraintlayout.widget.Group
android:id="@+id/groupStateNewRecover"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:constraint_referenced_ids="textStateNewRecover,imageView13"
tools:layout_editor_absoluteX="@dimen/dimen_84"
tools:layout_editor_absoluteY="@dimen/dimen_84" />
<androidx.constraintlayout.widget.Group
android:id="@+id/groupStateNewDeaths"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:constraint_referenced_ids="textStateNewDeath,imageView14"
tools:layout_editor_absoluteX="@dimen/dimen_84"
tools:layout_editor_absoluteY="@dimen/dimen_84" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
================================================
FILE: app/src/main/res/layout/item_total.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/dimen_4"
tools:context=".ui.main.MainActivity">
<!-- Confirmed Card view Tab-->
<com.google.android.material.card.MaterialCardView
android:id="@+id/confirmedLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen_16"
android:layout_marginTop="@dimen/dimen_8"
android:layout_marginEnd="@dimen/dimen_8"
android:layout_marginBottom="@dimen/dimen_8"
app:cardCornerRadius="@dimen/dimen_16"
app:cardElevation="@dimen/dimen_4"
app:cardBackgroundColor="@color/colorSurface"
app:layout_constraintBottom_toTopOf="@+id/recoverLayout"
app:layout_constraintEnd_toStartOf="@+id/activeLayout"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/dimen_8">
<ImageView
android:id="@+id/imageView2"
style="@style/ImageIcon"
android:layout_width="@dimen/dimen_72"
android:layout_height="@dimen/dimen_72"
android:layout_marginTop="@dimen/dimen_16"
android:contentDescription="@string/confirmed"
android:src="@drawable/ic_virus"
android:tint="@color/color_confirmed"
app:layout_constraintBottom_toTopOf="@+id/textConfirmed"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/imageView"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/imageView"
android:layout_width="@dimen/dimen_24"
android:layout_height="@dimen/dimen_24"
android:layout_gravity="center"
android:layout_marginTop="@dimen/dimen_4"
android:contentDescription="@string/confirmed"
android:src="@drawable/ic_trending_up"
android:tint="@color/color_confirmed"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textNewConfirmed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/dimen_4"
android:textColor="@color/color_confirmed"
android:textSize="12sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="@+id/imageView"
app:layout_constraintStart_toStartOf="@+id/imageView"
app:layout_constraintTop_toBottomOf="@+id/imageView"
tools:text="1138" />
<TextView
android:id="@+id/textConfirmed"
style="@style/TextCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/color_confirmed"
app:layout_constraintBottom_toTopOf="@+id/textView"
app:layout_constraintEnd_toEndOf="@+id/imageView2"
app:layout_constraintStart_toStartOf="@+id/imageView2"
app:layout_constraintTop_toBottomOf="@+id/imageView2"
tools:text="1138" />
<TextView
android:id="@+id/textView"
style="@style/TextTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen_16"
android:text="@string/confirmed"
android:textColor="@color/color_confirmed"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/textConfirmed"
app:layout_constraintStart_toStartOf="@+id/textConfirmed"
app:layout_constraintTop_toBottomOf="@+id/textConfirmed" />
<androidx.constraintlayout.widget.Group
android:id="@+id/groupNewConfirmed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:constraint_referenced_ids="imageView,textNewConfirmed" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
<!-- Active Card view Tab -->
<com.google.android.material.card.MaterialCardView
android:id="@+id/activeLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen_8"
android:layout_marginTop="@dimen/dimen_8"
android:layout_marginEnd="@dimen/dimen_16"
android:layout_marginBottom="@dimen/dimen_8"
app:cardCornerRadius="@dimen/dimen_16"
app:cardElevation="@dimen/dimen_4"
app:cardBackgroundColor="@color/colorSurface"
app:layout_constraintBottom_toTopOf="@+id/deathLayout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/confirmedLayout"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/dimen_8">
<ImageView
android:id="@+id/imageView3"
style="@style/ImageIcon"
android:layout_width="@dimen/dimen_72"
android:layout_height="@dimen/dimen_72"
android:layout_marginTop="@dimen/dimen_16"
android:contentDescription="@string/active"
android:src="@drawable/ic_patient"
android:tint="@color/color_active"
app:layout_constraintBottom_toTopOf="@+id/textActive"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textActive"
style="@style/TextCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/color_active"
app:layout_constraintBottom_toTopOf="@+id/textView2"
app:layout_constraintEnd_toEndOf="@+id/imageView3"
app:layout_constraintStart_toStartOf="@+id/imageView3"
app:layout_constraintTop_toBottomOf="@+id/imageView3"
tools:text="1138" />
<TextView
android:id="@+id/textView2"
style="@style/TextTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen_16"
android:text="@string/active"
android:textColor="@color/color_active"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/textActive"
app:layout_constraintStart_toStartOf="@+id/textActive"
app:layout_constraintTop_toBottomOf="@+id/textActive" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
<!-- Recovered Card view Tab -->
<com.google.android.material.card.MaterialCardView
android:id="@+id/recoverLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen_16"
android:layout_marginTop="@dimen/dimen_8"
android:layout_marginEnd="@dimen/dimen_8"
app:cardCornerRadius="@dimen/dimen_16"
app:cardElevation="@dimen/dimen_4"
app:cardBackgroundColor="@color/colorSurface"
app:layout_constraintBottom_toBottomOf="@+id/deathLayout"
app:layout_constraintEnd_toStartOf="@+id/deathLayout"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/confirmedLayout">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/dimen_8">
<ImageView
android:id="@+id/imageView4"
style="@style/ImageIcon"
android:layout_width="@dimen/dimen_72"
android:layout_height="@dimen/dimen_72"
android:layout_marginTop="@dimen/dimen_16"
android:contentDescription="@string/recovered"
android:src="@drawable/ic_heart"
android:tint="@color/color_recovered"
app:layout_constraintBottom_toTopOf="@+id/textRecovered"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/imageView5"
android:layout_width="@dimen/dimen_24"
android:layout_height="@dimen/dimen_24"
android:layout_marginTop="@dimen/dimen_4"
android:contentDescription="@string/recovered"
android:src="@drawable/ic_trending_up"
android:tint="@color/color_recovered"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textNewRecovered"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/dimen_4"
android:textColor="@color/color_recovered"
android:textSize="12sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="@+id/imageView5"
app:layout_constraintStart_toStartOf="@+id/imageView5"
app:layout_constraintTop_toBottomOf="@+id/imageView5"
tools:text="1138" />
<TextView
android:id="@+id/textRecovered"
style="@style/TextCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/color_recovered"
app:layout_constraintBottom_toTopOf="@+id/textView3"
app:layout_constraintEnd_toEndOf="@+id/imageView4"
app:layout_constraintStart_toStartOf="@+id/imageView4"
app:layout_constraintTop_toBottomOf="@+id/imageView4"
tools:text="1138" />
<TextView
android:id="@+id/textView3"
style="@style/TextTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen_16"
android:text="@string/recovered"
android:textColor="@color/color_recovered"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/textRecovered"
app:layout_constraintStart_toStartOf="@+id/textRecovered"
app:layout_constraintTop_toBottomOf="@+id/textRecovered" />
<androidx.constraintlayout.widget.Group
android:id="@+id/groupNewRecovered"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:constraint_referenced_ids="imageView5,textNewRecovered" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
<!-- Death Card view Tab -->
<com.google.android.material.card.MaterialCardView
android:id="@+id/deathLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dimen_8"
android:layout_marginTop="@dimen/dimen_8"
android:layout_marginEnd="@dimen/dimen_16"
android:layout_marginBottom="@dimen/dimen_8"
app:cardCornerRadius="@dimen/dimen_16"
app:cardElevation="@dimen/dimen_4"
app:cardBackgroundColor="@color/colorSurface"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/recoverLayout"
app:layout_constraintTop_toBottomOf="@+id/activeLayout">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/dimen_8">
<ImageView
android:id="@+id/imageView6"
style="@style/ImageIcon"
android:layout_width="@dimen/dimen_72"
android:layout_height="@dimen/dimen_72"
android:layout_marginTop="@dimen/dimen_16"
android:contentDescription="@string/deaths"
android:src="@drawable/ic_death"
android:tint="@color/color_death"
app:layout_constraintBottom_toTopOf="@+id/textDeceased"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/imageView7"
android:layout_width="@dimen/dimen_24"
android:layout_height="@dimen/dimen_24"
android:layout_marginTop="@dimen/dimen_4"
android:contentDescription="@string/deaths"
android:src="@drawable/ic_trending_up"
android:tint="@color/color_death"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textNewDeaths"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/dimen_4"
android:textColor="@color/color_death"
android:textSize="12sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="@+id/imageView7"
app:layout_constraintStart_toStartOf="@+id/imageView7"
app:layout_constraintTop_toBottomOf="@+id/imageView7"
tools:text="1138" />
<TextView
android:id="@+id/textDeceased"
style="@style/TextCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/color_death"
app:layout_constraintBottom_toTopOf="@+id/textView4"
app:layout_constraintEnd_toEndOf="@+id/imageView6"
app:layout_constraintStart_toStartOf="@+id/imageView6"
app:layout_constraintTop_toBottomOf="@+id/imageView6"
tools:text="1138" />
<TextView
android:id="@+id/textView4"
style="@style/TextTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dimen_16"
android:text="@string/deaths"
android:textColor="@color/color_death"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/textDeceased"
app:layout_constraintStart_toStartOf="@+id/textDeceased"
app:layout_constraintTop_toBottomOf="@+id/textDeceased" />
<androidx.constraintlayout.widget.Group
android:id="@+id/groupNewDeaths"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:constraint_referenced_ids="textNewDeaths,imageView7" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
</androidx.constraintlayout.widget.ConstraintLayout>
================================================
FILE: app/src/main/res/menu/toolbar_menu.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menu_uimode"
android:icon="@drawable/ic_lightbulb"
app:showAsAction="always"
android:title="@string/menu_ui_mode" />
</menu>
================================================
FILE: app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
================================================
FILE: app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
================================================
FILE: app/src/main/res/values/bool.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="windowLightStatusBar">true</bool>
</resources>
================================================
FILE: app/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#FFFFFF</color>
<color name="colorPrimaryDark">#0E0E0E</color>
<color name="colorAccent">#000</color>
<color name="background">#F1F1F1</color>
<!--Tint Colors for the Icons and Text-->
<color name="color_confirmed">#D32F2F</color>
<color name="color_recovered">#388E3C</color>
<color name="color_active">#1976D2</color>
<color name="color_death">#6D6D6D</color>
<!-- Text Colors-->
<color name="colorSurface">#FFFFFF</color>
<color name="colorTextLastUpdated">#000</color>
<color name="colorTextDefault">#000</color>
<color name="color_toolbar_title">#000</color>
<color name="color_bulb_icon">#000</color>
</resources>
================================================
FILE: app/src/main/res/values/dimens.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="dimen_16">16dp</dimen>
<dimen name="dimen_4">4dp</dimen>
<dimen name="dimen_8">8dp</dimen>
<dimen name="dimen_24">24dp</dimen>
<dimen name="dimen_72">72dp</dimen>
</resources>
================================================
FILE: app/src/main/res/values/ic_launcher_background.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#FFFFFF</color>
</resources>
================================================
FILE: app/src/main/res/values/strings.xml
================================================
<resources>
<string name="app_name">COVID19 Notifier 🇮🇳</string>
<string name="confirmed">Confirmed</string>
<string name="active">Active</string>
<string name="recovered">Recovered</string>
<string name="deaths">Deaths</string>
<string name="default_notification_channel_id">default</string>
<string name="text_confirmed_cases">Confirmed Cases : %s</string>
<string name="text_last_updated">Last Updated : %s</string>
<string name="default_notification_channel_name">Covid-19 India</string>
<string name="menu_ui_mode">Dark Mode</string>
</resources>
================================================
FILE: app/src/main/res/values/styles.xml
================================================
<resources>
<style name="TextTitle">
<item name="android:layout_gravity">center</item>
<item name="android:textAppearance">@style/TextAppearance.MaterialComponents.Headline6
</item>
</style>
<style name="ToolBarSubtitle" parent="TextAppearance.MaterialComponents.Subtitle2">
<item name="android:textColor">@color/colorTextLastUpdated</item>
</style>
<style name="TextStateName">
<item name="android:layout_gravity">center</item>
<item name="android:textAppearance">@style/TextAppearance.MaterialComponents.Body1</item>
<item name="android:textColor">@color/colorAccent</item>
</style>
<style name="TextLastUpdatedTime">
<item name="android:layout_gravity">center</item>
<item name="android:textStyle">italic</item>
<item name="android:textAppearance">@style/TextAppearance.MaterialComponents.Overline
</item>
</style>
<style name="ImageIcon">
<item name="android:layout_gravity">center</item>
<item name="android:tint">?colorAccent</item>
</style>
<style name="TextCount">
<item name="android:textAppearance">@style/TextAppearance.MaterialComponents.Headline5
</item>
<item name="android:textColor">@android:color/white</item>
<item name="android:textStyle">bold</item>
<item name="android:layout_gravity">center</item>
</style>
<style name="TextCountSmall">
<item name="android:textAppearance">@style/TextAppearance.MaterialComponents.Subtitle2
</item>
<item name="android:textStyle">bold</item>
<item name="android:layout_gravity">center</item>
<item name="android:layout_margin">4dp</item>
</style>
<style name="LayoutStyle">
<item name="android:orientation">vertical</item>
<item name="android:padding">@dimen/dimen_16</item>
<item name="android:gravity">center_vertical</item>
<item name="android:layout_margin">4dp</item>
</style>
<style name="TextCountDelta">
<item name="android:textAppearance">@style/TextAppearance.MaterialComponents.Overline</item>
<item name="android:textStyle">bold</item>
</style>
</resources>
================================================
FILE: app/src/main/res/values/theme.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="colorSurface">@color/colorSurface</item>
<item name="android:colorBackground">@color/background</item>
<item name="android:statusBarColor">@color/colorPrimary</item>
<item name="android:windowLightStatusBar" tools:targetApi="m">@bool/windowLightStatusBar
</item>
<item name="fontFamily">@font/google_sans</item>
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="fontFamily">@font/google_sans</item>
</style>
</resources>
================================================
FILE: app/src/main/res/values-night/bool.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="windowLightStatusBar">false</bool>
</resources>
================================================
FILE: app/src/main/res/values-night/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#0E0E0E</color>
<color name="colorPrimaryDark">#000000</color>
<color name="colorAccent">#F1FFAA00</color>
<color name="background">#000000</color>
<color name="colorSurface">#121212</color>
<!--Tint Colors for the Icons and Text-->
<color name="color_confirmed">#EF6C6C</color>
<color name="color_recovered">#6BC697</color>
<color name="color_active">#65D1D6</color>
<color name="color_death">#A0A0A0</color>
<!-- Text Colors-->
<color name="colorTextLastUpdated">#F1E5BC</color>
<color name="colorTextDefault">#DEFFFFFF</color>
<color name="color_toolbar_title">#F1FFAA00</color>
<color name="color_bulb_icon">#F1FFAA00</color>
</resources>
================================================
FILE: app/src/test/java/dev/shreyaspatil/covid19notify/ExampleUnitTest.kt
================================================
package dev.shreyaspatil.covid19notify
import org.junit.Assert.assertEquals
import org.junit.Test
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}
================================================
FILE: build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.4.21'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.0.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
#Mon Mar 30 19:22:13 IST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
================================================
FILE: gradle.properties
================================================
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app's APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
================================================
FILE: gradlew
================================================
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ]; do
ls=$(ls -ld "$PRG")
link=$(expr "$ls" : '.*-> \(.*\)$')
if expr "$link" : '/.*' >/dev/null; then
PRG="$link"
else
PRG=$(dirname "$PRG")"/$link"
fi
done
SAVED="$(pwd)"
cd "$(dirname \"$PRG\")/" >/dev/null
APP_HOME="$(pwd -P)"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=$(basename "$0")
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn() {
echo "$*"
}
die() {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$(uname)" in
CYGWIN*)
cygwin=true
;;
Darwin*)
darwin=true
;;
MINGW*)
msys=true
;;
NONSTOP*)
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ]; then
if [ -x "$JAVA_HOME/jre/sh/java" ]; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ]; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ]; then
MAX_FD_LIMIT=$(ulimit -H -n)
if [ $? -eq 0 ]; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ]; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ]; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
APP_HOME=$(cygpath --path --mixed "$APP_HOME")
CLASSPATH=$(cygpath --path --mixed "$CLASSPATH")
JAVACMD=$(cygpath --unix "$JAVACMD")
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=$(find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null)
SEP=""
for dir in $ROOTDIRSRAW; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ]; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@"; do
CHECK=$(echo "$arg" | egrep -c "$OURCYGPATTERN" -)
CHECK2=$(echo "$arg" | egrep -c "^-") ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ]; then ### Added a condition
eval $(echo args$i)=$(cygpath --path --ignore --mixed "$arg")
else
eval $(echo args$i)="\"$arg\""
fi
i=$((i + 1))
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save() {
for i; do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/"; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
================================================
FILE: gradlew.bat
================================================
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
================================================
FILE: settings.gradle
================================================
rootProject.name='Covid19Notify'
include ':app'
gitextract_cjuovg5p/ ├── .github/ │ ├── CODEOWNERS │ ├── FUNDING.yml │ ├── dependabot.yml │ └── workflows/ │ └── Build.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── app/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── dev/ │ │ └── shreyaspatil/ │ │ └── covid19notify/ │ │ └── ExampleInstrumentedTest.kt │ ├── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── dev/ │ │ │ └── shreyaspatil/ │ │ │ └── covid19notify/ │ │ │ ├── CovidNotifyApp.kt │ │ │ ├── api/ │ │ │ │ └── Covid19IndiaApiService.kt │ │ │ ├── di/ │ │ │ │ ├── NetworkModule.kt │ │ │ │ └── ViewModelModule.kt │ │ │ ├── model/ │ │ │ │ ├── Details.kt │ │ │ │ ├── StateDetails.kt │ │ │ │ └── StateResponse.kt │ │ │ ├── repository/ │ │ │ │ ├── CovidIndiaRepository.kt │ │ │ │ └── NetworkBoundRepository.kt │ │ │ ├── ui/ │ │ │ │ ├── adapter/ │ │ │ │ │ └── TotalAdapter.kt │ │ │ │ ├── details/ │ │ │ │ │ ├── StateDetailsActivity.kt │ │ │ │ │ ├── StateDetailsViewModel.kt │ │ │ │ │ └── adapter/ │ │ │ │ │ └── DistrictsAdapter.kt │ │ │ │ └── main/ │ │ │ │ ├── MainActivity.kt │ │ │ │ ├── MainViewModel.kt │ │ │ │ └── adapter/ │ │ │ │ └── ItemAdapter.kt │ │ │ ├── utils/ │ │ │ │ ├── NetworkUtils.kt │ │ │ │ ├── State.kt │ │ │ │ ├── ThemeUtils.kt │ │ │ │ └── TimeUtils.kt │ │ │ └── worker/ │ │ │ └── NotificationWorker.kt │ │ └── res/ │ │ ├── drawable/ │ │ │ ├── ic_death.xml │ │ │ ├── ic_heart.xml │ │ │ ├── ic_info.xml │ │ │ ├── ic_launcher_foreground.xml │ │ │ ├── ic_lightbulb.xml │ │ │ ├── ic_patient.xml │ │ │ ├── ic_settings.xml │ │ │ ├── ic_trending_up.xml │ │ │ └── ic_virus.xml │ │ ├── drawable-anydpi-v24/ │ │ │ └── ic_stat_notification_icon.xml │ │ ├── layout/ │ │ │ ├── activity_main.xml │ │ │ ├── activity_state_details.xml │ │ │ ├── appbar_layout.xml │ │ │ ├── item_district.xml │ │ │ ├── item_state.xml │ │ │ └── item_total.xml │ │ ├── menu/ │ │ │ └── toolbar_menu.xml │ │ ├── mipmap-anydpi-v26/ │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ ├── values/ │ │ │ ├── bool.xml │ │ │ ├── colors.xml │ │ │ ├── dimens.xml │ │ │ ├── ic_launcher_background.xml │ │ │ ├── strings.xml │ │ │ ├── styles.xml │ │ │ └── theme.xml │ │ └── values-night/ │ │ ├── bool.xml │ │ └── colors.xml │ └── test/ │ └── java/ │ └── dev/ │ └── shreyaspatil/ │ └── covid19notify/ │ └── ExampleUnitTest.kt ├── build.gradle ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat └── settings.gradle
Condensed preview — 71 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (165K chars).
[
{
"path": ".github/CODEOWNERS",
"chars": 16,
"preview": "* @PatilShreyas\n"
},
{
"path": ".github/FUNDING.yml",
"chars": 575,
"preview": "# These are supported funding model platforms\n\ngithub: #\npatreon: # Replace with a single Patreon username\nopen_collecti"
},
{
"path": ".github/dependabot.yml",
"chars": 432,
"preview": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where "
},
{
"path": ".github/workflows/Build.yml",
"chars": 928,
"preview": "name: Build\non: [push, pull_request]\n\njobs:\n test:\n name: Run Unit Tests\n runs-on: ubuntu-18.04\n\n steps:\n "
},
{
"path": ".gitignore",
"chars": 431,
"preview": "#built application files\n*.apk\n*.ap_\n\n# files for the dex VM\n*.dex\n\n# Java class files\n*.class\n\n# generated files\nbin/\ng"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 3355,
"preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
},
{
"path": "CONTRIBUTING.md",
"chars": 355,
"preview": "## Feeling Awesome! Thanks for thinking about this.\n\nYou can contribute us by filing issues, bugs and PRs.\n\n### Contribu"
},
{
"path": "LICENSE",
"chars": 1070,
"preview": "MIT License\n\nCopyright (c) 2020 Shreyas Patil\n\nPermission is hereby granted, free of charge, to any person obtaining a c"
},
{
"path": "README.md",
"chars": 6403,
"preview": "<p align=\"center\">\n <img src=\"app/src/main/ic_launcher-playstore.png\" height=\"200\"/>\n</p>\n\n# COVID19 Notifier - India 🇮"
},
{
"path": "app/.gitignore",
"chars": 7,
"preview": "/build\n"
},
{
"path": "app/build.gradle",
"chars": 3510,
"preview": "apply plugin: 'com.android.application'\napply plugin: 'kotlin-android'\napply plugin: 'kotlin-kapt'\napply plugin: 'kotlin"
},
{
"path": "app/proguard-rules.pro",
"chars": 751,
"preview": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguar"
},
{
"path": "app/src/androidTest/java/dev/shreyaspatil/covid19notify/ExampleInstrumentedTest.kt",
"chars": 697,
"preview": "package dev.shreyaspatil.covid19notify\n\nimport androidx.test.ext.junit.runners.AndroidJUnit4\nimport androidx.test.platfo"
},
{
"path": "app/src/main/AndroidManifest.xml",
"chars": 1444,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:to"
},
{
"path": "app/src/main/java/dev/shreyaspatil/covid19notify/CovidNotifyApp.kt",
"chars": 757,
"preview": "package dev.shreyaspatil.covid19notify\n\nimport android.app.Application\nimport dev.shreyaspatil.covid19notify.di.networkM"
},
{
"path": "app/src/main/java/dev/shreyaspatil/covid19notify/api/Covid19IndiaApiService.kt",
"chars": 540,
"preview": "package dev.shreyaspatil.covid19notify.api\n\nimport dev.shreyaspatil.covid19notify.model.StateDetailsResponse\nimport dev."
},
{
"path": "app/src/main/java/dev/shreyaspatil/covid19notify/di/NetworkModule.kt",
"chars": 1867,
"preview": "package dev.shreyaspatil.covid19notify.di\n\nimport android.content.Context\nimport com.squareup.moshi.Moshi\nimport com.squ"
},
{
"path": "app/src/main/java/dev/shreyaspatil/covid19notify/di/ViewModelModule.kt",
"chars": 569,
"preview": "package dev.shreyaspatil.covid19notify.di\n\nimport dev.shreyaspatil.covid19notify.ui.details.StateDetailsViewModel\nimport"
},
{
"path": "app/src/main/java/dev/shreyaspatil/covid19notify/model/Details.kt",
"chars": 702,
"preview": "package dev.shreyaspatil.covid19notify.model\n\nimport android.os.Parcelable\nimport com.squareup.moshi.Json\nimport kotlinx"
},
{
"path": "app/src/main/java/dev/shreyaspatil/covid19notify/model/StateDetails.kt",
"chars": 771,
"preview": "package dev.shreyaspatil.covid19notify.model\n\nimport android.os.Parcelable\nimport com.squareup.moshi.JsonClass\nimport ko"
},
{
"path": "app/src/main/java/dev/shreyaspatil/covid19notify/model/StateResponse.kt",
"chars": 268,
"preview": "package dev.shreyaspatil.covid19notify.model\n\nimport android.os.Parcelable\nimport com.squareup.moshi.Json\nimport kotlinx"
},
{
"path": "app/src/main/java/dev/shreyaspatil/covid19notify/repository/CovidIndiaRepository.kt",
"chars": 1911,
"preview": "package dev.shreyaspatil.covid19notify.repository\n\nimport dev.shreyaspatil.covid19notify.api.Covid19IndiaApiService\nimpo"
},
{
"path": "app/src/main/java/dev/shreyaspatil/covid19notify/repository/NetworkBoundRepository.kt",
"chars": 1201,
"preview": "package dev.shreyaspatil.covid19notify.repository\n\nimport androidx.annotation.MainThread\nimport dev.shreyaspatil.covid19"
},
{
"path": "app/src/main/java/dev/shreyaspatil/covid19notify/ui/adapter/TotalAdapter.kt",
"chars": 2760,
"preview": "package dev.shreyaspatil.covid19notify.ui.adapter\n\nimport android.view.LayoutInflater\nimport android.view.View\nimport an"
},
{
"path": "app/src/main/java/dev/shreyaspatil/covid19notify/ui/details/StateDetailsActivity.kt",
"chars": 3589,
"preview": "package dev.shreyaspatil.covid19notify.ui.details\n\nimport android.os.Bundle\nimport android.widget.Toast\nimport androidx."
},
{
"path": "app/src/main/java/dev/shreyaspatil/covid19notify/ui/details/StateDetailsViewModel.kt",
"chars": 1170,
"preview": "package dev.shreyaspatil.covid19notify.ui.details\n\nimport androidx.lifecycle.LiveData\nimport androidx.lifecycle.MutableL"
},
{
"path": "app/src/main/java/dev/shreyaspatil/covid19notify/ui/details/adapter/DistrictsAdapter.kt",
"chars": 3332,
"preview": "package dev.shreyaspatil.covid19notify.ui.details.adapter\n\nimport android.view.LayoutInflater\nimport android.view.View\ni"
},
{
"path": "app/src/main/java/dev/shreyaspatil/covid19notify/ui/main/MainActivity.kt",
"chars": 5376,
"preview": "package dev.shreyaspatil.covid19notify.ui.main\n\nimport android.content.Intent\nimport android.os.Bundle\nimport android.vi"
},
{
"path": "app/src/main/java/dev/shreyaspatil/covid19notify/ui/main/MainViewModel.kt",
"chars": 1051,
"preview": "package dev.shreyaspatil.covid19notify.ui.main\n\nimport androidx.lifecycle.LiveData\nimport androidx.lifecycle.MutableLive"
},
{
"path": "app/src/main/java/dev/shreyaspatil/covid19notify/ui/main/adapter/ItemAdapter.kt",
"chars": 3594,
"preview": "package dev.shreyaspatil.covid19notify.ui.main.adapter\n\nimport android.view.LayoutInflater\nimport android.view.View\nimpo"
},
{
"path": "app/src/main/java/dev/shreyaspatil/covid19notify/utils/NetworkUtils.kt",
"chars": 559,
"preview": "package dev.shreyaspatil.covid19notify.utils\n\nimport android.content.Context\nimport android.net.ConnectivityManager\nimpo"
},
{
"path": "app/src/main/java/dev/shreyaspatil/covid19notify/utils/State.kt",
"chars": 396,
"preview": "package dev.shreyaspatil.covid19notify.utils\n\nsealed class State<T> {\n class Loading<T> : State<T>()\n data class S"
},
{
"path": "app/src/main/java/dev/shreyaspatil/covid19notify/utils/ThemeUtils.kt",
"chars": 781,
"preview": "package dev.shreyaspatil.covid19notify.utils\n\nimport android.content.res.Configuration\nimport androidx.appcompat.app.App"
},
{
"path": "app/src/main/java/dev/shreyaspatil/covid19notify/utils/TimeUtils.kt",
"chars": 1134,
"preview": "package dev.shreyaspatil.covid19notify.utils\n\nimport android.annotation.SuppressLint\nimport java.text.SimpleDateFormat\ni"
},
{
"path": "app/src/main/java/dev/shreyaspatil/covid19notify/worker/NotificationWorker.kt",
"chars": 3918,
"preview": "package dev.shreyaspatil.covid19notify.worker\n\nimport android.annotation.SuppressLint\nimport android.app.NotificationCha"
},
{
"path": "app/src/main/res/drawable/ic_death.xml",
"chars": 7185,
"preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:width=\"24dp\"\n android:height=\"24dp\"\n "
},
{
"path": "app/src/main/res/drawable/ic_heart.xml",
"chars": 1645,
"preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:width=\"24dp\"\n android:height=\"24dp\"\n "
},
{
"path": "app/src/main/res/drawable/ic_info.xml",
"chars": 393,
"preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:width=\"14dp\"\n android:height=\""
},
{
"path": "app/src/main/res/drawable/ic_launcher_foreground.xml",
"chars": 6906,
"preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:width=\"108dp\"\n android:height=\"108dp\"\n"
},
{
"path": "app/src/main/res/drawable/ic_lightbulb.xml",
"chars": 621,
"preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:width=\"24dp\"\n android:height=\"24dp\"\n "
},
{
"path": "app/src/main/res/drawable/ic_patient.xml",
"chars": 6120,
"preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:width=\"24dp\"\n android:height=\"24dp\"\n "
},
{
"path": "app/src/main/res/drawable/ic_settings.xml",
"chars": 940,
"preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:width=\"24dp\"\n android:height=\""
},
{
"path": "app/src/main/res/drawable/ic_trending_up.xml",
"chars": 366,
"preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:width=\"24dp\"\n android:height=\""
},
{
"path": "app/src/main/res/drawable/ic_virus.xml",
"chars": 6617,
"preview": "<vector android:height=\"24.0465dp\" android:viewportHeight=\"181.512\"\n android:viewportWidth=\"181.161\" android:width=\"2"
},
{
"path": "app/src/main/res/drawable-anydpi-v24/ic_stat_notification_icon.xml",
"chars": 6930,
"preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:width=\"24dp\"\n android:height=\"24dp\"\n "
},
{
"path": "app/src/main/res/layout/activity_main.xml",
"chars": 1538,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xml"
},
{
"path": "app/src/main/res/layout/activity_state_details.xml",
"chars": 1554,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xml"
},
{
"path": "app/src/main/res/layout/appbar_layout.xml",
"chars": 925,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.google.android.material.appbar.AppBarLayout xmlns:android=\"http://schemas.an"
},
{
"path": "app/src/main/res/layout/item_district.xml",
"chars": 11434,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.google.android.material.card.MaterialCardView xmlns:android=\"http://schemas."
},
{
"path": "app/src/main/res/layout/item_state.xml",
"chars": 11208,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.google.android.material.card.MaterialCardView xmlns:android=\"http://schemas."
},
{
"path": "app/src/main/res/layout/item_total.xml",
"chars": 17224,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas"
},
{
"path": "app/src/main/res/menu/toolbar_menu.xml",
"chars": 344,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:app=\"h"
},
{
"path": "app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
"chars": 269,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <b"
},
{
"path": "app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
"chars": 269,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <b"
},
{
"path": "app/src/main/res/values/bool.xml",
"chars": 113,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <bool name=\"windowLightStatusBar\">true</bool>\n</resources>"
},
{
"path": "app/src/main/res/values/colors.xml",
"chars": 761,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <color name=\"colorPrimary\">#FFFFFF</color>\n <color name=\"color"
},
{
"path": "app/src/main/res/values/dimens.xml",
"chars": 259,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <dimen name=\"dimen_16\">16dp</dimen>\n <dimen name=\"dimen_4\">4dp"
},
{
"path": "app/src/main/res/values/ic_launcher_background.xml",
"chars": 120,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <color name=\"ic_launcher_background\">#FFFFFF</color>\n</resources>"
},
{
"path": "app/src/main/res/values/strings.xml",
"chars": 593,
"preview": "<resources>\n <string name=\"app_name\">COVID19 Notifier 🇮🇳</string>\n <string name=\"confirmed\">Confirmed</string>\n "
},
{
"path": "app/src/main/res/values/styles.xml",
"chars": 2239,
"preview": "<resources>\n\n <style name=\"TextTitle\">\n <item name=\"android:layout_gravity\">center</item>\n <item name=\""
},
{
"path": "app/src/main/res/values/theme.xml",
"chars": 1058,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\">\n\n <!-- Base applica"
},
{
"path": "app/src/main/res/values-night/bool.xml",
"chars": 114,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <bool name=\"windowLightStatusBar\">false</bool>\n</resources>"
},
{
"path": "app/src/main/res/values-night/colors.xml",
"chars": 784,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <color name=\"colorPrimary\">#0E0E0E</color>\n <color name=\"color"
},
{
"path": "app/src/test/java/dev/shreyaspatil/covid19notify/ExampleUnitTest.kt",
"chars": 365,
"preview": "package dev.shreyaspatil.covid19notify\n\nimport org.junit.Assert.assertEquals\nimport org.junit.Test\n\n/**\n * Example local"
},
{
"path": "build.gradle",
"chars": 662,
"preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n e"
},
{
"path": "gradle/wrapper/gradle-wrapper.properties",
"chars": 232,
"preview": "#Mon Mar 30 19:22:13 IST 2020\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
},
{
"path": "gradle.properties",
"chars": 1163,
"preview": "# Project-wide Gradle settings.\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will ov"
},
{
"path": "gradlew",
"chars": 4962,
"preview": "#!/usr/bin/env sh\n\n##############################################################################\n##\n## Gradle start up"
},
{
"path": "gradlew.bat",
"chars": 2176,
"preview": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem "
},
{
"path": "settings.gradle",
"chars": 48,
"preview": "rootProject.name='Covid19Notify'\ninclude ':app'\n"
}
]
// ... and 1 more files (download for full content)
About this extraction
This page contains the full source code of the PatilShreyas/Covid19-Notifier-IN GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 71 files (150.7 KB), approximately 51.7k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.