├── .gitignore
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── mindorks
│ │ └── framework
│ │ └── mvp
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── assets
│ │ └── seed
│ │ │ ├── options.json
│ │ │ └── questions.json
│ ├── java
│ │ └── com
│ │ │ └── mindorks
│ │ │ └── framework
│ │ │ └── mvp
│ │ │ ├── MvpApp.kt
│ │ │ ├── data
│ │ │ ├── database
│ │ │ │ ├── AppDatabase.kt
│ │ │ │ └── repository
│ │ │ │ │ ├── options
│ │ │ │ │ ├── Options.kt
│ │ │ │ │ ├── OptionsDao.kt
│ │ │ │ │ ├── OptionsRepo.kt
│ │ │ │ │ └── OptionsRepository.kt
│ │ │ │ │ └── questions
│ │ │ │ │ ├── Question.kt
│ │ │ │ │ ├── QuestionRepo.kt
│ │ │ │ │ ├── QuestionRepository.kt
│ │ │ │ │ └── QuestionsDao.kt
│ │ │ ├── network
│ │ │ │ ├── ApiEndPoint.kt
│ │ │ │ ├── ApiHeader.kt
│ │ │ │ ├── ApiHelper.kt
│ │ │ │ ├── AppApiHelper.kt
│ │ │ │ ├── Blog.kt
│ │ │ │ ├── BlogResponse.kt
│ │ │ │ ├── LoginRequest.kt
│ │ │ │ ├── LoginResponse.kt
│ │ │ │ ├── LogoutResponse.kt
│ │ │ │ ├── OpenSource.kt
│ │ │ │ └── OpenSourceResponse.kt
│ │ │ └── preferences
│ │ │ │ ├── AppPreferenceHelper.kt
│ │ │ │ └── PreferenceHelper.kt
│ │ │ ├── di
│ │ │ ├── ApiKeyInfo.kt
│ │ │ ├── PreferenceInfo.kt
│ │ │ ├── builder
│ │ │ │ └── ActivityBuilder.kt
│ │ │ ├── component
│ │ │ │ └── AppComponent.kt
│ │ │ └── module
│ │ │ │ └── AppModule.kt
│ │ │ ├── ui
│ │ │ ├── about
│ │ │ │ ├── AboutFragmentProvider.kt
│ │ │ │ └── view
│ │ │ │ │ └── AboutFragment.kt
│ │ │ ├── base
│ │ │ │ ├── interactor
│ │ │ │ │ ├── BaseInteractor.kt
│ │ │ │ │ └── MVPInteractor.kt
│ │ │ │ ├── presenter
│ │ │ │ │ ├── BasePresenter.kt
│ │ │ │ │ └── MVPPresenter.kt
│ │ │ │ └── view
│ │ │ │ │ ├── BaseActivity.kt
│ │ │ │ │ ├── BaseDialogView.kt
│ │ │ │ │ ├── BaseFragment.kt
│ │ │ │ │ ├── DialogMVPView.kt
│ │ │ │ │ └── MVPView.kt
│ │ │ ├── feed
│ │ │ │ ├── FeedPagerAdapter.kt
│ │ │ │ ├── blog
│ │ │ │ │ ├── BlogFragmentModule.kt
│ │ │ │ │ ├── BlogFragmentProvider.kt
│ │ │ │ │ ├── interactor
│ │ │ │ │ │ ├── BlogInteractor.kt
│ │ │ │ │ │ └── BlogMVPInteractor.kt
│ │ │ │ │ ├── presenter
│ │ │ │ │ │ ├── BlogMVPPresenter.kt
│ │ │ │ │ │ └── BlogPresenter.kt
│ │ │ │ │ └── view
│ │ │ │ │ │ ├── BlogAdapter.kt
│ │ │ │ │ │ ├── BlogFragment.kt
│ │ │ │ │ │ └── BlogMVPView.kt
│ │ │ │ ├── opensource
│ │ │ │ │ ├── OpenSourceFragmentModule.kt
│ │ │ │ │ ├── OpenSourceFragmentProvider.kt
│ │ │ │ │ ├── interactor
│ │ │ │ │ │ ├── OpenSourceInteractor.kt
│ │ │ │ │ │ └── OpenSourceMVPInteractor.kt
│ │ │ │ │ ├── presenter
│ │ │ │ │ │ ├── OpenSourceMVPPresenter.kt
│ │ │ │ │ │ └── OpenSourcePresenter.kt
│ │ │ │ │ └── view
│ │ │ │ │ │ ├── OpenSourceAdapter.kt
│ │ │ │ │ │ ├── OpenSourceFragment.kt
│ │ │ │ │ │ └── OpenSourceMVPView.kt
│ │ │ │ └── view
│ │ │ │ │ └── FeedActivity.kt
│ │ │ ├── login
│ │ │ │ ├── LoginActivityModule.kt
│ │ │ │ ├── interactor
│ │ │ │ │ ├── LoginInteractor.kt
│ │ │ │ │ └── LoginMVPInteractor.kt
│ │ │ │ ├── presenter
│ │ │ │ │ ├── LoginMVPPresenter.kt
│ │ │ │ │ └── LoginPresenter.kt
│ │ │ │ └── view
│ │ │ │ │ ├── LoginActivity.kt
│ │ │ │ │ └── LoginMVPView.kt
│ │ │ ├── main
│ │ │ │ ├── MainActivityModule.kt
│ │ │ │ ├── interactor
│ │ │ │ │ ├── MainInteractor.kt
│ │ │ │ │ ├── MainMVPInteractor.kt
│ │ │ │ │ └── QuestionCardData.kt
│ │ │ │ ├── presenter
│ │ │ │ │ ├── MainMVPPresenter.kt
│ │ │ │ │ └── MainPresenter.kt
│ │ │ │ └── view
│ │ │ │ │ ├── MainActivity.kt
│ │ │ │ │ ├── MainMVPView.kt
│ │ │ │ │ └── QuestionCardView.kt
│ │ │ ├── rate
│ │ │ │ ├── RateUsDialogFragmentProvider.kt
│ │ │ │ ├── RateUsFragmentModule.kt
│ │ │ │ ├── interactor
│ │ │ │ │ ├── RateUsInteractor.kt
│ │ │ │ │ └── RateUsMVPInterator.kt
│ │ │ │ ├── presenter
│ │ │ │ │ ├── RateUsMVPPresenter.kt
│ │ │ │ │ └── RateUsPresenter.kt
│ │ │ │ └── view
│ │ │ │ │ ├── RateUsDialog.kt
│ │ │ │ │ └── RateUsDialogMVPView.kt
│ │ │ └── splash
│ │ │ │ ├── SplashActivityModule.kt
│ │ │ │ ├── interactor
│ │ │ │ ├── SplashInteractor.kt
│ │ │ │ └── SplashMVPInteractor.kt
│ │ │ │ ├── presenter
│ │ │ │ ├── SplashMVPPresenter.kt
│ │ │ │ └── SplashPresenter.kt
│ │ │ │ └── view
│ │ │ │ ├── SplashMVPActivity.kt
│ │ │ │ └── SplashMVPView.kt
│ │ │ └── util
│ │ │ ├── AppConstants.kt
│ │ │ ├── CommonUtil.kt
│ │ │ ├── FileUtils.kt
│ │ │ ├── SchedulerProvider.kt
│ │ │ ├── ScreenUtils.kt
│ │ │ └── extension
│ │ │ ├── FragmentManager.kt
│ │ │ └── ImageView.kt
│ └── res
│ │ ├── anim
│ │ ├── slide_left.xml
│ │ └── slide_right.xml
│ │ ├── drawable-v21
│ │ ├── button_primary_bg.xml
│ │ ├── button_secondary_bg.xml
│ │ ├── ic_menu_camera.xml
│ │ ├── ic_menu_gallery.xml
│ │ ├── ic_menu_manage.xml
│ │ ├── ic_menu_send.xml
│ │ ├── ic_menu_share.xml
│ │ └── ic_menu_slideshow.xml
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ ├── bg_design.xml
│ │ ├── border_dark_color.xml
│ │ ├── bottom_border_shadow.xml
│ │ ├── button_bg.xml
│ │ ├── button_negative_text_drawable.xml
│ │ ├── button_positive_text_drawable.xml
│ │ ├── button_secondary_bg.xml
│ │ ├── corner_border_rect_gray.xml
│ │ ├── ic_arrow_back_white_24px.xml
│ │ ├── ic_facebook.xml
│ │ ├── ic_google_plus.xml
│ │ ├── ic_info_24px.xml
│ │ ├── ic_keyboard_backspace_24px.xml
│ │ ├── ic_launcher_background.xml
│ │ ├── ic_power_settings_new_24px.xml
│ │ ├── ic_rabbit.xml
│ │ ├── ic_rss_symbol.xml
│ │ ├── ic_star.xml
│ │ ├── input_border_bottom.xml
│ │ └── side_nav_bar.xml
│ │ ├── layout
│ │ ├── activity_feed.xml
│ │ ├── activity_login.xml
│ │ ├── activity_main.xml
│ │ ├── activity_splash.xml
│ │ ├── app_bar_navigation.xml
│ │ ├── card_layout.xml
│ │ ├── content_navigation.xml
│ │ ├── dialog_rate_us.xml
│ │ ├── fragment_about.xml
│ │ ├── fragment_blog.xml
│ │ ├── fragment_open_source.xml
│ │ ├── item_blog_list.xml
│ │ ├── item_open_source_list.xml
│ │ ├── nav_header_navigation.xml
│ │ └── progress_dialog.xml
│ │ ├── menu
│ │ ├── activity_navigation_drawer.xml
│ │ ├── activity_navigation_drawer_drawer.xml
│ │ ├── drawer_items.xml
│ │ ├── navigation.xml
│ │ └── navigation_drawer.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── values-v21
│ │ └── styles.xml
│ │ └── values
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── drawables.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── mindorks
│ └── framework
│ └── mvp
│ └── ExampleUnitTest.kt
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 | /.idea
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | 1. Fork it!
4 | 2. Checkout the development branch: `git checkout development`
5 | 3. Create your feature branch: `git checkout -b my-new-feature`
6 | 4. Add your changes to the index: `git add .`
7 | 5. Commit your changes: `git commit -m 'Add some feature'`
8 | 6. Push to the branch: `git push origin my-new-feature`
9 | 7. Submit a pull request against the `development` branch
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://github.com/janishar/wimm-android-app)
2 |
3 | ---
4 | # This Project is [Deprecated] goto latest project: [Modern Android Development - WhereIsMyMotivation](https://github.com/janishar/wimm-android-app)
5 | ---
6 |
7 | # Deprecated
8 | ### Android Kotlin MVP Architecture: Sample App
9 |
10 | This repository contains a detailed sample app that implements MVP architecture in Kotlin using Dagger2, Room, RxJava, FastAndroidNetworking, PlaceHolderView and AndroidDebugDatabase
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | # Architecture Blueprint
27 | 
28 |
29 |
30 | # Project Structure
31 | 
32 |
33 |
34 | # About The Author
35 | You can connect with me here:
36 | * [Janishar Ali](https://janisharali.com)
37 | * [Twitter](https://twitter.com/janisharali)
38 | * [YouTube Channel](https://www.youtube.com/@unusualcode)
39 |
40 | # Read the below listed articles. They describe the MVP concepts and the Project structure.
41 | 1. [MVP: Part 1](https://janisharali.com/blog/essential-guide-for-designing-your-android-app-architecture-mvp-part-1-74efaf1cda40#.lkml1yggq)
42 | 2. [MVP: Part 2](https://janisharali.com/blog/essential-guide-for-designing-your-android-app-architecture-mvp-part-2-b2ac6f3f9637#.dge0wl8rl)
43 | 3. [MVP: Part 3](https://janisharali.com/blog/essential-guide-for-designing-your-android-app-architecture-mvp-part-3-dialog-viewpager-and-7bdfab86aabb)
44 | 4. [Extension with Interactors and Repositories](https://janisharali.com/blog/android-mvp-architecture-extension-with-interactors-and-repositories-bd4b51972339)
45 |
46 | #### The app has following packages:
47 | 1. **data**: It contains all the data accessing and manipulating components.
48 | 2. **di**: Dependency providing classes using Dagger2.
49 | 3. **ui**: View classes along with their corresponding Presenters.
50 | 4. **utils**: Utility classes.
51 |
52 | #### Classes have been designed in such a way that it could be inherited and maximize the code reuse.
53 |
54 | ### Library reference resources:
55 | 2. Dagger2: https://github.com/janishar/android-dagger2-example
56 | 4. PlaceHolderView: https://github.com/janishar/PlaceHolderView
57 | 6. Calligraphy: https://github.com/chrisjenx/Calligraphy
58 | 7. GreenDao: http://greenrobot.org/greendao/
59 | 8. ButterKnife: http://jakewharton.github.io/butterknife/
60 |
61 | ### Concept reference resources:
62 | 1. [Introduction to Dagger 2: Part 1](https://janisharali.com/blog/introduction-to-dagger-2-using-dependency-injection-in-android-part-1-223289c2a01b#.ki6nt86l6)
63 | 2. [Introduction to Dagger 2: Part 2](https://janisharali.com/blog/introduction-to-dagger-2-using-dependency-injection-in-android-part-2-b55857911bcd#.mkpzyk8sa)
64 | 3. [Android Dagger2: Critical things to know before you implement](https://janisharali.com/blog/android-dagger2-critical-things-to-know-before-you-implement-275663aecc3e#.bskiz1879)
65 | 4. [Android Tinder Swipe View Example](https://janisharali.com/blog/android-tinder-swipe-view-example-3eca9b0d4794#.u7i7jbbvy)
66 | 5. [RxJava Anatomy: What is RxJava, how RxJava is designed, and how RxJava works.](https://janisharali.com/blog/rxjava-anatomy-what-is-rxjava-how-rxjava-is-designed-and-how-rxjava-works-d357b3aca586)
67 |
68 | ### Looking for MVVM Architecture - [Check here](https://github.com/janishar/android-mvvm-architecture)
69 |
70 | ### License
71 | ```
72 | Copyright (C) 2022 JANISHAR ALI ANWAR
73 |
74 | Licensed under the Apache License, Version 2.0 (the "License");
75 | you may not use this file except in compliance with the License.
76 | You may obtain a copy of the License at
77 |
78 | http://www.apache.org/licenses/LICENSE-2.0
79 |
80 | Unless required by applicable law or agreed to in writing, software
81 | distributed under the License is distributed on an "AS IS" BASIS,
82 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
83 | See the License for the specific language governing permissions and
84 | limitations under the License.
85 | ```
86 |
87 | ### Contributing to Android Kotlin MVP Architecture
88 | All pull requests are welcome, make sure to follow the [contribution guidelines](CONTRIBUTING.md)
89 | when you submit pull request.
90 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | apply plugin: 'kotlin-android'
4 |
5 | apply plugin: 'kotlin-android-extensions'
6 |
7 | apply plugin: 'kotlin-kapt'
8 |
9 | android {
10 | compileSdkVersion rootProject.ext.compileSdkVersion
11 | defaultConfig {
12 | applicationId "com.mindorks.framework.mvp"
13 | minSdkVersion rootProject.ext.minSdkVersion
14 | targetSdkVersion rootProject.ext.targetSdkVersion
15 | versionCode 1
16 | versionName "1.0"
17 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
18 | vectorDrawables.useSupportLibrary = true
19 | }
20 | buildTypes {
21 | debug {
22 | buildConfigField("String", "BASE_URL", "\"http://www.mocky.io/v2\"")
23 | buildConfigField("String", "API_KEY", "\"ABCXYZ123TEST\"")
24 | }
25 | release {
26 | minifyEnabled true
27 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
28 | buildConfigField("String", "BASE_URL", "\"http://www.mocky.io/v2\"")
29 | buildConfigField("String", "API_KEY", "\"ABCXYZ123TEST\"")
30 | }
31 | }
32 | }
33 |
34 | dependencies {
35 | implementation fileTree(dir: 'libs', include: ['*.jar'])
36 |
37 | // kotlin
38 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$rootProject.kotlinVersion"
39 |
40 | // android support libraries
41 | implementation "com.android.support:appcompat-v7:$rootProject.supportLibraryVersion"
42 | implementation "com.android.support:recyclerview-v7:$rootProject.supportLibraryVersion"
43 | implementation "com.android.support:cardview-v7:$rootProject.supportLibraryVersion"
44 | implementation "com.android.support:design:$rootProject.supportLibraryVersion"
45 | implementation "com.android.support:support-vector-drawable:$rootProject.supportLibraryVersion"
46 | implementation "com.android.support:animated-vector-drawable:$rootProject.supportLibraryVersion"
47 |
48 | // network
49 | implementation "com.amitshekhar.android:rx2-android-networking:$rootProject.rx2FastAndroidNetworking"
50 |
51 | // database
52 | implementation "android.arch.persistence.room:rxjava2:$rootProject.roomDatabaseVersion"
53 | implementation 'com.android.support.constraint:constraint-layout:1.0.2'
54 | kapt "android.arch.persistence.room:compiler:$rootProject.roomDatabaseVersion"
55 |
56 | // font
57 | implementation "uk.co.chrisjenx:calligraphy:$rootProject.calligraphyVersion"
58 |
59 | // image
60 | implementation "com.github.bumptech.glide:glide:$rootProject.glideVersion"
61 |
62 | // parser
63 | implementation "com.google.code.gson:gson:$rootProject.gsonVersion"
64 |
65 | // debug database
66 | debugImplementation "com.amitshekhar.android:debug-db:$rootProject.debugDBVersion"
67 |
68 | // dependency injection
69 | implementation "com.google.dagger:dagger:$rootProject.dagger2Version"
70 | kapt "com.google.dagger:dagger-compiler:$rootProject.dagger2Version"
71 | kapt "com.google.dagger:dagger-android-processor:$rootProject.dagger2Version"
72 | implementation "com.google.dagger:dagger-android-support:$rootProject.dagger2Version"
73 |
74 | // reactive
75 | implementation "io.reactivex.rxjava2:rxjava:$rootProject.rxjava2Version"
76 | implementation "io.reactivex.rxjava2:rxandroid:$rootProject.rxandroidVersion"
77 |
78 | // code generator for view
79 | implementation "com.jakewharton:butterknife:$rootProject.butterKnifeVersion"
80 | kapt "com.jakewharton:butterknife-compiler:$rootProject.butterKnifeVersion"
81 |
82 | // swipe view
83 | implementation "com.mindorks:placeholderview:$rootProject.placeholderviewVersion"
84 |
85 | // logger
86 | implementation "com.jakewharton.timber:timber:$rootProject.timberVersion"
87 |
88 | // dependencies for local unit tests
89 | testImplementation "junit:junit:$rootProject.ext.junitVersion"
90 | testImplementation "org.mockito:mockito-core:$rootProject.mockitoVersion"
91 | kaptTest "com.google.dagger:dagger-compiler:$rootProject.dagger2Version"
92 |
93 | // UI Testing
94 | androidTestImplementation "com.android.support.test.espresso:espresso-core:$rootProject.espressoVersion"
95 | androidTestImplementation "com.android.support.test.espresso:espresso-intents:$rootProject.espressoVersion"
96 | androidTestImplementation "org.mockito:mockito-core:$rootProject.mockitoVersion"
97 | kaptAndroidTest "com.google.dagger:dagger-compiler:$rootProject.dagger2Version"
98 |
99 | // Android Kotlin Extension
100 | implementation "androidx.core:core-ktx:$rootProject.androidKTXVersion"
101 | }
102 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/mindorks/framework/mvp/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp
2 |
3 | import android.support.test.InstrumentationRegistry
4 | import android.support.test.runner.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getTargetContext()
22 | assertEquals("com.mindorks.framework.mvp", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/assets/seed/options.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "option_text": "MVVM",
4 | "question_id": 1,
5 | "is_correct": false
6 | },
7 | {
8 | "option_text": "MVP",
9 | "question_id": 1,
10 | "is_correct": true
11 | },
12 | {
13 | "option_text": "MVC",
14 | "question_id": 1,
15 | "is_correct": false
16 | },
17 | {
18 | "option_text": "Data Manager",
19 | "question_id": 2,
20 | "is_correct": true
21 | },
22 | {
23 | "option_text": "View",
24 | "question_id": 2,
25 | "is_correct": false
26 | },
27 | {
28 | "option_text": "Presenter",
29 | "question_id": 2,
30 | "is_correct": false
31 | },
32 | {
33 | "option_text": "Yes",
34 | "question_id": 3,
35 | "is_correct": false
36 | },
37 | {
38 | "option_text": "Never",
39 | "question_id": 3,
40 | "is_correct": true
41 | },
42 | {
43 | "option_text": "Sometimes",
44 | "question_id": 3,
45 | "is_correct": false
46 | },
47 | {
48 | "option_text": "It fetches the data from the database.",
49 | "question_id": 4,
50 | "is_correct": false
51 | },
52 | {
53 | "option_text": "It delegates View's requirements to Data Manager.",
54 | "question_id": 4,
55 | "is_correct": true
56 | },
57 | {
58 | "option_text": "It instructs the View to perform actions.",
59 | "question_id": 4,
60 | "is_correct": true
61 | },
62 | {
63 | "option_text": "It created a readable code.",
64 | "question_id": 5,
65 | "is_correct": true
66 | },
67 | {
68 | "option_text": "It is highly testable.",
69 | "question_id": 5,
70 | "is_correct": true
71 | },
72 | {
73 | "option_text": "It provides reusable code.",
74 | "question_id": 5,
75 | "is_correct": true
76 | },
77 | {
78 | "option_text": "Linus Torvalds",
79 | "question_id": 6,
80 | "is_correct": true
81 | },
82 | {
83 | "option_text": "Janishar Ali",
84 | "question_id": 6,
85 | "is_correct": false
86 | },
87 | {
88 | "option_text": "Amit Shekhar",
89 | "question_id": 6,
90 | "is_correct": false
91 | },
92 | {
93 | "option_text": "None",
94 | "question_id": 7,
95 | "is_correct": false
96 | },
97 | {
98 | "option_text": "Mindorks",
99 | "question_id": 7,
100 | "is_correct": true
101 | },
102 | {
103 | "option_text": "Google",
104 | "question_id": 7,
105 | "is_correct": false
106 | }
107 | ]
--------------------------------------------------------------------------------
/app/src/main/assets/seed/questions.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": 1,
4 | "question_text": "What is the architecture of this app?",
5 | "question_img_url": null
6 | },
7 | {
8 | "id": 2,
9 | "question_text": "Which component of the MVP controls the data flow?",
10 | "question_img_url": null
11 | },
12 | {
13 | "id": 3,
14 | "question_text": "Can a View ask for data from a Data Manager?",
15 | "question_img_url": null
16 | },
17 | {
18 | "id": 4,
19 | "question_text": "What is the role of a Presenter?",
20 | "question_img_url": null
21 | },
22 | {
23 | "id": 5,
24 | "question_text": "Why should we follow MVP?",
25 | "question_img_url": null
26 | },
27 | {
28 | "id": 6,
29 | "question_text": "Who is this person?",
30 | "question_img_url": "https://avatars3.githubusercontent.com/u/1024025"
31 | },
32 | {
33 | "id": 7,
34 | "question_text": "Which company's logo is this?",
35 | "question_img_url": "https://janishar.github.io/images/mindorks-logo-small.png"
36 | }
37 | ]
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/MvpApp.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp
2 |
3 | import android.app.Activity
4 | import android.app.Application
5 | import com.mindorks.framework.mvp.di.component.DaggerAppComponent
6 | import dagger.android.DispatchingAndroidInjector
7 | import dagger.android.HasActivityInjector
8 | import javax.inject.Inject
9 |
10 | /**
11 | * Created by amitshekhar on 24/12/17.
12 | */
13 | class MvpApp : Application(), HasActivityInjector {
14 |
15 | @Inject
16 | lateinit internal var activityDispatchingAndroidInjector: DispatchingAndroidInjector
17 |
18 |
19 | override fun activityInjector() = activityDispatchingAndroidInjector
20 |
21 | override fun onCreate() {
22 | super.onCreate()
23 | DaggerAppComponent.builder()
24 | .application(this)
25 | .build()
26 | .inject(this)
27 | }
28 |
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/data/database/AppDatabase.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.data.database
2 |
3 | import android.arch.persistence.room.Database
4 | import android.arch.persistence.room.RoomDatabase
5 | import com.mindorks.framework.mvp.data.database.repository.options.Options
6 | import com.mindorks.framework.mvp.data.database.repository.options.OptionsDao
7 | import com.mindorks.framework.mvp.data.database.repository.questions.Question
8 | import com.mindorks.framework.mvp.data.database.repository.questions.QuestionsDao
9 |
10 | /**
11 | * Created by jyotidubey on 03/01/18.
12 | */
13 | @Database(entities = [(Question::class), (Options::class)], version = 1)
14 | abstract class AppDatabase : RoomDatabase() {
15 |
16 | abstract fun optionsDao(): OptionsDao
17 |
18 | abstract fun questionsDao(): QuestionsDao
19 |
20 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/data/database/repository/options/Options.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.data.database.repository.options
2 |
3 | import android.arch.persistence.room.ColumnInfo
4 | import android.arch.persistence.room.Entity
5 | import android.arch.persistence.room.ForeignKey
6 | import android.arch.persistence.room.PrimaryKey
7 | import com.google.gson.annotations.Expose
8 | import com.google.gson.annotations.SerializedName
9 | import com.mindorks.framework.mvp.data.database.repository.questions.Question
10 |
11 | /**
12 | * Created by jyotidubey on 03/01/18.
13 | */
14 | @Entity(tableName = "options", foreignKeys = [(ForeignKey(entity = Question::class,
15 | parentColumns = arrayOf("id"),
16 | childColumns = arrayOf("question_id"),
17 | onDelete = ForeignKey.CASCADE))])
18 | data class Options(
19 |
20 | @PrimaryKey(autoGenerate = true) var id: Long,
21 |
22 | @Expose
23 | @SerializedName("option_text")
24 | @ColumnInfo(name = "option_text")
25 | var optionText: String,
26 |
27 | @Expose
28 | @SerializedName("question_id")
29 | @ColumnInfo(name = "question_id")
30 | var questionId: Long,
31 |
32 | @Expose
33 | @SerializedName("is_correct")
34 | @ColumnInfo(name = "is_correct")
35 | var isCorrect: Boolean,
36 |
37 | @Expose
38 | @SerializedName("created_at")
39 | @ColumnInfo(name = "created_at")
40 | var createdAt: String?,
41 |
42 | @Expose
43 | @SerializedName("updated_at")
44 | @ColumnInfo(name = "updated_at")
45 | var updatedAt: String?
46 | )
47 |
48 |
49 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/data/database/repository/options/OptionsDao.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.data.database.repository.options
2 |
3 | import android.arch.persistence.room.Dao
4 | import android.arch.persistence.room.Insert
5 | import android.arch.persistence.room.OnConflictStrategy
6 | import android.arch.persistence.room.Query
7 |
8 | /**
9 | * Created by jyotidubey on 03/01/18.
10 | */
11 | @Dao
12 | interface OptionsDao {
13 |
14 | @Insert(onConflict = OnConflictStrategy.REPLACE)
15 | fun insertAll(options: List)
16 |
17 | @Query("SELECT * FROM options WHERE question_id = :questionId")
18 | fun loadOptionsByQuestionId(questionId: Long): List
19 |
20 | @Query("SELECT * FROM options")
21 | fun loadAll(): List
22 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/data/database/repository/options/OptionsRepo.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.data.database.repository.options
2 |
3 | import io.reactivex.Observable
4 | import io.reactivex.Single
5 |
6 | /**
7 | * Created by jyotidubey on 06/01/18.
8 | */
9 | interface OptionsRepo {
10 |
11 | fun isOptionsRepoEmpty(): Observable
12 |
13 | fun insertOptions(options: List): Observable
14 |
15 | fun loadOptions(questionId: Long): Single>
16 |
17 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/data/database/repository/options/OptionsRepository.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.data.database.repository.options
2 |
3 | import io.reactivex.Observable
4 | import io.reactivex.Single
5 | import javax.inject.Inject
6 |
7 | /**
8 | * Created by jyotidubey on 06/01/18.
9 | */
10 | class OptionsRepository @Inject constructor(private val optionsDao: OptionsDao) : OptionsRepo {
11 |
12 | override fun isOptionsRepoEmpty(): Observable = Observable.just(optionsDao.loadAll().isEmpty())
13 |
14 | override fun insertOptions(options: List): Observable {
15 | optionsDao.insertAll(options)
16 | return Observable.just(true)
17 | }
18 |
19 | override fun loadOptions(questionId: Long): Single>
20 | = Single.fromCallable({ optionsDao.loadOptionsByQuestionId(questionId) })
21 |
22 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/data/database/repository/questions/Question.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.data.database.repository.questions
2 |
3 | import android.arch.persistence.room.ColumnInfo
4 | import android.arch.persistence.room.Entity
5 | import android.arch.persistence.room.PrimaryKey
6 | import com.google.gson.annotations.Expose
7 | import com.google.gson.annotations.SerializedName
8 |
9 | /**
10 | * Created by jyotidubey on 03/01/18.
11 | */
12 | @Entity(tableName = "questions")
13 | data class Question(
14 | @Expose
15 | @PrimaryKey
16 | var id: Long,
17 |
18 | @Expose
19 | @SerializedName("question_text")
20 | @ColumnInfo(name = "question_text")
21 | var questionText: String,
22 |
23 | @Expose
24 | @SerializedName("question_img_url")
25 | @ColumnInfo(name = "question_img_url")
26 | var imgUrl: String?,
27 |
28 | @Expose
29 | @SerializedName("created_at")
30 | @ColumnInfo(name = "created_at")
31 | var createdAt: String?,
32 |
33 | @Expose
34 | @SerializedName("updated_at")
35 | @ColumnInfo(name = "updated_at")
36 | var updatedAt: String?
37 |
38 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/data/database/repository/questions/QuestionRepo.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.data.database.repository.questions
2 |
3 | import io.reactivex.Observable
4 |
5 | /**
6 | * Created by jyotidubey on 06/01/18.
7 | */
8 | interface QuestionRepo {
9 |
10 | fun isQuestionsRepoEmpty(): Observable
11 |
12 | fun insertQuestions(questions: List): Observable
13 |
14 | fun loadQuestions(): Observable>
15 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/data/database/repository/questions/QuestionRepository.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.data.database.repository.questions
2 |
3 | import io.reactivex.Observable
4 | import javax.inject.Inject
5 |
6 | /**
7 | * Created by jyotidubey on 06/01/18.
8 | */
9 | class QuestionRepository @Inject internal constructor(private val questionsDao: QuestionsDao) : QuestionRepo {
10 |
11 | override fun isQuestionsRepoEmpty(): Observable = Observable.fromCallable({ questionsDao.loadAll().isEmpty() })
12 |
13 | override fun insertQuestions(questions: List): Observable {
14 | questionsDao.insertAll(questions)
15 | return Observable.just(true)
16 | }
17 |
18 | override fun loadQuestions(): Observable> = Observable.fromCallable({ questionsDao.loadAll() })
19 | }
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/data/database/repository/questions/QuestionsDao.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.data.database.repository.questions
2 |
3 | import android.arch.persistence.room.Dao
4 | import android.arch.persistence.room.Insert
5 | import android.arch.persistence.room.OnConflictStrategy
6 | import android.arch.persistence.room.Query
7 |
8 | /**
9 | * Created by jyotidubey on 04/01/18.
10 | */
11 | @Dao
12 | interface QuestionsDao {
13 |
14 | @Insert(onConflict = OnConflictStrategy.REPLACE)
15 | fun insertAll(question: List)
16 |
17 | @Query("SELECT * FROM questions")
18 | fun loadAll(): List
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/data/network/ApiEndPoint.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.data.network
2 |
3 | import com.mindorks.framework.mvp.BuildConfig
4 |
5 | /**
6 | * Created by jyotidubey on 11/01/18.
7 | */
8 | object ApiEndPoint {
9 |
10 | val ENDPOINT_GOOGLE_LOGIN = BuildConfig.BASE_URL + "/588d14f4100000a9072d2943"
11 | val ENDPOINT_FACEBOOK_LOGIN = BuildConfig.BASE_URL + "/588d15d3100000ae072d2944"
12 | val ENDPOINT_SERVER_LOGIN = BuildConfig.BASE_URL + "/588d15f5100000a8072d2945"
13 | val ENDPOINT_LOGOUT = BuildConfig.BASE_URL + "/588d161c100000a9072d2946"
14 | val ENDPOINT_BLOG = BuildConfig.BASE_URL + "/5926ce9d11000096006ccb30"
15 | val ENDPOINT_OPEN_SOURCE = BuildConfig.BASE_URL + "/5926c34212000035026871cd"
16 |
17 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/data/network/ApiHeader.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.data.network
2 |
3 | import com.google.gson.annotations.Expose
4 | import com.google.gson.annotations.SerializedName
5 | import com.mindorks.framework.mvp.di.ApiKeyInfo
6 | import javax.inject.Inject
7 |
8 | /**
9 | * Created by jyotidubey on 11/01/18.
10 | */
11 | class ApiHeader @Inject constructor(internal val publicApiHeader: PublicApiHeader, internal val protectedApiHeader: ProtectedApiHeader) {
12 |
13 | class PublicApiHeader @Inject constructor(@ApiKeyInfo
14 | @Expose
15 | @SerializedName
16 | ("api_key") val apiKey: String)
17 |
18 | class ProtectedApiHeader @Inject constructor(@Expose
19 | @SerializedName("api_key") val apiKey: String,
20 | @Expose
21 | @SerializedName("user_id") val userId: Long?,
22 | @Expose
23 | @SerializedName("access_token") val accessToken: String?)
24 |
25 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/data/network/ApiHelper.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.data.network
2 |
3 | import io.reactivex.Observable
4 |
5 | /**
6 | * Created by jyotidubey on 04/01/18.
7 | */
8 | interface ApiHelper {
9 |
10 | fun performServerLogin(request: LoginRequest.ServerLoginRequest): Observable
11 |
12 | fun performFBLogin(request: LoginRequest.FacebookLoginRequest): Observable
13 |
14 | fun performGoogleLogin(request: LoginRequest.GoogleLoginRequest): Observable
15 |
16 | fun performLogoutApiCall(): Observable
17 |
18 | fun getBlogApiCall(): Observable
19 |
20 | fun getOpenSourceApiCall(): Observable
21 |
22 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/data/network/AppApiHelper.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.data.network
2 |
3 | import com.rx2androidnetworking.Rx2AndroidNetworking
4 | import io.reactivex.Observable
5 | import javax.inject.Inject
6 |
7 | /**
8 | * Created by jyotidubey on 04/01/18.
9 | */
10 | class AppApiHelper @Inject constructor(private val apiHeader: ApiHeader) : ApiHelper {
11 |
12 | override fun performServerLogin(request: LoginRequest.ServerLoginRequest): Observable =
13 | Rx2AndroidNetworking.post(ApiEndPoint.ENDPOINT_SERVER_LOGIN)
14 | .addHeaders(apiHeader.publicApiHeader)
15 | .addBodyParameter(request)
16 | .build()
17 | .getObjectObservable(LoginResponse::class.java)
18 |
19 | override fun performFBLogin(request: LoginRequest.FacebookLoginRequest): Observable =
20 | Rx2AndroidNetworking.post(ApiEndPoint.ENDPOINT_FACEBOOK_LOGIN)
21 | .addHeaders(apiHeader.publicApiHeader)
22 | .addBodyParameter(request)
23 | .build()
24 | .getObjectObservable(LoginResponse::class.java)
25 |
26 | override fun performGoogleLogin(request: LoginRequest.GoogleLoginRequest): Observable =
27 | Rx2AndroidNetworking.post(ApiEndPoint.ENDPOINT_GOOGLE_LOGIN)
28 | .addHeaders(apiHeader.publicApiHeader)
29 | .addBodyParameter(request)
30 | .build()
31 | .getObjectObservable(LoginResponse::class.java)
32 |
33 | override fun performLogoutApiCall(): Observable =
34 | Rx2AndroidNetworking.post(ApiEndPoint.ENDPOINT_LOGOUT)
35 | .addHeaders(apiHeader.protectedApiHeader)
36 | .build()
37 | .getObjectObservable(LogoutResponse::class.java)
38 |
39 | override fun getBlogApiCall(): Observable =
40 | Rx2AndroidNetworking.get(ApiEndPoint.ENDPOINT_BLOG)
41 | .addHeaders(apiHeader.protectedApiHeader)
42 | .build()
43 | .getObjectObservable(BlogResponse::class.java)
44 |
45 | override fun getOpenSourceApiCall(): Observable =
46 | Rx2AndroidNetworking.get(ApiEndPoint.ENDPOINT_OPEN_SOURCE)
47 | .addHeaders(apiHeader.protectedApiHeader)
48 | .build()
49 | .getObjectObservable(OpenSourceResponse::class.java)
50 |
51 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/data/network/Blog.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.data.network
2 |
3 | import com.google.gson.annotations.Expose
4 | import com.google.gson.annotations.SerializedName
5 |
6 | /**
7 | * Created by jyotidubey on 17/01/18.
8 | */
9 | data class Blog(@Expose
10 | @SerializedName("blog_url")
11 | var blogUrl: String? = null,
12 |
13 | @Expose
14 | @SerializedName("img_url")
15 | var coverImgUrl: String? = null,
16 |
17 | @Expose
18 | @SerializedName("title")
19 | var title: String? = null,
20 |
21 | @Expose
22 | @SerializedName("description")
23 | var description: String? = null,
24 |
25 | @Expose
26 | @SerializedName("author")
27 | var author: String? = null,
28 |
29 | @Expose
30 | @SerializedName("published_at")
31 | var date: String? = null)
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/data/network/BlogResponse.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.data.network
2 |
3 | import com.google.gson.annotations.Expose
4 | import com.google.gson.annotations.SerializedName
5 |
6 | /**
7 | * Created by jyotidubey on 13/01/18.
8 | */
9 | data class BlogResponse(@Expose
10 | @SerializedName("status_code")
11 | private var statusCode: String? = null,
12 |
13 | @Expose
14 | @SerializedName("message")
15 | private var message: String? = null,
16 |
17 | @Expose
18 | @SerializedName("data")
19 | var data: List? = null)
20 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/data/network/LoginRequest.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.data.network
2 |
3 | import com.google.gson.annotations.Expose
4 | import com.google.gson.annotations.SerializedName
5 |
6 | /**
7 | * Created by jyotidubey on 11/01/18.
8 | */
9 | class LoginRequest {
10 |
11 | data class ServerLoginRequest internal constructor(@Expose
12 | @SerializedName("email") internal val email: String,
13 | @Expose
14 | @SerializedName("password") internal val password: String)
15 |
16 | data class FacebookLoginRequest internal constructor(@Expose
17 | @SerializedName("fb_user_id")
18 | internal val fbUserId: String,
19 | @Expose
20 | @SerializedName("fb_access_token")
21 | internal val fbAccessToken: String)
22 |
23 | data class GoogleLoginRequest internal constructor(@Expose
24 | @SerializedName("google_user_id")
25 | internal val googleUserId: String,
26 | @Expose
27 | @SerializedName("google_id_token")
28 | internal val idToken: String)
29 |
30 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/data/network/LoginResponse.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.data.network
2 |
3 | import com.google.gson.annotations.Expose
4 | import com.google.gson.annotations.SerializedName
5 |
6 | /**
7 | * Created by jyotidubey on 11/01/18.
8 | */
9 | data class LoginResponse(@Expose
10 | @SerializedName("status_code")
11 | var statusCode: String? = null,
12 |
13 | @Expose
14 | @SerializedName("user_id")
15 | var userId: Long? = null,
16 |
17 | @Expose
18 | @SerializedName("access_token")
19 | var accessToken: String? = null,
20 |
21 | @Expose
22 | @SerializedName("user_name")
23 | var userName: String? = null,
24 |
25 | @Expose
26 | @SerializedName("email")
27 | var userEmail: String? = null,
28 |
29 | @Expose
30 | @SerializedName("server_profile_pic_url")
31 | var serverProfilePicUrl: String? = null,
32 |
33 | @Expose
34 | @SerializedName("fb_profile_pic_url")
35 | var fbProfilePicUrl: String? = null,
36 |
37 | @Expose
38 | @SerializedName("google_profile_pic_url")
39 | var googleProfilePicUrl: String? = null,
40 |
41 | @Expose
42 | @SerializedName("message")
43 | var message: String? = null)
44 |
45 |
46 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/data/network/LogoutResponse.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.data.network
2 |
3 | import com.google.gson.annotations.Expose
4 | import com.google.gson.annotations.SerializedName
5 |
6 | /**
7 | * Created by jyotidubey on 12/01/18.
8 | */
9 | data class LogoutResponse internal constructor(@Expose
10 | @SerializedName("status_code")
11 | private var statusCode: String? = null,
12 | @Expose
13 | @SerializedName("message")
14 | private var message: String? = null)
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/data/network/OpenSource.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.data.network
2 |
3 | import com.google.gson.annotations.Expose
4 | import com.google.gson.annotations.SerializedName
5 |
6 | /**
7 | * Created by jyotidubey on 17/01/18.
8 | */
9 | data class OpenSource(@Expose
10 | @SerializedName("project_url")
11 | var projectUrl: String? = null,
12 |
13 | @Expose
14 | @SerializedName("img_url")
15 | var coverImgUrl: String? = null,
16 |
17 | @Expose
18 | @SerializedName("title")
19 | var title: String? = null,
20 |
21 | @Expose
22 | @SerializedName("description")
23 | var description: String? = null)
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/data/network/OpenSourceResponse.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.data.network
2 |
3 | import com.google.gson.annotations.Expose
4 | import com.google.gson.annotations.SerializedName
5 |
6 | /**
7 | * Created by jyotidubey on 14/01/18.
8 | */
9 | data class OpenSourceResponse(@Expose
10 | @SerializedName("status_code")
11 | private var statusCode: String? = null,
12 |
13 | @Expose
14 | @SerializedName("message")
15 | private var message: String? = null,
16 |
17 | @Expose
18 | @SerializedName("data")
19 | var data: List? = null)
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/data/preferences/AppPreferenceHelper.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.data.preferences
2 |
3 | import android.content.Context
4 | import android.content.SharedPreferences
5 | import androidx.content.edit
6 | import com.mindorks.framework.mvp.di.PreferenceInfo
7 | import com.mindorks.framework.mvp.util.AppConstants
8 | import javax.inject.Inject
9 |
10 | /**
11 | * Created by jyotidubey on 04/01/18.
12 | */
13 | class AppPreferenceHelper @Inject constructor(context: Context,
14 | @PreferenceInfo private val prefFileName: String) : PreferenceHelper {
15 | companion object {
16 | private val PREF_KEY_USER_LOGGED_IN_MODE = "PREF_KEY_USER_LOGGED_IN_MODE"
17 | private val PREF_KEY_CURRENT_USER_ID = "PREF_KEY_CURRENT_USER_ID"
18 | private val PREF_KEY_ACCESS_TOKEN = "PREF_KEY_ACCESS_TOKEN"
19 | private val PREF_KEY_CURRENT_USER_NAME = "PREF_KEY_CURRENT_USER_NAME"
20 | private val PREF_KEY_CURRENT_USER_EMAIL = "PREF_KEY_CURRENT_USER_EMAIL"
21 | }
22 |
23 | private val mPrefs: SharedPreferences = context.getSharedPreferences(prefFileName, Context.MODE_PRIVATE)
24 |
25 | override fun getCurrentUserLoggedInMode() = mPrefs.getInt(PREF_KEY_USER_LOGGED_IN_MODE, AppConstants.LoggedInMode.LOGGED_IN_MODE_LOGGED_OUT.type)
26 |
27 | override fun getCurrentUserName(): String = mPrefs.getString(PREF_KEY_CURRENT_USER_NAME, "ABC")
28 |
29 | override fun setCurrentUserName(userName: String?) = mPrefs.edit { putString(PREF_KEY_CURRENT_USER_NAME, userName) }
30 |
31 | override fun getCurrentUserEmail(): String = mPrefs.getString(PREF_KEY_CURRENT_USER_EMAIL, "abc@gmail.com")
32 |
33 | override fun setCurrentUserEmail(email: String?) = mPrefs.edit { putString(PREF_KEY_CURRENT_USER_EMAIL, email) }
34 |
35 | override fun getAccessToken(): String = mPrefs.getString(PREF_KEY_ACCESS_TOKEN, "")
36 |
37 | override fun setAccessToken(accessToken: String?) = mPrefs.edit { putString(PREF_KEY_ACCESS_TOKEN, accessToken) }
38 |
39 | override fun getCurrentUserId(): Long? {
40 | val userId = mPrefs.getLong(PREF_KEY_CURRENT_USER_ID, AppConstants.NULL_INDEX)
41 | return when (userId) {
42 | AppConstants.NULL_INDEX -> null
43 | else -> userId
44 | }
45 | }
46 |
47 | override fun setCurrentUserId(userId: Long?) {
48 | val id = userId ?: AppConstants.NULL_INDEX
49 | mPrefs.edit { putLong(PREF_KEY_CURRENT_USER_ID, id) }
50 | }
51 |
52 | override fun setCurrentUserLoggedInMode(mode: AppConstants.LoggedInMode) {
53 | mPrefs.edit { putInt(PREF_KEY_USER_LOGGED_IN_MODE, mode.type) }
54 | }
55 |
56 |
57 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/data/preferences/PreferenceHelper.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.data.preferences
2 |
3 | import com.mindorks.framework.mvp.util.AppConstants
4 |
5 | /**
6 | * Created by jyotidubey on 04/01/18.
7 | */
8 | interface PreferenceHelper {
9 |
10 | fun getCurrentUserLoggedInMode(): Int
11 |
12 | fun setCurrentUserLoggedInMode(mode: AppConstants.LoggedInMode)
13 |
14 | fun getCurrentUserId(): Long?
15 |
16 | fun setCurrentUserId(userId: Long?)
17 |
18 | fun getCurrentUserName(): String
19 |
20 | fun setCurrentUserName(userName: String?)
21 |
22 | fun getCurrentUserEmail(): String?
23 |
24 | fun setCurrentUserEmail(email: String?)
25 |
26 | fun getAccessToken(): String?
27 |
28 | fun setAccessToken(accessToken: String?)
29 |
30 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/di/ApiKeyInfo.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.di
2 |
3 | import javax.inject.Qualifier
4 |
5 | /**
6 | * Created by jyotidubey on 22/01/18.
7 | */
8 | @Qualifier
9 | @Retention annotation class ApiKeyInfo
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/di/PreferenceInfo.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.di
2 |
3 | import javax.inject.Qualifier
4 |
5 | /**
6 | * Created by jyotidubey on 11/01/18.
7 | */
8 | @Qualifier
9 | @Retention annotation class PreferenceInfo
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/di/builder/ActivityBuilder.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.di.builder
2 |
3 | import com.mindorks.framework.mvp.ui.about.AboutFragmentProvider
4 | import com.mindorks.framework.mvp.ui.feed.blog.BlogFragmentProvider
5 | import com.mindorks.framework.mvp.ui.feed.opensource.OpenSourceFragmentProvider
6 | import com.mindorks.framework.mvp.ui.feed.view.FeedActivity
7 | import com.mindorks.framework.mvp.ui.login.LoginActivityModule
8 | import com.mindorks.framework.mvp.ui.login.view.LoginActivity
9 | import com.mindorks.framework.mvp.ui.main.MainActivityModule
10 | import com.mindorks.framework.mvp.ui.main.view.MainActivity
11 | import com.mindorks.framework.mvp.ui.rate.RateUsDialogFragmentProvider
12 | import com.mindorks.framework.mvp.ui.splash.SplashActivityModule
13 | import com.mindorks.framework.mvp.ui.splash.view.SplashMVPActivity
14 | import dagger.Module
15 | import dagger.android.ContributesAndroidInjector
16 |
17 | /**
18 | * Created by jyotidubey on 05/01/18.
19 | */
20 | @Module
21 | abstract class ActivityBuilder {
22 |
23 | @ContributesAndroidInjector(modules = [(SplashActivityModule::class)])
24 | abstract fun bindSplashActivity(): SplashMVPActivity
25 |
26 | @ContributesAndroidInjector(modules = [(MainActivityModule::class), (RateUsDialogFragmentProvider::class), (AboutFragmentProvider::class)])
27 | abstract fun bindMainActivity(): MainActivity
28 |
29 | @ContributesAndroidInjector(modules = [(LoginActivityModule::class)])
30 | abstract fun bindLoginActivity(): LoginActivity
31 |
32 | @ContributesAndroidInjector(modules = [(BlogFragmentProvider::class), (OpenSourceFragmentProvider::class)])
33 | abstract fun bindFeedActivity(): FeedActivity
34 |
35 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/di/component/AppComponent.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.di.component
2 |
3 | import android.app.Application
4 | import com.mindorks.framework.mvp.MvpApp
5 | import com.mindorks.framework.mvp.di.builder.ActivityBuilder
6 | import com.mindorks.framework.mvp.di.module.AppModule
7 | import dagger.BindsInstance
8 | import dagger.Component
9 | import dagger.android.AndroidInjectionModule
10 | import javax.inject.Singleton
11 |
12 | /**
13 | * Created by jyotidubey on 05/01/18.
14 | */
15 | @Singleton
16 | @Component(modules = [(AndroidInjectionModule::class), (AppModule::class), (ActivityBuilder::class)])
17 | interface AppComponent {
18 |
19 | @Component.Builder
20 | interface Builder {
21 |
22 | @BindsInstance
23 | fun application(application: Application): Builder
24 |
25 | fun build(): AppComponent
26 | }
27 |
28 | fun inject(app: MvpApp)
29 |
30 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/di/module/AppModule.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.di.module
2 |
3 | import android.app.Application
4 | import android.arch.persistence.room.Room
5 | import android.content.Context
6 | import com.mindorks.framework.mvp.BuildConfig
7 | import com.mindorks.framework.mvp.data.database.AppDatabase
8 | import com.mindorks.framework.mvp.data.database.repository.options.OptionsRepo
9 | import com.mindorks.framework.mvp.data.database.repository.options.OptionsRepository
10 | import com.mindorks.framework.mvp.data.database.repository.questions.QuestionRepo
11 | import com.mindorks.framework.mvp.data.database.repository.questions.QuestionRepository
12 | import com.mindorks.framework.mvp.data.network.ApiHeader
13 | import com.mindorks.framework.mvp.data.network.ApiHelper
14 | import com.mindorks.framework.mvp.data.network.AppApiHelper
15 | import com.mindorks.framework.mvp.data.preferences.AppPreferenceHelper
16 | import com.mindorks.framework.mvp.data.preferences.PreferenceHelper
17 | import com.mindorks.framework.mvp.di.ApiKeyInfo
18 | import com.mindorks.framework.mvp.di.PreferenceInfo
19 | import com.mindorks.framework.mvp.util.AppConstants
20 | import com.mindorks.framework.mvp.util.SchedulerProvider
21 | import dagger.Module
22 | import dagger.Provides
23 | import io.reactivex.disposables.CompositeDisposable
24 | import javax.inject.Singleton
25 |
26 | /**
27 | * Created by jyotidubey on 05/01/18.
28 | */
29 | @Module
30 | class AppModule {
31 |
32 | @Provides
33 | @Singleton
34 | internal fun provideContext(application: Application): Context = application
35 |
36 | @Provides
37 | @Singleton
38 | internal fun provideAppDatabase(context: Context): AppDatabase =
39 | Room.databaseBuilder(context, AppDatabase::class.java, AppConstants.APP_DB_NAME).build()
40 |
41 | @Provides
42 | @ApiKeyInfo
43 | internal fun provideApiKey(): String = BuildConfig.API_KEY
44 |
45 | @Provides
46 | @PreferenceInfo
47 | internal fun provideprefFileName(): String = AppConstants.PREF_NAME
48 |
49 | @Provides
50 | @Singleton
51 | internal fun providePrefHelper(appPreferenceHelper: AppPreferenceHelper): PreferenceHelper = appPreferenceHelper
52 |
53 | @Provides
54 | @Singleton
55 | internal fun provideProtectedApiHeader(@ApiKeyInfo apiKey: String, preferenceHelper: PreferenceHelper)
56 | : ApiHeader.ProtectedApiHeader = ApiHeader.ProtectedApiHeader(apiKey = apiKey,
57 | userId = preferenceHelper.getCurrentUserId(),
58 | accessToken = preferenceHelper.getAccessToken())
59 |
60 | @Provides
61 | @Singleton
62 | internal fun provideApiHelper(appApiHelper: AppApiHelper): ApiHelper = appApiHelper
63 |
64 | @Provides
65 | @Singleton
66 | internal fun provideQuestionRepoHelper(appDatabase: AppDatabase): QuestionRepo = QuestionRepository(appDatabase.questionsDao())
67 |
68 | @Provides
69 | @Singleton
70 | internal fun provideOptionsRepoHelper(appDatabase: AppDatabase): OptionsRepo = OptionsRepository(appDatabase.optionsDao())
71 |
72 | @Provides
73 | internal fun provideCompositeDisposable(): CompositeDisposable = CompositeDisposable()
74 |
75 | @Provides
76 | internal fun provideSchedulerProvider(): SchedulerProvider = SchedulerProvider()
77 |
78 |
79 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/about/AboutFragmentProvider.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.about
2 |
3 | import com.mindorks.framework.mvp.ui.about.view.AboutFragment
4 | import dagger.Module
5 | import dagger.android.ContributesAndroidInjector
6 |
7 | /**
8 | * Created by jyotidubey on 15/01/18.
9 | */
10 | @Module
11 | abstract class AboutFragmentProvider {
12 |
13 | @ContributesAndroidInjector
14 | abstract internal fun provideAboutFragment(): AboutFragment
15 |
16 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/about/view/AboutFragment.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.about.view
2 |
3 | import android.os.Bundle
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import com.mindorks.framework.mvp.R
8 | import com.mindorks.framework.mvp.ui.base.view.BaseFragment
9 | import kotlinx.android.synthetic.main.fragment_about.*
10 |
11 | /**
12 | * Created by jyotidubey on 12/01/18.
13 | */
14 | class AboutFragment : BaseFragment() {
15 |
16 | companion object {
17 |
18 | internal val TAG = "AboutFragment"
19 |
20 | fun newInstance(): AboutFragment {
21 | return AboutFragment()
22 | }
23 |
24 | }
25 |
26 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
27 | inflater.inflate(R.layout.fragment_about, container, false)
28 |
29 | override fun setUp() = navBackBtn.setOnClickListener { getBaseActivity()?.onFragmentDetached(TAG) }
30 |
31 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/base/interactor/BaseInteractor.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.base.interactor
2 |
3 | import com.mindorks.framework.mvp.data.network.ApiHelper
4 | import com.mindorks.framework.mvp.data.preferences.PreferenceHelper
5 | import com.mindorks.framework.mvp.util.AppConstants
6 |
7 | /**
8 | * Created by jyotidubey on 04/01/18.
9 | */
10 | open class BaseInteractor() : MVPInteractor {
11 |
12 | protected lateinit var preferenceHelper: PreferenceHelper
13 | protected lateinit var apiHelper: ApiHelper
14 |
15 | constructor(preferenceHelper: PreferenceHelper, apiHelper: ApiHelper) : this() {
16 | this.preferenceHelper = preferenceHelper
17 | this.apiHelper = apiHelper
18 | }
19 |
20 | override fun isUserLoggedIn() = this.preferenceHelper.getCurrentUserLoggedInMode() != AppConstants.LoggedInMode.LOGGED_IN_MODE_LOGGED_OUT.type
21 |
22 | override fun performUserLogout() = preferenceHelper.let {
23 | it.setCurrentUserId(null)
24 | it.setAccessToken(null)
25 | it.setCurrentUserEmail(null)
26 | it.setCurrentUserLoggedInMode(AppConstants.LoggedInMode.LOGGED_IN_MODE_LOGGED_OUT)
27 | }
28 |
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/base/interactor/MVPInteractor.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.base.interactor
2 |
3 | /**
4 | * Created by jyotidubey on 04/01/18.
5 | */
6 | interface MVPInteractor {
7 |
8 | fun isUserLoggedIn(): Boolean
9 |
10 | fun performUserLogout()
11 |
12 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/base/presenter/BasePresenter.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.base.presenter
2 |
3 | import com.mindorks.framework.mvp.ui.base.interactor.MVPInteractor
4 | import com.mindorks.framework.mvp.ui.base.view.MVPView
5 | import com.mindorks.framework.mvp.util.SchedulerProvider
6 | import io.reactivex.disposables.CompositeDisposable
7 |
8 | /**
9 | * Created by jyotidubey on 04/01/18.
10 | */
11 | abstract class BasePresenter internal constructor(protected var interactor: I?, protected val schedulerProvider: SchedulerProvider, protected val compositeDisposable: CompositeDisposable) : MVPPresenter {
12 |
13 | private var view: V? = null
14 | private val isViewAttached: Boolean get() = view != null
15 |
16 | override fun onAttach(view: V?) {
17 | this.view = view
18 | }
19 |
20 | override fun getView(): V? = view
21 |
22 | override fun onDetach() {
23 | compositeDisposable.dispose()
24 | view = null
25 | interactor = null
26 | }
27 |
28 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/base/presenter/MVPPresenter.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.base.presenter
2 |
3 | import com.mindorks.framework.mvp.ui.base.interactor.MVPInteractor
4 | import com.mindorks.framework.mvp.ui.base.view.MVPView
5 |
6 | /**
7 | * Created by jyotidubey on 04/01/18.
8 | */
9 | interface MVPPresenter {
10 |
11 | fun onAttach(view: V?)
12 |
13 | fun onDetach()
14 |
15 | fun getView(): V?
16 |
17 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/base/view/BaseActivity.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.base.view
2 |
3 | import android.app.ProgressDialog
4 | import android.os.Bundle
5 | import android.support.v7.app.AppCompatActivity
6 | import com.mindorks.framework.mvp.util.CommonUtil
7 | import dagger.android.AndroidInjection
8 |
9 | /**
10 | * Created by jyotidubey on 04/01/18.
11 | */
12 | abstract class BaseActivity : AppCompatActivity(), MVPView, BaseFragment.CallBack {
13 |
14 | private var progressDialog: ProgressDialog? = null
15 |
16 | override fun onCreate(savedInstanceState: Bundle?) {
17 | performDI()
18 | super.onCreate(savedInstanceState)
19 | }
20 |
21 | override fun hideProgress() {
22 | progressDialog?.let { if (it.isShowing) it.cancel() }
23 | }
24 |
25 | override fun showProgress() {
26 | hideProgress()
27 | progressDialog = CommonUtil.showLoadingDialog(this)
28 | }
29 |
30 | private fun performDI() = AndroidInjection.inject(this)
31 |
32 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/base/view/BaseDialogView.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.base.view
2 |
3 | import android.app.ProgressDialog
4 | import android.content.Context
5 | import android.os.Bundle
6 | import android.support.v4.app.DialogFragment
7 | import android.support.v4.app.FragmentManager
8 | import com.mindorks.framework.mvp.util.CommonUtil
9 | import dagger.android.support.AndroidSupportInjection
10 |
11 |
12 | /**
13 | * Created by jyotidubey on 14/01/18.
14 | */
15 | abstract class BaseDialogView : DialogFragment(), DialogMVPView {
16 |
17 | private var parentActivity: BaseActivity? = null
18 | private var progressDialog: ProgressDialog? = null
19 |
20 | override fun onAttach(context: Context?) {
21 | super.onAttach(context)
22 | if (context is BaseActivity) {
23 | val activity = context as BaseActivity?
24 | this.parentActivity = activity
25 | activity?.onFragmentAttached()
26 | }
27 | }
28 |
29 | override fun onCreate(savedInstanceState: Bundle?) {
30 | super.onCreate(savedInstanceState)
31 | performDependencyInjection()
32 | }
33 |
34 | override fun show(fragmentManager: FragmentManager, tag: String) {
35 | val transaction = fragmentManager.beginTransaction()
36 |
37 | val prevFragment = fragmentManager.findFragmentByTag(tag)
38 | if (prevFragment != null) {
39 | transaction.remove(prevFragment)
40 | }
41 | transaction.addToBackStack(null)
42 | show(transaction, tag)
43 | }
44 |
45 | override fun hideProgress() {
46 | if (progressDialog != null && progressDialog?.isShowing!!) {
47 | progressDialog?.cancel()
48 | }
49 | }
50 |
51 | override fun showProgress() {
52 | hideProgress()
53 | progressDialog = CommonUtil.showLoadingDialog(this.context)
54 | }
55 |
56 | private fun performDependencyInjection() {
57 | AndroidSupportInjection.inject(this)
58 | }
59 |
60 | fun dismissDialog(tag: String) {
61 | dismiss()
62 | getBaseActivity()?.onFragmentDetached(tag)
63 | }
64 |
65 | private fun getBaseActivity(): BaseActivity? {
66 | return parentActivity
67 | }
68 |
69 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/base/view/BaseFragment.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.base.view
2 |
3 | import android.app.ProgressDialog
4 | import android.content.Context
5 | import android.os.Bundle
6 | import android.support.v4.app.Fragment
7 | import android.view.View
8 | import com.mindorks.framework.mvp.util.CommonUtil
9 | import dagger.android.support.AndroidSupportInjection
10 |
11 |
12 | /**
13 | * Created by jyotidubey on 12/01/18.
14 | */
15 | abstract class BaseFragment : Fragment(), MVPView {
16 |
17 | private var parentActivity: BaseActivity? = null
18 | private var progressDialog: ProgressDialog? = null
19 |
20 | override fun onAttach(context: Context?) {
21 | super.onAttach(context)
22 | if (context is BaseActivity) {
23 | val activity = context as BaseActivity?
24 | this.parentActivity = activity
25 | activity?.onFragmentAttached()
26 | }
27 | }
28 |
29 | override fun onCreate(savedInstanceState: Bundle?) {
30 | performDependencyInjection()
31 | super.onCreate(savedInstanceState)
32 | setHasOptionsMenu(false)
33 | }
34 |
35 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
36 | super.onViewCreated(view, savedInstanceState)
37 | setUp()
38 | }
39 |
40 | override fun hideProgress() {
41 | if (progressDialog != null && progressDialog?.isShowing!!) {
42 | progressDialog?.cancel()
43 | }
44 | }
45 |
46 | override fun showProgress() {
47 | hideProgress()
48 | progressDialog = CommonUtil.showLoadingDialog(this.context)
49 | }
50 |
51 | fun getBaseActivity() = parentActivity
52 |
53 | private fun performDependencyInjection() = AndroidSupportInjection.inject(this)
54 |
55 | interface CallBack {
56 | fun onFragmentAttached()
57 | fun onFragmentDetached(tag: String)
58 | }
59 |
60 | abstract fun setUp()
61 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/base/view/DialogMVPView.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.base.view
2 |
3 | /**
4 | * Created by jyotidubey on 15/01/18.
5 | */
6 | interface DialogMVPView : MVPView
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/base/view/MVPView.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.base.view
2 |
3 | /**
4 | * Created by jyotidubey on 04/01/18.
5 | */
6 | interface MVPView {
7 |
8 | fun showProgress()
9 |
10 | fun hideProgress()
11 |
12 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/feed/FeedPagerAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.feed
2 |
3 | import android.support.v4.app.Fragment
4 | import android.support.v4.app.FragmentManager
5 | import android.support.v4.app.FragmentStatePagerAdapter
6 | import com.mindorks.framework.mvp.ui.feed.blog.view.BlogFragment
7 | import com.mindorks.framework.mvp.ui.feed.opensource.view.OpenSourceFragment
8 |
9 | /**
10 | * Created by jyotidubey on 13/01/18.
11 | */
12 | class FeedPagerAdapter(fragmentManager: FragmentManager) : FragmentStatePagerAdapter(fragmentManager) {
13 |
14 | private var tabCount = 0
15 |
16 | override fun getCount(): Int {
17 | return tabCount
18 | }
19 |
20 | override fun getItem(position: Int): Fragment? {
21 | return when (position) {
22 | 0 -> BlogFragment.newInstance()
23 | 1 -> OpenSourceFragment.newInstance()
24 | else -> null
25 | }
26 | }
27 |
28 | internal fun setCount(count: Int) {
29 | this.tabCount = count
30 | }
31 |
32 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/feed/blog/BlogFragmentModule.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.feed.blog
2 |
3 | import android.support.v7.widget.LinearLayoutManager
4 | import com.mindorks.framework.mvp.ui.feed.blog.interactor.BlogInteractor
5 | import com.mindorks.framework.mvp.ui.feed.blog.interactor.BlogMVPInteractor
6 | import com.mindorks.framework.mvp.ui.feed.blog.presenter.BlogMVPPresenter
7 | import com.mindorks.framework.mvp.ui.feed.blog.presenter.BlogPresenter
8 | import com.mindorks.framework.mvp.ui.feed.blog.view.BlogAdapter
9 | import com.mindorks.framework.mvp.ui.feed.blog.view.BlogFragment
10 | import com.mindorks.framework.mvp.ui.feed.blog.view.BlogMVPView
11 | import dagger.Module
12 | import dagger.Provides
13 | import java.util.*
14 |
15 | /**
16 | * Created by jyotidubey on 14/01/18.
17 | */
18 | @Module
19 | class BlogFragmentModule {
20 |
21 | @Provides
22 | internal fun provideBlogInteractor(interactor: BlogInteractor): BlogMVPInteractor = interactor
23 |
24 | @Provides
25 | internal fun provideBlogPresenter(presenter: BlogPresenter)
26 | : BlogMVPPresenter = presenter
27 |
28 | @Provides
29 | internal fun provideBlogAdapter(): BlogAdapter = BlogAdapter(ArrayList())
30 |
31 | @Provides
32 | internal fun provideLinearLayoutManager(fragment: BlogFragment): LinearLayoutManager = LinearLayoutManager(fragment.activity)
33 |
34 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/feed/blog/BlogFragmentProvider.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.feed.blog
2 |
3 | import com.mindorks.framework.mvp.ui.feed.blog.view.BlogFragment
4 | import dagger.Module
5 | import dagger.android.ContributesAndroidInjector
6 |
7 | /**
8 | * Created by jyotidubey on 14/01/18.
9 | */
10 | @Module
11 | internal abstract class BlogFragmentProvider {
12 |
13 | @ContributesAndroidInjector(modules = [BlogFragmentModule::class])
14 | internal abstract fun provideBlogFragmentFactory(): BlogFragment
15 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/feed/blog/interactor/BlogInteractor.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.feed.blog.interactor
2 |
3 | import com.mindorks.framework.mvp.data.network.ApiHelper
4 | import com.mindorks.framework.mvp.data.preferences.PreferenceHelper
5 | import com.mindorks.framework.mvp.ui.base.interactor.BaseInteractor
6 | import javax.inject.Inject
7 |
8 | /**
9 | * Created by jyotidubey on 13/01/18.
10 | */
11 | class BlogInteractor @Inject internal constructor(preferenceHelper: PreferenceHelper, apiHelper: ApiHelper) : BaseInteractor(preferenceHelper, apiHelper), BlogMVPInteractor {
12 |
13 | override fun getBlogList() = apiHelper.getBlogApiCall()
14 |
15 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/feed/blog/interactor/BlogMVPInteractor.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.feed.blog.interactor
2 |
3 | import com.mindorks.framework.mvp.data.network.BlogResponse
4 | import com.mindorks.framework.mvp.ui.base.interactor.MVPInteractor
5 | import io.reactivex.Observable
6 |
7 | /**
8 | * Created by jyotidubey on 13/01/18.
9 | */
10 | interface BlogMVPInteractor : MVPInteractor {
11 |
12 | fun getBlogList(): Observable
13 |
14 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/feed/blog/presenter/BlogMVPPresenter.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.feed.blog.presenter
2 |
3 | import com.mindorks.framework.mvp.ui.base.presenter.MVPPresenter
4 | import com.mindorks.framework.mvp.ui.feed.blog.interactor.BlogMVPInteractor
5 | import com.mindorks.framework.mvp.ui.feed.blog.view.BlogMVPView
6 |
7 | /**
8 | * Created by jyotidubey on 13/01/18.
9 | */
10 | interface BlogMVPPresenter : MVPPresenter {
11 |
12 | fun onViewPrepared()
13 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/feed/blog/presenter/BlogPresenter.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.feed.blog.presenter
2 |
3 | import com.mindorks.framework.mvp.ui.base.presenter.BasePresenter
4 | import com.mindorks.framework.mvp.ui.feed.blog.interactor.BlogMVPInteractor
5 | import com.mindorks.framework.mvp.ui.feed.blog.view.BlogMVPView
6 | import com.mindorks.framework.mvp.util.SchedulerProvider
7 | import io.reactivex.disposables.CompositeDisposable
8 | import javax.inject.Inject
9 |
10 | /**
11 | * Created by jyotidubey on 13/01/18.
12 | */
13 | class BlogPresenter @Inject constructor(interactor: I, schedulerProvider: SchedulerProvider, compositeDisposable: CompositeDisposable) : BasePresenter(interactor = interactor, schedulerProvider = schedulerProvider, compositeDisposable = compositeDisposable), BlogMVPPresenter {
14 |
15 | override fun onViewPrepared() {
16 | getView()?.showProgress()
17 | interactor?.let {
18 | it.getBlogList()
19 | .compose(schedulerProvider.ioToMainObservableScheduler())
20 | .subscribe { blogResponse ->
21 | getView()?.let {
22 | it.hideProgress()
23 | it.displayBlogList(blogResponse.data)
24 | }
25 | }
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/feed/blog/view/BlogAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.feed.blog.view
2 |
3 | import android.content.Intent
4 | import android.net.Uri
5 | import android.support.v7.widget.RecyclerView
6 | import android.view.LayoutInflater
7 | import android.view.View
8 | import android.view.ViewGroup
9 | import com.mindorks.framework.mvp.R
10 | import com.mindorks.framework.mvp.data.network.Blog
11 | import com.mindorks.framework.mvp.util.extension.loadImage
12 | import kotlinx.android.synthetic.main.item_blog_list.view.*
13 |
14 |
15 | /**
16 | * Created by jyotidubey on 14/01/18.
17 | */
18 | class BlogAdapter(private val blogListItems: MutableList) : RecyclerView.Adapter() {
19 |
20 | override fun getItemCount() = this.blogListItems.size
21 |
22 | override fun onBindViewHolder(holder: BlogViewHolder, position: Int) = holder.let {
23 | it.clear()
24 | it.onBind(position)
25 | }
26 |
27 | override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int) = BlogViewHolder(LayoutInflater.from(parent?.context)
28 | .inflate(R.layout.item_blog_list, parent, false))
29 |
30 | internal fun addBlogsToList(blogs: List) {
31 | this.blogListItems.addAll(blogs)
32 | notifyDataSetChanged()
33 | }
34 |
35 | inner class BlogViewHolder(view: View) : RecyclerView.ViewHolder(view) {
36 |
37 | fun clear() {
38 | itemView.coverImageView.setImageDrawable(null)
39 | itemView.titleTextView.text = ""
40 | itemView.contentTextView.text = ""
41 | }
42 |
43 | fun onBind(position: Int) {
44 |
45 | val (title, coverPageUrl, date, description, author, blogUrl) = blogListItems[position]
46 |
47 | inflateData(title, author, date, description, coverPageUrl)
48 | setItemClickListener(blogUrl)
49 | }
50 |
51 | private fun setItemClickListener(blogUrl: String?) {
52 | itemView.setOnClickListener {
53 | blogUrl?.let {
54 | try {
55 | val intent = Intent()
56 | // using "with" as an example
57 | with(intent) {
58 | action = Intent.ACTION_VIEW
59 | data = Uri.parse(it)
60 | addCategory(Intent.CATEGORY_BROWSABLE)
61 | }
62 | itemView.context.startActivity(intent)
63 | } catch (e: Exception) {
64 | }
65 | }
66 |
67 | }
68 | }
69 |
70 | private fun inflateData(title: String?, author: String?, date: String?, description: String?, coverPageUrl: String?) {
71 | title?.let { itemView.titleTextView.text = it }
72 | author?.let { itemView.authorTextView.text = it }
73 | date?.let { itemView.dateTextView.text = it }
74 | description?.let { itemView.contentTextView.text = it }
75 | coverPageUrl?.let {
76 | itemView.coverImageView.loadImage(it)
77 | }
78 | }
79 |
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/feed/blog/view/BlogFragment.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.feed.blog.view
2 |
3 | import android.os.Bundle
4 | import android.support.v7.widget.DefaultItemAnimator
5 | import android.support.v7.widget.LinearLayoutManager
6 | import android.view.LayoutInflater
7 | import android.view.View
8 | import android.view.ViewGroup
9 | import com.mindorks.framework.mvp.R
10 | import com.mindorks.framework.mvp.data.network.Blog
11 | import com.mindorks.framework.mvp.ui.base.view.BaseFragment
12 | import com.mindorks.framework.mvp.ui.feed.blog.interactor.BlogMVPInteractor
13 | import com.mindorks.framework.mvp.ui.feed.blog.presenter.BlogMVPPresenter
14 | import kotlinx.android.synthetic.main.fragment_blog.*
15 | import javax.inject.Inject
16 |
17 |
18 | /**
19 | * Created by jyotidubey on 13/01/18.
20 | */
21 | class BlogFragment : BaseFragment(), BlogMVPView {
22 |
23 | companion object {
24 |
25 | fun newInstance(): BlogFragment {
26 | return BlogFragment()
27 | }
28 | }
29 |
30 | @Inject
31 | internal lateinit var blogAdapter: BlogAdapter
32 | @Inject
33 | internal lateinit var layoutManager: LinearLayoutManager
34 | @Inject
35 | internal lateinit var presenter: BlogMVPPresenter
36 |
37 |
38 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?)
39 | = inflater.inflate(R.layout.fragment_blog, container, false)
40 |
41 |
42 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
43 | presenter.onAttach(this)
44 | super.onViewCreated(view, savedInstanceState)
45 | }
46 |
47 | override fun setUp() {
48 | layoutManager.orientation = LinearLayoutManager.VERTICAL
49 | blog_recycler_view.layoutManager = layoutManager
50 | blog_recycler_view.itemAnimator = DefaultItemAnimator()
51 | blog_recycler_view.adapter = blogAdapter
52 | presenter.onViewPrepared()
53 | }
54 |
55 | override fun displayBlogList(blogs: List?) = blogs?.let {
56 | blogAdapter.addBlogsToList(it)
57 | }
58 |
59 | override fun onDestroyView() {
60 | presenter.onDetach()
61 | super.onDestroyView()
62 | }
63 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/feed/blog/view/BlogMVPView.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.feed.blog.view
2 |
3 | import com.mindorks.framework.mvp.data.network.Blog
4 | import com.mindorks.framework.mvp.ui.base.view.MVPView
5 |
6 | /**
7 | * Created by jyotidubey on 13/01/18.
8 | */
9 | interface BlogMVPView : MVPView {
10 |
11 | fun displayBlogList(blogs: List?) : Unit?
12 |
13 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/feed/opensource/OpenSourceFragmentModule.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.feed.opensource
2 |
3 | import android.support.v7.widget.LinearLayoutManager
4 | import com.mindorks.framework.mvp.ui.feed.opensource.interactor.OpenSourceInteractor
5 | import com.mindorks.framework.mvp.ui.feed.opensource.interactor.OpenSourceMVPInteractor
6 | import com.mindorks.framework.mvp.ui.feed.opensource.presenter.OpenSourceMVPPresenter
7 | import com.mindorks.framework.mvp.ui.feed.opensource.presenter.OpenSourcePresenter
8 | import com.mindorks.framework.mvp.ui.feed.opensource.view.OpenSourceAdapter
9 | import com.mindorks.framework.mvp.ui.feed.opensource.view.OpenSourceFragment
10 | import com.mindorks.framework.mvp.ui.feed.opensource.view.OpenSourceMVPView
11 | import dagger.Module
12 | import dagger.Provides
13 |
14 | /**
15 | * Created by jyotidubey on 14/01/18.
16 | */
17 | @Module
18 | class OpenSourceFragmentModule {
19 |
20 | @Provides
21 | internal fun provideOpenSourceInteractor(interactor: OpenSourceInteractor): OpenSourceMVPInteractor = interactor
22 |
23 | @Provides
24 | internal fun provideOpenSourcePresenter(presenter: OpenSourcePresenter)
25 | : OpenSourceMVPPresenter = presenter
26 |
27 | @Provides
28 | internal fun provideOpenSourceAdapter(): OpenSourceAdapter = OpenSourceAdapter(ArrayList())
29 |
30 | @Provides
31 | internal fun provideLinearLayoutManager(fragment: OpenSourceFragment): LinearLayoutManager = LinearLayoutManager(fragment.activity)
32 |
33 |
34 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/feed/opensource/OpenSourceFragmentProvider.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.feed.opensource
2 |
3 | import com.mindorks.framework.mvp.ui.feed.opensource.view.OpenSourceFragment
4 | import dagger.Module
5 | import dagger.android.ContributesAndroidInjector
6 |
7 | /**
8 | * Created by jyotidubey on 14/01/18.
9 | */
10 | @Module
11 | internal abstract class OpenSourceFragmentProvider {
12 |
13 | @ContributesAndroidInjector(modules = [(OpenSourceFragmentModule::class)])
14 | internal abstract fun provideBlogFragmentFactory(): OpenSourceFragment
15 |
16 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/feed/opensource/interactor/OpenSourceInteractor.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.feed.opensource.interactor
2 |
3 | import com.mindorks.framework.mvp.data.network.ApiHelper
4 | import com.mindorks.framework.mvp.data.network.OpenSourceResponse
5 | import com.mindorks.framework.mvp.data.preferences.PreferenceHelper
6 | import com.mindorks.framework.mvp.ui.base.interactor.BaseInteractor
7 | import io.reactivex.Observable
8 | import javax.inject.Inject
9 |
10 | /**
11 | * Created by jyotidubey on 14/01/18.
12 | */
13 | class OpenSourceInteractor @Inject internal constructor(preferenceHelper: PreferenceHelper, apiHelper: ApiHelper) : BaseInteractor(preferenceHelper, apiHelper), OpenSourceMVPInteractor {
14 |
15 | override fun getOpenSourceList(): Observable {
16 | return apiHelper.getOpenSourceApiCall()
17 | }
18 |
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/feed/opensource/interactor/OpenSourceMVPInteractor.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.feed.opensource.interactor
2 |
3 | import com.mindorks.framework.mvp.data.network.OpenSourceResponse
4 | import com.mindorks.framework.mvp.ui.base.interactor.MVPInteractor
5 | import io.reactivex.Observable
6 |
7 | /**
8 | * Created by jyotidubey on 14/01/18.
9 | */
10 | interface OpenSourceMVPInteractor : MVPInteractor {
11 |
12 | fun getOpenSourceList(): Observable
13 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/feed/opensource/presenter/OpenSourceMVPPresenter.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.feed.opensource.presenter
2 |
3 | import com.mindorks.framework.mvp.ui.base.presenter.MVPPresenter
4 | import com.mindorks.framework.mvp.ui.feed.opensource.interactor.OpenSourceMVPInteractor
5 | import com.mindorks.framework.mvp.ui.feed.opensource.view.OpenSourceMVPView
6 |
7 | /**
8 | * Created by jyotidubey on 14/01/18.
9 | */
10 | interface OpenSourceMVPPresenter : MVPPresenter {
11 |
12 | fun onViewPrepared()
13 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/feed/opensource/presenter/OpenSourcePresenter.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.feed.opensource.presenter
2 |
3 | import com.mindorks.framework.mvp.ui.base.presenter.BasePresenter
4 | import com.mindorks.framework.mvp.ui.feed.opensource.interactor.OpenSourceMVPInteractor
5 | import com.mindorks.framework.mvp.ui.feed.opensource.view.OpenSourceMVPView
6 | import com.mindorks.framework.mvp.util.SchedulerProvider
7 | import io.reactivex.disposables.CompositeDisposable
8 | import javax.inject.Inject
9 |
10 | /**
11 | * Created by jyotidubey on 14/01/18.
12 | */
13 | class OpenSourcePresenter @Inject constructor(interactor: I, schedulerProvider: SchedulerProvider, compositeDisposable: CompositeDisposable) : BasePresenter(interactor = interactor, schedulerProvider = schedulerProvider, compositeDisposable = compositeDisposable), OpenSourceMVPPresenter {
14 |
15 | override fun onViewPrepared() {
16 | getView()?.showProgress()
17 | interactor?.let {
18 | compositeDisposable.add(it.getOpenSourceList()
19 | .compose(schedulerProvider.ioToMainObservableScheduler())
20 | .subscribe { openSourceResponse ->
21 | getView()?.let {
22 | it.hideProgress()
23 | it.displayOpenSourceList(openSourceResponse.data)
24 | }
25 | })
26 | }
27 |
28 | }
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/feed/opensource/view/OpenSourceAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.feed.opensource.view
2 |
3 | import android.content.Intent
4 | import android.support.v7.widget.RecyclerView
5 | import android.view.LayoutInflater
6 | import android.view.View
7 | import android.view.ViewGroup
8 | import androidx.net.toUri
9 | import com.mindorks.framework.mvp.R
10 | import com.mindorks.framework.mvp.data.network.OpenSource
11 | import com.mindorks.framework.mvp.util.extension.loadImage
12 | import kotlinx.android.synthetic.main.item_open_source_list.view.*
13 |
14 |
15 | /**
16 | * Created by jyotidubey on 14/01/18.
17 | */
18 | class OpenSourceAdapter(openSourceListItems: MutableList) : RecyclerView.Adapter() {
19 |
20 | private val openSourceListItems: MutableList = openSourceListItems
21 |
22 |
23 | override fun getItemCount() = openSourceListItems.size
24 |
25 | override fun onBindViewHolder(holder: OpenSourceViewHolder, position: Int) = holder.run {
26 | clear()
27 | onBind(position)
28 | }
29 |
30 | override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int) = OpenSourceViewHolder(LayoutInflater.from(parent?.context)
31 | .inflate(R.layout.item_open_source_list, parent, false))
32 |
33 |
34 | internal fun addOpenSourcesToList(OpenSources: List) {
35 | this.openSourceListItems.addAll(OpenSources)
36 | notifyDataSetChanged()
37 | }
38 |
39 | inner class OpenSourceViewHolder(view: View) : RecyclerView.ViewHolder(view) {
40 |
41 | fun clear() {
42 | itemView.coverImageView.setImageDrawable(null)
43 | itemView.titleTextView.text = ""
44 | itemView.contentTextView.text = ""
45 | }
46 |
47 | fun onBind(position: Int) {
48 | val (projectUrl, coverImgUrl, title, description) = openSourceListItems[position]
49 |
50 | inflateData(title, description, coverImgUrl)
51 | setItemClickListener(projectUrl)
52 | }
53 |
54 | private fun setItemClickListener(projectUrl: String?) {
55 | itemView.setOnClickListener {
56 | projectUrl?.let {
57 | try {
58 | // using "apply" as an example
59 | itemView.context.startActivity(Intent().apply {
60 | action = Intent.ACTION_VIEW
61 | data = it.toUri()
62 | addCategory(Intent.CATEGORY_BROWSABLE)
63 | })
64 | } catch (e: Exception) {
65 | }
66 | }
67 | }
68 | }
69 |
70 | private fun inflateData(title: String?, description: String?, coverImgUrl: String?) {
71 | title?.let { itemView.titleTextView.text = it }
72 | description?.let { itemView.contentTextView.text = it }
73 | coverImgUrl?.let {
74 | itemView.coverImageView.loadImage(it)
75 | }
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/feed/opensource/view/OpenSourceFragment.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.feed.opensource.view
2 |
3 | import android.os.Bundle
4 | import android.support.v7.widget.DefaultItemAnimator
5 | import android.support.v7.widget.LinearLayoutManager
6 | import android.view.LayoutInflater
7 | import android.view.View
8 | import android.view.ViewGroup
9 | import com.mindorks.framework.mvp.R
10 | import com.mindorks.framework.mvp.data.network.OpenSource
11 | import com.mindorks.framework.mvp.ui.base.view.BaseFragment
12 | import com.mindorks.framework.mvp.ui.feed.opensource.interactor.OpenSourceMVPInteractor
13 | import com.mindorks.framework.mvp.ui.feed.opensource.presenter.OpenSourceMVPPresenter
14 | import kotlinx.android.synthetic.main.fragment_open_source.*
15 | import javax.inject.Inject
16 |
17 | /**
18 | * Created by jyotidubey on 13/01/18.
19 | */
20 | class OpenSourceFragment : BaseFragment(), OpenSourceMVPView {
21 |
22 | companion object {
23 |
24 | fun newInstance(): OpenSourceFragment {
25 | return OpenSourceFragment()
26 | }
27 |
28 | }
29 |
30 | @Inject
31 | internal lateinit var openSourceAdapter: OpenSourceAdapter
32 | @Inject
33 | internal lateinit var layoutManager: LinearLayoutManager
34 | @Inject
35 | internal lateinit var presenter: OpenSourceMVPPresenter
36 |
37 |
38 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
39 | return inflater.inflate(R.layout.fragment_open_source, container, false)
40 | }
41 |
42 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
43 | presenter.onAttach(this)
44 | super.onViewCreated(view, savedInstanceState)
45 | }
46 |
47 | override fun setUp() {
48 | layoutManager.orientation = LinearLayoutManager.VERTICAL
49 | repo_recycler_view.layoutManager = layoutManager
50 | repo_recycler_view.itemAnimator = DefaultItemAnimator()
51 | repo_recycler_view.adapter = openSourceAdapter
52 | presenter.onViewPrepared()
53 | }
54 |
55 | override fun displayOpenSourceList(OpenSources: List?) {
56 | OpenSources?.let {
57 | openSourceAdapter.addOpenSourcesToList(it)
58 | }
59 | }
60 |
61 | override fun onDestroyView() {
62 | presenter.onDetach()
63 | super.onDestroyView()
64 | }
65 |
66 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/feed/opensource/view/OpenSourceMVPView.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.feed.opensource.view
2 |
3 | import com.mindorks.framework.mvp.data.network.OpenSource
4 | import com.mindorks.framework.mvp.ui.base.view.MVPView
5 |
6 | /**
7 | * Created by jyotidubey on 14/01/18.
8 | */
9 | interface OpenSourceMVPView : MVPView {
10 | fun displayOpenSourceList(blogs: List?)
11 |
12 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/feed/view/FeedActivity.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.feed.view
2 |
3 | import android.os.Bundle
4 | import android.support.design.widget.TabLayout
5 | import android.support.v4.app.Fragment
6 | import com.mindorks.framework.mvp.R
7 | import com.mindorks.framework.mvp.ui.base.view.BaseActivity
8 | import com.mindorks.framework.mvp.ui.feed.FeedPagerAdapter
9 | import dagger.android.AndroidInjector
10 | import dagger.android.DispatchingAndroidInjector
11 | import dagger.android.support.HasSupportFragmentInjector
12 | import kotlinx.android.synthetic.main.activity_feed.*
13 | import javax.inject.Inject
14 |
15 | /**
16 | * Created by jyotidubey on 13/01/18.
17 | */
18 | class FeedActivity : BaseActivity(), HasSupportFragmentInjector {
19 |
20 | @Inject
21 | internal lateinit var fragmentDispatchingAndroidInjector: DispatchingAndroidInjector
22 | internal lateinit var feedPagerAdapter: FeedPagerAdapter
23 |
24 |
25 | override fun onCreate(savedInstanceState: Bundle?) {
26 | super.onCreate(savedInstanceState)
27 | setContentView(R.layout.activity_feed)
28 | feedPagerAdapter = FeedPagerAdapter(supportFragmentManager)
29 | setUpFeedPagerAdapter()
30 | }
31 |
32 | override fun onFragmentAttached() {
33 | }
34 |
35 | override fun onFragmentDetached(tag: String) {
36 | }
37 |
38 | override fun supportFragmentInjector(): AndroidInjector? {
39 | return fragmentDispatchingAndroidInjector
40 | }
41 |
42 | private fun setUpFeedPagerAdapter() {
43 | feedPagerAdapter.count = 2
44 | feedViewPager.adapter = feedPagerAdapter
45 | tabLayout.addTab(tabLayout.newTab().setText(R.string.blogs))
46 | tabLayout.addTab(tabLayout.newTab().setText(R.string.open_source))
47 | feedViewPager.offscreenPageLimit = tabLayout.tabCount;
48 | feedViewPager.addOnPageChangeListener(TabLayout.TabLayoutOnPageChangeListener(tabLayout));
49 | tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
50 | override fun onTabSelected(tab: TabLayout.Tab) {
51 | feedViewPager.currentItem = tab.position
52 | }
53 | override fun onTabUnselected(tab: TabLayout.Tab) {}
54 | override fun onTabReselected(tab: TabLayout.Tab) {}
55 | })
56 |
57 |
58 | }
59 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/login/LoginActivityModule.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.login
2 |
3 | import com.mindorks.framework.mvp.ui.login.interactor.LoginInteractor
4 | import com.mindorks.framework.mvp.ui.login.interactor.LoginMVPInteractor
5 | import com.mindorks.framework.mvp.ui.login.presenter.LoginMVPPresenter
6 | import com.mindorks.framework.mvp.ui.login.presenter.LoginPresenter
7 | import com.mindorks.framework.mvp.ui.login.view.LoginMVPView
8 | import dagger.Module
9 | import dagger.Provides
10 |
11 | /**
12 | * Created by jyotidubey on 10/01/18.
13 | */
14 | @Module
15 | class LoginActivityModule {
16 |
17 | @Provides
18 | internal fun provideLoginInteractor(interactor: LoginInteractor): LoginMVPInteractor = interactor
19 |
20 | @Provides
21 | internal fun provideLoginPresenter(presenter: LoginPresenter)
22 | : LoginMVPPresenter = presenter
23 |
24 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/login/interactor/LoginInteractor.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.login.interactor
2 |
3 | import com.mindorks.framework.mvp.data.network.ApiHelper
4 | import com.mindorks.framework.mvp.data.network.LoginRequest
5 | import com.mindorks.framework.mvp.data.network.LoginResponse
6 | import com.mindorks.framework.mvp.data.preferences.PreferenceHelper
7 | import com.mindorks.framework.mvp.ui.base.interactor.BaseInteractor
8 | import com.mindorks.framework.mvp.util.AppConstants
9 | import javax.inject.Inject
10 |
11 | /**
12 | * Created by jyotidubey on 10/01/18.
13 | */
14 | class LoginInteractor @Inject internal constructor(preferenceHelper: PreferenceHelper, apiHelper: ApiHelper) : BaseInteractor(preferenceHelper, apiHelper), LoginMVPInteractor {
15 |
16 | override fun doGoogleLoginApiCall() =
17 | apiHelper.performGoogleLogin(LoginRequest.GoogleLoginRequest("test1", "test1"))
18 |
19 | override fun doFBLoginApiCall() =
20 | apiHelper.performFBLogin(LoginRequest.FacebookLoginRequest("test3", "test4"))
21 |
22 |
23 | override fun doServerLoginApiCall(email: String, password: String) =
24 | apiHelper.performServerLogin(LoginRequest.ServerLoginRequest(email = email, password = password))
25 |
26 |
27 | override fun updateUserInSharedPref(loginResponse: LoginResponse, loggedInMode: AppConstants.LoggedInMode) =
28 | preferenceHelper.let {
29 | it.setCurrentUserId(loginResponse.userId)
30 | it.setAccessToken(loginResponse.accessToken)
31 | it.setCurrentUserLoggedInMode(loggedInMode)
32 | }
33 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/login/interactor/LoginMVPInteractor.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.login.interactor
2 |
3 | import com.mindorks.framework.mvp.data.network.LoginResponse
4 | import com.mindorks.framework.mvp.ui.base.interactor.MVPInteractor
5 | import com.mindorks.framework.mvp.util.AppConstants
6 | import io.reactivex.Observable
7 |
8 | /**
9 | * Created by jyotidubey on 10/01/18.
10 | */
11 | interface LoginMVPInteractor : MVPInteractor {
12 |
13 | fun doServerLoginApiCall(email: String, password: String): Observable
14 |
15 | fun doFBLoginApiCall(): Observable
16 |
17 | fun doGoogleLoginApiCall(): Observable
18 |
19 | fun updateUserInSharedPref(loginResponse: LoginResponse, loggedInMode: AppConstants.LoggedInMode)
20 |
21 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/login/presenter/LoginMVPPresenter.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.login.presenter
2 |
3 | import com.mindorks.framework.mvp.ui.base.presenter.MVPPresenter
4 | import com.mindorks.framework.mvp.ui.login.interactor.LoginMVPInteractor
5 | import com.mindorks.framework.mvp.ui.login.view.LoginMVPView
6 |
7 | /**
8 | * Created by jyotidubey on 10/01/18.
9 | */
10 | interface LoginMVPPresenter : MVPPresenter {
11 |
12 | fun onServerLoginClicked(email: String, password: String)
13 | fun onFBLoginClicked()
14 | fun onGoogleLoginClicked()
15 |
16 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/login/presenter/LoginPresenter.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.login.presenter
2 |
3 | import com.mindorks.framework.mvp.data.network.LoginResponse
4 | import com.mindorks.framework.mvp.ui.base.presenter.BasePresenter
5 | import com.mindorks.framework.mvp.ui.login.interactor.LoginMVPInteractor
6 | import com.mindorks.framework.mvp.ui.login.view.LoginMVPView
7 | import com.mindorks.framework.mvp.util.AppConstants
8 | import com.mindorks.framework.mvp.util.SchedulerProvider
9 | import io.reactivex.disposables.CompositeDisposable
10 | import io.reactivex.functions.Consumer
11 | import javax.inject.Inject
12 |
13 | /**
14 | * Created by jyotidubey on 10/01/18.
15 | */
16 | class LoginPresenter @Inject internal constructor(interactor: I, schedulerProvider: SchedulerProvider, disposable: CompositeDisposable) : BasePresenter(interactor = interactor, schedulerProvider = schedulerProvider, compositeDisposable = disposable), LoginMVPPresenter {
17 |
18 | override fun onServerLoginClicked(email: String, password: String) {
19 | when {
20 | email.isEmpty() -> getView()?.showValidationMessage(AppConstants.EMPTY_EMAIL_ERROR)
21 | password.isEmpty() -> getView()?.showValidationMessage(AppConstants.EMPTY_PASSWORD_ERROR)
22 | else -> {
23 | getView()?.showProgress()
24 | interactor?.let {
25 | compositeDisposable.add(it.doServerLoginApiCall(email, password)
26 | .compose(schedulerProvider.ioToMainObservableScheduler())
27 | .subscribe({ loginResponse ->
28 | updateUserInSharedPref(loginResponse = loginResponse,
29 | loggedInMode = AppConstants.LoggedInMode.LOGGED_IN_MODE_SERVER)
30 | getView()?.openMainActivity()
31 | }, { err -> println(err) }))
32 | }
33 |
34 | }
35 | }
36 | }
37 |
38 | override fun onFBLoginClicked() {
39 | getView()?.showProgress()
40 | interactor?.let {
41 | compositeDisposable.add(it.doFBLoginApiCall()
42 | .compose(schedulerProvider.ioToMainObservableScheduler())
43 | .subscribe({ loginResponse ->
44 | updateUserInSharedPref(loginResponse = loginResponse,
45 | loggedInMode = AppConstants.LoggedInMode.LOGGED_IN_MODE_FB)
46 | getView()?.let {
47 | it.hideProgress()
48 | it.openMainActivity()
49 | }
50 | }, { err -> println(err) }))
51 | }
52 |
53 |
54 | }
55 |
56 | override fun onGoogleLoginClicked() {
57 | getView()?.showProgress()
58 | interactor?.let {
59 | compositeDisposable.add(it.doGoogleLoginApiCall()
60 | .compose(schedulerProvider.ioToMainObservableScheduler())
61 | .subscribe({ loginResponse ->
62 | updateUserInSharedPref(loginResponse = loginResponse,
63 | loggedInMode = AppConstants.LoggedInMode.LOGGED_IN_MODE_GOOGLE)
64 | getView()?.let {
65 | it.hideProgress()
66 | it.openMainActivity()
67 | }
68 | }, { err -> println(err) }))
69 | }
70 |
71 | }
72 |
73 | private fun updateUserInSharedPref(loginResponse: LoginResponse,
74 | loggedInMode: AppConstants.LoggedInMode) =
75 | interactor?.updateUserInSharedPref(loginResponse, loggedInMode)
76 |
77 |
78 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/login/view/LoginActivity.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.login.view
2 |
3 | import android.content.Intent
4 | import android.os.Bundle
5 | import android.widget.Toast
6 | import com.mindorks.framework.mvp.R
7 | import com.mindorks.framework.mvp.ui.base.view.BaseActivity
8 | import com.mindorks.framework.mvp.ui.login.interactor.LoginMVPInteractor
9 | import com.mindorks.framework.mvp.ui.login.presenter.LoginMVPPresenter
10 | import com.mindorks.framework.mvp.ui.main.view.MainActivity
11 | import com.mindorks.framework.mvp.util.AppConstants
12 | import kotlinx.android.synthetic.main.activity_login.*
13 | import javax.inject.Inject
14 |
15 | /**
16 | * Created by jyotidubey on 10/01/18.
17 | */
18 | class LoginActivity : BaseActivity(), LoginMVPView {
19 |
20 | @Inject
21 | internal lateinit var presenter: LoginMVPPresenter
22 |
23 | override fun onCreate(savedInstanceState: Bundle?) {
24 | super.onCreate(savedInstanceState)
25 | setContentView(R.layout.activity_login)
26 | presenter.onAttach(this)
27 | setOnClickListeners()
28 | }
29 |
30 | override fun onDestroy() {
31 | presenter.onDetach()
32 | super.onDestroy()
33 | }
34 |
35 | override fun onFragmentDetached(tag: String) {
36 | }
37 |
38 | override fun onFragmentAttached() {
39 | }
40 |
41 | override fun showValidationMessage(errorCode: Int) {
42 | when (errorCode) {
43 | AppConstants.EMPTY_EMAIL_ERROR -> Toast.makeText(this, getString(R.string.empty_email_error_message), Toast.LENGTH_LONG).show()
44 | AppConstants.INVALID_EMAIL_ERROR -> Toast.makeText(this, getString(R.string.invalid_email_error_message), Toast.LENGTH_LONG).show()
45 | AppConstants.EMPTY_PASSWORD_ERROR -> Toast.makeText(this, getString(R.string.empty_password_error_message), Toast.LENGTH_LONG).show()
46 | AppConstants.LOGIN_FAILURE -> Toast.makeText(this, getString(R.string.login_failure), Toast.LENGTH_LONG).show()
47 | }
48 | }
49 |
50 | override fun openMainActivity() {
51 | val intent = Intent(this, MainActivity::class.java)
52 | startActivity(intent)
53 | finish()
54 | }
55 |
56 | private fun setOnClickListeners() {
57 | btnServerLogin.setOnClickListener { presenter.onServerLoginClicked(et_email.text.toString(), et_password.text.toString()) }
58 | ibGoogleLogin.setOnClickListener { presenter.onGoogleLoginClicked() }
59 | ibFbLogin.setOnClickListener { presenter.onFBLoginClicked() }
60 | }
61 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/login/view/LoginMVPView.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.login.view
2 |
3 | import com.mindorks.framework.mvp.ui.base.view.MVPView
4 |
5 | /**
6 | * Created by jyotidubey on 10/01/18.
7 | */
8 | interface LoginMVPView : MVPView {
9 |
10 | fun showValidationMessage(errorCode: Int)
11 | fun openMainActivity()
12 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/main/MainActivityModule.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.main
2 |
3 | import com.mindorks.framework.mvp.ui.main.interactor.MainInteractor
4 | import com.mindorks.framework.mvp.ui.main.interactor.MainMVPInteractor
5 | import com.mindorks.framework.mvp.ui.main.presenter.MainMVPPresenter
6 | import com.mindorks.framework.mvp.ui.main.presenter.MainPresenter
7 | import com.mindorks.framework.mvp.ui.main.view.MainMVPView
8 | import dagger.Module
9 | import dagger.Provides
10 |
11 | /**
12 | * Created by jyotidubey on 09/01/18.
13 | */
14 | @Module
15 | class MainActivityModule {
16 |
17 | @Provides
18 | internal fun provideMainInteractor(mainInteractor: MainInteractor): MainMVPInteractor = mainInteractor
19 |
20 | @Provides
21 | internal fun provideMainPresenter(mainPresenter: MainPresenter)
22 | : MainMVPPresenter = mainPresenter
23 |
24 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/main/interactor/MainInteractor.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.main.interactor
2 |
3 | import com.mindorks.framework.mvp.data.database.repository.options.Options
4 | import com.mindorks.framework.mvp.data.database.repository.options.OptionsRepo
5 | import com.mindorks.framework.mvp.data.database.repository.questions.Question
6 | import com.mindorks.framework.mvp.data.database.repository.questions.QuestionRepo
7 | import com.mindorks.framework.mvp.data.network.ApiHelper
8 | import com.mindorks.framework.mvp.data.preferences.PreferenceHelper
9 | import com.mindorks.framework.mvp.ui.base.interactor.BaseInteractor
10 | import javax.inject.Inject
11 |
12 | /**
13 | * Created by jyotidubey on 08/01/18.
14 | */
15 | class MainInteractor @Inject internal constructor(private val questionRepoHelper: QuestionRepo, private val optionsRepoHelper: OptionsRepo, preferenceHelper: PreferenceHelper, apiHelper: ApiHelper) : BaseInteractor(preferenceHelper = preferenceHelper, apiHelper = apiHelper), MainMVPInteractor {
16 |
17 | override fun getQuestionCardData() = questionRepoHelper.loadQuestions()
18 | .flatMapIterable { question -> question }
19 | .flatMapSingle { question -> getQuestionCards(question) }
20 | .toList()
21 |
22 | override fun getUserDetails() = Pair(preferenceHelper.getCurrentUserName(),
23 | preferenceHelper.getCurrentUserEmail())
24 |
25 | override fun makeLogoutApiCall() = apiHelper.performLogoutApiCall()
26 |
27 | private fun getQuestionCards(question: Question) = optionsRepoHelper.loadOptions(question.id)
28 | .map { options -> createQuestionCard(options, question) }
29 |
30 | private fun createQuestionCard(options: List, question: Question) = QuestionCardData(options, question)
31 |
32 | }
33 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/main/interactor/MainMVPInteractor.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.main.interactor
2 |
3 | import com.mindorks.framework.mvp.data.network.LogoutResponse
4 | import com.mindorks.framework.mvp.ui.base.interactor.MVPInteractor
5 | import io.reactivex.Observable
6 | import io.reactivex.Single
7 |
8 | /**
9 | * Created by jyotidubey on 08/01/18.
10 | */
11 | interface MainMVPInteractor : MVPInteractor {
12 |
13 | fun getQuestionCardData(): Single>
14 | fun getUserDetails() : Pair
15 | fun makeLogoutApiCall() : Observable
16 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/main/interactor/QuestionCardData.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.main.interactor
2 |
3 | import com.mindorks.framework.mvp.data.database.repository.options.Options
4 | import com.mindorks.framework.mvp.data.database.repository.questions.Question
5 |
6 | /**
7 | * Created by jyotidubey on 08/01/18.
8 | */
9 | data class QuestionCardData(val option: List, val question: Question)
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/main/presenter/MainMVPPresenter.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.main.presenter
2 |
3 | import com.mindorks.framework.mvp.ui.base.presenter.MVPPresenter
4 | import com.mindorks.framework.mvp.ui.main.interactor.MainMVPInteractor
5 | import com.mindorks.framework.mvp.ui.main.view.MainMVPView
6 |
7 | /**
8 | * Created by jyotidubey on 08/01/18.
9 | */
10 | interface MainMVPPresenter : MVPPresenter {
11 |
12 | fun refreshQuestionCards(): Boolean?
13 | fun onDrawerOptionAboutClick() : Unit?
14 | fun onDrawerOptionRateUsClick(): Unit?
15 | fun onDrawerOptionFeedClick(): Unit?
16 | fun onDrawerOptionLogoutClick()
17 |
18 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/main/presenter/MainPresenter.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.main.presenter
2 |
3 | import com.mindorks.framework.mvp.ui.base.presenter.BasePresenter
4 | import com.mindorks.framework.mvp.ui.main.interactor.MainMVPInteractor
5 | import com.mindorks.framework.mvp.ui.main.view.MainMVPView
6 | import com.mindorks.framework.mvp.util.SchedulerProvider
7 | import io.reactivex.disposables.CompositeDisposable
8 | import javax.inject.Inject
9 |
10 | /**
11 | * Created by jyotidubey on 08/01/18.
12 | */
13 | class MainPresenter @Inject internal constructor(interactor: I, schedulerProvider: SchedulerProvider, disposable: CompositeDisposable) : BasePresenter(interactor = interactor, schedulerProvider = schedulerProvider, compositeDisposable = disposable), MainMVPPresenter {
14 |
15 | override fun onAttach(view: V?) {
16 | super.onAttach(view)
17 | getUserData()
18 | getQuestionCards()
19 | }
20 |
21 | override fun refreshQuestionCards() = getQuestionCards()
22 |
23 | override fun onDrawerOptionRateUsClick() = getView()?.openRateUsDialog()
24 |
25 | override fun onDrawerOptionFeedClick() = getView()?.openFeedActivity()
26 |
27 | override fun onDrawerOptionAboutClick() = getView()?.openAboutFragment()
28 |
29 | override fun onDrawerOptionLogoutClick() {
30 | getView()?.showProgress()
31 | interactor?.let {
32 | compositeDisposable.add(
33 | it.makeLogoutApiCall()
34 | .compose(schedulerProvider.ioToMainObservableScheduler())
35 | .subscribe({
36 | interactor?.performUserLogout()
37 | getView()?.let {
38 | it.hideProgress()
39 | it.openLoginActivity()
40 | }
41 | }, { err -> println(err) }))
42 | }
43 |
44 | }
45 |
46 | private fun getQuestionCards() = interactor?.let {
47 | compositeDisposable.add(it.getQuestionCardData()
48 | .compose(schedulerProvider.ioToMainSingleScheduler())
49 | .subscribe({ questionCard ->
50 | getView()?.let {
51 | if (questionCard.isEmpty()) return@subscribe
52 | else it.displayQuestionCard(questionCard)
53 | }
54 | }, { err -> println(err) }))
55 | }
56 |
57 |
58 | private fun getUserData() = interactor?.let {
59 | val userData = it.getUserDetails()
60 | getView()?.inflateUserDetails(userData)
61 | }
62 |
63 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/main/view/MainMVPView.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.main.view
2 |
3 | import com.mindorks.framework.mvp.ui.base.view.MVPView
4 | import com.mindorks.framework.mvp.ui.main.interactor.QuestionCardData
5 |
6 | /**
7 | * Created by jyotidubey on 08/01/18.
8 | */
9 | interface MainMVPView : MVPView {
10 |
11 | fun inflateUserDetails(userDetails: Pair)
12 | fun displayQuestionCard(questionCard: List)
13 | fun openLoginActivity()
14 | fun openFeedActivity()
15 | fun openAboutFragment()
16 | fun openRateUsDialog(): Unit?
17 | fun lockDrawer(): Unit?
18 | fun unlockDrawer(): Unit?
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/main/view/QuestionCardView.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.main.view
2 |
3 | import android.graphics.Color
4 | import android.widget.Button
5 | import android.widget.TextView
6 | import com.androidnetworking.widget.ANImageView
7 | import com.mindorks.framework.mvp.R
8 | import com.mindorks.framework.mvp.ui.main.interactor.QuestionCardData
9 | import com.mindorks.placeholderview.annotations.*
10 |
11 | /**
12 | * Created by jyotidubey on 09/01/18.
13 | */
14 | @NonReusable
15 | @Layout(R.layout.card_layout)
16 | class QuestionCard(private val mQuestion: QuestionCardData) {
17 |
18 | @View(R.id.tv_question_txt)
19 | private lateinit var mQuestionTextView: TextView
20 |
21 | @View(R.id.btn_option_1)
22 | private lateinit var mOption1Button: Button
23 |
24 | @View(R.id.btn_option_2)
25 | private lateinit var mOption2Button: Button
26 |
27 | @View(R.id.btn_option_3)
28 | private lateinit var mOption3Button: Button
29 |
30 | @View(R.id.iv_pic)
31 | private lateinit var mPicImageView: ANImageView
32 |
33 | @Click(R.id.btn_option_1)
34 | internal fun onOption1Click() {
35 | showCorrectOptions()
36 | }
37 |
38 | @Click(R.id.btn_option_2)
39 | internal fun onOption2Click() {
40 | showCorrectOptions()
41 | }
42 |
43 | @Click(R.id.btn_option_3)
44 | internal fun onOption3Click() {
45 | showCorrectOptions()
46 | }
47 |
48 | @Resolve
49 | private fun onResolved() {
50 | mQuestionTextView.text = mQuestion.question.questionText
51 | for (i in 0..2) {
52 | var button: Button? = null
53 | when (i) {
54 | 0 -> button = mOption1Button
55 | 1 -> button = mOption2Button
56 | 2 -> button = mOption3Button
57 | }
58 | button?.text = mQuestion.option[i].optionText
59 | mQuestion.question.imgUrl?.let { mPicImageView.setImageUrl(it) }
60 |
61 | }
62 | }
63 |
64 | private fun showCorrectOptions() {
65 | for (i in 0..2) {
66 | val option = mQuestion.option[i]
67 | var button: Button? = null
68 | when (i) {
69 | 0 -> button = mOption1Button
70 | 1 -> button = mOption2Button
71 | 2 -> button = mOption3Button
72 | }
73 | button?.let{
74 | if(option.isCorrect) it.setBackgroundColor(Color.GREEN) else it.setBackgroundColor(Color.RED)
75 | }
76 |
77 | }
78 | }
79 |
80 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/rate/RateUsDialogFragmentProvider.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.rate
2 |
3 | import com.mindorks.framework.mvp.ui.rate.view.RateUsDialog
4 | import dagger.Module
5 | import dagger.android.ContributesAndroidInjector
6 |
7 | /**
8 | * Created by jyotidubey on 15/01/18.
9 | */
10 | @Module
11 | abstract class RateUsDialogFragmentProvider{
12 |
13 | @ContributesAndroidInjector(modules = [RateUsFragmentModule::class])
14 | internal abstract fun provideRateUsFragment() : RateUsDialog
15 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/rate/RateUsFragmentModule.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.rate
2 |
3 | import com.mindorks.framework.mvp.ui.rate.interactor.RateUsInteractor
4 | import com.mindorks.framework.mvp.ui.rate.interactor.RateUsMVPInterator
5 | import com.mindorks.framework.mvp.ui.rate.presenter.RateUsMVPPresenter
6 | import com.mindorks.framework.mvp.ui.rate.presenter.RateUsPresenter
7 | import com.mindorks.framework.mvp.ui.rate.view.RateUsDialogMVPView
8 | import dagger.Module
9 | import dagger.Provides
10 |
11 | /**
12 | * Created by jyotidubey on 15/01/18.
13 | */
14 | @Module
15 | class RateUsFragmentModule {
16 |
17 | @Provides
18 | internal fun provideRateUsInteractor(interactor: RateUsInteractor): RateUsMVPInterator = interactor
19 |
20 | @Provides
21 | internal fun provideRateUsPresenter(presenter: RateUsPresenter)
22 | : RateUsMVPPresenter = presenter
23 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/rate/interactor/RateUsInteractor.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.rate.interactor
2 |
3 | import com.mindorks.framework.mvp.data.network.ApiHelper
4 | import com.mindorks.framework.mvp.data.preferences.PreferenceHelper
5 | import com.mindorks.framework.mvp.ui.base.interactor.BaseInteractor
6 | import javax.inject.Inject
7 |
8 | /**
9 | * Created by jyotidubey on 15/01/18.
10 | */
11 | class RateUsInteractor @Inject internal constructor(apiHelper: ApiHelper, preferenceHelper: PreferenceHelper) : BaseInteractor(apiHelper = apiHelper, preferenceHelper = preferenceHelper), RateUsMVPInterator {
12 |
13 | override fun submitRating() {}
14 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/rate/interactor/RateUsMVPInterator.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.rate.interactor
2 |
3 | import com.mindorks.framework.mvp.ui.base.interactor.MVPInteractor
4 |
5 | /**
6 | * Created by jyotidubey on 15/01/18.
7 | */
8 | interface RateUsMVPInterator : MVPInteractor{
9 |
10 | fun submitRating()
11 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/rate/presenter/RateUsMVPPresenter.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.rate.presenter
2 |
3 | import com.mindorks.framework.mvp.ui.base.presenter.MVPPresenter
4 | import com.mindorks.framework.mvp.ui.rate.interactor.RateUsMVPInterator
5 | import com.mindorks.framework.mvp.ui.rate.view.RateUsDialogMVPView
6 |
7 | /**
8 | * Created by jyotidubey on 15/01/18.
9 | */
10 | interface RateUsMVPPresenter : MVPPresenter {
11 |
12 | fun onLaterOptionClicked() : Unit?
13 | fun onSubmitOptionClicked() : Unit?
14 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/rate/presenter/RateUsPresenter.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.rate.presenter
2 |
3 | import com.mindorks.framework.mvp.ui.base.presenter.BasePresenter
4 | import com.mindorks.framework.mvp.ui.rate.interactor.RateUsMVPInterator
5 | import com.mindorks.framework.mvp.ui.rate.view.RateUsDialogMVPView
6 | import com.mindorks.framework.mvp.util.SchedulerProvider
7 | import io.reactivex.disposables.CompositeDisposable
8 | import javax.inject.Inject
9 |
10 | /**
11 | * Created by jyotidubey on 15/01/18.
12 | */
13 | class RateUsPresenter @Inject internal constructor(interator: I, schedulerProvider: SchedulerProvider, compositeDisposable: CompositeDisposable) : BasePresenter(interactor = interator, schedulerProvider = schedulerProvider, compositeDisposable = compositeDisposable), RateUsMVPPresenter {
14 |
15 | override fun onLaterOptionClicked() = getView()?.let { it.dismissDialog() }
16 |
17 | override fun onSubmitOptionClicked() = interactor?.let {
18 | it.submitRating()
19 | getView()?.let {
20 | it.showRatingSubmissionSuccessMessage()
21 | it.dismissDialog()
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/rate/view/RateUsDialog.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.rate.view
2 |
3 | import android.os.Bundle
4 | import android.support.v4.app.FragmentManager
5 | import android.view.LayoutInflater
6 | import android.view.View
7 | import android.view.ViewGroup
8 | import android.widget.Toast
9 | import com.mindorks.framework.mvp.R
10 | import com.mindorks.framework.mvp.ui.base.view.BaseDialogView
11 | import com.mindorks.framework.mvp.ui.rate.interactor.RateUsMVPInterator
12 | import com.mindorks.framework.mvp.ui.rate.presenter.RateUsMVPPresenter
13 | import kotlinx.android.synthetic.main.dialog_rate_us.*
14 | import javax.inject.Inject
15 |
16 | /**
17 | * Created by jyotidubey on 14/01/18.
18 | */
19 | class RateUsDialog : BaseDialogView(), RateUsDialogMVPView {
20 |
21 | companion object {
22 | fun newInstance(): RateUsDialog? {
23 | return RateUsDialog()
24 | }
25 |
26 | }
27 |
28 | @Inject
29 | internal lateinit var presenter: RateUsMVPPresenter
30 |
31 | private val TAG = "RateUsDialog"
32 |
33 |
34 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? =
35 | inflater.inflate(R.layout.dialog_rate_us, container, false)
36 |
37 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
38 | super.onViewCreated(view, savedInstanceState)
39 | presenter.onAttach(this)
40 | btnLater.setOnClickListener { presenter.onLaterOptionClicked() }
41 | btnSubmit.setOnClickListener { presenter.onSubmitOptionClicked() }
42 | }
43 |
44 | override fun onDestroyView() {
45 | presenter.onDetach()
46 | super.onDestroyView()
47 | }
48 |
49 | override fun dismissDialog() = super.dismissDialog(TAG)
50 |
51 | override fun showRatingSubmissionSuccessMessage() = Toast.makeText(context, getString(R.string.rating_submitted_successfully), Toast.LENGTH_LONG).show()
52 |
53 | internal fun show(fragmentManager: FragmentManager) = super.show(fragmentManager, TAG)
54 |
55 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/rate/view/RateUsDialogMVPView.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.rate.view
2 |
3 | import com.mindorks.framework.mvp.ui.base.view.MVPView
4 |
5 | /**
6 | * Created by jyotidubey on 14/01/18.
7 | */
8 | interface RateUsDialogMVPView : MVPView{
9 |
10 | fun dismissDialog()
11 | fun showRatingSubmissionSuccessMessage()
12 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/splash/SplashActivityModule.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.splash
2 |
3 | import com.mindorks.framework.mvp.ui.splash.interactor.SplashInteractor
4 | import com.mindorks.framework.mvp.ui.splash.interactor.SplashMVPInteractor
5 | import com.mindorks.framework.mvp.ui.splash.presenter.SplashMVPPresenter
6 | import com.mindorks.framework.mvp.ui.splash.presenter.SplashPresenter
7 | import com.mindorks.framework.mvp.ui.splash.view.SplashMVPView
8 | import dagger.Module
9 | import dagger.Provides
10 |
11 | /**
12 | * Created by jyotidubey on 06/01/18.
13 | */
14 | @Module
15 | class SplashActivityModule {
16 |
17 | @Provides
18 | internal fun provideSplashInteractor(splashInteractor: SplashInteractor): SplashMVPInteractor = splashInteractor
19 |
20 | @Provides
21 | internal fun provideSplashPresenter(splashPresenter: SplashPresenter)
22 | : SplashMVPPresenter = splashPresenter
23 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/splash/interactor/SplashInteractor.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.splash.interactor
2 |
3 | import android.content.Context
4 | import com.google.gson.GsonBuilder
5 | import com.google.gson.internal.`$Gson$Types`
6 | import com.mindorks.framework.mvp.data.database.repository.options.Options
7 | import com.mindorks.framework.mvp.data.database.repository.options.OptionsRepo
8 | import com.mindorks.framework.mvp.data.database.repository.questions.Question
9 | import com.mindorks.framework.mvp.data.database.repository.questions.QuestionRepo
10 | import com.mindorks.framework.mvp.data.network.ApiHelper
11 | import com.mindorks.framework.mvp.data.preferences.PreferenceHelper
12 | import com.mindorks.framework.mvp.ui.base.interactor.BaseInteractor
13 | import com.mindorks.framework.mvp.util.AppConstants
14 | import com.mindorks.framework.mvp.util.FileUtils
15 | import io.reactivex.Observable
16 | import javax.inject.Inject
17 |
18 | /**
19 | * Created by jyotidubey on 04/01/18.
20 | */
21 | class SplashInteractor @Inject constructor(private val mContext: Context, private val questionRepoHelper: QuestionRepo, private val optionsRepoHelper: OptionsRepo, preferenceHelper: PreferenceHelper, apiHelper: ApiHelper) : BaseInteractor(preferenceHelper, apiHelper), SplashMVPInteractor {
22 |
23 | override fun getQuestion(): Observable> {
24 | return questionRepoHelper.loadQuestions()
25 | }
26 |
27 | override fun seedQuestions(): Observable {
28 | val builder = GsonBuilder().excludeFieldsWithoutExposeAnnotation()
29 | val gson = builder.create()
30 | return questionRepoHelper.isQuestionsRepoEmpty().concatMap { isEmpty ->
31 | if (isEmpty) {
32 | val type = `$Gson$Types`.newParameterizedTypeWithOwner(null, List::class.java, Question::class.java)
33 | val questionList = gson.fromJson>(
34 | FileUtils.loadJSONFromAsset(
35 | mContext,
36 | AppConstants.SEED_DATABASE_QUESTIONS),
37 | type)
38 | questionRepoHelper.insertQuestions(questionList)
39 | } else
40 | Observable.just(false)
41 | }
42 | }
43 |
44 | override fun seedOptions(): Observable {
45 | val builder = GsonBuilder().excludeFieldsWithoutExposeAnnotation()
46 | val gson = builder.create()
47 | return optionsRepoHelper.isOptionsRepoEmpty().concatMap { isEmpty ->
48 | if (isEmpty) {
49 | val type = `$Gson$Types`.newParameterizedTypeWithOwner(null, List::class.java, Options::class.java)
50 | val optionsList = gson.fromJson>(
51 | FileUtils.loadJSONFromAsset(
52 | mContext,
53 | AppConstants.SEED_DATABASE_OPTIONS),
54 | type)
55 | optionsRepoHelper.insertOptions(optionsList)
56 | } else
57 | Observable.just(false)
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/splash/interactor/SplashMVPInteractor.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.splash.interactor
2 |
3 | import com.mindorks.framework.mvp.data.database.repository.questions.Question
4 | import com.mindorks.framework.mvp.ui.base.interactor.MVPInteractor
5 | import io.reactivex.Observable
6 |
7 | /**
8 | * Created by jyotidubey on 04/01/18.
9 | */
10 | interface SplashMVPInteractor : MVPInteractor {
11 |
12 | fun seedQuestions(): Observable
13 | fun seedOptions(): Observable
14 | fun getQuestion() : Observable>
15 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/splash/presenter/SplashMVPPresenter.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.splash.presenter
2 |
3 | import com.mindorks.framework.mvp.ui.base.presenter.MVPPresenter
4 | import com.mindorks.framework.mvp.ui.splash.interactor.SplashMVPInteractor
5 | import com.mindorks.framework.mvp.ui.splash.view.SplashMVPView
6 |
7 | /**
8 | * Created by jyotidubey on 04/01/18.
9 | */
10 | interface SplashMVPPresenter : MVPPresenter
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/splash/presenter/SplashPresenter.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.splash.presenter
2 |
3 | import com.mindorks.framework.mvp.ui.base.presenter.BasePresenter
4 | import com.mindorks.framework.mvp.ui.splash.interactor.SplashMVPInteractor
5 | import com.mindorks.framework.mvp.ui.splash.view.SplashMVPView
6 | import com.mindorks.framework.mvp.util.SchedulerProvider
7 | import io.reactivex.disposables.CompositeDisposable
8 | import javax.inject.Inject
9 |
10 | /**
11 | * Created by jyotidubey on 04/01/18.
12 | */
13 | class SplashPresenter @Inject internal constructor(interactor: I, schedulerProvider: SchedulerProvider, disposable: CompositeDisposable) : BasePresenter(interactor = interactor, schedulerProvider = schedulerProvider, compositeDisposable = disposable), SplashMVPPresenter {
14 |
15 | override fun onAttach(view: V?) {
16 | super.onAttach(view)
17 | feedInDatabase()
18 | }
19 |
20 | private fun feedInDatabase() = interactor?.let {
21 | compositeDisposable.add(it.seedQuestions()
22 | .flatMap { interactor?.seedOptions() }
23 | .compose(schedulerProvider.ioToMainObservableScheduler())
24 | .subscribe({
25 | getView()?.let { decideActivityToOpen() }
26 | }))
27 | }
28 |
29 | private fun decideActivityToOpen() = getView()?.let {
30 | if (isUserLoggedIn())
31 | it.openMainActivity()
32 | else
33 | it.openLoginActivity()
34 | }
35 |
36 | private fun isUserLoggedIn(): Boolean {
37 | interactor?.let { return it.isUserLoggedIn() }
38 | return false
39 | }
40 |
41 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/splash/view/SplashMVPActivity.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.splash.view
2 |
3 | import android.content.Intent
4 | import android.os.Bundle
5 | import com.mindorks.framework.mvp.R
6 | import com.mindorks.framework.mvp.ui.base.view.BaseActivity
7 | import com.mindorks.framework.mvp.ui.login.view.LoginActivity
8 | import com.mindorks.framework.mvp.ui.main.view.MainActivity
9 | import com.mindorks.framework.mvp.ui.splash.interactor.SplashMVPInteractor
10 | import com.mindorks.framework.mvp.ui.splash.presenter.SplashMVPPresenter
11 | import javax.inject.Inject
12 |
13 | class SplashMVPActivity : BaseActivity(), SplashMVPView {
14 |
15 | @Inject
16 | lateinit var presenter: SplashMVPPresenter
17 |
18 |
19 | override fun onCreate(savedInstanceState: Bundle?) {
20 | super.onCreate(savedInstanceState)
21 | setContentView(R.layout.activity_splash)
22 | presenter.onAttach(this)
23 | }
24 |
25 | override fun onDestroy() {
26 | presenter.onDetach()
27 | super.onDestroy()
28 | }
29 |
30 | override fun onFragmentDetached(tag: String) {
31 | }
32 |
33 | override fun onFragmentAttached() {
34 | }
35 |
36 | override fun showSuccessToast() {
37 | }
38 |
39 | override fun showErrorToast() {
40 | }
41 |
42 | override fun openMainActivity() {
43 | val intent = Intent(this, MainActivity::class.java)
44 | startActivity(intent)
45 | finish()
46 | }
47 |
48 | override fun openLoginActivity() {
49 | val intent = Intent(this, LoginActivity::class.java)
50 | startActivity(intent)
51 | finish()
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/ui/splash/view/SplashMVPView.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.ui.splash.view
2 |
3 | import com.mindorks.framework.mvp.ui.base.view.MVPView
4 |
5 | /**
6 | * Created by jyotidubey on 04/01/18.
7 | */
8 | interface SplashMVPView : MVPView {
9 |
10 | fun showSuccessToast()
11 | fun showErrorToast()
12 | fun openMainActivity()
13 | fun openLoginActivity()
14 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/util/AppConstants.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.util
2 |
3 |
4 | /**
5 | * Created by jyotidubey on 05/01/18.
6 | */
7 | object AppConstants {
8 |
9 | internal val APP_DB_NAME = "mindorks_mvp.db"
10 | internal val PREF_NAME = "mindorks_pref"
11 | internal val SEED_DATABASE_QUESTIONS = "seed/questions.json"
12 | internal val SEED_DATABASE_OPTIONS = "seed/options.json"
13 | internal val EMPTY_EMAIL_ERROR = 1001
14 | internal val INVALID_EMAIL_ERROR = 1002
15 | internal val EMPTY_PASSWORD_ERROR = 1003
16 | internal val LOGIN_FAILURE = 1004
17 | internal val NULL_INDEX = -1L
18 |
19 | enum class LoggedInMode constructor(val type: Int) {
20 | LOGGED_IN_MODE_LOGGED_OUT(0),
21 | LOGGED_IN_MODE_GOOGLE(1),
22 | LOGGED_IN_MODE_FB(2),
23 | LOGGED_IN_MODE_SERVER(3)
24 | }
25 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/util/CommonUtil.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.util
2 |
3 | import android.app.ProgressDialog
4 | import android.content.Context
5 | import android.graphics.Color
6 | import android.graphics.drawable.ColorDrawable
7 | import androidx.graphics.drawable.toDrawable
8 | import com.mindorks.framework.mvp.R
9 |
10 | /**
11 | * Created by jyotidubey on 11/01/18.
12 | */
13 | object CommonUtil {
14 |
15 | fun showLoadingDialog(context: Context?): ProgressDialog {
16 | val progressDialog = ProgressDialog(context)
17 | progressDialog.let {
18 | it.show()
19 | it.window?.setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
20 | it.setContentView(R.layout.progress_dialog)
21 | it.isIndeterminate = true
22 | it.setCancelable(false)
23 | it.setCanceledOnTouchOutside(false)
24 | return it
25 | }
26 | }
27 |
28 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/util/FileUtils.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.util
2 |
3 | import android.content.Context
4 | import java.io.IOException
5 | import java.nio.charset.Charset
6 |
7 | /**
8 | * Created by jyotidubey on 07/01/18.
9 | */
10 | object FileUtils {
11 |
12 | @Throws(IOException::class)
13 | fun loadJSONFromAsset(context: Context, jsonFileName: String): String {
14 | (context.assets).open(jsonFileName).let {
15 | val buffer = ByteArray(it.available())
16 | it.read(buffer)
17 | it.close()
18 | return String(buffer, Charset.forName("UTF-8"))
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/util/SchedulerProvider.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.util
2 |
3 | import io.reactivex.*
4 | import io.reactivex.android.schedulers.AndroidSchedulers
5 | import io.reactivex.schedulers.Schedulers
6 |
7 | /**
8 | * Created by jyotidubey on 16/01/18.
9 | */
10 | class SchedulerProvider {
11 |
12 | fun ioToMainObservableScheduler(): ObservableTransformer = ObservableTransformer { upstream ->
13 | upstream.subscribeOn(getIOThreadScheduler())
14 | .observeOn(getMainThreadScheduler())
15 | }
16 |
17 | fun ioToMainSingleScheduler(): SingleTransformer = SingleTransformer { upstream ->
18 | upstream.subscribeOn(getIOThreadScheduler())
19 | .observeOn(getMainThreadScheduler())
20 | }
21 |
22 |
23 | fun ioToMainCompletableScheduler(): CompletableTransformer = CompletableTransformer { upstream ->
24 | upstream.subscribeOn(getIOThreadScheduler())
25 | .observeOn(getMainThreadScheduler())
26 | }
27 |
28 |
29 | fun ioToMainFlowableScheduler(): FlowableTransformer = FlowableTransformer { upstream ->
30 | upstream.subscribeOn(getIOThreadScheduler())
31 | .observeOn(getMainThreadScheduler())
32 | }
33 |
34 |
35 | fun ioToMainMaybeScheduler(): MaybeTransformer = MaybeTransformer { upstream ->
36 | upstream.subscribeOn(getIOThreadScheduler())
37 | .observeOn(getMainThreadScheduler())
38 | }
39 |
40 | private fun getIOThreadScheduler() = Schedulers.io()
41 |
42 | private fun getMainThreadScheduler() = AndroidSchedulers.mainThread()
43 |
44 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/util/ScreenUtils.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.util
2 |
3 | import android.content.Context
4 | import android.util.DisplayMetrics
5 | import android.view.WindowManager
6 |
7 | /**
8 | * Created by jyotidubey on 09/01/18.
9 | */
10 | object ScreenUtils {
11 |
12 | fun getScreenWidth(context: Context): Int {
13 | val windowManager = context
14 | .getSystemService(Context.WINDOW_SERVICE) as WindowManager
15 | windowManager.let {
16 | val dm = DisplayMetrics()
17 | it.defaultDisplay.getMetrics(dm)
18 | return dm.widthPixels
19 | }
20 | }
21 |
22 | fun getScreenHeight(context: Context): Int {
23 | val windowManager = context
24 | .getSystemService(Context.WINDOW_SERVICE) as WindowManager
25 | windowManager.let {
26 | val dm = DisplayMetrics()
27 | it.defaultDisplay.getMetrics(dm)
28 | return dm.heightPixels
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/util/extension/FragmentManager.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.util.extension
2 |
3 | import android.support.v4.app.Fragment
4 | import android.support.v4.app.FragmentManager
5 | import android.widget.ImageView
6 | import com.bumptech.glide.Glide
7 | import com.mindorks.framework.mvp.R
8 |
9 | /**
10 | * Created by jyotidubey on 18/01/18.
11 | */
12 | internal fun FragmentManager.removeFragment(tag: String,
13 | slideIn: Int = R.anim.slide_left,
14 | slideOut: Int = R.anim.slide_right) {
15 | this.beginTransaction()
16 | .disallowAddToBackStack()
17 | .setCustomAnimations(slideIn, slideOut)
18 | .remove(this.findFragmentByTag(tag))
19 | .commitNow()
20 | }
21 |
22 | internal fun FragmentManager.addFragment(containerViewId: Int,
23 | fragment: Fragment,
24 | tag: String,
25 | slideIn: Int = R.anim.slide_left,
26 | slideOut: Int = R.anim.slide_right) {
27 | this.beginTransaction().disallowAddToBackStack()
28 | .setCustomAnimations(slideIn, slideOut)
29 | .add(containerViewId, fragment, tag)
30 | .commit()
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mindorks/framework/mvp/util/extension/ImageView.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp.util.extension
2 |
3 | import android.widget.ImageView
4 | import com.bumptech.glide.Glide
5 |
6 | /**
7 | * Created by jyotidubey on 24/01/18.
8 | */
9 | internal fun ImageView.loadImage(url: String) {
10 | Glide.with(this.context)
11 | .load(url)
12 | .asBitmap()
13 | .centerCrop()
14 | .into(this)
15 | }
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_right.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/button_primary_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/button_secondary_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_menu_camera.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_menu_gallery.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_menu_manage.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_menu_send.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_menu_share.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_menu_slideshow.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_design.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 | -
9 |
14 |
15 |
16 |
17 |
18 |
19 | -
20 |
25 |
26 |
27 |
28 |
29 |
30 | -
31 |
36 |
37 |
38 |
39 |
40 |
41 | -
42 |
47 |
48 |
49 |
50 |
51 |
52 | -
53 |
58 |
59 |
60 |
61 |
62 |
63 | -
64 |
69 |
70 |
71 |
72 |
73 |
74 | -
75 |
80 |
81 |
82 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/border_dark_color.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 |
10 | -
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bottom_border_shadow.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 |
10 | -
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/button_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/button_negative_text_drawable.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/button_positive_text_drawable.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/button_secondary_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/corner_border_rect_gray.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_arrow_back_white_24px.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_facebook.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_google_plus.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_info_24px.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_keyboard_backspace_24px.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_power_settings_new_24px.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_rabbit.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
13 |
16 |
19 |
22 |
25 |
28 |
31 |
34 |
37 |
40 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_rss_symbol.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_star.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/input_border_bottom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/side_nav_bar.xml:
--------------------------------------------------------------------------------
1 |
3 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_feed.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
12 |
21 |
22 |
30 |
31 |
32 |
33 |
39 |
40 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_login.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
18 |
19 |
28 |
29 |
35 |
36 |
41 |
42 |
58 |
59 |
60 |
61 |
68 |
69 |
85 |
86 |
87 |
88 |
98 |
99 |
100 |
106 |
107 |
113 |
114 |
121 |
122 |
123 |
124 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
15 |
16 |
20 |
21 |
25 |
26 |
27 |
28 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_splash.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/app_bar_navigation.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/card_layout.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
17 |
28 |
29 |
38 |
39 |
45 |
46 |
51 |
52 |
58 |
59 |
64 |
65 |
72 |
73 |
84 |
85 |
92 |
93 |
94 |
95 |
96 |
97 |
105 |
106 |
114 |
115 |
123 |
124 |
125 |
126 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_navigation.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_about.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
15 |
16 |
26 |
27 |
35 |
36 |
37 |
47 |
48 |
58 |
59 |
68 |
69 |
78 |
79 |
88 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_blog.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_open_source.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_blog_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
23 |
24 |
30 |
31 |
40 |
41 |
48 |
49 |
56 |
57 |
64 |
65 |
66 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_open_source_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
23 |
24 |
30 |
31 |
40 |
41 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/nav_header_navigation.xml:
--------------------------------------------------------------------------------
1 |
2 |
15 |
16 |
22 |
23 |
30 |
31 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/progress_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/activity_navigation_drawer.xml:
--------------------------------------------------------------------------------
1 |
2 |
39 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/activity_navigation_drawer_drawer.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
11 |
15 |
19 |
23 |
24 |
25 | -
26 |
27 |
31 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/drawer_items.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
14 |
19 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/navigation.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/navigation_drawer.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/janishar/android-kotlin-mvp-architecture/e1818a526417730f567f992784748e9170d3de5b/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/janishar/android-kotlin-mvp-architecture/e1818a526417730f567f992784748e9170d3de5b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/janishar/android-kotlin-mvp-architecture/e1818a526417730f567f992784748e9170d3de5b/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/janishar/android-kotlin-mvp-architecture/e1818a526417730f567f992784748e9170d3de5b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/janishar/android-kotlin-mvp-architecture/e1818a526417730f567f992784748e9170d3de5b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/janishar/android-kotlin-mvp-architecture/e1818a526417730f567f992784748e9170d3de5b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/janishar/android-kotlin-mvp-architecture/e1818a526417730f567f992784748e9170d3de5b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/janishar/android-kotlin-mvp-architecture/e1818a526417730f567f992784748e9170d3de5b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/janishar/android-kotlin-mvp-architecture/e1818a526417730f567f992784748e9170d3de5b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/janishar/android-kotlin-mvp-architecture/e1818a526417730f567f992784748e9170d3de5b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | @color/blue_black_light
4 | @color/black
5 | #FF4081
6 | #dbdbdb
7 | #7e7e7e
8 | #979797
9 | #696969
10 | #f7f7f7
11 | #000000
12 | #ffffff
13 | #2a2a2a
14 | #d0d8dc
15 | #00000000
16 | #88ffffff
17 | #3b5998
18 | #d34836
19 |
20 |
21 | #F06423
22 | #D85A1B
23 | #c9ebee
24 | #b5e3e7
25 | #70BDC6
26 | #214258
27 | #1C3A4E
28 | #78DC96
29 | #55C8F0
30 | #13171d
31 | #516179
32 | #A5B4C8
33 | #FFA500
34 | #fff44f
35 |
36 |
37 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 | 8dp
6 | 176dp
7 | 16dp
8 | 0dp
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/drawables.xml:
--------------------------------------------------------------------------------
1 |
2 | - @android:drawable/ic_menu_camera
3 | - @android:drawable/ic_menu_gallery
4 | - @android:drawable/ic_menu_slideshow
5 | - @android:drawable/ic_menu_manage
6 | - @android:drawable/ic_menu_share
7 | - @android:drawable/ic_menu_send
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Kotlin MVP
3 | Login Dummy
4 | Email
5 | Password
6 | Login
7 | Email cannot be blank
8 | Please Enter a valid email address
9 | Password cannot be empty
10 | Login failed
11 | About
12 | Rate Us
13 | Feed
14 | Logout
15 | NavigationDrawerActivity
16 |
17 | Open navigation drawer
18 | Close navigation drawer
19 |
20 | Settings
21 | NavigationActivity
22 |
23 | This sample app implements MVP architecture using Dagger2, GreenDao, RxJava, FastAndroidNetworking and PlaceholderView
24 | 1. https://blog.mindorks.com
25 | 2. https://github.com/MindorksOpenSource/android-mvp-architecture
26 | 3. https://blog.mindorks.com
27 | 4. https://github.com/MindorksOpenSource
28 | "version"
29 | Feed
30 | Blogs
31 | Open Source
32 | Please let us know, how can we improve ourselves?
33 | Awesome! Thank you for the 5 stars
34 | Please help others, in knowing some good things about this app.
35 | Later
36 | Submit
37 | Rate us on Play Store
38 | Rating submitted successfully
39 |
40 |
--------------------------------------------------------------------------------
/app/src/test/java/com/mindorks/framework/mvp/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.mindorks.framework.mvp
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext.kotlinVersion = '1.2.10'
5 | repositories {
6 | google()
7 | jcenter()
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.0.1'
11 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
12 |
13 | // NOTE: Do not place your application dependencies here; they belong
14 | // in the individual module build.gradle files
15 | }
16 | }
17 |
18 | allprojects {
19 | repositories {
20 | google()
21 | jcenter()
22 | }
23 | }
24 |
25 | task clean(type: Delete) {
26 | delete rootProject.buildDir
27 | }
28 |
29 | // Define versions in a single place
30 | ext {
31 | // Sdk and tools
32 | minSdkVersion = 16
33 | targetSdkVersion = 26
34 | compileSdkVersion = 26
35 | buildToolsVersion = '26.0.2'
36 |
37 | // App dependencies
38 | kotlinVersion = kotlinVersion
39 | supportLibraryVersion = '26.1.0'
40 | gsonVersion = '2.8.0'
41 | calligraphyVersion = '2.2.0'
42 | glideVersion = '3.7.0'
43 | rx2FastAndroidNetworking = '1.0.1'
44 | dagger2Version = '2.11'
45 | rxjava2Version = '2.0.6'
46 | rxandroidVersion = '2.0.1'
47 | butterKnifeVersion = '8.8.1'
48 | roomDatabaseVersion = '1.0.0'
49 | placeholderviewVersion = '0.6.1'
50 | debugDBVersion = '1.0.3'
51 | timberVersion = '4.6.0'
52 |
53 | //Test dependencies
54 | junitVersion = '4.12'
55 | espressoVersion = '2.2.2'
56 | mockitoVersion = '2.7.1'
57 | androidKTXVersion = '0.1'
58 | }
59 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/janishar/android-kotlin-mvp-architecture/e1818a526417730f567f992784748e9170d3de5b/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sun Dec 24 17:23:41 IST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------