From cf2ba22fd9354effb7529e7e0d72a0d42ff54d92 Mon Sep 17 00:00:00 2001 From: muhammadyoussef Date: Sat, 7 Sep 2019 15:31:09 +0200 Subject: [PATCH 01/20] Create the initial state of common, local and remote modules. --- .idea/misc.xml | 2 +- app/build.gradle | 79 +---------------- common/.gitignore | 1 + common/build.gradle | 14 +++ common/consumer-rules.pro | 0 common/proguard-rules.pro | 21 +++++ .../common/ExampleInstrumentedTest.java | 27 ++++++ common/src/main/AndroidManifest.xml | 1 + common/src/main/res/values/strings.xml | 3 + .../com/egdroid/common/ExampleUnitTest.java | 17 ++++ datasource/local/.gitignore | 1 + datasource/local/build.gradle | 14 +++ datasource/local/consumer-rules.pro | 0 datasource/local/proguard-rules.pro | 21 +++++ .../local/ExampleInstrumentedTest.java | 27 ++++++ datasource/local/src/main/AndroidManifest.xml | 1 + .../local/src/main/res/values/strings.xml | 3 + .../datasource/local/ExampleUnitTest.java | 17 ++++ datasource/remote/.gitignore | 1 + datasource/remote/build.gradle | 14 +++ datasource/remote/consumer-rules.pro | 0 datasource/remote/proguard-rules.pro | 21 +++++ .../remote/ExampleInstrumentedTest.java | 27 ++++++ .../remote/src/main/AndroidManifest.xml | 1 + .../remote/src/main/res/values/strings.xml | 3 + .../datasource/remote/ExampleUnitTest.java | 17 ++++ settings.gradle | 2 +- tools/gradle/base.gradle | 88 +++++++++++++++++++ 28 files changed, 343 insertions(+), 80 deletions(-) create mode 100644 common/.gitignore create mode 100644 common/build.gradle create mode 100644 common/consumer-rules.pro create mode 100644 common/proguard-rules.pro create mode 100644 common/src/androidTest/java/com/egdroid/common/ExampleInstrumentedTest.java create mode 100644 common/src/main/AndroidManifest.xml create mode 100644 common/src/main/res/values/strings.xml create mode 100644 common/src/test/java/com/egdroid/common/ExampleUnitTest.java create mode 100644 datasource/local/.gitignore create mode 100644 datasource/local/build.gradle create mode 100644 datasource/local/consumer-rules.pro create mode 100644 datasource/local/proguard-rules.pro create mode 100644 datasource/local/src/androidTest/java/com/egdroid/datasource/local/ExampleInstrumentedTest.java create mode 100644 datasource/local/src/main/AndroidManifest.xml create mode 100644 datasource/local/src/main/res/values/strings.xml create mode 100644 datasource/local/src/test/java/com/egdroid/datasource/local/ExampleUnitTest.java create mode 100644 datasource/remote/.gitignore create mode 100644 datasource/remote/build.gradle create mode 100644 datasource/remote/consumer-rules.pro create mode 100644 datasource/remote/proguard-rules.pro create mode 100644 datasource/remote/src/androidTest/java/com/egdroid/datasource/remote/ExampleInstrumentedTest.java create mode 100644 datasource/remote/src/main/AndroidManifest.xml create mode 100644 datasource/remote/src/main/res/values/strings.xml create mode 100644 datasource/remote/src/test/java/com/egdroid/datasource/remote/ExampleUnitTest.java create mode 100644 tools/gradle/base.gradle diff --git a/.idea/misc.xml b/.idea/misc.xml index af0bbdd..703e5d4 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -5,7 +5,7 @@ - + diff --git a/app/build.gradle b/app/build.gradle index 6521609..205810a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,15 +1,10 @@ apply plugin: 'com.android.application' apply from: "$project.rootDir/tools/gradle/script/quality.gradle" +apply from: "$project.rootDir/tools/gradle/base.gradle" android { - compileSdkVersion deps.build.compileSdkVersion defaultConfig { applicationId "com.egdroid.movieapp" - minSdkVersion deps.build.minSdkVersion - targetSdkVersion deps.build.targetSdkVersion - versionCode deps.build.versionCode - versionName deps.build.versionName - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { @@ -21,76 +16,4 @@ android { proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } -} - -dependencies { - //UI - implementation deps.support.design - implementation deps.support.recyclerview - implementation deps.support.constraintLayout - - // Arch Component - implementation deps.architecturecomponents.lifecycles - implementation deps.architecturecomponents.room - annotationProcessor deps.architecturecomponents.room_compiler - - // Rx - implementation deps.rx.java - implementation deps.rx.relay - implementation deps.rx.android - implementation deps.rx.binding - implementation deps.rx.retrofitAdapter - - // Dependency Injection - implementation deps.dependencyInjection.dagger - implementation deps.dependencyInjection.daggerSupportAndroid - annotationProcessor deps.dependencyInjection.daggerCompiler - annotationProcessor deps.dependencyInjection.daggerAndroidCompiler - - // View Binding - implementation deps.viewBinding.butterknife - annotationProcessor deps.viewBinding.butterknifeCompiler - - // Images - implementation deps.image.glide - annotationProcessor deps.image.glideCompiler - - // Network - implementation deps.network.retrofit - implementation deps.network.retrofitGsonConverter - - // Log - implementation deps.log.timber - debugImplementation deps.log.leakCanaryDebug - releaseImplementation deps.log.leakCanaryRelease - - // Testing - testImplementation deps.test.junit - androidTestImplementation deps.test.runner - androidTestImplementation deps.test.robolectric - androidTestImplementation deps.test.espresso - androidTestImplementation deps.test.mockito - androidTestImplementation deps.test.powermock_mockito - androidTestImplementation deps.test.powermock_easymock - androidTestImplementation deps.test.powermock_reflect - androidTestImplementation deps.test.powermock_junit4 - androidTestImplementation deps.test.powermock_junit4_rule - androidTestImplementation deps.test.powermock_classloading - - implementation fileTree(dir: 'libs', include: ['*.jar']) - configurations.all { - resolutionStrategy { - force deps.support.annotations - } - resolutionStrategy.eachDependency { details -> - if (details.requested.group == 'com.android.support' - && !details.requested.name.contains('multidex')) { - details.useVersion deps.versions.support - } - } - } } diff --git a/common/.gitignore b/common/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/common/.gitignore @@ -0,0 +1 @@ +/build diff --git a/common/build.gradle b/common/build.gradle new file mode 100644 index 0000000..a1b4430 --- /dev/null +++ b/common/build.gradle @@ -0,0 +1,14 @@ +apply plugin: 'com.android.library' +apply from: "$project.rootDir/tools/gradle/script/quality.gradle" +apply from: "$project.rootDir/tools/gradle/base.gradle" + +android { + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + +} diff --git a/common/consumer-rules.pro b/common/consumer-rules.pro new file mode 100644 index 0000000..e69de29 diff --git a/common/proguard-rules.pro b/common/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/common/proguard-rules.pro @@ -0,0 +1,21 @@ +# 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 diff --git a/common/src/androidTest/java/com/egdroid/common/ExampleInstrumentedTest.java b/common/src/androidTest/java/com/egdroid/common/ExampleInstrumentedTest.java new file mode 100644 index 0000000..22ced8c --- /dev/null +++ b/common/src/androidTest/java/com/egdroid/common/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.egdroid.common; + +import android.content.Context; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import androidx.test.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.egdroid.common.test", appContext.getPackageName()); + } +} diff --git a/common/src/main/AndroidManifest.xml b/common/src/main/AndroidManifest.xml new file mode 100644 index 0000000..9eab0b6 --- /dev/null +++ b/common/src/main/AndroidManifest.xml @@ -0,0 +1 @@ + diff --git a/common/src/main/res/values/strings.xml b/common/src/main/res/values/strings.xml new file mode 100644 index 0000000..9e44af5 --- /dev/null +++ b/common/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + common + diff --git a/common/src/test/java/com/egdroid/common/ExampleUnitTest.java b/common/src/test/java/com/egdroid/common/ExampleUnitTest.java new file mode 100644 index 0000000..3061f3c --- /dev/null +++ b/common/src/test/java/com/egdroid/common/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.egdroid.common; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/datasource/local/.gitignore b/datasource/local/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/datasource/local/.gitignore @@ -0,0 +1 @@ +/build diff --git a/datasource/local/build.gradle b/datasource/local/build.gradle new file mode 100644 index 0000000..a1b4430 --- /dev/null +++ b/datasource/local/build.gradle @@ -0,0 +1,14 @@ +apply plugin: 'com.android.library' +apply from: "$project.rootDir/tools/gradle/script/quality.gradle" +apply from: "$project.rootDir/tools/gradle/base.gradle" + +android { + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + +} diff --git a/datasource/local/consumer-rules.pro b/datasource/local/consumer-rules.pro new file mode 100644 index 0000000..e69de29 diff --git a/datasource/local/proguard-rules.pro b/datasource/local/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/datasource/local/proguard-rules.pro @@ -0,0 +1,21 @@ +# 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 diff --git a/datasource/local/src/androidTest/java/com/egdroid/datasource/local/ExampleInstrumentedTest.java b/datasource/local/src/androidTest/java/com/egdroid/datasource/local/ExampleInstrumentedTest.java new file mode 100644 index 0000000..751eb9e --- /dev/null +++ b/datasource/local/src/androidTest/java/com/egdroid/datasource/local/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.egdroid.datasource.local; + +import android.content.Context; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import androidx.test.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.egdroid.datasource.local.test", appContext.getPackageName()); + } +} diff --git a/datasource/local/src/main/AndroidManifest.xml b/datasource/local/src/main/AndroidManifest.xml new file mode 100644 index 0000000..aee27b6 --- /dev/null +++ b/datasource/local/src/main/AndroidManifest.xml @@ -0,0 +1 @@ + diff --git a/datasource/local/src/main/res/values/strings.xml b/datasource/local/src/main/res/values/strings.xml new file mode 100644 index 0000000..b74fbf3 --- /dev/null +++ b/datasource/local/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + local + diff --git a/datasource/local/src/test/java/com/egdroid/datasource/local/ExampleUnitTest.java b/datasource/local/src/test/java/com/egdroid/datasource/local/ExampleUnitTest.java new file mode 100644 index 0000000..d2bdc22 --- /dev/null +++ b/datasource/local/src/test/java/com/egdroid/datasource/local/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.egdroid.datasource.local; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/datasource/remote/.gitignore b/datasource/remote/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/datasource/remote/.gitignore @@ -0,0 +1 @@ +/build diff --git a/datasource/remote/build.gradle b/datasource/remote/build.gradle new file mode 100644 index 0000000..a1b4430 --- /dev/null +++ b/datasource/remote/build.gradle @@ -0,0 +1,14 @@ +apply plugin: 'com.android.library' +apply from: "$project.rootDir/tools/gradle/script/quality.gradle" +apply from: "$project.rootDir/tools/gradle/base.gradle" + +android { + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + +} diff --git a/datasource/remote/consumer-rules.pro b/datasource/remote/consumer-rules.pro new file mode 100644 index 0000000..e69de29 diff --git a/datasource/remote/proguard-rules.pro b/datasource/remote/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/datasource/remote/proguard-rules.pro @@ -0,0 +1,21 @@ +# 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 diff --git a/datasource/remote/src/androidTest/java/com/egdroid/datasource/remote/ExampleInstrumentedTest.java b/datasource/remote/src/androidTest/java/com/egdroid/datasource/remote/ExampleInstrumentedTest.java new file mode 100644 index 0000000..b4c2eea --- /dev/null +++ b/datasource/remote/src/androidTest/java/com/egdroid/datasource/remote/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.egdroid.datasource.remote; + +import android.content.Context; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import androidx.test.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.egdroid.datasource.remote.test", appContext.getPackageName()); + } +} diff --git a/datasource/remote/src/main/AndroidManifest.xml b/datasource/remote/src/main/AndroidManifest.xml new file mode 100644 index 0000000..0de894b --- /dev/null +++ b/datasource/remote/src/main/AndroidManifest.xml @@ -0,0 +1 @@ + diff --git a/datasource/remote/src/main/res/values/strings.xml b/datasource/remote/src/main/res/values/strings.xml new file mode 100644 index 0000000..16f98ce --- /dev/null +++ b/datasource/remote/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + remote + diff --git a/datasource/remote/src/test/java/com/egdroid/datasource/remote/ExampleUnitTest.java b/datasource/remote/src/test/java/com/egdroid/datasource/remote/ExampleUnitTest.java new file mode 100644 index 0000000..e158e77 --- /dev/null +++ b/datasource/remote/src/test/java/com/egdroid/datasource/remote/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.egdroid.datasource.remote; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 9d78681..7de50da 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,2 @@ -include ':app' +include ':app', ':common', ':datasource:local', ':datasource:remote' rootProject.name='AnotherMovieApp' diff --git a/tools/gradle/base.gradle b/tools/gradle/base.gradle new file mode 100644 index 0000000..6869265 --- /dev/null +++ b/tools/gradle/base.gradle @@ -0,0 +1,88 @@ +android { + + compileSdkVersion deps.build.compileSdkVersion + + defaultConfig { + + minSdkVersion deps.build.minSdkVersion + targetSdkVersion deps.build.targetSdkVersion + versionCode deps.build.versionCode + versionName deps.build.versionName + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles 'consumer-rules.pro' + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + //UI + implementation deps.support.design + implementation deps.support.recyclerview + implementation deps.support.constraintLayout + + // Arch Component + implementation deps.architecturecomponents.lifecycles + implementation deps.architecturecomponents.room + annotationProcessor deps.architecturecomponents.room_compiler + + // Rx + api deps.rx.java + api deps.rx.relay + api deps.rx.android + api deps.rx.binding + api deps.rx.retrofitAdapter + + // Dependency Injection + api deps.dependencyInjection.dagger + api deps.dependencyInjection.daggerSupportAndroid + annotationProcessor deps.dependencyInjection.daggerCompiler + annotationProcessor deps.dependencyInjection.daggerAndroidCompiler + + // View Binding + api deps.viewBinding.butterknife + annotationProcessor deps.viewBinding.butterknifeCompiler + + // Images + api deps.image.glide + annotationProcessor deps.image.glideCompiler + + // Network + implementation deps.network.retrofit + implementation deps.network.retrofitGsonConverter + + // Log + implementation deps.log.timber + debugImplementation deps.log.leakCanaryDebug + releaseImplementation deps.log.leakCanaryRelease + + // Testing + testImplementation deps.test.junit + androidTestImplementation deps.test.runner + androidTestImplementation deps.test.espresso + androidTestImplementation deps.test.robolectric + androidTestImplementation deps.test.mockito + androidTestImplementation deps.test.powermock_mockito + androidTestImplementation deps.test.powermock_easymock + androidTestImplementation deps.test.powermock_reflect + androidTestImplementation deps.test.powermock_junit4 + androidTestImplementation deps.test.powermock_junit4_rule + androidTestImplementation deps.test.powermock_classloading + + implementation fileTree(dir: 'libs', include: ['*.jar']) + configurations.all { + resolutionStrategy { + force deps.support.annotations + } + resolutionStrategy.eachDependency { details -> + if (details.requested.group == 'com.android.support' + && !details.requested.name.contains('multidex')) { + details.useVersion deps.versions.support + } + } + } +} \ No newline at end of file From 31effebebfade813a0287e43a65b48ff4c5ebfe5 Mon Sep 17 00:00:00 2001 From: muhammadyoussef Date: Sun, 8 Sep 2019 02:00:35 +0200 Subject: [PATCH 02/20] architecture --- datasource/local/build.gradle | 6 +++ .../datasource/local/MovieLocalDatabase.java | 11 ++++++ datasource/remote/build.gradle | 6 +++ .../datasource/remote/MovieRemote.java | 11 ++++++ features/upcomingmovies/.gitignore | 1 + features/upcomingmovies/build.gradle | 38 +++++++++++++++++++ features/upcomingmovies/consumer-rules.pro | 0 features/upcomingmovies/proguard-rules.pro | 21 ++++++++++ .../ExampleInstrumentedTest.java | 27 +++++++++++++ .../src/main/AndroidManifest.xml | 2 + .../feature/upcomingmovies/rep/MovieRepo.java | 30 +++++++++++++++ .../src/main/res/values/strings.xml | 3 ++ .../upcomingmovies/ExampleUnitTest.java | 17 +++++++++ models/datasourcemodel/.gitignore | 1 + models/datasourcemodel/build.gradle | 14 +++++++ models/datasourcemodel/consumer-rules.pro | 0 models/datasourcemodel/proguard-rules.pro | 21 ++++++++++ .../datasource/ExampleInstrumentedTest.java | 27 +++++++++++++ .../src/main/AndroidManifest.xml | 2 + .../model/datasource/MovieDataSource.java | 12 ++++++ .../src/main/res/values/strings.xml | 3 ++ .../model/datasource/ExampleUnitTest.java | 17 +++++++++ models/localmodel/.gitignore | 1 + models/localmodel/build.gradle | 14 +++++++ models/localmodel/consumer-rules.pro | 0 models/localmodel/proguard-rules.pro | 21 ++++++++++ .../models/local/ExampleInstrumentedTest.java | 27 +++++++++++++ .../localmodel/src/main/AndroidManifest.xml | 1 + .../models/local/movie/MovieLocal.java | 11 ++++++ .../src/main/res/values/strings.xml | 3 ++ .../egdroid/models/local/ExampleUnitTest.java | 17 +++++++++ models/mapper/.gitignore | 1 + models/mapper/build.gradle | 23 +++++++++++ models/mapper/consumer-rules.pro | 0 models/mapper/proguard-rules.pro | 21 ++++++++++ .../mapper/ExampleInstrumentedTest.java | 27 +++++++++++++ models/mapper/src/main/AndroidManifest.xml | 2 + .../java/com/egdroid/mapper/MovieMapper.java | 17 +++++++++ models/mapper/src/main/res/values/strings.xml | 3 ++ .../com/egdroid/mapper/ExampleUnitTest.java | 17 +++++++++ models/remotemodel/.gitignore | 1 + models/remotemodel/build.gradle | 14 +++++++ models/remotemodel/consumer-rules.pro | 0 models/remotemodel/proguard-rules.pro | 21 ++++++++++ .../remote/ExampleInstrumentedTest.java | 27 +++++++++++++ .../remotemodel/src/main/AndroidManifest.xml | 1 + .../models/remote/movie/MovieResponse.java | 11 ++++++ .../src/main/res/values/strings.xml | 3 ++ .../models/remote/ExampleUnitTest.java | 17 +++++++++ settings.gradle | 5 ++- 50 files changed, 574 insertions(+), 2 deletions(-) create mode 100644 datasource/local/src/main/java/com/egdroid/datasource/local/MovieLocalDatabase.java create mode 100644 datasource/remote/src/main/java/com/egdroid/datasource/remote/MovieRemote.java create mode 100644 features/upcomingmovies/.gitignore create mode 100644 features/upcomingmovies/build.gradle create mode 100644 features/upcomingmovies/consumer-rules.pro create mode 100644 features/upcomingmovies/proguard-rules.pro create mode 100644 features/upcomingmovies/src/androidTest/java/com/egdroid/feature/upcomingmovies/ExampleInstrumentedTest.java create mode 100644 features/upcomingmovies/src/main/AndroidManifest.xml create mode 100644 features/upcomingmovies/src/main/java/com/egdroid/feature/upcomingmovies/rep/MovieRepo.java create mode 100644 features/upcomingmovies/src/main/res/values/strings.xml create mode 100644 features/upcomingmovies/src/test/java/com/egdroid/feature/upcomingmovies/ExampleUnitTest.java create mode 100644 models/datasourcemodel/.gitignore create mode 100644 models/datasourcemodel/build.gradle create mode 100644 models/datasourcemodel/consumer-rules.pro create mode 100644 models/datasourcemodel/proguard-rules.pro create mode 100644 models/datasourcemodel/src/androidTest/java/com/egdroid/model/datasource/ExampleInstrumentedTest.java create mode 100644 models/datasourcemodel/src/main/AndroidManifest.xml create mode 100644 models/datasourcemodel/src/main/java/com/egdroid/model/datasource/MovieDataSource.java create mode 100644 models/datasourcemodel/src/main/res/values/strings.xml create mode 100644 models/datasourcemodel/src/test/java/com/egdroid/model/datasource/ExampleUnitTest.java create mode 100644 models/localmodel/.gitignore create mode 100644 models/localmodel/build.gradle create mode 100644 models/localmodel/consumer-rules.pro create mode 100644 models/localmodel/proguard-rules.pro create mode 100644 models/localmodel/src/androidTest/java/com/egdroid/models/local/ExampleInstrumentedTest.java create mode 100644 models/localmodel/src/main/AndroidManifest.xml create mode 100644 models/localmodel/src/main/java/com/egdroid/models/local/movie/MovieLocal.java create mode 100644 models/localmodel/src/main/res/values/strings.xml create mode 100644 models/localmodel/src/test/java/com/egdroid/models/local/ExampleUnitTest.java create mode 100644 models/mapper/.gitignore create mode 100644 models/mapper/build.gradle create mode 100644 models/mapper/consumer-rules.pro create mode 100644 models/mapper/proguard-rules.pro create mode 100644 models/mapper/src/androidTest/java/com/egdroid/mapper/ExampleInstrumentedTest.java create mode 100644 models/mapper/src/main/AndroidManifest.xml create mode 100644 models/mapper/src/main/java/com/egdroid/mapper/MovieMapper.java create mode 100644 models/mapper/src/main/res/values/strings.xml create mode 100644 models/mapper/src/test/java/com/egdroid/mapper/ExampleUnitTest.java create mode 100644 models/remotemodel/.gitignore create mode 100644 models/remotemodel/build.gradle create mode 100644 models/remotemodel/consumer-rules.pro create mode 100644 models/remotemodel/proguard-rules.pro create mode 100644 models/remotemodel/src/androidTest/java/com/egdroid/models/remote/ExampleInstrumentedTest.java create mode 100644 models/remotemodel/src/main/AndroidManifest.xml create mode 100644 models/remotemodel/src/main/java/com/egdroid/models/remote/movie/MovieResponse.java create mode 100644 models/remotemodel/src/main/res/values/strings.xml create mode 100644 models/remotemodel/src/test/java/com/egdroid/models/remote/ExampleUnitTest.java diff --git a/datasource/local/build.gradle b/datasource/local/build.gradle index a1b4430..247c60f 100644 --- a/datasource/local/build.gradle +++ b/datasource/local/build.gradle @@ -11,4 +11,10 @@ android { } } + dependencies{ + + api project(":models:localmodel") + + } + } diff --git a/datasource/local/src/main/java/com/egdroid/datasource/local/MovieLocalDatabase.java b/datasource/local/src/main/java/com/egdroid/datasource/local/MovieLocalDatabase.java new file mode 100644 index 0000000..97eecc8 --- /dev/null +++ b/datasource/local/src/main/java/com/egdroid/datasource/local/MovieLocalDatabase.java @@ -0,0 +1,11 @@ +package com.egdroid.datasource.local; + +import com.egdroid.models.local.movie.MovieLocal; + +public class MovieLocalDatabase { + + public MovieLocal getMovie() { + return new MovieLocal(12); + } + +} diff --git a/datasource/remote/build.gradle b/datasource/remote/build.gradle index a1b4430..b043839 100644 --- a/datasource/remote/build.gradle +++ b/datasource/remote/build.gradle @@ -11,4 +11,10 @@ android { } } + dependencies{ + + api project(":models:remotemodel") + + } + } diff --git a/datasource/remote/src/main/java/com/egdroid/datasource/remote/MovieRemote.java b/datasource/remote/src/main/java/com/egdroid/datasource/remote/MovieRemote.java new file mode 100644 index 0000000..5d602d3 --- /dev/null +++ b/datasource/remote/src/main/java/com/egdroid/datasource/remote/MovieRemote.java @@ -0,0 +1,11 @@ +package com.egdroid.datasource.remote; + +import com.egdroid.models.remote.movie.MovieResponse; + +public class MovieRemote { + + public MovieResponse getMovie(){ + return new MovieResponse(2); + } + +} diff --git a/features/upcomingmovies/.gitignore b/features/upcomingmovies/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/features/upcomingmovies/.gitignore @@ -0,0 +1 @@ +/build diff --git a/features/upcomingmovies/build.gradle b/features/upcomingmovies/build.gradle new file mode 100644 index 0000000..d839900 --- /dev/null +++ b/features/upcomingmovies/build.gradle @@ -0,0 +1,38 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion 28 + + + defaultConfig { + minSdkVersion 24 + targetSdkVersion 28 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles 'consumer-rules.pro' + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + api project(":datasource:local") + api project(":datasource:remote") + api project(":models:mapper") + implementation project(":models:datasourcemodel") + + implementation 'androidx.appcompat:appcompat:1.1.0' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test:runner:1.2.0' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' +} diff --git a/features/upcomingmovies/consumer-rules.pro b/features/upcomingmovies/consumer-rules.pro new file mode 100644 index 0000000..e69de29 diff --git a/features/upcomingmovies/proguard-rules.pro b/features/upcomingmovies/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/features/upcomingmovies/proguard-rules.pro @@ -0,0 +1,21 @@ +# 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 diff --git a/features/upcomingmovies/src/androidTest/java/com/egdroid/feature/upcomingmovies/ExampleInstrumentedTest.java b/features/upcomingmovies/src/androidTest/java/com/egdroid/feature/upcomingmovies/ExampleInstrumentedTest.java new file mode 100644 index 0000000..30b2cf2 --- /dev/null +++ b/features/upcomingmovies/src/androidTest/java/com/egdroid/feature/upcomingmovies/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.egdroid.feature.upcomingmovies; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.egdroid.feature.upcomingmovies.test", appContext.getPackageName()); + } +} diff --git a/features/upcomingmovies/src/main/AndroidManifest.xml b/features/upcomingmovies/src/main/AndroidManifest.xml new file mode 100644 index 0000000..898d25d --- /dev/null +++ b/features/upcomingmovies/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + diff --git a/features/upcomingmovies/src/main/java/com/egdroid/feature/upcomingmovies/rep/MovieRepo.java b/features/upcomingmovies/src/main/java/com/egdroid/feature/upcomingmovies/rep/MovieRepo.java new file mode 100644 index 0000000..cd0b5b9 --- /dev/null +++ b/features/upcomingmovies/src/main/java/com/egdroid/feature/upcomingmovies/rep/MovieRepo.java @@ -0,0 +1,30 @@ +package com.egdroid.feature.upcomingmovies.rep; + +import com.egdroid.datasource.local.MovieLocalDatabase; +import com.egdroid.datasource.remote.MovieRemote; +import com.egdroid.mapper.MovieMapper; +import com.egdroid.model.datasource.MovieDataSource; +import com.egdroid.models.local.movie.MovieLocal; +import com.egdroid.models.remote.movie.MovieResponse; + +public class MovieRepo { + + public MovieDataSource getMovies() { + + MovieMapper movieMapper = new MovieMapper(); + + // Room integration + MovieLocal movieLocalDatabase = new MovieLocalDatabase().getMovie(); + + // Retrofit integration + MovieResponse movieRemote = new MovieRemote().getMovie(); + + if (movieLocalDatabase != null) { + return movieMapper.mapToDataSource(movieLocalDatabase); + } else { + return movieMapper.mapToDataSource(movieRemote); + } + + } + +} diff --git a/features/upcomingmovies/src/main/res/values/strings.xml b/features/upcomingmovies/src/main/res/values/strings.xml new file mode 100644 index 0000000..ef66922 --- /dev/null +++ b/features/upcomingmovies/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + upcomingmovies + diff --git a/features/upcomingmovies/src/test/java/com/egdroid/feature/upcomingmovies/ExampleUnitTest.java b/features/upcomingmovies/src/test/java/com/egdroid/feature/upcomingmovies/ExampleUnitTest.java new file mode 100644 index 0000000..de997df --- /dev/null +++ b/features/upcomingmovies/src/test/java/com/egdroid/feature/upcomingmovies/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.egdroid.feature.upcomingmovies; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/models/datasourcemodel/.gitignore b/models/datasourcemodel/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/models/datasourcemodel/.gitignore @@ -0,0 +1 @@ +/build diff --git a/models/datasourcemodel/build.gradle b/models/datasourcemodel/build.gradle new file mode 100644 index 0000000..34f1ca3 --- /dev/null +++ b/models/datasourcemodel/build.gradle @@ -0,0 +1,14 @@ +apply plugin: 'com.android.library' +apply from: "$project.rootDir/tools/gradle/script/quality.gradle" +apply from: "$project.rootDir/tools/gradle/base.gradle" + +android { + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + +} \ No newline at end of file diff --git a/models/datasourcemodel/consumer-rules.pro b/models/datasourcemodel/consumer-rules.pro new file mode 100644 index 0000000..e69de29 diff --git a/models/datasourcemodel/proguard-rules.pro b/models/datasourcemodel/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/models/datasourcemodel/proguard-rules.pro @@ -0,0 +1,21 @@ +# 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 diff --git a/models/datasourcemodel/src/androidTest/java/com/egdroid/model/datasource/ExampleInstrumentedTest.java b/models/datasourcemodel/src/androidTest/java/com/egdroid/model/datasource/ExampleInstrumentedTest.java new file mode 100644 index 0000000..dd3b67b --- /dev/null +++ b/models/datasourcemodel/src/androidTest/java/com/egdroid/model/datasource/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.egdroid.model.datasource; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.egdroid.model.datasource.test", appContext.getPackageName()); + } +} diff --git a/models/datasourcemodel/src/main/AndroidManifest.xml b/models/datasourcemodel/src/main/AndroidManifest.xml new file mode 100644 index 0000000..ae633c3 --- /dev/null +++ b/models/datasourcemodel/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + diff --git a/models/datasourcemodel/src/main/java/com/egdroid/model/datasource/MovieDataSource.java b/models/datasourcemodel/src/main/java/com/egdroid/model/datasource/MovieDataSource.java new file mode 100644 index 0000000..5299a14 --- /dev/null +++ b/models/datasourcemodel/src/main/java/com/egdroid/model/datasource/MovieDataSource.java @@ -0,0 +1,12 @@ +package com.egdroid.model.datasource; + +public class MovieDataSource { + + public final int id; + //more fields + + public MovieDataSource(int id) { + this.id = id; + } + +} diff --git a/models/datasourcemodel/src/main/res/values/strings.xml b/models/datasourcemodel/src/main/res/values/strings.xml new file mode 100644 index 0000000..7c4da98 --- /dev/null +++ b/models/datasourcemodel/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + datasourcemodel + diff --git a/models/datasourcemodel/src/test/java/com/egdroid/model/datasource/ExampleUnitTest.java b/models/datasourcemodel/src/test/java/com/egdroid/model/datasource/ExampleUnitTest.java new file mode 100644 index 0000000..415c734 --- /dev/null +++ b/models/datasourcemodel/src/test/java/com/egdroid/model/datasource/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.egdroid.model.datasource; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/models/localmodel/.gitignore b/models/localmodel/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/models/localmodel/.gitignore @@ -0,0 +1 @@ +/build diff --git a/models/localmodel/build.gradle b/models/localmodel/build.gradle new file mode 100644 index 0000000..34f1ca3 --- /dev/null +++ b/models/localmodel/build.gradle @@ -0,0 +1,14 @@ +apply plugin: 'com.android.library' +apply from: "$project.rootDir/tools/gradle/script/quality.gradle" +apply from: "$project.rootDir/tools/gradle/base.gradle" + +android { + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + +} \ No newline at end of file diff --git a/models/localmodel/consumer-rules.pro b/models/localmodel/consumer-rules.pro new file mode 100644 index 0000000..e69de29 diff --git a/models/localmodel/proguard-rules.pro b/models/localmodel/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/models/localmodel/proguard-rules.pro @@ -0,0 +1,21 @@ +# 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 diff --git a/models/localmodel/src/androidTest/java/com/egdroid/models/local/ExampleInstrumentedTest.java b/models/localmodel/src/androidTest/java/com/egdroid/models/local/ExampleInstrumentedTest.java new file mode 100644 index 0000000..8bde83b --- /dev/null +++ b/models/localmodel/src/androidTest/java/com/egdroid/models/local/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.egdroid.models.local; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.egdroid.models.local.test", appContext.getPackageName()); + } +} diff --git a/models/localmodel/src/main/AndroidManifest.xml b/models/localmodel/src/main/AndroidManifest.xml new file mode 100644 index 0000000..229fad5 --- /dev/null +++ b/models/localmodel/src/main/AndroidManifest.xml @@ -0,0 +1 @@ + diff --git a/models/localmodel/src/main/java/com/egdroid/models/local/movie/MovieLocal.java b/models/localmodel/src/main/java/com/egdroid/models/local/movie/MovieLocal.java new file mode 100644 index 0000000..21afeb1 --- /dev/null +++ b/models/localmodel/src/main/java/com/egdroid/models/local/movie/MovieLocal.java @@ -0,0 +1,11 @@ +package com.egdroid.models.local.movie; + +public class MovieLocal { + + public final int id; + //more fields + + public MovieLocal(int id) { + this.id = id; + } +} diff --git a/models/localmodel/src/main/res/values/strings.xml b/models/localmodel/src/main/res/values/strings.xml new file mode 100644 index 0000000..3888986 --- /dev/null +++ b/models/localmodel/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + localmodel + diff --git a/models/localmodel/src/test/java/com/egdroid/models/local/ExampleUnitTest.java b/models/localmodel/src/test/java/com/egdroid/models/local/ExampleUnitTest.java new file mode 100644 index 0000000..5799b7e --- /dev/null +++ b/models/localmodel/src/test/java/com/egdroid/models/local/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.egdroid.models.local; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/models/mapper/.gitignore b/models/mapper/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/models/mapper/.gitignore @@ -0,0 +1 @@ +/build diff --git a/models/mapper/build.gradle b/models/mapper/build.gradle new file mode 100644 index 0000000..7cdb92e --- /dev/null +++ b/models/mapper/build.gradle @@ -0,0 +1,23 @@ +apply plugin: 'com.android.library' +apply from: "$project.rootDir/tools/gradle/script/quality.gradle" +apply from: "$project.rootDir/tools/gradle/base.gradle" + +android { + compileSdkVersion 28 + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + +} + +dependencies { + + implementation project(":models:remotemodel") + implementation project(":models:localmodel") + implementation project(":models:datasourcemodel") + +} diff --git a/models/mapper/consumer-rules.pro b/models/mapper/consumer-rules.pro new file mode 100644 index 0000000..e69de29 diff --git a/models/mapper/proguard-rules.pro b/models/mapper/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/models/mapper/proguard-rules.pro @@ -0,0 +1,21 @@ +# 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 diff --git a/models/mapper/src/androidTest/java/com/egdroid/mapper/ExampleInstrumentedTest.java b/models/mapper/src/androidTest/java/com/egdroid/mapper/ExampleInstrumentedTest.java new file mode 100644 index 0000000..14046e6 --- /dev/null +++ b/models/mapper/src/androidTest/java/com/egdroid/mapper/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.egdroid.mapper; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.egdroid.mapper.test", appContext.getPackageName()); + } +} diff --git a/models/mapper/src/main/AndroidManifest.xml b/models/mapper/src/main/AndroidManifest.xml new file mode 100644 index 0000000..a1e6b54 --- /dev/null +++ b/models/mapper/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + diff --git a/models/mapper/src/main/java/com/egdroid/mapper/MovieMapper.java b/models/mapper/src/main/java/com/egdroid/mapper/MovieMapper.java new file mode 100644 index 0000000..ce1aea3 --- /dev/null +++ b/models/mapper/src/main/java/com/egdroid/mapper/MovieMapper.java @@ -0,0 +1,17 @@ +package com.egdroid.mapper; + +import com.egdroid.model.datasource.MovieDataSource; +import com.egdroid.models.local.movie.MovieLocal; +import com.egdroid.models.remote.movie.MovieResponse; + +public class MovieMapper { + + public MovieDataSource mapToDataSource(MovieResponse movieResponse){ + return new MovieDataSource(movieResponse.id); + } + + public MovieDataSource mapToDataSource(MovieLocal movieLocal){ + return new MovieDataSource(movieLocal.id); + } + +} diff --git a/models/mapper/src/main/res/values/strings.xml b/models/mapper/src/main/res/values/strings.xml new file mode 100644 index 0000000..22d889b --- /dev/null +++ b/models/mapper/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + mapper + diff --git a/models/mapper/src/test/java/com/egdroid/mapper/ExampleUnitTest.java b/models/mapper/src/test/java/com/egdroid/mapper/ExampleUnitTest.java new file mode 100644 index 0000000..8c5a8b8 --- /dev/null +++ b/models/mapper/src/test/java/com/egdroid/mapper/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.egdroid.mapper; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/models/remotemodel/.gitignore b/models/remotemodel/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/models/remotemodel/.gitignore @@ -0,0 +1 @@ +/build diff --git a/models/remotemodel/build.gradle b/models/remotemodel/build.gradle new file mode 100644 index 0000000..a1b4430 --- /dev/null +++ b/models/remotemodel/build.gradle @@ -0,0 +1,14 @@ +apply plugin: 'com.android.library' +apply from: "$project.rootDir/tools/gradle/script/quality.gradle" +apply from: "$project.rootDir/tools/gradle/base.gradle" + +android { + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + +} diff --git a/models/remotemodel/consumer-rules.pro b/models/remotemodel/consumer-rules.pro new file mode 100644 index 0000000..e69de29 diff --git a/models/remotemodel/proguard-rules.pro b/models/remotemodel/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/models/remotemodel/proguard-rules.pro @@ -0,0 +1,21 @@ +# 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 diff --git a/models/remotemodel/src/androidTest/java/com/egdroid/models/remote/ExampleInstrumentedTest.java b/models/remotemodel/src/androidTest/java/com/egdroid/models/remote/ExampleInstrumentedTest.java new file mode 100644 index 0000000..1a97ba2 --- /dev/null +++ b/models/remotemodel/src/androidTest/java/com/egdroid/models/remote/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.egdroid.models.remote; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.egdroid.models.remote.test", appContext.getPackageName()); + } +} diff --git a/models/remotemodel/src/main/AndroidManifest.xml b/models/remotemodel/src/main/AndroidManifest.xml new file mode 100644 index 0000000..8edf1c8 --- /dev/null +++ b/models/remotemodel/src/main/AndroidManifest.xml @@ -0,0 +1 @@ + diff --git a/models/remotemodel/src/main/java/com/egdroid/models/remote/movie/MovieResponse.java b/models/remotemodel/src/main/java/com/egdroid/models/remote/movie/MovieResponse.java new file mode 100644 index 0000000..fb19873 --- /dev/null +++ b/models/remotemodel/src/main/java/com/egdroid/models/remote/movie/MovieResponse.java @@ -0,0 +1,11 @@ +package com.egdroid.models.remote.movie; + +public class MovieResponse { + + public final int id; + //more fields + + public MovieResponse(int id) { + this.id = id; + } +} diff --git a/models/remotemodel/src/main/res/values/strings.xml b/models/remotemodel/src/main/res/values/strings.xml new file mode 100644 index 0000000..85af1b3 --- /dev/null +++ b/models/remotemodel/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + remotemodel + diff --git a/models/remotemodel/src/test/java/com/egdroid/models/remote/ExampleUnitTest.java b/models/remotemodel/src/test/java/com/egdroid/models/remote/ExampleUnitTest.java new file mode 100644 index 0000000..329b3b7 --- /dev/null +++ b/models/remotemodel/src/test/java/com/egdroid/models/remote/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.egdroid.models.remote; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 7de50da..49faa91 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,3 @@ -include ':app', ':common', ':datasource:local', ':datasource:remote' -rootProject.name='AnotherMovieApp' +include ':app', ':common', ':models:remotemodel', ':models:localmodel', ':models:datasourcemodel', + ':features:upcomingmovies', ':datasource:local', ':datasource:remote', ':models:mapper' +rootProject.name = 'AnotherMovieApp' From 277e0baceb86558212b48f19d23d886bb84c1576 Mon Sep 17 00:00:00 2001 From: Ahmed Date: Mon, 9 Sep 2019 21:12:53 +0200 Subject: [PATCH 03/20] Create remote-model module with MovieResponse POJO class --- app/build.gradle | 2 ++ build.gradle | 4 +++- models/remotemodel/build.gradle | 2 ++ .../remote/movie/popularmovie/MovieResponse.kt | 18 ++++++++++++++++++ tools/gradle/base.gradle | 3 +++ tools/gradle/dependencies.gradle | 8 ++++++++ 6 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 models/remotemodel/src/main/java/com/egdroid/models/remote/movie/popularmovie/MovieResponse.kt diff --git a/app/build.gradle b/app/build.gradle index 205810a..a302ffe 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,4 +1,6 @@ apply plugin: 'com.android.application' +apply plugin: 'kotlin-android-extensions' +apply plugin: 'kotlin-android' apply from: "$project.rootDir/tools/gradle/script/quality.gradle" apply from: "$project.rootDir/tools/gradle/base.gradle" diff --git a/build.gradle b/build.gradle index 22f601a..d509b55 100644 --- a/build.gradle +++ b/build.gradle @@ -1,13 +1,15 @@ apply from: "$project.rootDir/tools/gradle/dependencies.gradle" buildscript { + ext.kotlin_version = '1.3.50' repositories { google() jcenter() - + mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:3.5.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/models/remotemodel/build.gradle b/models/remotemodel/build.gradle index a1b4430..4b552df 100644 --- a/models/remotemodel/build.gradle +++ b/models/remotemodel/build.gradle @@ -1,4 +1,6 @@ apply plugin: 'com.android.library' +apply plugin: 'kotlin-android-extensions' +apply plugin: 'kotlin-android' apply from: "$project.rootDir/tools/gradle/script/quality.gradle" apply from: "$project.rootDir/tools/gradle/base.gradle" diff --git a/models/remotemodel/src/main/java/com/egdroid/models/remote/movie/popularmovie/MovieResponse.kt b/models/remotemodel/src/main/java/com/egdroid/models/remote/movie/popularmovie/MovieResponse.kt new file mode 100644 index 0000000..35ec489 --- /dev/null +++ b/models/remotemodel/src/main/java/com/egdroid/models/remote/movie/popularmovie/MovieResponse.kt @@ -0,0 +1,18 @@ +package com.egdroid.models.remote.movie.popularmovie + +data class MovieResponse( + val overview: String? = null, + val originalLanguage: String? = null, + val originalTitle: String? = null, + val video: Boolean? = null, + val title: String? = null, + val genreIds: List? = null, + val posterPath: String? = null, + val backdropPath: String? = null, + val releaseDate: String? = null, + val popularity: Double? = null, + val voteAverage: Double? = null, + val id: Int? = null, + val adult: Boolean? = null, + val voteCount: Int? = null +) diff --git a/tools/gradle/base.gradle b/tools/gradle/base.gradle index 6869265..5421faa 100644 --- a/tools/gradle/base.gradle +++ b/tools/gradle/base.gradle @@ -60,6 +60,9 @@ dependencies { debugImplementation deps.log.leakCanaryDebug releaseImplementation deps.log.leakCanaryRelease + api deps.kotlin.kotlin + api deps.kotlin.kotlinCore + // Testing testImplementation deps.test.junit androidTestImplementation deps.test.runner diff --git a/tools/gradle/dependencies.gradle b/tools/gradle/dependencies.gradle index 0ac530c..b042027 100644 --- a/tools/gradle/dependencies.gradle +++ b/tools/gradle/dependencies.gradle @@ -22,6 +22,8 @@ def versions = [ powermock : '1.6.6', mockito : '1.9.5', robolectric: '3.8', + kotlinCore : '1.1.0', + kotlin : '1.3.50' ] def support = [ @@ -63,6 +65,11 @@ def image = [ glideCompiler: "com.github.bumptech.glide:compiler:${versions.glide}" ] +def kotlin = [ + kotlinCore: "androidx.core:core-ktx:${versions.kotlinCore}", + kotlin : "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${versions.kotlin}" +] + def test = [ junit : "junit:junit:${versions.junit}", runner : "com.android.support.test:runner:${versions.testrunner}", @@ -101,4 +108,5 @@ ext.deps = [ rx : rx, network : network, architecturecomponents: architecturecomponents, + kotlin: kotlin, ] \ No newline at end of file From 69423fd37229705e131fd4bf605c4344d4b77f58 Mon Sep 17 00:00:00 2001 From: Ahmed Date: Mon, 9 Sep 2019 21:13:54 +0200 Subject: [PATCH 04/20] Create local-model module with MovieLocal POJO class "which is room entity class". --- .../models/local/movie/MovieLocal.java | 11 --------- .../egdroid/models/local/movie/MovieLocal.kt | 23 +++++++++++++++++++ 2 files changed, 23 insertions(+), 11 deletions(-) delete mode 100644 models/localmodel/src/main/java/com/egdroid/models/local/movie/MovieLocal.java create mode 100644 models/localmodel/src/main/java/com/egdroid/models/local/movie/MovieLocal.kt diff --git a/models/localmodel/src/main/java/com/egdroid/models/local/movie/MovieLocal.java b/models/localmodel/src/main/java/com/egdroid/models/local/movie/MovieLocal.java deleted file mode 100644 index 21afeb1..0000000 --- a/models/localmodel/src/main/java/com/egdroid/models/local/movie/MovieLocal.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.egdroid.models.local.movie; - -public class MovieLocal { - - public final int id; - //more fields - - public MovieLocal(int id) { - this.id = id; - } -} diff --git a/models/localmodel/src/main/java/com/egdroid/models/local/movie/MovieLocal.kt b/models/localmodel/src/main/java/com/egdroid/models/local/movie/MovieLocal.kt new file mode 100644 index 0000000..0697c87 --- /dev/null +++ b/models/localmodel/src/main/java/com/egdroid/models/local/movie/MovieLocal.kt @@ -0,0 +1,23 @@ +package com.egdroid.models.local.movie + +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Entity(tableName = "movies") +data class MovieLocal( + val overview: String? = null, + val originalLanguage: String? = null, + val originalTitle: String? = null, + val video: Boolean? = null, + val title: String? = null, + val genreIds: List? = null, + val posterPath: String? = null, + val backdropPath: String? = null, + val releaseDate: String? = null, + val popularity: Double? = null, + val voteAverage: Double? = null, + @PrimaryKey(autoGenerate = false) + val id: Int, + val adult: Boolean? = null, + val voteCount: Int? = null +) From ee441620540c65af42defaee50e68b3d4c8c2ebc Mon Sep 17 00:00:00 2001 From: Ahmed Date: Thu, 12 Sep 2019 23:31:58 +0200 Subject: [PATCH 05/20] - Create models package that will contains remote-model, local-model, datasource-model and mapper - Create remote-model module with MovieResponse POJO class - Create local-model module with MovieLocal POJO class "which is room entity class". - Create datasource-model module with MovieDataSource POJO class - Create mapper module that contains mapper classes which maps datasource models to entity models. --- build.gradle | 3 +- .../model/datasource/MovieDataSource.java | 12 ---- .../model/datasource/MovieDataSource.kt | 8 +++ .../egdroid/models/local/movie/MovieLocal.kt | 17 ++--- models/mapper/build.gradle | 11 +--- .../java/com/egdroid/mapper/MapperFactory.kt | 8 +++ .../java/com/egdroid/mapper/MovieMapper.java | 17 ----- .../java/com/egdroid/mapper/MovieMapper.kt | 65 +++++++++++++++++++ models/remotemodel/build.gradle | 2 - .../models/remote/movie/MovieResponse.java | 11 ---- .../remote/movie/popularmovie/MovieRemote.kt | 33 ++++++++++ .../movie/popularmovie/MovieResponse.kt | 18 ++--- settings.gradle | 1 + tools/gradle/base.gradle | 9 ++- tools/gradle/dependencies.gradle | 9 ++- 15 files changed, 143 insertions(+), 81 deletions(-) delete mode 100644 models/datasourcemodel/src/main/java/com/egdroid/model/datasource/MovieDataSource.java create mode 100644 models/datasourcemodel/src/main/java/com/egdroid/model/datasource/MovieDataSource.kt create mode 100644 models/mapper/src/main/java/com/egdroid/mapper/MapperFactory.kt delete mode 100644 models/mapper/src/main/java/com/egdroid/mapper/MovieMapper.java create mode 100644 models/mapper/src/main/java/com/egdroid/mapper/MovieMapper.kt delete mode 100644 models/remotemodel/src/main/java/com/egdroid/models/remote/movie/MovieResponse.java create mode 100644 models/remotemodel/src/main/java/com/egdroid/models/remote/movie/popularmovie/MovieRemote.kt diff --git a/build.gradle b/build.gradle index d509b55..3b16c23 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ apply from: "$project.rootDir/tools/gradle/dependencies.gradle" buildscript { - ext.kotlin_version = '1.3.50' + ext.kotlin_version = '1.3.41' repositories { google() jcenter() @@ -17,6 +17,7 @@ allprojects { repositories { google() jcenter() + mavenCentral() } } diff --git a/models/datasourcemodel/src/main/java/com/egdroid/model/datasource/MovieDataSource.java b/models/datasourcemodel/src/main/java/com/egdroid/model/datasource/MovieDataSource.java deleted file mode 100644 index 5299a14..0000000 --- a/models/datasourcemodel/src/main/java/com/egdroid/model/datasource/MovieDataSource.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.egdroid.model.datasource; - -public class MovieDataSource { - - public final int id; - //more fields - - public MovieDataSource(int id) { - this.id = id; - } - -} diff --git a/models/datasourcemodel/src/main/java/com/egdroid/model/datasource/MovieDataSource.kt b/models/datasourcemodel/src/main/java/com/egdroid/model/datasource/MovieDataSource.kt new file mode 100644 index 0000000..6f09a29 --- /dev/null +++ b/models/datasourcemodel/src/main/java/com/egdroid/model/datasource/MovieDataSource.kt @@ -0,0 +1,8 @@ +package com.egdroid.model.datasource + +data class MovieDataSource( + val id: Int? = null, + val title: String? = null, + val overview: String? = null, + val posterPath: String? = null +) \ No newline at end of file diff --git a/models/localmodel/src/main/java/com/egdroid/models/local/movie/MovieLocal.kt b/models/localmodel/src/main/java/com/egdroid/models/local/movie/MovieLocal.kt index 0697c87..6627ca1 100644 --- a/models/localmodel/src/main/java/com/egdroid/models/local/movie/MovieLocal.kt +++ b/models/localmodel/src/main/java/com/egdroid/models/local/movie/MovieLocal.kt @@ -5,19 +5,10 @@ import androidx.room.PrimaryKey @Entity(tableName = "movies") data class MovieLocal( - val overview: String? = null, - val originalLanguage: String? = null, - val originalTitle: String? = null, - val video: Boolean? = null, - val title: String? = null, - val genreIds: List? = null, - val posterPath: String? = null, - val backdropPath: String? = null, - val releaseDate: String? = null, - val popularity: Double? = null, - val voteAverage: Double? = null, @PrimaryKey(autoGenerate = false) val id: Int, - val adult: Boolean? = null, - val voteCount: Int? = null + val title: String? = null, + val overview: String? = null, + val posterPath: String? = null + ) diff --git a/models/mapper/build.gradle b/models/mapper/build.gradle index 7cdb92e..ecd79a5 100644 --- a/models/mapper/build.gradle +++ b/models/mapper/build.gradle @@ -3,21 +3,16 @@ apply from: "$project.rootDir/tools/gradle/script/quality.gradle" apply from: "$project.rootDir/tools/gradle/base.gradle" android { - compileSdkVersion 28 - buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } - } dependencies { - - implementation project(":models:remotemodel") - implementation project(":models:localmodel") - implementation project(":models:datasourcemodel") - + api project(":models:remotemodel") + api project(":models:localmodel") + api project(":models:datasourcemodel") } diff --git a/models/mapper/src/main/java/com/egdroid/mapper/MapperFactory.kt b/models/mapper/src/main/java/com/egdroid/mapper/MapperFactory.kt new file mode 100644 index 0000000..c8d356a --- /dev/null +++ b/models/mapper/src/main/java/com/egdroid/mapper/MapperFactory.kt @@ -0,0 +1,8 @@ +package com.egdroid.mapper + +object MapperFactory { + + fun providePopularMovieMapper(): MovieMapper { + return MovieMapper() + } +} \ No newline at end of file diff --git a/models/mapper/src/main/java/com/egdroid/mapper/MovieMapper.java b/models/mapper/src/main/java/com/egdroid/mapper/MovieMapper.java deleted file mode 100644 index ce1aea3..0000000 --- a/models/mapper/src/main/java/com/egdroid/mapper/MovieMapper.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.egdroid.mapper; - -import com.egdroid.model.datasource.MovieDataSource; -import com.egdroid.models.local.movie.MovieLocal; -import com.egdroid.models.remote.movie.MovieResponse; - -public class MovieMapper { - - public MovieDataSource mapToDataSource(MovieResponse movieResponse){ - return new MovieDataSource(movieResponse.id); - } - - public MovieDataSource mapToDataSource(MovieLocal movieLocal){ - return new MovieDataSource(movieLocal.id); - } - -} diff --git a/models/mapper/src/main/java/com/egdroid/mapper/MovieMapper.kt b/models/mapper/src/main/java/com/egdroid/mapper/MovieMapper.kt new file mode 100644 index 0000000..8adc636 --- /dev/null +++ b/models/mapper/src/main/java/com/egdroid/mapper/MovieMapper.kt @@ -0,0 +1,65 @@ +package com.egdroid.mapper + +import com.egdroid.model.datasource.MovieDataSource +import com.egdroid.models.local.movie.MovieLocal +import com.egdroid.models.remote.movie.popularmovie.MovieRemote + +class MovieMapper { + + fun mapDataSourceToMovieLocal(movieDataSource: MovieDataSource): MovieLocal { + return MovieLocal( + movieDataSource.id!!, + movieDataSource.title, + movieDataSource.overview, + movieDataSource.posterPath + ) + } + + fun mapMovieLocalToDataSource(movieLocal: List): List { + val moviesDataSource = mutableListOf() + for (movie in movieLocal) { + moviesDataSource.add(MovieDataSource( + movie.id, + movie.title, + movie.overview, + movie.posterPath + )) + } + return moviesDataSource + } + + fun mapMovieResponseToDataSource(moviesResponse: List): List { + val moviesDataSource = mutableListOf() + for (movie in moviesResponse) { + moviesDataSource.add(MovieDataSource( + movie.id, + movie.title, + movie.overview, + movie.poster_path + )) + } + return moviesDataSource + } + + fun mapMovieResponseToLocalMovie(moviesResponse: List): List { + val moviesDataSource = mutableListOf() + for (movie in moviesResponse) { + moviesDataSource.add(MovieLocal( + movie.id, + movie.title, + movie.overview, + movie.poster_path + )) + } + return moviesDataSource + } + + fun mapMovieDataSourceToMovieLocal(movieDataSource: MovieDataSource): MovieLocal { + return MovieLocal( + movieDataSource.id!!, + movieDataSource.title, + movieDataSource.overview, + movieDataSource.posterPath + ) + } +} diff --git a/models/remotemodel/build.gradle b/models/remotemodel/build.gradle index 4b552df..a1b4430 100644 --- a/models/remotemodel/build.gradle +++ b/models/remotemodel/build.gradle @@ -1,6 +1,4 @@ apply plugin: 'com.android.library' -apply plugin: 'kotlin-android-extensions' -apply plugin: 'kotlin-android' apply from: "$project.rootDir/tools/gradle/script/quality.gradle" apply from: "$project.rootDir/tools/gradle/base.gradle" diff --git a/models/remotemodel/src/main/java/com/egdroid/models/remote/movie/MovieResponse.java b/models/remotemodel/src/main/java/com/egdroid/models/remote/movie/MovieResponse.java deleted file mode 100644 index fb19873..0000000 --- a/models/remotemodel/src/main/java/com/egdroid/models/remote/movie/MovieResponse.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.egdroid.models.remote.movie; - -public class MovieResponse { - - public final int id; - //more fields - - public MovieResponse(int id) { - this.id = id; - } -} diff --git a/models/remotemodel/src/main/java/com/egdroid/models/remote/movie/popularmovie/MovieRemote.kt b/models/remotemodel/src/main/java/com/egdroid/models/remote/movie/popularmovie/MovieRemote.kt new file mode 100644 index 0000000..b36a60a --- /dev/null +++ b/models/remotemodel/src/main/java/com/egdroid/models/remote/movie/popularmovie/MovieRemote.kt @@ -0,0 +1,33 @@ +package com.egdroid.models.remote.movie.popularmovie + +import com.google.gson.annotations.SerializedName + +data class MovieRemote( + @SerializedName("popularity") + val popularity: Double, + @SerializedName("vote_count") + val vote_count: Int, + @SerializedName("video") + val video: Boolean, + @SerializedName("poster_path") + val poster_path: String, + @SerializedName("id") + val id: Int, + @SerializedName("adult") + val adult: Boolean, + @SerializedName("backdrop_path") + val backdrop_path: String, + @SerializedName("original_language") + val original_language: String, + @SerializedName("original_title") + val original_title: String, + @SerializedName("genre_ids") + val genre_ids: List, + @SerializedName("title") + val title: String, + @SerializedName("vote_average") + val vote_average: Double, + @SerializedName("overview") + val overview: String, + @SerializedName("release_date") + val release_date: String) diff --git a/models/remotemodel/src/main/java/com/egdroid/models/remote/movie/popularmovie/MovieResponse.kt b/models/remotemodel/src/main/java/com/egdroid/models/remote/movie/popularmovie/MovieResponse.kt index 35ec489..5027a28 100644 --- a/models/remotemodel/src/main/java/com/egdroid/models/remote/movie/popularmovie/MovieResponse.kt +++ b/models/remotemodel/src/main/java/com/egdroid/models/remote/movie/popularmovie/MovieResponse.kt @@ -1,18 +1,8 @@ package com.egdroid.models.remote.movie.popularmovie data class MovieResponse( - val overview: String? = null, - val originalLanguage: String? = null, - val originalTitle: String? = null, - val video: Boolean? = null, - val title: String? = null, - val genreIds: List? = null, - val posterPath: String? = null, - val backdropPath: String? = null, - val releaseDate: String? = null, - val popularity: Double? = null, - val voteAverage: Double? = null, - val id: Int? = null, - val adult: Boolean? = null, - val voteCount: Int? = null + val page: Int? = null, + val totalPages: Int? = null, + val results: List? = null, + val totalResults: Int? = null ) diff --git a/settings.gradle b/settings.gradle index 49faa91..917e530 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,3 +1,4 @@ include ':app', ':common', ':models:remotemodel', ':models:localmodel', ':models:datasourcemodel', + ':features:popularmovies', ':presentation:popularmoviespresentation', ':features:upcomingmovies', ':datasource:local', ':datasource:remote', ':models:mapper' rootProject.name = 'AnotherMovieApp' diff --git a/tools/gradle/base.gradle b/tools/gradle/base.gradle index 5421faa..7b18b42 100644 --- a/tools/gradle/base.gradle +++ b/tools/gradle/base.gradle @@ -1,3 +1,7 @@ +apply plugin: 'kotlin-android-extensions' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-kapt' + android { compileSdkVersion deps.build.compileSdkVersion @@ -23,12 +27,14 @@ dependencies { //UI implementation deps.support.design implementation deps.support.recyclerview + implementation deps.support.superRecyclerView implementation deps.support.constraintLayout // Arch Component implementation deps.architecturecomponents.lifecycles implementation deps.architecturecomponents.room - annotationProcessor deps.architecturecomponents.room_compiler + implementation deps.architecturecomponents.room_kotlin + kapt deps.architecturecomponents.room_compiler // Rx api deps.rx.java @@ -54,6 +60,7 @@ dependencies { // Network implementation deps.network.retrofit implementation deps.network.retrofitGsonConverter + implementation deps.network.okhttpLogging // Log implementation deps.log.timber diff --git a/tools/gradle/dependencies.gradle b/tools/gradle/dependencies.gradle index b042027..6084bfe 100644 --- a/tools/gradle/dependencies.gradle +++ b/tools/gradle/dependencies.gradle @@ -23,7 +23,9 @@ def versions = [ mockito : '1.9.5', robolectric: '3.8', kotlinCore : '1.1.0', - kotlin : '1.3.50' + kotlin : '1.3.50', + okhttpLogging : '3.12.0', + superRecyclerView : '1.1.4' ] def support = [ @@ -31,6 +33,7 @@ def support = [ design : "com.android.support:design:${versions.support}", recyclerview : "com.android.support:recyclerview-v7:${versions.support}", constraintLayout: 'com.android.support.constraint:constraint-layout:1.0.2', + superRecyclerView: "com.malinskiy:superrecyclerview:${versions.superRecyclerView}" ] def rx = [ @@ -43,7 +46,8 @@ def rx = [ def network = [ retrofit : "com.squareup.retrofit2:retrofit:${versions.retrofit}", - retrofitGsonConverter: "com.squareup.retrofit2:converter-gson:${versions.retrofit}" + retrofitGsonConverter: "com.squareup.retrofit2:converter-gson:${versions.retrofit}", + okhttpLogging: "com.squareup.okhttp3:logging-interceptor:${versions.okhttpLogging}" ] def dependencyInjection = [ @@ -87,6 +91,7 @@ def test = [ def architecturecomponents = [ lifecycles : "android.arch.lifecycle:common-java8:1.1.0", room : "androidx.room:room-runtime:${versions.room}", + room_kotlin : "androidx.room:room-ktx:${versions.room}", room_compiler: "androidx.room:room-compiler:${versions.room}", ] From 7b9c7bd4e35816ccbd47a6ccc0465559357b88ea Mon Sep 17 00:00:00 2001 From: Ahmed Date: Thu, 12 Sep 2019 23:35:58 +0200 Subject: [PATCH 06/20] - Create datasource package that will contains remote and local modules. - Create remote module for initializing network library "which is retrofit". - Create local module for initializing local library "which is room". - Create MovieDao for CRUD operations and MovieDatabase for room database integration. --- datasource/local/build.gradle | 9 +- .../datasource/local/MovieLocalDatabase.java | 11 -- .../datasource/local/movie/DataConverter.kt | 30 ++++++ .../local/movie/LocalMovieFactory.kt | 10 ++ .../datasource/local/movie/MovieDao.kt | 21 ++++ .../local/movie/MovieLocalDatabase.kt | 37 +++++++ datasource/remote/build.gradle | 9 +- .../remote/src/main/AndroidManifest.xml | 7 +- .../datasource/remote/MovieRemote.java | 11 -- .../datasource/remote/movie/MovieRemote.kt | 3 + .../remote/movie/MoviesServiceFactory.kt | 100 ++++++++++++++++++ .../remote/movie/PopularMovieService.kt | 12 +++ .../datasource/remote/utils/NetworkUtils.kt | 15 +++ 13 files changed, 240 insertions(+), 35 deletions(-) delete mode 100644 datasource/local/src/main/java/com/egdroid/datasource/local/MovieLocalDatabase.java create mode 100644 datasource/local/src/main/java/com/egdroid/datasource/local/movie/DataConverter.kt create mode 100644 datasource/local/src/main/java/com/egdroid/datasource/local/movie/LocalMovieFactory.kt create mode 100644 datasource/local/src/main/java/com/egdroid/datasource/local/movie/MovieDao.kt create mode 100644 datasource/local/src/main/java/com/egdroid/datasource/local/movie/MovieLocalDatabase.kt delete mode 100644 datasource/remote/src/main/java/com/egdroid/datasource/remote/MovieRemote.java create mode 100644 datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/MovieRemote.kt create mode 100644 datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/MoviesServiceFactory.kt create mode 100644 datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/PopularMovieService.kt create mode 100644 datasource/remote/src/main/java/com/egdroid/datasource/remote/utils/NetworkUtils.kt diff --git a/datasource/local/build.gradle b/datasource/local/build.gradle index 247c60f..a3d0e29 100644 --- a/datasource/local/build.gradle +++ b/datasource/local/build.gradle @@ -10,11 +10,8 @@ android { proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } +} - dependencies{ - - api project(":models:localmodel") - - } - +dependencies{ + api project(":models:localmodel") } diff --git a/datasource/local/src/main/java/com/egdroid/datasource/local/MovieLocalDatabase.java b/datasource/local/src/main/java/com/egdroid/datasource/local/MovieLocalDatabase.java deleted file mode 100644 index 97eecc8..0000000 --- a/datasource/local/src/main/java/com/egdroid/datasource/local/MovieLocalDatabase.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.egdroid.datasource.local; - -import com.egdroid.models.local.movie.MovieLocal; - -public class MovieLocalDatabase { - - public MovieLocal getMovie() { - return new MovieLocal(12); - } - -} diff --git a/datasource/local/src/main/java/com/egdroid/datasource/local/movie/DataConverter.kt b/datasource/local/src/main/java/com/egdroid/datasource/local/movie/DataConverter.kt new file mode 100644 index 0000000..97070ee --- /dev/null +++ b/datasource/local/src/main/java/com/egdroid/datasource/local/movie/DataConverter.kt @@ -0,0 +1,30 @@ +package com.egdroid.datasource.local.movie + +import androidx.room.TypeConverter +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken + +class DataConverter { + + companion object { + @TypeConverter + @JvmStatic + fun fromIntList(list: List?): String? { + if (list == null) { + return null + } + val type = object : TypeToken>() {}.type + return Gson().toJson(list, type) + } + + @TypeConverter + @JvmStatic + fun toIntList(listString: String?): List? { + if (listString == null) { + return null + } + val type = object : TypeToken>() {}.type + return Gson().fromJson>(listString, type) + } + } +} \ No newline at end of file diff --git a/datasource/local/src/main/java/com/egdroid/datasource/local/movie/LocalMovieFactory.kt b/datasource/local/src/main/java/com/egdroid/datasource/local/movie/LocalMovieFactory.kt new file mode 100644 index 0000000..635eb23 --- /dev/null +++ b/datasource/local/src/main/java/com/egdroid/datasource/local/movie/LocalMovieFactory.kt @@ -0,0 +1,10 @@ +package com.egdroid.datasource.local.movie + +import android.content.Context + +object LocalMovieFactory { + + fun provideDatabase(context: Context): MovieLocalDatabase { + return MovieLocalDatabase.getDatabase(context) + } +} diff --git a/datasource/local/src/main/java/com/egdroid/datasource/local/movie/MovieDao.kt b/datasource/local/src/main/java/com/egdroid/datasource/local/movie/MovieDao.kt new file mode 100644 index 0000000..1e228b9 --- /dev/null +++ b/datasource/local/src/main/java/com/egdroid/datasource/local/movie/MovieDao.kt @@ -0,0 +1,21 @@ +package com.egdroid.datasource.local.movie + +import androidx.lifecycle.LiveData +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query +import com.egdroid.models.local.movie.MovieLocal + +@Dao +interface MovieDao { + + @Query("SELECT * FROM movies") + fun getAllMovies(): LiveData> + + @Insert(onConflict = OnConflictStrategy.REPLACE) + fun insertAllMovies(movies: List) + + @Query("DELETE FROM movies") + fun deleteAllMovies() +} \ No newline at end of file diff --git a/datasource/local/src/main/java/com/egdroid/datasource/local/movie/MovieLocalDatabase.kt b/datasource/local/src/main/java/com/egdroid/datasource/local/movie/MovieLocalDatabase.kt new file mode 100644 index 0000000..8a6ec14 --- /dev/null +++ b/datasource/local/src/main/java/com/egdroid/datasource/local/movie/MovieLocalDatabase.kt @@ -0,0 +1,37 @@ +package com.egdroid.datasource.local.movie + +import android.content.Context +import androidx.room.Database +import androidx.room.Room +import androidx.room.RoomDatabase +import androidx.room.TypeConverters +import com.egdroid.models.local.movie.MovieLocal + +@Database(entities = [MovieLocal::class], version = 1) +@TypeConverters(DataConverter::class) +abstract class MovieLocalDatabase : RoomDatabase() { + abstract fun movieDao(): MovieDao + + companion object { + // Singleton prevents multiple instances of database opening at the + // same time. + @Volatile + private var INSTANCE: MovieLocalDatabase? = null + + fun getDatabase(context: Context): MovieLocalDatabase { + val tempInstance = INSTANCE + if (tempInstance != null) { + return tempInstance + } + synchronized(this) { + val instance = Room.databaseBuilder( + context.applicationContext, + MovieLocalDatabase::class.java, + "movies_database" + ).build() + INSTANCE = instance + return instance + } + } + } +} diff --git a/datasource/remote/build.gradle b/datasource/remote/build.gradle index b043839..cd6efff 100644 --- a/datasource/remote/build.gradle +++ b/datasource/remote/build.gradle @@ -10,11 +10,8 @@ android { proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } +} - dependencies{ - - api project(":models:remotemodel") - - } - +dependencies{ + api project(":models:remotemodel") } diff --git a/datasource/remote/src/main/AndroidManifest.xml b/datasource/remote/src/main/AndroidManifest.xml index 0de894b..b26f111 100644 --- a/datasource/remote/src/main/AndroidManifest.xml +++ b/datasource/remote/src/main/AndroidManifest.xml @@ -1 +1,6 @@ - + + + + + + diff --git a/datasource/remote/src/main/java/com/egdroid/datasource/remote/MovieRemote.java b/datasource/remote/src/main/java/com/egdroid/datasource/remote/MovieRemote.java deleted file mode 100644 index 5d602d3..0000000 --- a/datasource/remote/src/main/java/com/egdroid/datasource/remote/MovieRemote.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.egdroid.datasource.remote; - -import com.egdroid.models.remote.movie.MovieResponse; - -public class MovieRemote { - - public MovieResponse getMovie(){ - return new MovieResponse(2); - } - -} diff --git a/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/MovieRemote.kt b/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/MovieRemote.kt new file mode 100644 index 0000000..1f1440a --- /dev/null +++ b/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/MovieRemote.kt @@ -0,0 +1,3 @@ +package com.egdroid.datasource.remote.movie + +class MovieRemote diff --git a/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/MoviesServiceFactory.kt b/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/MoviesServiceFactory.kt new file mode 100644 index 0000000..a3a9722 --- /dev/null +++ b/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/MoviesServiceFactory.kt @@ -0,0 +1,100 @@ +package com.egdroid.datasource.remote.movie + +import android.content.Context +import com.egdroid.datasource.remote.utils.NetworkUtils +import okhttp3.Cache +import okhttp3.CacheControl +import okhttp3.Interceptor +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory +import timber.log.Timber +import java.io.File +import java.util.concurrent.TimeUnit + +object MoviesServiceFactory { + + fun provideRetrofitService(context: Context): PopularMovieService { + return provideRetrofit(context).create(PopularMovieService::class.java) + + } + + fun provideRetrofit(context: Context): Retrofit { + return Retrofit.Builder() + .baseUrl("https://api.themoviedb.org/3/movie/") + .addConverterFactory(GsonConverterFactory.create()) + .client(provideOkHttpClient(context)) + .build() + } + + private fun provideOkHttpClient(context: Context): OkHttpClient { + return OkHttpClient.Builder() + .addInterceptor(provideLoggingInterceptor()) +// .addInterceptor(provideAuthInterceptor()) + .addInterceptor(provideCashingInterceptor()) + .addNetworkInterceptor(provideOfflineCashingInterceptor(context)) + .cache(provideCache(context)) + .build() + } + + private fun provideLoggingInterceptor(): Interceptor { + val logging = HttpLoggingInterceptor() + logging.level = HttpLoggingInterceptor.Level.HEADERS + logging.level = HttpLoggingInterceptor.Level.BODY + return logging + } + + private fun provideAuthInterceptor(): Interceptor { + return Interceptor { chain -> + val request = chain.request().newBuilder() + .addHeader("Application-Auth", "key") + .build() + chain.proceed(request) + } + } + + private fun provideCache(context: Context): Cache? { + var cache: Cache? = null + try { + // 10 MB for cache + val file = File(context.cacheDir, "okhttp_cache") + cache = Cache(file, 10 * 1024 * 1024) + } catch (e: Exception) { + Timber.w("Failed to create cache. Error: $e") + } + return cache + } + + private fun provideCashingInterceptor(): Interceptor { + return Interceptor { chain -> + val response = chain.proceed(chain.request()) + val cashControl = CacheControl.Builder() + .maxAge(3, TimeUnit.MINUTES) + .build() + response.newBuilder() + .header("Cache-Control", cashControl.toString()) + .build() + } + } + + // even if cashing time passed and user don't have network fetch data from cache + private fun provideOfflineCashingInterceptor(context: Context): Interceptor { + return Interceptor { chain -> + val request = chain.request() + + if (!NetworkUtils.isNetworkConnected(context)) { + val cacheControl = CacheControl.Builder() + .maxStale(7, TimeUnit.DAYS) + .build() + + request.newBuilder() + .cacheControl(cacheControl) + .build() + } + chain.proceed(request) + } + } + + +} \ No newline at end of file diff --git a/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/PopularMovieService.kt b/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/PopularMovieService.kt new file mode 100644 index 0000000..dba6b52 --- /dev/null +++ b/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/PopularMovieService.kt @@ -0,0 +1,12 @@ +package com.egdroid.datasource.remote.movie + +import com.egdroid.models.remote.movie.popularmovie.MovieResponse +import retrofit2.Call +import retrofit2.http.GET + + +interface PopularMovieService { + + @GET("popular?api_key=828157095a54ed8f68b8882624ed7660&language=en-US&page=1") + fun getMovies(): Call +} \ No newline at end of file diff --git a/datasource/remote/src/main/java/com/egdroid/datasource/remote/utils/NetworkUtils.kt b/datasource/remote/src/main/java/com/egdroid/datasource/remote/utils/NetworkUtils.kt new file mode 100644 index 0000000..394c476 --- /dev/null +++ b/datasource/remote/src/main/java/com/egdroid/datasource/remote/utils/NetworkUtils.kt @@ -0,0 +1,15 @@ +package com.egdroid.datasource.remote.utils + +import android.content.Context +import android.net.ConnectivityManager +import android.net.NetworkInfo + +object NetworkUtils { + fun isNetworkConnected(context: Context): Boolean { + val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) + return if (connectivityManager is ConnectivityManager) { + val networkInfo: NetworkInfo? = connectivityManager.activeNetworkInfo + networkInfo?.isConnected ?: false + } else false + } +} \ No newline at end of file From 7272a0323bc92c935de8c17b2a41815ea623cee7 Mon Sep 17 00:00:00 2001 From: Ahmed Date: Thu, 12 Sep 2019 23:38:36 +0200 Subject: [PATCH 07/20] - Create features package that will contains all the application features modules inside it. - Create popular-movies module inside features package. - Create PopularMovieRepo class inside repository package that handles offline first architecture. - Create PopularMovieUseCase class inside usecase package that deals with PopularMovieRepo class - Create PopularMovieService interface that contains retrofit functions --- features/popularmovies/.gitignore | 1 + features/popularmovies/build.gradle | 21 ++++++++++ features/popularmovies/consumer-rules.pro | 0 features/popularmovies/proguard-rules.pro | 21 ++++++++++ .../popularmovies/ExampleInstrumentedTest.kt | 22 ++++++++++ .../src/main/AndroidManifest.xml | 1 + .../repository/PopularMovieRepo.kt | 42 +++++++++++++++++++ .../repository/PopularMoviesRepoFactory.kt | 13 ++++++ .../usecase/PopularMovieUseCase.kt | 9 ++++ .../usecase/PopularMoviesUseCaseFactory.kt | 11 +++++ .../src/main/res/values/strings.xml | 3 ++ .../features/popularmovies/ExampleUnitTest.kt | 16 +++++++ features/upcomingmovies/build.gradle | 23 ++-------- .../feature/upcomingmovies/rep/MovieRepo.java | 41 ++++++++---------- 14 files changed, 180 insertions(+), 44 deletions(-) create mode 100644 features/popularmovies/.gitignore create mode 100644 features/popularmovies/build.gradle create mode 100644 features/popularmovies/consumer-rules.pro create mode 100644 features/popularmovies/proguard-rules.pro create mode 100644 features/popularmovies/src/androidTest/java/com/egdroid/features/popularmovies/ExampleInstrumentedTest.kt create mode 100644 features/popularmovies/src/main/AndroidManifest.xml create mode 100644 features/popularmovies/src/main/java/com/egdroid/features/popularmovies/repository/PopularMovieRepo.kt create mode 100644 features/popularmovies/src/main/java/com/egdroid/features/popularmovies/repository/PopularMoviesRepoFactory.kt create mode 100644 features/popularmovies/src/main/java/com/egdroid/features/popularmovies/usecase/PopularMovieUseCase.kt create mode 100644 features/popularmovies/src/main/java/com/egdroid/features/popularmovies/usecase/PopularMoviesUseCaseFactory.kt create mode 100644 features/popularmovies/src/main/res/values/strings.xml create mode 100644 features/popularmovies/src/test/java/com/egdroid/features/popularmovies/ExampleUnitTest.kt diff --git a/features/popularmovies/.gitignore b/features/popularmovies/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/features/popularmovies/.gitignore @@ -0,0 +1 @@ +/build diff --git a/features/popularmovies/build.gradle b/features/popularmovies/build.gradle new file mode 100644 index 0000000..2bc5b55 --- /dev/null +++ b/features/popularmovies/build.gradle @@ -0,0 +1,21 @@ +apply plugin: 'com.android.library' +apply from: "$project.rootDir/tools/gradle/script/quality.gradle" +apply from: "$project.rootDir/tools/gradle/base.gradle" + +android { + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } +} + +dependencies{ + api project(":datasource:local") + api project(":datasource:remote") + api project(":models:localmodel") + api project(":models:remotemodel") + api project(":models:mapper") + api project(":models:datasourcemodel") +} diff --git a/features/popularmovies/consumer-rules.pro b/features/popularmovies/consumer-rules.pro new file mode 100644 index 0000000..e69de29 diff --git a/features/popularmovies/proguard-rules.pro b/features/popularmovies/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/features/popularmovies/proguard-rules.pro @@ -0,0 +1,21 @@ +# 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 diff --git a/features/popularmovies/src/androidTest/java/com/egdroid/features/popularmovies/ExampleInstrumentedTest.kt b/features/popularmovies/src/androidTest/java/com/egdroid/features/popularmovies/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..2073145 --- /dev/null +++ b/features/popularmovies/src/androidTest/java/com/egdroid/features/popularmovies/ExampleInstrumentedTest.kt @@ -0,0 +1,22 @@ +package com.egdroid.features.popularmovies + +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("com.egdroid.features.popularmovies.test", appContext.packageName) + } +} diff --git a/features/popularmovies/src/main/AndroidManifest.xml b/features/popularmovies/src/main/AndroidManifest.xml new file mode 100644 index 0000000..13bb866 --- /dev/null +++ b/features/popularmovies/src/main/AndroidManifest.xml @@ -0,0 +1 @@ + diff --git a/features/popularmovies/src/main/java/com/egdroid/features/popularmovies/repository/PopularMovieRepo.kt b/features/popularmovies/src/main/java/com/egdroid/features/popularmovies/repository/PopularMovieRepo.kt new file mode 100644 index 0000000..3efc8c1 --- /dev/null +++ b/features/popularmovies/src/main/java/com/egdroid/features/popularmovies/repository/PopularMovieRepo.kt @@ -0,0 +1,42 @@ +package com.egdroid.features.popularmovies.repository + +import androidx.lifecycle.LiveData +import androidx.lifecycle.Transformations +import com.egdroid.datasource.local.movie.MovieLocalDatabase +import com.egdroid.datasource.remote.movie.PopularMovieService +import com.egdroid.mapper.MovieMapper +import com.egdroid.model.datasource.MovieDataSource +import com.egdroid.models.remote.movie.popularmovie.MovieResponse +import retrofit2.Call +import retrofit2.Callback +import retrofit2.Response +import kotlin.concurrent.thread + +class PopularMovieRepo(private val database: MovieLocalDatabase, + private val popularMovieService: PopularMovieService, + private val mapper: MovieMapper) { + + fun getLocalMovies(): LiveData> { + getRemoteMovies() + return Transformations.map(database.movieDao().getAllMovies()) { + mapper.mapMovieLocalToDataSource(it) + } + } + + private fun getRemoteMovies() { + popularMovieService.getMovies().enqueue(object : Callback { + override fun onResponse(call: Call, + response: Response) { + if (response.isSuccessful) { + thread { + database.movieDao().deleteAllMovies() + database.movieDao() + .insertAllMovies(mapper.mapMovieResponseToLocalMovie(response.body().results!!)) + } + } + } + + override fun onFailure(call: Call, t: Throwable?) {} + }) + } +} \ No newline at end of file diff --git a/features/popularmovies/src/main/java/com/egdroid/features/popularmovies/repository/PopularMoviesRepoFactory.kt b/features/popularmovies/src/main/java/com/egdroid/features/popularmovies/repository/PopularMoviesRepoFactory.kt new file mode 100644 index 0000000..94d9888 --- /dev/null +++ b/features/popularmovies/src/main/java/com/egdroid/features/popularmovies/repository/PopularMoviesRepoFactory.kt @@ -0,0 +1,13 @@ +package com.egdroid.features.popularmovies.repository + +import android.content.Context +import com.egdroid.datasource.local.movie.LocalMovieFactory.provideDatabase +import com.egdroid.datasource.remote.movie.MoviesServiceFactory.provideRetrofitService +import com.egdroid.mapper.MapperFactory.providePopularMovieMapper + +object PopularMoviesRepoFactory { + + fun providePopularMoviesRepo(context: Context): PopularMovieRepo { + return PopularMovieRepo(provideDatabase(context), provideRetrofitService(context), providePopularMovieMapper()) + } +} \ No newline at end of file diff --git a/features/popularmovies/src/main/java/com/egdroid/features/popularmovies/usecase/PopularMovieUseCase.kt b/features/popularmovies/src/main/java/com/egdroid/features/popularmovies/usecase/PopularMovieUseCase.kt new file mode 100644 index 0000000..09fc7b0 --- /dev/null +++ b/features/popularmovies/src/main/java/com/egdroid/features/popularmovies/usecase/PopularMovieUseCase.kt @@ -0,0 +1,9 @@ +package com.egdroid.features.popularmovies.usecase + +import com.egdroid.features.popularmovies.repository.PopularMovieRepo + +class PopularMovieUseCase(repo: PopularMovieRepo) { + + val popularmovies = repo.getLocalMovies() + +} \ No newline at end of file diff --git a/features/popularmovies/src/main/java/com/egdroid/features/popularmovies/usecase/PopularMoviesUseCaseFactory.kt b/features/popularmovies/src/main/java/com/egdroid/features/popularmovies/usecase/PopularMoviesUseCaseFactory.kt new file mode 100644 index 0000000..35ca9fb --- /dev/null +++ b/features/popularmovies/src/main/java/com/egdroid/features/popularmovies/usecase/PopularMoviesUseCaseFactory.kt @@ -0,0 +1,11 @@ +package com.egdroid.features.popularmovies.usecase + +import android.content.Context +import com.egdroid.features.popularmovies.repository.PopularMoviesRepoFactory + +object PopularMoviesUseCaseFactory { + + fun providePopularMoviesUseCase(context: Context): PopularMovieUseCase { + return PopularMovieUseCase(PopularMoviesRepoFactory.providePopularMoviesRepo(context)) + } +} \ No newline at end of file diff --git a/features/popularmovies/src/main/res/values/strings.xml b/features/popularmovies/src/main/res/values/strings.xml new file mode 100644 index 0000000..e3bd89a --- /dev/null +++ b/features/popularmovies/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + popularmovies + diff --git a/features/popularmovies/src/test/java/com/egdroid/features/popularmovies/ExampleUnitTest.kt b/features/popularmovies/src/test/java/com/egdroid/features/popularmovies/ExampleUnitTest.kt new file mode 100644 index 0000000..34ef6b5 --- /dev/null +++ b/features/popularmovies/src/test/java/com/egdroid/features/popularmovies/ExampleUnitTest.kt @@ -0,0 +1,16 @@ +package com.egdroid.features.popularmovies + +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) + } +} diff --git a/features/upcomingmovies/build.gradle b/features/upcomingmovies/build.gradle index d839900..a6c4712 100644 --- a/features/upcomingmovies/build.gradle +++ b/features/upcomingmovies/build.gradle @@ -1,19 +1,8 @@ apply plugin: 'com.android.library' +apply from: "$project.rootDir/tools/gradle/script/quality.gradle" +apply from: "$project.rootDir/tools/gradle/base.gradle" android { - compileSdkVersion 28 - - - defaultConfig { - minSdkVersion 24 - targetSdkVersion 28 - versionCode 1 - versionName "1.0" - - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles 'consumer-rules.pro' - } - buildTypes { release { minifyEnabled false @@ -24,15 +13,9 @@ android { } dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) - api project(":datasource:local") api project(":datasource:remote") api project(":models:mapper") - implementation project(":models:datasourcemodel") + api project(":models:datasourcemodel") - implementation 'androidx.appcompat:appcompat:1.1.0' - testImplementation 'junit:junit:4.12' - androidTestImplementation 'androidx.test:runner:1.2.0' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' } diff --git a/features/upcomingmovies/src/main/java/com/egdroid/feature/upcomingmovies/rep/MovieRepo.java b/features/upcomingmovies/src/main/java/com/egdroid/feature/upcomingmovies/rep/MovieRepo.java index cd0b5b9..36c2a2d 100644 --- a/features/upcomingmovies/src/main/java/com/egdroid/feature/upcomingmovies/rep/MovieRepo.java +++ b/features/upcomingmovies/src/main/java/com/egdroid/feature/upcomingmovies/rep/MovieRepo.java @@ -1,30 +1,23 @@ package com.egdroid.feature.upcomingmovies.rep; -import com.egdroid.datasource.local.MovieLocalDatabase; -import com.egdroid.datasource.remote.MovieRemote; -import com.egdroid.mapper.MovieMapper; -import com.egdroid.model.datasource.MovieDataSource; -import com.egdroid.models.local.movie.MovieLocal; -import com.egdroid.models.remote.movie.MovieResponse; - public class MovieRepo { - public MovieDataSource getMovies() { - - MovieMapper movieMapper = new MovieMapper(); - - // Room integration - MovieLocal movieLocalDatabase = new MovieLocalDatabase().getMovie(); - - // Retrofit integration - MovieResponse movieRemote = new MovieRemote().getMovie(); - - if (movieLocalDatabase != null) { - return movieMapper.mapToDataSource(movieLocalDatabase); - } else { - return movieMapper.mapToDataSource(movieRemote); - } - - } +// public MovieDataSource getMovies() { +// +// MovieMapper movieMapper = new MovieMapper(); +// +// // Room integration +// MovieLocal movieLocalDatabase = new MovieLocalDatabase().getMovie(); +// +// // Retrofit integration +// MovieResponse movieRemote = new MovieRemote().getMovie(); +// +// if (movieLocalDatabase != null) { +// return movieMapper.mapToDataSource(movieLocalDatabase); +// } else { +// return movieMapper.mapToDataSource(movieRemote); +// } +// +// } } From 6d464561d1ec7ff0c442ce71b803ce26640f12ec Mon Sep 17 00:00:00 2001 From: Ahmed Date: Thu, 12 Sep 2019 23:41:40 +0200 Subject: [PATCH 08/20] - Create presentation package that will contains presentation modules for each feature. - Create popular-movie-presentation module inside presentation folder. - Create PopularMovieVM inside vm folder. - Create PopularFragment that will has One-To-One relationship with PopularMovieVM. - Create PopularMovieAdapter that handles the list of the popular movie. --- app/build.gradle | 8 +++- app/src/main/AndroidManifest.xml | 3 ++ .../java/com/egdroid/movieapp/EgdoidApp.kt | 15 +++++++ .../com/egdroid/movieapp/MainActivity.java | 14 ------- .../java/com/egdroid/movieapp/MainActivity.kt | 18 ++++++++ app/src/main/res/layout/activity_main.xml | 16 ++++---- .../popularmoviespresentation/.gitignore | 1 + .../popularmoviespresentation/build.gradle | 16 ++++++++ .../consumer-rules.pro | 0 .../proguard-rules.pro | 21 ++++++++++ .../ExampleInstrumentedTest.kt | 22 ++++++++++ .../src/main/AndroidManifest.xml | 1 + .../PopularMovieAdapter.kt | 41 +++++++++++++++++++ .../PopularMoviePresentationFactory.kt | 8 ++++ .../PopularMoviesFragment.kt | 34 +++++++++++++++ .../popularmovies/PopularMoviesViewModel.kt | 2 + .../src/main/res/layout/emptyview.xml | 14 +++++++ .../res/layout/fragment_popular_movies.xml | 23 +++++++++++ .../src/main/res/layout/popular_movie_row.xml | 39 ++++++++++++++++++ .../src/main/res/values/strings.xml | 8 ++++ .../ExampleUnitTest.kt | 16 ++++++++ 21 files changed, 297 insertions(+), 23 deletions(-) create mode 100644 app/src/main/java/com/egdroid/movieapp/EgdoidApp.kt delete mode 100644 app/src/main/java/com/egdroid/movieapp/MainActivity.java create mode 100644 app/src/main/java/com/egdroid/movieapp/MainActivity.kt create mode 100644 presentation/popularmoviespresentation/.gitignore create mode 100644 presentation/popularmoviespresentation/build.gradle create mode 100644 presentation/popularmoviespresentation/consumer-rules.pro create mode 100644 presentation/popularmoviespresentation/proguard-rules.pro create mode 100644 presentation/popularmoviespresentation/src/androidTest/java/com/egdroid/presentation/popularmoviespresentation/ExampleInstrumentedTest.kt create mode 100644 presentation/popularmoviespresentation/src/main/AndroidManifest.xml create mode 100644 presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMovieAdapter.kt create mode 100644 presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMoviePresentationFactory.kt create mode 100644 presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMoviesFragment.kt create mode 100644 presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/viewmodel/popularmovies/PopularMoviesViewModel.kt create mode 100644 presentation/popularmoviespresentation/src/main/res/layout/emptyview.xml create mode 100644 presentation/popularmoviespresentation/src/main/res/layout/fragment_popular_movies.xml create mode 100644 presentation/popularmoviespresentation/src/main/res/layout/popular_movie_row.xml create mode 100644 presentation/popularmoviespresentation/src/main/res/values/strings.xml create mode 100644 presentation/popularmoviespresentation/src/test/java/com/egdroid/presentation/popularmoviespresentation/ExampleUnitTest.kt diff --git a/app/build.gradle b/app/build.gradle index a302ffe..5b04cea 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,6 +1,4 @@ apply plugin: 'com.android.application' -apply plugin: 'kotlin-android-extensions' -apply plugin: 'kotlin-android' apply from: "$project.rootDir/tools/gradle/script/quality.gradle" apply from: "$project.rootDir/tools/gradle/base.gradle" @@ -19,3 +17,9 @@ android { } } } + +dependencies{ + + implementation project(":presentation:popularmoviespresentation") + +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c533410..285e4a2 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,10 +2,13 @@ + + diff --git a/app/src/main/java/com/egdroid/movieapp/EgdoidApp.kt b/app/src/main/java/com/egdroid/movieapp/EgdoidApp.kt new file mode 100644 index 0000000..87107b1 --- /dev/null +++ b/app/src/main/java/com/egdroid/movieapp/EgdoidApp.kt @@ -0,0 +1,15 @@ +package com.egdroid.movieapp + +import android.app.Application +import timber.log.Timber + +class EgdoidApp : Application() { + + override fun onCreate() { + super.onCreate() + + if (BuildConfig.DEBUG) { + Timber.plant(Timber.DebugTree()) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/egdroid/movieapp/MainActivity.java b/app/src/main/java/com/egdroid/movieapp/MainActivity.java deleted file mode 100644 index c6c4f6c..0000000 --- a/app/src/main/java/com/egdroid/movieapp/MainActivity.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.egdroid.movieapp; - -import androidx.appcompat.app.AppCompatActivity; - -import android.os.Bundle; - -public class MainActivity extends AppCompatActivity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - } -} diff --git a/app/src/main/java/com/egdroid/movieapp/MainActivity.kt b/app/src/main/java/com/egdroid/movieapp/MainActivity.kt new file mode 100644 index 0000000..4001a4c --- /dev/null +++ b/app/src/main/java/com/egdroid/movieapp/MainActivity.kt @@ -0,0 +1,18 @@ +package com.egdroid.movieapp + +import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +import com.egdroid.presentation.popularmoviespresentation.PopularMoviesFragment + +class MainActivity : AppCompatActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + + val manager = supportFragmentManager + val transaction = manager.beginTransaction() + transaction.replace(R.id.container, PopularMoviesFragment()) + transaction.commit() + } +} diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 4fc2444..06dbc4c 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -6,13 +6,15 @@ android:layout_height="match_parent" tools:context=".MainActivity"> - + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent"> + + \ No newline at end of file diff --git a/presentation/popularmoviespresentation/.gitignore b/presentation/popularmoviespresentation/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/presentation/popularmoviespresentation/.gitignore @@ -0,0 +1 @@ +/build diff --git a/presentation/popularmoviespresentation/build.gradle b/presentation/popularmoviespresentation/build.gradle new file mode 100644 index 0000000..a00aa70 --- /dev/null +++ b/presentation/popularmoviespresentation/build.gradle @@ -0,0 +1,16 @@ +apply plugin: 'com.android.library' +apply from: "$project.rootDir/tools/gradle/script/quality.gradle" +apply from: "$project.rootDir/tools/gradle/base.gradle" + +android { + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + api project(":features:popularmovies") +} diff --git a/presentation/popularmoviespresentation/consumer-rules.pro b/presentation/popularmoviespresentation/consumer-rules.pro new file mode 100644 index 0000000..e69de29 diff --git a/presentation/popularmoviespresentation/proguard-rules.pro b/presentation/popularmoviespresentation/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/presentation/popularmoviespresentation/proguard-rules.pro @@ -0,0 +1,21 @@ +# 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 diff --git a/presentation/popularmoviespresentation/src/androidTest/java/com/egdroid/presentation/popularmoviespresentation/ExampleInstrumentedTest.kt b/presentation/popularmoviespresentation/src/androidTest/java/com/egdroid/presentation/popularmoviespresentation/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..b0ff535 --- /dev/null +++ b/presentation/popularmoviespresentation/src/androidTest/java/com/egdroid/presentation/popularmoviespresentation/ExampleInstrumentedTest.kt @@ -0,0 +1,22 @@ +package com.egdroid.presentation.popularmoviespresentation + +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("com.egdroid.presentation.popularmoviespresentation.test", appContext.packageName) + } +} diff --git a/presentation/popularmoviespresentation/src/main/AndroidManifest.xml b/presentation/popularmoviespresentation/src/main/AndroidManifest.xml new file mode 100644 index 0000000..50c7d0c --- /dev/null +++ b/presentation/popularmoviespresentation/src/main/AndroidManifest.xml @@ -0,0 +1 @@ + diff --git a/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMovieAdapter.kt b/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMovieAdapter.kt new file mode 100644 index 0000000..155b6a4 --- /dev/null +++ b/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMovieAdapter.kt @@ -0,0 +1,41 @@ +package com.egdroid.presentation.popularmoviespresentation + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.egdroid.model.datasource.MovieDataSource +import kotlinx.android.synthetic.main.popular_movie_row.view.* + +class PopularMovieAdapter : RecyclerView.Adapter() { + + private val moviesList: MutableList = arrayListOf() + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MovieViewHolder { + val inflater = LayoutInflater.from(parent.context) + return MovieViewHolder(inflater, parent) + } + + override fun onBindViewHolder(holder: MovieViewHolder, position: Int) { + val movie: MovieDataSource = moviesList[position] + holder.bind(movie) + } + + override fun getItemCount(): Int = moviesList.size + + fun addPopularMovies(movies: List) { + moviesList.addAll(movies) + notifyDataSetChanged() + } + + class MovieViewHolder(inflater: LayoutInflater, parent: ViewGroup) : + RecyclerView.ViewHolder(inflater.inflate(R.layout.popular_movie_row, parent, false)) { + + fun bind(movie: MovieDataSource) { + Glide.with(itemView).load("https://image.tmdb.org/t/p/w600_and_h900_bestv2/" + movie.posterPath).into(itemView.movieImageView) + itemView.titleTextView.text = movie.title + itemView.overviewTextView.text = movie.overview + } + + } +} diff --git a/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMoviePresentationFactory.kt b/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMoviePresentationFactory.kt new file mode 100644 index 0000000..2537fc1 --- /dev/null +++ b/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMoviePresentationFactory.kt @@ -0,0 +1,8 @@ +package com.egdroid.presentation.popularmoviespresentation + +object PopularMoviePresentationFactory { + + fun providePopularMoviesAdapter(): PopularMovieAdapter { + return PopularMovieAdapter() + } +} \ No newline at end of file diff --git a/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMoviesFragment.kt b/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMoviesFragment.kt new file mode 100644 index 0000000..0e44071 --- /dev/null +++ b/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMoviesFragment.kt @@ -0,0 +1,34 @@ +package com.egdroid.presentation.popularmoviespresentation + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.lifecycle.Observer +import androidx.recyclerview.widget.LinearLayoutManager +import com.egdroid.features.popularmovies.usecase.PopularMoviesUseCaseFactory +import kotlinx.android.synthetic.main.fragment_popular_movies.view.* + +/** + * A simple [Fragment] subclass. + */ +class PopularMoviesFragment : Fragment() { + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle?): View? { + val view = inflater.inflate(R.layout.fragment_popular_movies, container, false) + + val popularMovieUseCase = PopularMoviesUseCaseFactory.providePopularMoviesUseCase(activity!!) + val popularMovieAdapter = PopularMoviePresentationFactory.providePopularMoviesAdapter() + view.popularMoviesRecyclerView.setLayoutManager(LinearLayoutManager(activity)) + view.popularMoviesRecyclerView.adapter = popularMovieAdapter + + popularMovieUseCase.popularmovies.observe(this, Observer { + if (it != null) { + popularMovieAdapter.addPopularMovies(it) + } + }) + return view + } +} \ No newline at end of file diff --git a/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/viewmodel/popularmovies/PopularMoviesViewModel.kt b/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/viewmodel/popularmovies/PopularMoviesViewModel.kt new file mode 100644 index 0000000..3c0bc84 --- /dev/null +++ b/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/viewmodel/popularmovies/PopularMoviesViewModel.kt @@ -0,0 +1,2 @@ +package com.egdroid.presentation.popularmoviespresentation.viewmodel + diff --git a/presentation/popularmoviespresentation/src/main/res/layout/emptyview.xml b/presentation/popularmoviespresentation/src/main/res/layout/emptyview.xml new file mode 100644 index 0000000..ea1ca05 --- /dev/null +++ b/presentation/popularmoviespresentation/src/main/res/layout/emptyview.xml @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git a/presentation/popularmoviespresentation/src/main/res/layout/fragment_popular_movies.xml b/presentation/popularmoviespresentation/src/main/res/layout/fragment_popular_movies.xml new file mode 100644 index 0000000..bfae834 --- /dev/null +++ b/presentation/popularmoviespresentation/src/main/res/layout/fragment_popular_movies.xml @@ -0,0 +1,23 @@ + + + + + + \ No newline at end of file diff --git a/presentation/popularmoviespresentation/src/main/res/layout/popular_movie_row.xml b/presentation/popularmoviespresentation/src/main/res/layout/popular_movie_row.xml new file mode 100644 index 0000000..eded7d4 --- /dev/null +++ b/presentation/popularmoviespresentation/src/main/res/layout/popular_movie_row.xml @@ -0,0 +1,39 @@ + + + + + + + + + \ No newline at end of file diff --git a/presentation/popularmoviespresentation/src/main/res/values/strings.xml b/presentation/popularmoviespresentation/src/main/res/values/strings.xml new file mode 100644 index 0000000..cca7901 --- /dev/null +++ b/presentation/popularmoviespresentation/src/main/res/values/strings.xml @@ -0,0 +1,8 @@ + + popularmoviespresentation + + + Hello blank fragment + popular movie image + Empty movies list + diff --git a/presentation/popularmoviespresentation/src/test/java/com/egdroid/presentation/popularmoviespresentation/ExampleUnitTest.kt b/presentation/popularmoviespresentation/src/test/java/com/egdroid/presentation/popularmoviespresentation/ExampleUnitTest.kt new file mode 100644 index 0000000..9b3ba98 --- /dev/null +++ b/presentation/popularmoviespresentation/src/test/java/com/egdroid/presentation/popularmoviespresentation/ExampleUnitTest.kt @@ -0,0 +1,16 @@ +package com.egdroid.presentation.popularmoviespresentation + +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) + } +} From ae6e283f3429a15e2c16e22b09f87e60a5741e8b Mon Sep 17 00:00:00 2001 From: AhmedSaber0 Date: Fri, 13 Sep 2019 14:13:15 +0200 Subject: [PATCH 09/20] - add access network permission in the remote module. --- datasource/remote/src/main/AndroidManifest.xml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/datasource/remote/src/main/AndroidManifest.xml b/datasource/remote/src/main/AndroidManifest.xml index b26f111..960d295 100644 --- a/datasource/remote/src/main/AndroidManifest.xml +++ b/datasource/remote/src/main/AndroidManifest.xml @@ -1,6 +1,5 @@ - + - - - + From a2e86593fce33fbb5f1a65c1d9e5be1641031aa6 Mon Sep 17 00:00:00 2001 From: AhmedSaber0 Date: Thu, 19 Sep 2019 11:27:35 +0200 Subject: [PATCH 10/20] Update datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/MoviesServiceFactory.kt Co-Authored-By: Muhammad --- .../egdroid/datasource/remote/movie/MoviesServiceFactory.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/MoviesServiceFactory.kt b/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/MoviesServiceFactory.kt index a3a9722..8774ac7 100644 --- a/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/MoviesServiceFactory.kt +++ b/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/MoviesServiceFactory.kt @@ -40,7 +40,6 @@ object MoviesServiceFactory { private fun provideLoggingInterceptor(): Interceptor { val logging = HttpLoggingInterceptor() - logging.level = HttpLoggingInterceptor.Level.HEADERS logging.level = HttpLoggingInterceptor.Level.BODY return logging } @@ -97,4 +96,4 @@ object MoviesServiceFactory { } -} \ No newline at end of file +} From 4e6214ffe87c57916ec89aa53d11b7d2e4595849 Mon Sep 17 00:00:00 2001 From: AhmedSaber0 Date: Thu, 19 Sep 2019 11:29:21 +0200 Subject: [PATCH 11/20] update AndroidManifest.xml --- datasource/remote/src/main/AndroidManifest.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/datasource/remote/src/main/AndroidManifest.xml b/datasource/remote/src/main/AndroidManifest.xml index b26f111..7c7c299 100644 --- a/datasource/remote/src/main/AndroidManifest.xml +++ b/datasource/remote/src/main/AndroidManifest.xml @@ -1,6 +1,4 @@ - - From ed786ced8c4ad8f2986821e01f3ebb4c57350392 Mon Sep 17 00:00:00 2001 From: AhmedSaber0 Date: Thu, 19 Sep 2019 11:34:04 +0200 Subject: [PATCH 12/20] update build.gradle remove local, remote and data source dependency from gradle --- features/popularmovies/build.gradle | 3 --- 1 file changed, 3 deletions(-) diff --git a/features/popularmovies/build.gradle b/features/popularmovies/build.gradle index 2bc5b55..eb0ab98 100644 --- a/features/popularmovies/build.gradle +++ b/features/popularmovies/build.gradle @@ -12,10 +12,7 @@ android { } dependencies{ - api project(":datasource:local") - api project(":datasource:remote") api project(":models:localmodel") api project(":models:remotemodel") api project(":models:mapper") - api project(":models:datasourcemodel") } From 9c705fb62baa7cc77be828af759f0d50cca40852 Mon Sep 17 00:00:00 2001 From: AhmedSaber0 Date: Thu, 19 Sep 2019 11:40:40 +0200 Subject: [PATCH 13/20] Update datasource/local/src/main/java/com/egdroid/datasource/local/movie/DataConverter.kt use object insted of class Co-Authored-By: Ahmed Adel --- .../java/com/egdroid/datasource/local/movie/DataConverter.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/datasource/local/src/main/java/com/egdroid/datasource/local/movie/DataConverter.kt b/datasource/local/src/main/java/com/egdroid/datasource/local/movie/DataConverter.kt index 97070ee..26c2d94 100644 --- a/datasource/local/src/main/java/com/egdroid/datasource/local/movie/DataConverter.kt +++ b/datasource/local/src/main/java/com/egdroid/datasource/local/movie/DataConverter.kt @@ -6,7 +6,7 @@ import com.google.gson.reflect.TypeToken class DataConverter { - companion object { +object DataConverter { @TypeConverter @JvmStatic fun fromIntList(list: List?): String? { @@ -27,4 +27,4 @@ class DataConverter { return Gson().fromJson>(listString, type) } } -} \ No newline at end of file +} From 4e871d145d01cdf4326170760ee99711d9aa8479 Mon Sep 17 00:00:00 2001 From: Ahmed Saber Date: Thu, 19 Sep 2019 15:16:10 +0200 Subject: [PATCH 14/20] - resolve session comments --- .../datasource/local/movie/DataConverter.kt | 33 +++++++++---------- datasource/remote/build.gradle | 8 +++++ .../remote/src/main/AndroidManifest.xml | 5 +-- .../datasource/remote/movie/Extensions.kt | 13 ++++++++ .../remote/movie/MoviesServiceFactory.kt | 23 ++++++++++--- .../remote/movie/PopularMovieService.kt | 2 +- .../datasource/remote/utils/NetworkUtils.kt | 15 --------- features/popularmovies/build.gradle | 4 +-- 8 files changed, 61 insertions(+), 42 deletions(-) create mode 100644 datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/Extensions.kt delete mode 100644 datasource/remote/src/main/java/com/egdroid/datasource/remote/utils/NetworkUtils.kt diff --git a/datasource/local/src/main/java/com/egdroid/datasource/local/movie/DataConverter.kt b/datasource/local/src/main/java/com/egdroid/datasource/local/movie/DataConverter.kt index 26c2d94..1be2963 100644 --- a/datasource/local/src/main/java/com/egdroid/datasource/local/movie/DataConverter.kt +++ b/datasource/local/src/main/java/com/egdroid/datasource/local/movie/DataConverter.kt @@ -4,27 +4,24 @@ import androidx.room.TypeConverter import com.google.gson.Gson import com.google.gson.reflect.TypeToken -class DataConverter { - object DataConverter { - @TypeConverter - @JvmStatic - fun fromIntList(list: List?): String? { - if (list == null) { - return null - } - val type = object : TypeToken>() {}.type - return Gson().toJson(list, type) + @TypeConverter + @JvmStatic + fun fromIntList(list: List?): String? { + if (list == null) { + return null } + val type = object : TypeToken>() {}.type + return Gson().toJson(list, type) + } - @TypeConverter - @JvmStatic - fun toIntList(listString: String?): List? { - if (listString == null) { - return null - } - val type = object : TypeToken>() {}.type - return Gson().fromJson>(listString, type) + @TypeConverter + @JvmStatic + fun toIntList(listString: String?): List? { + if (listString == null) { + return null } + val type = object : TypeToken>() {}.type + return Gson().fromJson>(listString, type) } } diff --git a/datasource/remote/build.gradle b/datasource/remote/build.gradle index cd6efff..02c51b3 100644 --- a/datasource/remote/build.gradle +++ b/datasource/remote/build.gradle @@ -8,6 +8,14 @@ android { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + buildConfigField 'String', "ApiKey", AnotherMovieApp_ApiKey + resValue 'string', "api_key", AnotherMovieApp_ApiKey + } + debug { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + buildConfigField 'String', "ApiKey", AnotherMovieApp_ApiKey + resValue 'string', "api_key", AnotherMovieApp_ApiKey } } } diff --git a/datasource/remote/src/main/AndroidManifest.xml b/datasource/remote/src/main/AndroidManifest.xml index 7c7c299..960d295 100644 --- a/datasource/remote/src/main/AndroidManifest.xml +++ b/datasource/remote/src/main/AndroidManifest.xml @@ -1,4 +1,5 @@ - + - + diff --git a/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/Extensions.kt b/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/Extensions.kt new file mode 100644 index 0000000..42e8ffb --- /dev/null +++ b/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/Extensions.kt @@ -0,0 +1,13 @@ +package com.egdroid.datasource.remote.movie + +import android.content.Context +import android.net.ConnectivityManager +import android.net.NetworkInfo + +fun isNetworkConnected(context: Context): Boolean { + val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) + return if (connectivityManager is ConnectivityManager) { + val networkInfo: NetworkInfo? = connectivityManager.activeNetworkInfo + networkInfo?.isConnected ?: false + } else false +} \ No newline at end of file diff --git a/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/MoviesServiceFactory.kt b/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/MoviesServiceFactory.kt index 8774ac7..6ef9be8 100644 --- a/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/MoviesServiceFactory.kt +++ b/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/MoviesServiceFactory.kt @@ -1,7 +1,7 @@ package com.egdroid.datasource.remote.movie import android.content.Context -import com.egdroid.datasource.remote.utils.NetworkUtils +import com.egdroid.datasource.remote.BuildConfig import okhttp3.Cache import okhttp3.CacheControl import okhttp3.Interceptor @@ -31,7 +31,7 @@ object MoviesServiceFactory { private fun provideOkHttpClient(context: Context): OkHttpClient { return OkHttpClient.Builder() .addInterceptor(provideLoggingInterceptor()) -// .addInterceptor(provideAuthInterceptor()) + .addInterceptor(provideQueryParamsInterceptor()) .addInterceptor(provideCashingInterceptor()) .addNetworkInterceptor(provideOfflineCashingInterceptor(context)) .cache(provideCache(context)) @@ -47,12 +47,27 @@ object MoviesServiceFactory { private fun provideAuthInterceptor(): Interceptor { return Interceptor { chain -> val request = chain.request().newBuilder() - .addHeader("Application-Auth", "key") + .addHeader("api_key", BuildConfig.ApiKey) + .addHeader("page", "1") + .addHeader("language", "en-US") .build() chain.proceed(request) } } + private fun provideQueryParamsInterceptor(): Interceptor { + return Interceptor { chain -> + var request = chain.request() + val url = request.url().newBuilder() + .addQueryParameter("api_key", BuildConfig.ApiKey) + .addQueryParameter("page", "1") + .addQueryParameter("language", "en-US") + .build() + request = request.newBuilder().url(url).build() + chain.proceed(request) + } + } + private fun provideCache(context: Context): Cache? { var cache: Cache? = null try { @@ -82,7 +97,7 @@ object MoviesServiceFactory { return Interceptor { chain -> val request = chain.request() - if (!NetworkUtils.isNetworkConnected(context)) { + if (!isNetworkConnected(context)) { val cacheControl = CacheControl.Builder() .maxStale(7, TimeUnit.DAYS) .build() diff --git a/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/PopularMovieService.kt b/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/PopularMovieService.kt index dba6b52..09c7f4f 100644 --- a/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/PopularMovieService.kt +++ b/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/PopularMovieService.kt @@ -7,6 +7,6 @@ import retrofit2.http.GET interface PopularMovieService { - @GET("popular?api_key=828157095a54ed8f68b8882624ed7660&language=en-US&page=1") + @GET("popular") fun getMovies(): Call } \ No newline at end of file diff --git a/datasource/remote/src/main/java/com/egdroid/datasource/remote/utils/NetworkUtils.kt b/datasource/remote/src/main/java/com/egdroid/datasource/remote/utils/NetworkUtils.kt deleted file mode 100644 index 394c476..0000000 --- a/datasource/remote/src/main/java/com/egdroid/datasource/remote/utils/NetworkUtils.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.egdroid.datasource.remote.utils - -import android.content.Context -import android.net.ConnectivityManager -import android.net.NetworkInfo - -object NetworkUtils { - fun isNetworkConnected(context: Context): Boolean { - val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) - return if (connectivityManager is ConnectivityManager) { - val networkInfo: NetworkInfo? = connectivityManager.activeNetworkInfo - networkInfo?.isConnected ?: false - } else false - } -} \ No newline at end of file diff --git a/features/popularmovies/build.gradle b/features/popularmovies/build.gradle index eb0ab98..6c4e3fd 100644 --- a/features/popularmovies/build.gradle +++ b/features/popularmovies/build.gradle @@ -12,7 +12,7 @@ android { } dependencies{ - api project(":models:localmodel") - api project(":models:remotemodel") + api project(":datasource:local") + api project(":datasource:remote") api project(":models:mapper") } From 8b09b0fb97cec595b63053af3a787081f464798f Mon Sep 17 00:00:00 2001 From: Ahmed Saber Date: Fri, 27 Sep 2019 08:53:36 +0200 Subject: [PATCH 15/20] - convert popular movies feature to be reactive using rxJava. --- .gitignore | 1 + .../datasource/local/movie/MovieDao.kt | 7 +-- .../remote/movie/MoviesServiceFactory.kt | 2 + .../remote/movie/PopularMovieService.kt | 4 +- .../repository/PopularMovieRepo.kt | 45 +++++++++---------- .../usecase/PopularMovieUseCase.kt | 2 +- .../PopularMoviePresentationFactory.kt | 8 ++++ .../PopularMoviesFragment.kt | 19 +++++--- .../popularmovies/PopularMoviesViewModel.kt | 31 +++++++++++++ .../popularmovies/PopularMoviesViewModel.kt | 2 - tools/gradle/base.gradle | 1 + tools/gradle/dependencies.gradle | 1 + 12 files changed, 85 insertions(+), 38 deletions(-) create mode 100644 presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/popularmovies/PopularMoviesViewModel.kt delete mode 100644 presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/viewmodel/popularmovies/PopularMoviesViewModel.kt diff --git a/.gitignore b/.gitignore index 6994a8f..0d35ee0 100644 --- a/.gitignore +++ b/.gitignore @@ -74,6 +74,7 @@ obj/ .idea/copyright/profiles_settings.xml .idea/encodings.xml .idea/misc.xml +.idea/gradle.xml .idea/modules.xml .idea/scopes/scope_settings.xml .idea/dictionaries diff --git a/datasource/local/src/main/java/com/egdroid/datasource/local/movie/MovieDao.kt b/datasource/local/src/main/java/com/egdroid/datasource/local/movie/MovieDao.kt index 1e228b9..5ac1bbc 100644 --- a/datasource/local/src/main/java/com/egdroid/datasource/local/movie/MovieDao.kt +++ b/datasource/local/src/main/java/com/egdroid/datasource/local/movie/MovieDao.kt @@ -1,21 +1,22 @@ package com.egdroid.datasource.local.movie -import androidx.lifecycle.LiveData import androidx.room.Dao import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query import com.egdroid.models.local.movie.MovieLocal +import io.reactivex.Completable +import io.reactivex.Maybe @Dao interface MovieDao { @Query("SELECT * FROM movies") - fun getAllMovies(): LiveData> + fun getAllMovies(): Maybe> @Insert(onConflict = OnConflictStrategy.REPLACE) fun insertAllMovies(movies: List) @Query("DELETE FROM movies") - fun deleteAllMovies() + fun deleteAllMovies(): Completable } \ No newline at end of file diff --git a/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/MoviesServiceFactory.kt b/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/MoviesServiceFactory.kt index 6ef9be8..950dba3 100644 --- a/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/MoviesServiceFactory.kt +++ b/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/MoviesServiceFactory.kt @@ -2,6 +2,7 @@ package com.egdroid.datasource.remote.movie import android.content.Context import com.egdroid.datasource.remote.BuildConfig +import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory import okhttp3.Cache import okhttp3.CacheControl import okhttp3.Interceptor @@ -24,6 +25,7 @@ object MoviesServiceFactory { return Retrofit.Builder() .baseUrl("https://api.themoviedb.org/3/movie/") .addConverterFactory(GsonConverterFactory.create()) + .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .client(provideOkHttpClient(context)) .build() } diff --git a/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/PopularMovieService.kt b/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/PopularMovieService.kt index 09c7f4f..a1967af 100644 --- a/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/PopularMovieService.kt +++ b/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/PopularMovieService.kt @@ -1,12 +1,12 @@ package com.egdroid.datasource.remote.movie import com.egdroid.models.remote.movie.popularmovie.MovieResponse -import retrofit2.Call +import io.reactivex.Single import retrofit2.http.GET interface PopularMovieService { @GET("popular") - fun getMovies(): Call + fun getMovies(): Single } \ No newline at end of file diff --git a/features/popularmovies/src/main/java/com/egdroid/features/popularmovies/repository/PopularMovieRepo.kt b/features/popularmovies/src/main/java/com/egdroid/features/popularmovies/repository/PopularMovieRepo.kt index 3efc8c1..1c270cd 100644 --- a/features/popularmovies/src/main/java/com/egdroid/features/popularmovies/repository/PopularMovieRepo.kt +++ b/features/popularmovies/src/main/java/com/egdroid/features/popularmovies/repository/PopularMovieRepo.kt @@ -1,42 +1,39 @@ package com.egdroid.features.popularmovies.repository -import androidx.lifecycle.LiveData -import androidx.lifecycle.Transformations import com.egdroid.datasource.local.movie.MovieLocalDatabase import com.egdroid.datasource.remote.movie.PopularMovieService import com.egdroid.mapper.MovieMapper import com.egdroid.model.datasource.MovieDataSource -import com.egdroid.models.remote.movie.popularmovie.MovieResponse -import retrofit2.Call -import retrofit2.Callback -import retrofit2.Response -import kotlin.concurrent.thread +import io.reactivex.Flowable +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.schedulers.Schedulers + class PopularMovieRepo(private val database: MovieLocalDatabase, private val popularMovieService: PopularMovieService, private val mapper: MovieMapper) { - fun getLocalMovies(): LiveData> { - getRemoteMovies() - return Transformations.map(database.movieDao().getAllMovies()) { + fun getMovies(): Flowable> { + return Flowable.merge(getLocalMovies(), getRemoteMovies()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + } + + private fun getLocalMovies(): Flowable> { + return database.movieDao().getAllMovies().map { mapper.mapMovieLocalToDataSource(it) - } + }.toFlowable() } - private fun getRemoteMovies() { - popularMovieService.getMovies().enqueue(object : Callback { - override fun onResponse(call: Call, - response: Response) { - if (response.isSuccessful) { - thread { - database.movieDao().deleteAllMovies() + private fun getRemoteMovies(): Flowable> { + return popularMovieService.getMovies().doOnSuccess { + database.movieDao().deleteAllMovies() + .doOnComplete { database.movieDao() - .insertAllMovies(mapper.mapMovieResponseToLocalMovie(response.body().results!!)) + .insertAllMovies(mapper.mapMovieResponseToLocalMovie(it.results!!)) } - } - } - - override fun onFailure(call: Call, t: Throwable?) {} - }) + }.map { + mapper.mapMovieResponseToDataSource(it.results!!) + }.toFlowable() } } \ No newline at end of file diff --git a/features/popularmovies/src/main/java/com/egdroid/features/popularmovies/usecase/PopularMovieUseCase.kt b/features/popularmovies/src/main/java/com/egdroid/features/popularmovies/usecase/PopularMovieUseCase.kt index 09fc7b0..22e5740 100644 --- a/features/popularmovies/src/main/java/com/egdroid/features/popularmovies/usecase/PopularMovieUseCase.kt +++ b/features/popularmovies/src/main/java/com/egdroid/features/popularmovies/usecase/PopularMovieUseCase.kt @@ -4,6 +4,6 @@ import com.egdroid.features.popularmovies.repository.PopularMovieRepo class PopularMovieUseCase(repo: PopularMovieRepo) { - val popularmovies = repo.getLocalMovies() + val popularmovies = repo.getMovies() } \ No newline at end of file diff --git a/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMoviePresentationFactory.kt b/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMoviePresentationFactory.kt index 2537fc1..1109ed3 100644 --- a/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMoviePresentationFactory.kt +++ b/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMoviePresentationFactory.kt @@ -1,8 +1,16 @@ package com.egdroid.presentation.popularmoviespresentation +import android.content.Context +import com.egdroid.features.popularmovies.usecase.PopularMoviesUseCaseFactory +import com.egdroid.presentation.popularmoviespresentation.popularmovies.PopularMoviesViewModel + object PopularMoviePresentationFactory { fun providePopularMoviesAdapter(): PopularMovieAdapter { return PopularMovieAdapter() } + + fun providePopularMoviesViewModel(context: Context): PopularMoviesViewModel { + return PopularMoviesViewModel(PopularMoviesUseCaseFactory.providePopularMoviesUseCase(context)) + } } \ No newline at end of file diff --git a/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMoviesFragment.kt b/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMoviesFragment.kt index 0e44071..4062182 100644 --- a/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMoviesFragment.kt +++ b/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMoviesFragment.kt @@ -7,7 +7,7 @@ import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.lifecycle.Observer import androidx.recyclerview.widget.LinearLayoutManager -import com.egdroid.features.popularmovies.usecase.PopularMoviesUseCaseFactory +import com.egdroid.presentation.popularmoviespresentation.PopularMoviePresentationFactory.providePopularMoviesViewModel import kotlinx.android.synthetic.main.fragment_popular_movies.view.* /** @@ -15,20 +15,27 @@ import kotlinx.android.synthetic.main.fragment_popular_movies.view.* */ class PopularMoviesFragment : Fragment() { + private lateinit var popularMovieAdapter: PopularMovieAdapter + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { val view = inflater.inflate(R.layout.fragment_popular_movies, container, false) - val popularMovieUseCase = PopularMoviesUseCaseFactory.providePopularMoviesUseCase(activity!!) - val popularMovieAdapter = PopularMoviePresentationFactory.providePopularMoviesAdapter() - view.popularMoviesRecyclerView.setLayoutManager(LinearLayoutManager(activity)) - view.popularMoviesRecyclerView.adapter = popularMovieAdapter + val popularMoviesViewModel = providePopularMoviesViewModel(activity!!) + + setupRecyclerView(view) - popularMovieUseCase.popularmovies.observe(this, Observer { + popularMoviesViewModel.getMovies().observe(this, Observer { if (it != null) { popularMovieAdapter.addPopularMovies(it) } }) return view } + + private fun setupRecyclerView(view: View) { + popularMovieAdapter = PopularMoviePresentationFactory.providePopularMoviesAdapter() + view.popularMoviesRecyclerView.setLayoutManager(LinearLayoutManager(activity)) + view.popularMoviesRecyclerView.adapter = popularMovieAdapter + } } \ No newline at end of file diff --git a/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/popularmovies/PopularMoviesViewModel.kt b/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/popularmovies/PopularMoviesViewModel.kt new file mode 100644 index 0000000..6170f08 --- /dev/null +++ b/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/popularmovies/PopularMoviesViewModel.kt @@ -0,0 +1,31 @@ +package com.egdroid.presentation.popularmoviespresentation.popularmovies + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import com.egdroid.features.popularmovies.usecase.PopularMovieUseCase +import com.egdroid.model.datasource.MovieDataSource +import io.reactivex.disposables.CompositeDisposable + +class PopularMoviesViewModel(private val popularMovieUseCase: PopularMovieUseCase) : ViewModel() { + + private var disposable: CompositeDisposable = CompositeDisposable() + + fun getMovies(): LiveData> { + val movies = MutableLiveData>() + disposable.add(popularMovieUseCase.popularmovies + .subscribe( + { movies.value = it }, + { movies.value = null }, + {} + )) + + return movies + } + + override fun onCleared() { + super.onCleared() + disposable.clear() + } + +} \ No newline at end of file diff --git a/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/viewmodel/popularmovies/PopularMoviesViewModel.kt b/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/viewmodel/popularmovies/PopularMoviesViewModel.kt deleted file mode 100644 index 3c0bc84..0000000 --- a/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/viewmodel/popularmovies/PopularMoviesViewModel.kt +++ /dev/null @@ -1,2 +0,0 @@ -package com.egdroid.presentation.popularmoviespresentation.viewmodel - diff --git a/tools/gradle/base.gradle b/tools/gradle/base.gradle index 7b18b42..888f408 100644 --- a/tools/gradle/base.gradle +++ b/tools/gradle/base.gradle @@ -42,6 +42,7 @@ dependencies { api deps.rx.android api deps.rx.binding api deps.rx.retrofitAdapter + api deps.rx.roomRxJava // Dependency Injection api deps.dependencyInjection.dagger diff --git a/tools/gradle/dependencies.gradle b/tools/gradle/dependencies.gradle index 6084bfe..c5c6a65 100644 --- a/tools/gradle/dependencies.gradle +++ b/tools/gradle/dependencies.gradle @@ -42,6 +42,7 @@ def rx = [ android : "io.reactivex.rxjava2:rxandroid:2.0.1", relay : "com.jakewharton.rxrelay2:rxrelay:2.0.0", retrofitAdapter: "com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0", + roomRxJava: "android.arch.persistence.room:rxjava2:1.1.1", ] def network = [ From 4edc166e3539c9586fdda05562ecfe84c7597747 Mon Sep 17 00:00:00 2001 From: Ahmed Saber Date: Fri, 27 Sep 2019 09:10:13 +0200 Subject: [PATCH 16/20] - replace anotationProcessor to kapt to support kotlin. --- tools/gradle/base.gradle | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/gradle/base.gradle b/tools/gradle/base.gradle index 888f408..dd104a9 100644 --- a/tools/gradle/base.gradle +++ b/tools/gradle/base.gradle @@ -47,16 +47,16 @@ dependencies { // Dependency Injection api deps.dependencyInjection.dagger api deps.dependencyInjection.daggerSupportAndroid - annotationProcessor deps.dependencyInjection.daggerCompiler - annotationProcessor deps.dependencyInjection.daggerAndroidCompiler + kapt deps.dependencyInjection.daggerCompiler + kapt deps.dependencyInjection.daggerAndroidCompiler // View Binding api deps.viewBinding.butterknife - annotationProcessor deps.viewBinding.butterknifeCompiler + kapt deps.viewBinding.butterknifeCompiler // Images api deps.image.glide - annotationProcessor deps.image.glideCompiler + kapt deps.image.glideCompiler // Network implementation deps.network.retrofit From 450a4a26d0730e9e047301ae80bebbe4b189ecec Mon Sep 17 00:00:00 2001 From: Ahmed Saber Date: Thu, 17 Oct 2019 09:29:23 +0200 Subject: [PATCH 17/20] - move popular movies fragment and adapter to app module --- .gitignore | 3 ++- .../egdroid/movieapp/popularmovies}/PopularMovieAdapter.kt | 1 + .../egdroid/movieapp/popularmovies}/PopularMoviesFragment.kt | 3 ++- .../src/main/res/layout/emptyview.xml | 0 .../src/main/res/layout/fragment_popular_movies.xml | 0 .../src/main/res/layout/popular_movie_row.xml | 0 .../com/egdroid/datasource/local/movie/MovieLocalDatabase.kt | 2 +- .../PopularMoviePresentationFactory.kt | 4 ---- 8 files changed, 6 insertions(+), 7 deletions(-) rename {presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation => app/src/main/java/com/egdroid/movieapp/popularmovies}/PopularMovieAdapter.kt (98%) rename {presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation => app/src/main/java/com/egdroid/movieapp/popularmovies}/PopularMoviesFragment.kt (93%) rename {presentation/popularmoviespresentation => app}/src/main/res/layout/emptyview.xml (100%) rename {presentation/popularmoviespresentation => app}/src/main/res/layout/fragment_popular_movies.xml (100%) rename {presentation/popularmoviespresentation => app}/src/main/res/layout/popular_movie_row.xml (100%) diff --git a/.gitignore b/.gitignore index 0d35ee0..258b027 100644 --- a/.gitignore +++ b/.gitignore @@ -133,4 +133,5 @@ fabric.properties !/gradle/wrapper/gradle-wrapper.jar -# End of https://www.gitignore.io/api/androidstudio \ No newline at end of file +# End of https://www.gitignore.io/api/androidstudio +src/main/java/com/egdroid/movieapp/di/ diff --git a/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMovieAdapter.kt b/app/src/main/java/com/egdroid/movieapp/popularmovies/PopularMovieAdapter.kt similarity index 98% rename from presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMovieAdapter.kt rename to app/src/main/java/com/egdroid/movieapp/popularmovies/PopularMovieAdapter.kt index 155b6a4..b1eb044 100644 --- a/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMovieAdapter.kt +++ b/app/src/main/java/com/egdroid/movieapp/popularmovies/PopularMovieAdapter.kt @@ -5,6 +5,7 @@ import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide import com.egdroid.model.datasource.MovieDataSource +import com.egdroid.movieapp.R import kotlinx.android.synthetic.main.popular_movie_row.view.* class PopularMovieAdapter : RecyclerView.Adapter() { diff --git a/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMoviesFragment.kt b/app/src/main/java/com/egdroid/movieapp/popularmovies/PopularMoviesFragment.kt similarity index 93% rename from presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMoviesFragment.kt rename to app/src/main/java/com/egdroid/movieapp/popularmovies/PopularMoviesFragment.kt index 4062182..6b83607 100644 --- a/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMoviesFragment.kt +++ b/app/src/main/java/com/egdroid/movieapp/popularmovies/PopularMoviesFragment.kt @@ -7,6 +7,7 @@ import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.lifecycle.Observer import androidx.recyclerview.widget.LinearLayoutManager +import com.egdroid.movieapp.R import com.egdroid.presentation.popularmoviespresentation.PopularMoviePresentationFactory.providePopularMoviesViewModel import kotlinx.android.synthetic.main.fragment_popular_movies.view.* @@ -34,7 +35,7 @@ class PopularMoviesFragment : Fragment() { } private fun setupRecyclerView(view: View) { - popularMovieAdapter = PopularMoviePresentationFactory.providePopularMoviesAdapter() + popularMovieAdapter = PopularMovieAdapter() view.popularMoviesRecyclerView.setLayoutManager(LinearLayoutManager(activity)) view.popularMoviesRecyclerView.adapter = popularMovieAdapter } diff --git a/presentation/popularmoviespresentation/src/main/res/layout/emptyview.xml b/app/src/main/res/layout/emptyview.xml similarity index 100% rename from presentation/popularmoviespresentation/src/main/res/layout/emptyview.xml rename to app/src/main/res/layout/emptyview.xml diff --git a/presentation/popularmoviespresentation/src/main/res/layout/fragment_popular_movies.xml b/app/src/main/res/layout/fragment_popular_movies.xml similarity index 100% rename from presentation/popularmoviespresentation/src/main/res/layout/fragment_popular_movies.xml rename to app/src/main/res/layout/fragment_popular_movies.xml diff --git a/presentation/popularmoviespresentation/src/main/res/layout/popular_movie_row.xml b/app/src/main/res/layout/popular_movie_row.xml similarity index 100% rename from presentation/popularmoviespresentation/src/main/res/layout/popular_movie_row.xml rename to app/src/main/res/layout/popular_movie_row.xml diff --git a/datasource/local/src/main/java/com/egdroid/datasource/local/movie/MovieLocalDatabase.kt b/datasource/local/src/main/java/com/egdroid/datasource/local/movie/MovieLocalDatabase.kt index 8a6ec14..2689e54 100644 --- a/datasource/local/src/main/java/com/egdroid/datasource/local/movie/MovieLocalDatabase.kt +++ b/datasource/local/src/main/java/com/egdroid/datasource/local/movie/MovieLocalDatabase.kt @@ -7,7 +7,7 @@ import androidx.room.RoomDatabase import androidx.room.TypeConverters import com.egdroid.models.local.movie.MovieLocal -@Database(entities = [MovieLocal::class], version = 1) +@Database(entities = [MovieLocal::class], version = 1, exportSchema = false) @TypeConverters(DataConverter::class) abstract class MovieLocalDatabase : RoomDatabase() { abstract fun movieDao(): MovieDao diff --git a/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMoviePresentationFactory.kt b/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMoviePresentationFactory.kt index 1109ed3..3153c2e 100644 --- a/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMoviePresentationFactory.kt +++ b/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMoviePresentationFactory.kt @@ -6,10 +6,6 @@ import com.egdroid.presentation.popularmoviespresentation.popularmovies.PopularM object PopularMoviePresentationFactory { - fun providePopularMoviesAdapter(): PopularMovieAdapter { - return PopularMovieAdapter() - } - fun providePopularMoviesViewModel(context: Context): PopularMoviesViewModel { return PopularMoviesViewModel(PopularMoviesUseCaseFactory.providePopularMoviesUseCase(context)) } From 3d47135b9ad9fb47a4afd3884e16f9b9519e53c7 Mon Sep 17 00:00:00 2001 From: Ahmed Saber Date: Thu, 17 Oct 2019 10:46:55 +0200 Subject: [PATCH 18/20] - add movie entity and movie ui modules --- .../popularmovies/PopularMovieAdapter.kt | 10 +++---- .../usecase/PopularMovieUseCase.kt | 7 +++-- .../usecase/PopularMoviesUseCaseFactory.kt | 4 ++- models/entitymodel/.gitignore | 1 + models/entitymodel/build.gradle | 13 +++++++++ models/entitymodel/consumer-rules.pro | 0 models/entitymodel/proguard-rules.pro | 21 ++++++++++++++ .../egdroid/models/ExampleInstrumentedTest.kt | 22 +++++++++++++++ .../entitymodel/src/main/AndroidManifest.xml | 1 + .../models/popularmovies/MovieEntity.kt | 9 ++++++ .../src/main/res/values/strings.xml | 3 ++ .../com/egdroid/models/ExampleUnitTest.kt | 16 +++++++++++ models/mapper/build.gradle | 2 ++ .../java/com/egdroid/mapper/MovieMapper.kt | 28 +++++++++++++++++++ models/uimodel/.gitignore | 1 + models/uimodel/build.gradle | 13 +++++++++ models/uimodel/consumer-rules.pro | 0 models/uimodel/proguard-rules.pro | 21 ++++++++++++++ .../egdroid/models/ExampleInstrumentedTest.kt | 22 +++++++++++++++ models/uimodel/src/main/AndroidManifest.xml | 1 + .../egdroid/models/popularmovies/MovieUi.kt | 9 ++++++ .../uimodel/src/main/res/values/strings.xml | 3 ++ .../com/egdroid/models/ExampleUnitTest.kt | 16 +++++++++++ .../PopularMoviePresentationFactory.kt | 5 +++- .../popularmovies/PopularMoviesViewModel.kt | 12 ++++---- settings.gradle | 1 + 26 files changed, 227 insertions(+), 14 deletions(-) create mode 100644 models/entitymodel/.gitignore create mode 100644 models/entitymodel/build.gradle create mode 100644 models/entitymodel/consumer-rules.pro create mode 100644 models/entitymodel/proguard-rules.pro create mode 100644 models/entitymodel/src/androidTest/java/com/egdroid/models/ExampleInstrumentedTest.kt create mode 100644 models/entitymodel/src/main/AndroidManifest.xml create mode 100644 models/entitymodel/src/main/java/com/egdroid/models/popularmovies/MovieEntity.kt create mode 100644 models/entitymodel/src/main/res/values/strings.xml create mode 100644 models/entitymodel/src/test/java/com/egdroid/models/ExampleUnitTest.kt create mode 100644 models/uimodel/.gitignore create mode 100644 models/uimodel/build.gradle create mode 100644 models/uimodel/consumer-rules.pro create mode 100644 models/uimodel/proguard-rules.pro create mode 100644 models/uimodel/src/androidTest/java/com/egdroid/models/ExampleInstrumentedTest.kt create mode 100644 models/uimodel/src/main/AndroidManifest.xml create mode 100644 models/uimodel/src/main/java/com/egdroid/models/popularmovies/MovieUi.kt create mode 100644 models/uimodel/src/main/res/values/strings.xml create mode 100644 models/uimodel/src/test/java/com/egdroid/models/ExampleUnitTest.kt diff --git a/app/src/main/java/com/egdroid/movieapp/popularmovies/PopularMovieAdapter.kt b/app/src/main/java/com/egdroid/movieapp/popularmovies/PopularMovieAdapter.kt index b1eb044..6ee35e0 100644 --- a/app/src/main/java/com/egdroid/movieapp/popularmovies/PopularMovieAdapter.kt +++ b/app/src/main/java/com/egdroid/movieapp/popularmovies/PopularMovieAdapter.kt @@ -4,13 +4,13 @@ import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide -import com.egdroid.model.datasource.MovieDataSource +import com.egdroid.models.popularmovies.MovieUi import com.egdroid.movieapp.R import kotlinx.android.synthetic.main.popular_movie_row.view.* class PopularMovieAdapter : RecyclerView.Adapter() { - private val moviesList: MutableList = arrayListOf() + private val moviesList: MutableList = arrayListOf() override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MovieViewHolder { val inflater = LayoutInflater.from(parent.context) @@ -18,13 +18,13 @@ class PopularMovieAdapter : RecyclerView.Adapter) { + fun addPopularMovies(movies: List) { moviesList.addAll(movies) notifyDataSetChanged() } @@ -32,7 +32,7 @@ class PopularMovieAdapter : RecyclerView.Adapter diff --git a/models/entitymodel/src/main/java/com/egdroid/models/popularmovies/MovieEntity.kt b/models/entitymodel/src/main/java/com/egdroid/models/popularmovies/MovieEntity.kt new file mode 100644 index 0000000..92dbde8 --- /dev/null +++ b/models/entitymodel/src/main/java/com/egdroid/models/popularmovies/MovieEntity.kt @@ -0,0 +1,9 @@ +package com.egdroid.models.popularmovies + +data class MovieEntity( + val id: Int, + val title: String? = null, + val overview: String? = null, + val posterPath: String? = null + +) diff --git a/models/entitymodel/src/main/res/values/strings.xml b/models/entitymodel/src/main/res/values/strings.xml new file mode 100644 index 0000000..edbd4f8 --- /dev/null +++ b/models/entitymodel/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + uimodel + diff --git a/models/entitymodel/src/test/java/com/egdroid/models/ExampleUnitTest.kt b/models/entitymodel/src/test/java/com/egdroid/models/ExampleUnitTest.kt new file mode 100644 index 0000000..c1df2ae --- /dev/null +++ b/models/entitymodel/src/test/java/com/egdroid/models/ExampleUnitTest.kt @@ -0,0 +1,16 @@ +package com.egdroid.models + +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) + } +} diff --git a/models/mapper/build.gradle b/models/mapper/build.gradle index ecd79a5..13b31e7 100644 --- a/models/mapper/build.gradle +++ b/models/mapper/build.gradle @@ -15,4 +15,6 @@ dependencies { api project(":models:remotemodel") api project(":models:localmodel") api project(":models:datasourcemodel") + api project(":models:uimodel") + api project(":models:entitymodel") } diff --git a/models/mapper/src/main/java/com/egdroid/mapper/MovieMapper.kt b/models/mapper/src/main/java/com/egdroid/mapper/MovieMapper.kt index 8adc636..a96bb25 100644 --- a/models/mapper/src/main/java/com/egdroid/mapper/MovieMapper.kt +++ b/models/mapper/src/main/java/com/egdroid/mapper/MovieMapper.kt @@ -2,6 +2,8 @@ package com.egdroid.mapper import com.egdroid.model.datasource.MovieDataSource import com.egdroid.models.local.movie.MovieLocal +import com.egdroid.models.popularmovies.MovieEntity +import com.egdroid.models.popularmovies.MovieUi import com.egdroid.models.remote.movie.popularmovie.MovieRemote class MovieMapper { @@ -28,6 +30,32 @@ class MovieMapper { return moviesDataSource } + fun mapMovieDataSourceToMovieEntity(movieDataSources: List): List { + val movieEntities = mutableListOf() + for (movie in movieDataSources) { + movieEntities.add(MovieEntity( + movie.id!!, + movie.title, + movie.overview, + movie.posterPath + )) + } + return movieEntities + } + + fun mapMovieEntityToMovieUi(movieEntities: List): List { + val movies = mutableListOf() + for (movie in movieEntities) { + movies.add(MovieUi( + movie.id, + movie.title, + movie.overview, + movie.posterPath + )) + } + return movies + } + fun mapMovieResponseToDataSource(moviesResponse: List): List { val moviesDataSource = mutableListOf() for (movie in moviesResponse) { diff --git a/models/uimodel/.gitignore b/models/uimodel/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/models/uimodel/.gitignore @@ -0,0 +1 @@ +/build diff --git a/models/uimodel/build.gradle b/models/uimodel/build.gradle new file mode 100644 index 0000000..f4f844d --- /dev/null +++ b/models/uimodel/build.gradle @@ -0,0 +1,13 @@ +apply plugin: 'com.android.library' +apply from: "$project.rootDir/tools/gradle/script/quality.gradle" +apply from: "$project.rootDir/tools/gradle/base.gradle" + +android { + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + +} diff --git a/models/uimodel/consumer-rules.pro b/models/uimodel/consumer-rules.pro new file mode 100644 index 0000000..e69de29 diff --git a/models/uimodel/proguard-rules.pro b/models/uimodel/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/models/uimodel/proguard-rules.pro @@ -0,0 +1,21 @@ +# 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 diff --git a/models/uimodel/src/androidTest/java/com/egdroid/models/ExampleInstrumentedTest.kt b/models/uimodel/src/androidTest/java/com/egdroid/models/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..ed7fd2c --- /dev/null +++ b/models/uimodel/src/androidTest/java/com/egdroid/models/ExampleInstrumentedTest.kt @@ -0,0 +1,22 @@ +package com.egdroid.models + +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("com.egdroid.models.test", appContext.packageName) + } +} diff --git a/models/uimodel/src/main/AndroidManifest.xml b/models/uimodel/src/main/AndroidManifest.xml new file mode 100644 index 0000000..cbaf9d2 --- /dev/null +++ b/models/uimodel/src/main/AndroidManifest.xml @@ -0,0 +1 @@ + diff --git a/models/uimodel/src/main/java/com/egdroid/models/popularmovies/MovieUi.kt b/models/uimodel/src/main/java/com/egdroid/models/popularmovies/MovieUi.kt new file mode 100644 index 0000000..3a04568 --- /dev/null +++ b/models/uimodel/src/main/java/com/egdroid/models/popularmovies/MovieUi.kt @@ -0,0 +1,9 @@ +package com.egdroid.models.popularmovies + +data class MovieUi( + val id: Int, + val title: String? = null, + val overview: String? = null, + val posterPath: String? = null + +) diff --git a/models/uimodel/src/main/res/values/strings.xml b/models/uimodel/src/main/res/values/strings.xml new file mode 100644 index 0000000..edbd4f8 --- /dev/null +++ b/models/uimodel/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + uimodel + diff --git a/models/uimodel/src/test/java/com/egdroid/models/ExampleUnitTest.kt b/models/uimodel/src/test/java/com/egdroid/models/ExampleUnitTest.kt new file mode 100644 index 0000000..c1df2ae --- /dev/null +++ b/models/uimodel/src/test/java/com/egdroid/models/ExampleUnitTest.kt @@ -0,0 +1,16 @@ +package com.egdroid.models + +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) + } +} diff --git a/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMoviePresentationFactory.kt b/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMoviePresentationFactory.kt index 3153c2e..ca7d0dd 100644 --- a/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMoviePresentationFactory.kt +++ b/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/PopularMoviePresentationFactory.kt @@ -2,11 +2,14 @@ package com.egdroid.presentation.popularmoviespresentation import android.content.Context import com.egdroid.features.popularmovies.usecase.PopularMoviesUseCaseFactory +import com.egdroid.mapper.MapperFactory import com.egdroid.presentation.popularmoviespresentation.popularmovies.PopularMoviesViewModel object PopularMoviePresentationFactory { fun providePopularMoviesViewModel(context: Context): PopularMoviesViewModel { - return PopularMoviesViewModel(PopularMoviesUseCaseFactory.providePopularMoviesUseCase(context)) + return PopularMoviesViewModel( + PopularMoviesUseCaseFactory.providePopularMoviesUseCase(context), + MapperFactory.providePopularMovieMapper()) } } \ No newline at end of file diff --git a/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/popularmovies/PopularMoviesViewModel.kt b/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/popularmovies/PopularMoviesViewModel.kt index 6170f08..340a79e 100644 --- a/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/popularmovies/PopularMoviesViewModel.kt +++ b/presentation/popularmoviespresentation/src/main/java/com/egdroid/presentation/popularmoviespresentation/popularmovies/PopularMoviesViewModel.kt @@ -4,18 +4,20 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import com.egdroid.features.popularmovies.usecase.PopularMovieUseCase -import com.egdroid.model.datasource.MovieDataSource +import com.egdroid.mapper.MovieMapper +import com.egdroid.models.popularmovies.MovieUi import io.reactivex.disposables.CompositeDisposable -class PopularMoviesViewModel(private val popularMovieUseCase: PopularMovieUseCase) : ViewModel() { +class PopularMoviesViewModel(private val popularMovieUseCase: PopularMovieUseCase, + private val mapper: MovieMapper) : ViewModel() { private var disposable: CompositeDisposable = CompositeDisposable() - fun getMovies(): LiveData> { - val movies = MutableLiveData>() + fun getMovies(): LiveData> { + val movies = MutableLiveData>() disposable.add(popularMovieUseCase.popularmovies .subscribe( - { movies.value = it }, + { movies.value = mapper.mapMovieEntityToMovieUi(it) }, { movies.value = null }, {} )) diff --git a/settings.gradle b/settings.gradle index 917e530..e379f23 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,4 +1,5 @@ include ':app', ':common', ':models:remotemodel', ':models:localmodel', ':models:datasourcemodel', + 'models:uimodel','models:entitymodel', ':features:popularmovies', ':presentation:popularmoviespresentation', ':features:upcomingmovies', ':datasource:local', ':datasource:remote', ':models:mapper' rootProject.name = 'AnotherMovieApp' From 08f010d0b383bb8fccf255c1b709bcee34df4aba Mon Sep 17 00:00:00 2001 From: Ahmed Saber Date: Thu, 17 Oct 2019 17:26:00 +0200 Subject: [PATCH 19/20] - enabled proguard to the project --- app/build.gradle | 10 ++++++++-- build.gradle | 4 ++-- common/build.gradle | 2 +- datasource/local/build.gradle | 2 +- datasource/remote/build.gradle | 4 ++-- features/popularmovies/build.gradle | 2 +- features/upcomingmovies/build.gradle | 2 +- models/datasourcemodel/build.gradle | 2 +- models/entitymodel/build.gradle | 2 +- models/entitymodel/src/main/AndroidManifest.xml | 2 +- .../models/{ => entity}/popularmovies/MovieEntity.kt | 0 models/localmodel/build.gradle | 2 +- models/mapper/build.gradle | 2 +- models/remotemodel/build.gradle | 2 +- models/uimodel/build.gradle | 2 +- models/uimodel/src/main/AndroidManifest.xml | 2 +- .../java/com/egdroid/models/popularmovies/MovieUi.kt | 9 --------- 17 files changed, 24 insertions(+), 27 deletions(-) rename models/entitymodel/src/main/java/com/egdroid/models/{ => entity}/popularmovies/MovieEntity.kt (100%) delete mode 100644 models/uimodel/src/main/java/com/egdroid/models/popularmovies/MovieUi.kt diff --git a/app/build.gradle b/app/build.gradle index 5b04cea..8382d6a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,16 +8,22 @@ android { } buildTypes { release { - minifyEnabled false + minifyEnabled true + shrinkResources true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } debug { - minifyEnabled false + minifyEnabled true + shrinkResources true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } } +configurations { + compile.exclude group: 'androidx.annotation', module: 'annotation' +} + dependencies{ implementation project(":presentation:popularmoviespresentation") diff --git a/build.gradle b/build.gradle index 3b16c23..1894440 100644 --- a/build.gradle +++ b/build.gradle @@ -1,14 +1,14 @@ apply from: "$project.rootDir/tools/gradle/dependencies.gradle" buildscript { - ext.kotlin_version = '1.3.41' + ext.kotlin_version = '1.3.50' repositories { google() jcenter() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:3.5.0' + classpath 'com.android.tools.build:gradle:3.5.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/common/build.gradle b/common/build.gradle index a1b4430..6fcf49c 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -6,7 +6,7 @@ android { buildTypes { release { - minifyEnabled false + minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } diff --git a/datasource/local/build.gradle b/datasource/local/build.gradle index a3d0e29..99ab598 100644 --- a/datasource/local/build.gradle +++ b/datasource/local/build.gradle @@ -6,7 +6,7 @@ android { buildTypes { release { - minifyEnabled false + minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } diff --git a/datasource/remote/build.gradle b/datasource/remote/build.gradle index 02c51b3..fca0bfd 100644 --- a/datasource/remote/build.gradle +++ b/datasource/remote/build.gradle @@ -6,13 +6,13 @@ android { buildTypes { release { - minifyEnabled false + minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' buildConfigField 'String', "ApiKey", AnotherMovieApp_ApiKey resValue 'string', "api_key", AnotherMovieApp_ApiKey } debug { - minifyEnabled false + minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' buildConfigField 'String', "ApiKey", AnotherMovieApp_ApiKey resValue 'string', "api_key", AnotherMovieApp_ApiKey diff --git a/features/popularmovies/build.gradle b/features/popularmovies/build.gradle index 6c4e3fd..86e8807 100644 --- a/features/popularmovies/build.gradle +++ b/features/popularmovies/build.gradle @@ -5,7 +5,7 @@ apply from: "$project.rootDir/tools/gradle/base.gradle" android { buildTypes { release { - minifyEnabled false + minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } diff --git a/features/upcomingmovies/build.gradle b/features/upcomingmovies/build.gradle index a6c4712..b40f635 100644 --- a/features/upcomingmovies/build.gradle +++ b/features/upcomingmovies/build.gradle @@ -5,7 +5,7 @@ apply from: "$project.rootDir/tools/gradle/base.gradle" android { buildTypes { release { - minifyEnabled false + minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } diff --git a/models/datasourcemodel/build.gradle b/models/datasourcemodel/build.gradle index 34f1ca3..8713285 100644 --- a/models/datasourcemodel/build.gradle +++ b/models/datasourcemodel/build.gradle @@ -6,7 +6,7 @@ android { buildTypes { release { - minifyEnabled false + minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } diff --git a/models/entitymodel/build.gradle b/models/entitymodel/build.gradle index f4f844d..4db41c0 100644 --- a/models/entitymodel/build.gradle +++ b/models/entitymodel/build.gradle @@ -5,7 +5,7 @@ apply from: "$project.rootDir/tools/gradle/base.gradle" android { buildTypes { release { - minifyEnabled false + minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } diff --git a/models/entitymodel/src/main/AndroidManifest.xml b/models/entitymodel/src/main/AndroidManifest.xml index cbaf9d2..6d8a19d 100644 --- a/models/entitymodel/src/main/AndroidManifest.xml +++ b/models/entitymodel/src/main/AndroidManifest.xml @@ -1 +1 @@ - + diff --git a/models/entitymodel/src/main/java/com/egdroid/models/popularmovies/MovieEntity.kt b/models/entitymodel/src/main/java/com/egdroid/models/entity/popularmovies/MovieEntity.kt similarity index 100% rename from models/entitymodel/src/main/java/com/egdroid/models/popularmovies/MovieEntity.kt rename to models/entitymodel/src/main/java/com/egdroid/models/entity/popularmovies/MovieEntity.kt diff --git a/models/localmodel/build.gradle b/models/localmodel/build.gradle index 34f1ca3..8713285 100644 --- a/models/localmodel/build.gradle +++ b/models/localmodel/build.gradle @@ -6,7 +6,7 @@ android { buildTypes { release { - minifyEnabled false + minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } diff --git a/models/mapper/build.gradle b/models/mapper/build.gradle index 13b31e7..03847d3 100644 --- a/models/mapper/build.gradle +++ b/models/mapper/build.gradle @@ -5,7 +5,7 @@ apply from: "$project.rootDir/tools/gradle/base.gradle" android { buildTypes { release { - minifyEnabled false + minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } diff --git a/models/remotemodel/build.gradle b/models/remotemodel/build.gradle index a1b4430..6fcf49c 100644 --- a/models/remotemodel/build.gradle +++ b/models/remotemodel/build.gradle @@ -6,7 +6,7 @@ android { buildTypes { release { - minifyEnabled false + minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } diff --git a/models/uimodel/build.gradle b/models/uimodel/build.gradle index f4f844d..4db41c0 100644 --- a/models/uimodel/build.gradle +++ b/models/uimodel/build.gradle @@ -5,7 +5,7 @@ apply from: "$project.rootDir/tools/gradle/base.gradle" android { buildTypes { release { - minifyEnabled false + minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } diff --git a/models/uimodel/src/main/AndroidManifest.xml b/models/uimodel/src/main/AndroidManifest.xml index cbaf9d2..549152b 100644 --- a/models/uimodel/src/main/AndroidManifest.xml +++ b/models/uimodel/src/main/AndroidManifest.xml @@ -1 +1 @@ - + diff --git a/models/uimodel/src/main/java/com/egdroid/models/popularmovies/MovieUi.kt b/models/uimodel/src/main/java/com/egdroid/models/popularmovies/MovieUi.kt deleted file mode 100644 index 3a04568..0000000 --- a/models/uimodel/src/main/java/com/egdroid/models/popularmovies/MovieUi.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.egdroid.models.popularmovies - -data class MovieUi( - val id: Int, - val title: String? = null, - val overview: String? = null, - val posterPath: String? = null - -) From 3e0c8eda5903a110c76725c7e518a88a0dddcd1c Mon Sep 17 00:00:00 2001 From: Ahmed Saber Date: Thu, 17 Oct 2019 18:29:06 +0200 Subject: [PATCH 20/20] - save api key in ndk --- app/build.gradle | 5 +++++ .../main/java/com/egdroid/movieapp/MainActivity.kt | 5 +++++ app/src/main/jni/Android.mk | 8 ++++++++ app/src/main/jni/Application.mk | 1 + app/src/main/jni/keys.c | 14 ++++++++++++++ .../remote/movie/MoviesServiceFactory.kt | 13 ++++++++++--- 6 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 app/src/main/jni/Android.mk create mode 100644 app/src/main/jni/Application.mk create mode 100644 app/src/main/jni/keys.c diff --git a/app/build.gradle b/app/build.gradle index 8382d6a..77a46ad 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -6,6 +6,11 @@ android { defaultConfig { applicationId "com.egdroid.movieapp" } + externalNativeBuild { + ndkBuild { + path 'src/main/jni/Android.mk' + } + } buildTypes { release { minifyEnabled true diff --git a/app/src/main/java/com/egdroid/movieapp/MainActivity.kt b/app/src/main/java/com/egdroid/movieapp/MainActivity.kt index 4001a4c..5f66df3 100644 --- a/app/src/main/java/com/egdroid/movieapp/MainActivity.kt +++ b/app/src/main/java/com/egdroid/movieapp/MainActivity.kt @@ -4,12 +4,17 @@ import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import com.egdroid.presentation.popularmoviespresentation.PopularMoviesFragment + class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) +// val key1 = String(Base64.decode(getNativeKey1(), Base64.DEFAULT)) +// Timber.w(key1) + + val manager = supportFragmentManager val transaction = manager.beginTransaction() transaction.replace(R.id.container, PopularMoviesFragment()) diff --git a/app/src/main/jni/Android.mk b/app/src/main/jni/Android.mk new file mode 100644 index 0000000..f42f188 --- /dev/null +++ b/app/src/main/jni/Android.mk @@ -0,0 +1,8 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := keys +LOCAL_SRC_FILES := keys.c + +include $(BUILD_SHARED_LIBRARY) \ No newline at end of file diff --git a/app/src/main/jni/Application.mk b/app/src/main/jni/Application.mk new file mode 100644 index 0000000..a252a72 --- /dev/null +++ b/app/src/main/jni/Application.mk @@ -0,0 +1 @@ +APP_ABI := all diff --git a/app/src/main/jni/keys.c b/app/src/main/jni/keys.c new file mode 100644 index 0000000..c9a9d40 --- /dev/null +++ b/app/src/main/jni/keys.c @@ -0,0 +1,14 @@ +#include + +//JNIEXPORT jstring JNICALL +//Java_com_egdroid_movieapp_MainActivity_getNativeKey1(JNIEnv *env, jobject instance) { +// +// return (*env)-> NewStringUTF(env, "ODI4MTU3MDk1YTU0ZWQ4ZjY4Yjg4ODI2MjRlZDc2NjA="); +//} + +JNIEXPORT jstring JNICALL +Java_com_egdroid_datasource_remote_movie_MoviesServiceFactory_getNativeKey(JNIEnv *env, + jobject instance) { + + return (*env)->NewStringUTF(env, "ODI4MTU3MDk1YTU0ZWQ4ZjY4Yjg4ODI2MjRlZDc2NjA="); +} \ No newline at end of file diff --git a/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/MoviesServiceFactory.kt b/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/MoviesServiceFactory.kt index 950dba3..e14550c 100644 --- a/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/MoviesServiceFactory.kt +++ b/datasource/remote/src/main/java/com/egdroid/datasource/remote/movie/MoviesServiceFactory.kt @@ -1,7 +1,7 @@ package com.egdroid.datasource.remote.movie import android.content.Context -import com.egdroid.datasource.remote.BuildConfig +import android.util.Base64 import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory import okhttp3.Cache import okhttp3.CacheControl @@ -16,6 +16,12 @@ import java.util.concurrent.TimeUnit object MoviesServiceFactory { + external fun getNativeKey(): String + + init { + System.loadLibrary("keys") + } + fun provideRetrofitService(context: Context): PopularMovieService { return provideRetrofit(context).create(PopularMovieService::class.java) @@ -49,7 +55,7 @@ object MoviesServiceFactory { private fun provideAuthInterceptor(): Interceptor { return Interceptor { chain -> val request = chain.request().newBuilder() - .addHeader("api_key", BuildConfig.ApiKey) + .addHeader("api_key", getNativeKey()) .addHeader("page", "1") .addHeader("language", "en-US") .build() @@ -58,10 +64,11 @@ object MoviesServiceFactory { } private fun provideQueryParamsInterceptor(): Interceptor { + val apiKey = String(Base64.decode(getNativeKey(), Base64.DEFAULT)) return Interceptor { chain -> var request = chain.request() val url = request.url().newBuilder() - .addQueryParameter("api_key", BuildConfig.ApiKey) + .addQueryParameter("api_key", apiKey) .addQueryParameter("page", "1") .addQueryParameter("language", "en-US") .build()