Skip to content

Commit

Permalink
Merge pull request #2 from mohamedebrahim96/feature/add-mvvm-architec…
Browse files Browse the repository at this point in the history
…ture

Feature/add mvvm architecture
  • Loading branch information
mohamedebrahim96 authored Apr 16, 2021
2 parents 263fbd0 + 595de44 commit ea4e37b
Show file tree
Hide file tree
Showing 27 changed files with 980 additions and 61 deletions.
148 changes: 125 additions & 23 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,56 +1,158 @@


plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-parcelize'
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
}

apply from: "$rootDir/dependencies.gradle"

android {
compileSdkVersion 30

compileSdkVersion versions.compileSdk
defaultConfig {
applicationId "com.tahmeel.task"
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "0.0.1"

minSdkVersion versions.minSdk
targetSdkVersion versions.compileSdk
versionCode versions.versionCode
versionName versions.versionName
vectorDrawables.useSupportLibrary = true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
javaCompileOptions {
annotationProcessorOptions {
arguments += ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
javaCompileOptions {
annotationProcessorOptions {
arguments["dagger.hilt.disableModulesHaveInstallInCheck"] = "true"
}
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
jvmTarget = JavaVersion.VERSION_1_8.toString()
}
buildFeatures {
dataBinding true
}
lintOptions {
abortOnError false
}
sourceSets {
androidTest.java.srcDirs += "src/test-common/java"
test.java.srcDirs += "src/test-common/java"
test.assets.srcDirs += files("$projectDir/schemas".toString())
}
testOptions {
unitTests {
includeAndroidResources = true
returnDefaultValues = true
}
}
packagingOptions {
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/license.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/notice.txt'
exclude 'META-INF/ASL2.0'
exclude("META-INF/*.kotlin_module")
}
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
kotlinOptions.freeCompilerArgs += ["-Xopt-in=kotlin.time.ExperimentalTime"]
kotlinOptions.freeCompilerArgs += ["-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi"]
}
}

dependencies {
// android supports
implementation "com.google.android.material:material:$versions.materialVersion"
implementation "androidx.constraintlayout:constraintlayout:$versions.constraintVersion"

implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
// architecture components
implementation "androidx.fragment:fragment-ktx:$versions.fragmentVersion"
implementation "androidx.lifecycle:lifecycle-extensions:$versions.lifecycleVersion"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$versions.lifecycleVersion"
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$versions.lifecycleVersion"
implementation "androidx.room:room-runtime:$versions.roomVersion"
implementation "androidx.room:room-ktx:$versions.roomVersion"
kapt "androidx.room:room-compiler:$versions.roomVersion"
testImplementation "androidx.arch.core:core-testing:$versions.archCompomentVersion"

// binding
implementation("com.github.skydoves:bindables:$versions.bindablesVersion") {
exclude group: "com.google.android.material"
}

// startup
implementation "androidx.startup:startup-runtime:$versions.startupVersion"

// hilt
implementation "com.google.dagger:hilt-android:$versions.hiltCoreVersion"
kapt "com.google.dagger:hilt-compiler:$versions.hiltCoreVersion"
kapt "androidx.hilt:hilt-compiler:$versions.hiltVersion"
androidTestImplementation "com.google.dagger:hilt-android-testing:$versions.hiltCoreVersion"
kaptAndroidTest "com.google.dagger:hilt-compiler:$versions.hiltCoreVersion"

// network
implementation "com.github.skydoves:sandwich:$versions.sandwichVersion"
implementation "com.squareup.retrofit2:retrofit:$versions.retrofitVersion"
implementation "com.squareup.retrofit2:converter-moshi:$versions.retrofitVersion"
implementation "com.squareup.okhttp3:logging-interceptor:$versions.okhttpVersion"
testImplementation "com.squareup.okhttp3:mockwebserver:$versions.okhttpVersion"

// moshi
implementation "com.squareup.moshi:moshi-kotlin:$versions.moshiVersion"
kapt "com.squareup.moshi:moshi-kotlin-codegen:$versions.moshiVersion"

// coroutines
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$versions.coroutinesVersion"
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$versions.coroutinesVersion"
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$versions.coroutinesVersion"

// whatIf
implementation "com.github.skydoves:whatif:$versions.whatIfVersion"

// glide
implementation "com.github.bumptech.glide:glide:$versions.glideVersion"
implementation "com.github.florent37:glidepalette:$versions.glidePaletteVersion"
kapt "com.github.bumptech.glide:compiler:$versions.glideVersion"

// bundler
implementation "com.github.skydoves:bundler:$versions.bundlerVersion"

// transformation
implementation "com.github.skydoves:transformationlayout:$versions.transformationLayout"

// recyclerView
implementation "androidx.recyclerview:recyclerview:$versions.recyclerView"
implementation "com.github.skydoves:baserecyclerviewadapter:$versions.baseAdapter"

// gradation
implementation "com.github.skydoves:rainbow:$versions.rainbowVersion"

// custom views
implementation "com.github.skydoves:androidribbon:$versions.androidRibbonVersion"
implementation "com.github.skydoves:progressview:$versions.progressViewVersion"

// debugging
implementation "com.jakewharton.timber:timber:$versions.timberVersion"

// unit test
testImplementation "junit:junit:$versions.junitVersion"
testImplementation "androidx.test:core:$versions.androidxTest"
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:$versions.mockitoKotlinVersion"
testImplementation "org.mockito:mockito-inline:$versions.mockitoInlineVersion"
testImplementation "app.cash.turbine:turbine:$versions.turbineVersion"
testImplementation "org.robolectric:robolectric:$versions.robolectricVersion"
androidTestImplementation "com.google.truth:truth:$versions.truthVersion"
androidTestImplementation "androidx.test.ext:junit:$versions.androidxTestJunit"
androidTestImplementation "com.android.support.test:runner:$versions.androidTestRunner"
androidTestImplementation "androidx.test.espresso:espresso-core:$versions.espressoVersion"
}
70 changes: 70 additions & 0 deletions app/schemas/com.tahmeel.task.persistence.AppDatabase/1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "bb00a4eab3771ce92f75e47927ce02c5",
"entities": [
{
"tableName": "Order",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`loadRef` INTEGER, `createdAt` TEXT, `customerName` TEXT, `orderNumber` TEXT, `orderPriceFormatted` TEXT, `phoneNumber` TEXT, `tahmeelFeeInCents` INTEGER, PRIMARY KEY(`loadRef`))",
"fields": [
{
"fieldPath": "loadRef",
"columnName": "loadRef",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "createdAt",
"columnName": "createdAt",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "customerName",
"columnName": "customerName",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "orderNumber",
"columnName": "orderNumber",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "orderPriceFormatted",
"columnName": "orderPriceFormatted",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "phoneNumber",
"columnName": "phoneNumber",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "tahmeelFeeInCents",
"columnName": "tahmeelFeeInCents",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"loadRef"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'bb00a4eab3771ce92f75e47927ce02c5')"
]
}
}
46 changes: 46 additions & 0 deletions app/src/main/java/com/tahmeel/task/binding/RecyclerViewBinding.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.tahmeel.task.binding

import androidx.databinding.BindingAdapter
import androidx.recyclerview.widget.RecyclerView
import com.skydoves.baserecyclerviewadapter.RecyclerViewPaginator
import com.skydoves.bindables.BindingListAdapter
import com.skydoves.whatif.whatIfNotNullAs
import com.tahmeel.task.ui.main.MainViewModel

/**
* Created by @mohamedebrahim96 on 16,April,2021
* ShopiniWorld, Inc
* ebrahimm131@gmail.com
*/

object RecyclerViewBinding {

@JvmStatic
@BindingAdapter("adapter")
fun bindAdapter(view: RecyclerView, adapter: RecyclerView.Adapter<*>) {
view.adapter = adapter.apply {
stateRestorationPolicy = RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY
}
}

@JvmStatic
@BindingAdapter("submitList")
fun bindSubmitList(view: RecyclerView, itemList: List<Any>?) {
view.adapter.whatIfNotNullAs<BindingListAdapter<Any, *>> { adapter ->
adapter.submitList(itemList)
}
}

@JvmStatic
@BindingAdapter("paginationPendingOrder")
fun paginationPendingOrderList(view: RecyclerView, viewModel: MainViewModel) {
RecyclerViewPaginator(
recyclerView = view,
isLoading = { viewModel.isLoading },
loadMore = { viewModel.fetchNextPendingOrderList() },
onLast = { false }
).run {
threshold = 8
}
}
}
33 changes: 33 additions & 0 deletions app/src/main/java/com/tahmeel/task/binding/ViewBinding.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.tahmeel.task.binding

import android.view.View
import android.widget.Toast
import androidx.databinding.BindingAdapter
import com.skydoves.whatif.whatIfNotNullOrEmpty

/**
* Created by @mohamedebrahim96 on 16,April,2021
* ShopiniWorld, Inc
* ebrahimm131@gmail.com
*/

object ViewBinding {

@JvmStatic
@BindingAdapter("toast")
fun bindToast(view: View, text: String?) {
text.whatIfNotNullOrEmpty {
Toast.makeText(view.context, it, Toast.LENGTH_SHORT).show()
}
}

@JvmStatic
@BindingAdapter("gone")
fun bindGone(view: View, shouldBeGone: Boolean) {
view.visibility = if (shouldBeGone) {
View.GONE
} else {
View.VISIBLE
}
}
}
50 changes: 50 additions & 0 deletions app/src/main/java/com/tahmeel/task/di/NetworkModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.tahmeel.task.di

import com.skydoves.sandwich.coroutines.CoroutinesResponseCallAdapterFactory
import com.tahmeel.task.network.HttpRequestInterceptor
import com.tahmeel.task.network.TahmeelClient
import com.tahmeel.task.network.TahmeelService
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {

@Provides
@Singleton
fun provideOkHttpClient(): OkHttpClient {
return OkHttpClient.Builder()
.addInterceptor(HttpRequestInterceptor())
.build()
}

@Provides
@Singleton
fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.client(okHttpClient)
.baseUrl("https://api.stagingtahmeelapp.com/")
.addConverterFactory(MoshiConverterFactory.create())
.addCallAdapterFactory(CoroutinesResponseCallAdapterFactory())
.build()
}

@Provides
@Singleton
fun provideTahmeelService(retrofit: Retrofit): TahmeelService {
return retrofit.create(TahmeelService::class.java)
}

@Provides
@Singleton
fun provideTahmeelClient(tahmeelService: TahmeelService): TahmeelClient {
return TahmeelClient(tahmeelService)
}
}
Loading

0 comments on commit ea4e37b

Please sign in to comment.