├── .gitignore
├── .idea
├── gradle.xml
├── misc.xml
├── modules.xml
└── runConfigurations.xml
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── levnovikov
│ │ └── postbus
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── levnovikov
│ │ │ └── postbus
│ │ │ ├── Application.kt
│ │ │ ├── deeplinks
│ │ │ └── DeeplinkParser.kt
│ │ │ └── root
│ │ │ ├── di
│ │ │ ├── AppComponent.kt
│ │ │ └── AppModule.java
│ │ │ └── home
│ │ │ ├── HomeActivity.kt
│ │ │ ├── HomeInteractor.kt
│ │ │ ├── HomeRouter.kt
│ │ │ ├── HomeView.kt
│ │ │ ├── allocating
│ │ │ ├── AllocatingInteractor.kt
│ │ │ ├── AllocatingNodeHolder.kt
│ │ │ ├── AllocatingRouter.kt
│ │ │ ├── AllocatingView.kt
│ │ │ └── di
│ │ │ │ ├── AllocatingComponent.kt
│ │ │ │ └── AllocatingScope.kt
│ │ │ ├── di
│ │ │ ├── HomeComponent.kt
│ │ │ ├── HomeComponentBuilder.kt
│ │ │ ├── HomeModule.kt
│ │ │ └── HomeScope.kt
│ │ │ └── prebooking
│ │ │ ├── PrebookingInteractor.kt
│ │ │ ├── PrebookingNodeHolder.kt
│ │ │ ├── PrebookingRouter.kt
│ │ │ ├── booking_extra_widget
│ │ │ ├── BookingExtraInteractor.kt
│ │ │ ├── BookingExtraNodeHolder.kt
│ │ │ ├── BookingExtraRouter.kt
│ │ │ ├── BookingExtraVM.kt
│ │ │ ├── BookingExtraView.kt
│ │ │ ├── di
│ │ │ │ ├── BookingExtraComponent.kt
│ │ │ │ └── BookingExtraScope.kt
│ │ │ ├── extra
│ │ │ │ ├── ExtraInteractor.kt
│ │ │ │ ├── ExtraNodeHolder.kt
│ │ │ │ ├── ExtraRouter.kt
│ │ │ │ ├── ExtraView.kt
│ │ │ │ └── di
│ │ │ │ │ ├── ExtraComponent.kt
│ │ │ │ │ └── ExtraScope.kt
│ │ │ └── options
│ │ │ │ ├── OptionsInteractor.kt
│ │ │ │ ├── OptionsNodeHolder.kt
│ │ │ │ ├── OptionsRouter.kt
│ │ │ │ ├── OptionsVM.kt
│ │ │ │ ├── OptionsView.kt
│ │ │ │ ├── di
│ │ │ │ └── OptionsComponent.kt
│ │ │ │ └── sub_options
│ │ │ │ ├── SubOptionsNodeHolder.kt
│ │ │ │ ├── SubOptionsRouter.kt
│ │ │ │ ├── SubOptionsView.kt
│ │ │ │ └── di
│ │ │ │ └── SubOptionsComponent.kt
│ │ │ ├── car_type_selector
│ │ │ ├── CarTypeSelectorInteractor.kt
│ │ │ ├── CarTypeSelectorNodeHolder.kt
│ │ │ ├── CarTypeSelectorRouter.kt
│ │ │ ├── CarTypeSelectorVM.kt
│ │ │ ├── car_type_list
│ │ │ │ ├── CarTypeListInteractor.kt
│ │ │ │ ├── CarTypeListNodeHolder.kt
│ │ │ │ ├── CarTypeListRouter.kt
│ │ │ │ ├── CarTypeListView.kt
│ │ │ │ └── di
│ │ │ │ │ ├── CarTypeListComponent.kt
│ │ │ │ │ └── CarTypeListScope.kt
│ │ │ ├── di
│ │ │ │ ├── CarTypeSelectorComponent.kt
│ │ │ │ └── CarTypeSelectorScope.kt
│ │ │ └── template
│ │ │ │ └── TemplateHodeHolder.kt
│ │ │ ├── di
│ │ │ ├── PrebookingComponent.kt
│ │ │ └── PrebookingScope.kt
│ │ │ ├── poi_selector
│ │ │ ├── PoiSelectorInteractor.kt
│ │ │ ├── PoiSelectorNodeHolder.kt
│ │ │ ├── PoiSelectorRouter.kt
│ │ │ ├── PoiSelectorView.kt
│ │ │ └── di
│ │ │ │ ├── PoiSelectorComponent.kt
│ │ │ │ └── PoiSelectorScope.kt
│ │ │ └── poi_widget
│ │ │ ├── PoiWidgetInteractor.kt
│ │ │ ├── PoiWidgetNodeHolder.kt
│ │ │ ├── PoiWidgetRouter.kt
│ │ │ ├── PoiWidgetVM.kt
│ │ │ ├── PoiWidgetView.kt
│ │ │ └── di
│ │ │ ├── PoiWidgetComponent.java
│ │ │ └── PoiWidgetScope.java
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ ├── ic_attach_money_black_24dp.xml
│ │ ├── ic_directions_car_black_24dp.xml
│ │ ├── ic_launcher_background.xml
│ │ ├── ic_more_horiz_black_24dp.xml
│ │ └── ic_receipt_black_24dp.xml
│ │ ├── layout
│ │ ├── activity_splash.xml
│ │ ├── alloc_view.xml
│ │ ├── booking_extra_widget.xml
│ │ ├── car_type_list_view.xml
│ │ ├── car_type_selector.xml
│ │ ├── extra_view.xml
│ │ ├── home_view.xml
│ │ ├── options_view.xml
│ │ ├── poi_selector.xml
│ │ ├── poi_selector_item.xml
│ │ ├── poi_widget.xml
│ │ ├── sub_options_view.xml
│ │ ├── template_view.xml
│ │ ├── test_layout.xml
│ │ └── wtf_view.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
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── levnovikov
│ └── postbus
│ └── ExampleUnitTest.java
├── build.gradle
├── core-auth
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ └── core_auth
│ │ │ ├── di
│ │ │ └── AuthProviderModule.java
│ │ │ └── provider
│ │ │ ├── AuthProvider.java
│ │ │ ├── FacebookAuthProvider.java
│ │ │ └── GoogleAuthProvider.java
│ └── res
│ │ └── values
│ │ └── strings.xml
│ └── test
│ └── java
│ └── com
│ └── example
│ └── core_auth
│ └── ExampleUnitTest.java
├── core-booking
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ └── core_booking
│ │ │ └── PrebookingRepo.java
│ └── res
│ │ └── values
│ │ └── strings.xml
│ └── test
│ └── java
│ └── com
│ └── example
│ └── core_booking
│ └── ExampleUnitTest.java
├── core-geo
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ └── core_geo
│ │ │ ├── Coordinates.kt
│ │ │ └── Point.kt
│ └── res
│ │ └── values
│ │ └── strings.xml
│ └── test
│ └── java
│ └── com
│ └── example
│ └── core_geo
│ └── ExampleUnitTest.java
├── core-location
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ └── core_location
│ │ │ └── PoiSuggestionProvider.java
│ └── res
│ │ └── values
│ │ └── strings.xml
│ └── test
│ └── java
│ └── com
│ └── example
│ └── core_location
│ └── ExampleUnitTest.java
├── core-profile
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── levnovikov
│ │ └── core_profile
│ │ ├── UserRepository.kt
│ │ ├── di
│ │ ├── ProfileComponent.kt
│ │ ├── ProfileModule.kt
│ │ └── stubs
│ │ │ └── UserRepoStub.kt
│ │ └── model
│ │ └── UserProfile.kt
│ └── res
│ └── values
│ └── strings.xml
├── dependency.gradle
├── feature-auth
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── levnovikov
│ │ └── feature_auth
│ │ ├── AuthInteractor.kt
│ │ ├── AuthNodeHolder.kt
│ │ ├── AuthRouter.kt
│ │ ├── AuthView.kt
│ │ ├── dependency
│ │ └── AuthDependency.kt
│ │ ├── di
│ │ ├── AuthComponent.kt
│ │ └── AuthScope.kt
│ │ └── view_model
│ │ ├── AuthActions.kt
│ │ ├── AuthViewModel.kt
│ │ └── AuthViewModelImpl.kt
│ └── res
│ ├── layout
│ └── auth_view.xml
│ └── values
│ └── strings.xml
├── feature-map
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── levnovikov
│ │ └── feature_map
│ │ ├── MapInteractor.kt
│ │ ├── MapNodeHolder.kt
│ │ ├── MapRouter.kt
│ │ ├── MapView.kt
│ │ ├── dependency
│ │ ├── MapDependency.kt
│ │ ├── MapProvider.kt
│ │ └── MapSetter.kt
│ │ ├── di
│ │ ├── MapComponent.kt
│ │ └── MapScope.java
│ │ ├── lifecycle
│ │ ├── MapLifecycleEvent.kt
│ │ └── MapLifecycleListener.kt
│ │ └── map_wrapper
│ │ ├── MapInterface.java
│ │ └── MapWrapper.kt
│ └── res
│ ├── drawable
│ └── ic_vehicle_taxi.xml
│ ├── layout
│ └── map_view.xml
│ └── values
│ └── strings.xml
├── feature-promo
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── levnovikov
│ │ └── feature_promo
│ │ ├── domain
│ │ └── Promo.kt
│ │ └── promo_list
│ │ ├── PromoListInteractor.kt
│ │ ├── PromoListNodeHolder.kt
│ │ ├── PromoListPresenter.kt
│ │ ├── PromoListRouter.kt
│ │ ├── PromoListView.kt
│ │ ├── dependency
│ │ ├── OnPromoSelectedListener.kt
│ │ └── PromoListDependency.kt
│ │ └── di
│ │ ├── PromoListComponent.kt
│ │ └── PromoListScope.kt
│ └── res
│ ├── layout
│ ├── promo_list_item.xml
│ └── promo_list_view.xml
│ └── values
│ └── strings.xml
├── feature-ride
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── levnovikov
│ │ │ └── feature_ride
│ │ │ └── ride
│ │ │ ├── BehaviorField.kt
│ │ │ ├── RidePrebookingData.kt
│ │ │ └── RidePrebookingRepo.kt
│ └── res
│ │ └── values
│ │ └── strings.xml
│ └── test
│ └── java
│ └── com
│ └── levnovikov
│ └── feature_ride
│ └── ExampleUnitTest.java
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
├── stream-state
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── levnovikov
│ │ └── stream_state
│ │ ├── AppState.kt
│ │ ├── AppStateStreamProvider.kt
│ │ └── PrebookingState.kt
│ └── res
│ └── values
│ └── strings.xml
├── system-base
├── .gitignore
├── build.gradle
├── proguard-rules.pro
├── readme-structure
│ ├── Node architecture - communiacation.png
│ ├── Node architecture - node structure.png
│ └── Node architecture overview.png
└── src
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── levnovikov
│ │ │ └── system_base
│ │ │ ├── BackStateInteractor.kt
│ │ │ ├── BindingNodeHolder.kt
│ │ │ ├── Interactor.kt
│ │ │ ├── NodeHolder.kt
│ │ │ ├── Router.kt
│ │ │ ├── StateDataProvider.kt
│ │ │ ├── StateInteractor.kt
│ │ │ ├── ViewNodeHolder.kt
│ │ │ ├── back_handling
│ │ │ └── BackHandler.kt
│ │ │ ├── base_di
│ │ │ ├── ActivityComponent.kt
│ │ │ ├── ComponentBuilder.kt
│ │ │ ├── ComponentKey.kt
│ │ │ └── SubComponentProvider.kt
│ │ │ ├── exceptions
│ │ │ ├── RouterAlreadyAttachedException.kt
│ │ │ └── ViewIsAlreadyAttachedException.kt
│ │ │ ├── lifecycle
│ │ │ ├── Lifecycle.kt
│ │ │ ├── LifecycleActivity.kt
│ │ │ └── LifecycleEvent.kt
│ │ │ └── node_state
│ │ │ ├── ActivityState.kt
│ │ │ └── NodeState.kt
│ └── res
│ │ └── values
│ │ └── strings.xml
│ └── test
│ └── java
│ └── com
│ ├── example
│ └── system_base
│ │ └── ExampleUnitTest.java
│ └── levnovikov
│ └── system_base
│ └── RouterTest.kt
└── template
├── NewNode_MVP
├── globals.xml.ftl
├── recipe.xml.ftl
├── root
│ ├── res
│ │ └── layout
│ │ │ └── fragment_blank.xml.ftl
│ └── src
│ │ └── app_package
│ │ └── NodeHolder.kt.ftl
└── template.xml
├── NewNode_MVVM
├── globals.xml.ftl
├── recipe.xml.ftl
├── root
│ ├── res
│ │ └── layout
│ │ │ └── fragment_blank.xml.ftl
│ └── src
│ │ └── app_package
│ │ └── NodeHolder.kt.ftl
└── template.xml
├── NewNode_MVVM_custom_view
├── globals.xml.ftl
├── recipe.xml.ftl
├── root
│ ├── res
│ │ └── layout
│ │ │ └── fragment_blank.xml.ftl
│ └── src
│ │ └── app_package
│ │ └── NodeHolder.kt.ftl
└── template.xml
├── README.MD
└── sync_templates.sh
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | .idea
5 | .DS_Store
6 | /build
7 | /captures
8 | .externalNativeBuild
9 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
27 |
28 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | 1.8
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PostBusApp #
2 | Transportation app architecture example
3 |
4 | ## Overview ##
5 |
6 | 
7 |
8 | ## Node structure ##
9 | 
10 |
11 | ## Communication ##
12 | 
13 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | apply plugin: 'kotlin-kapt'
5 |
6 | android androidConfiguration
7 |
8 | androidExtensions {
9 | experimental = true
10 | }
11 |
12 | android {
13 | dataBinding {
14 | enabled = true
15 | }
16 | }
17 |
18 | dependencies {
19 | implementation libs.appcompatV7
20 | implementation libs.constraintLayout
21 | implementation libs.recyclerView
22 | implementation libs.appcompatV7
23 | implementation libs.rxJava
24 | implementation libs.rxAndroid
25 | implementation libs.kotlin
26 | implementation libs.supportMultidex
27 |
28 | implementation libs.dagger
29 | }
30 |
31 | dependencies {
32 | kapt aptLibs.databinding
33 | kapt libs.daggerCompiler
34 | }
35 |
36 | dependencies {
37 | implementation fileTree(dir: 'libs', include: ['*.jar'])
38 | implementation 'com.google.android.gms:play-services-maps:11.8.0'
39 | }
40 |
41 | dependencies {
42 | implementation project(path: ':system-base')
43 | implementation project(path: ':core-profile')
44 | implementation project(path: ':stream-state')
45 | implementation project(path: ':feature-ride')
46 | implementation project(path: ':core-geo')
47 | implementation project(path: ':core-location')
48 | implementation project(path: ':core-booking')
49 | implementation project(path: ':feature-promo')
50 | implementation project(path: ':feature-map')
51 | }
52 |
53 | dependencies {
54 | testImplementation testLibs.jUnit
55 | testImplementation testLibs.mockito
56 | testImplementation testLibs.mockito_inline
57 | testImplementation testLibs.mockitoKotlin
58 | }
59 |
--------------------------------------------------------------------------------
/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/levnovikov/postbus/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.levnovikov.postbus", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
24 |
25 |
28 |
29 |
32 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/Application.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus
2 |
3 | import android.content.Context
4 | import android.support.multidex.MultiDex
5 | import com.levnovikov.postbus.root.di.AppComponent
6 | import com.levnovikov.postbus.root.di.AppModule
7 | import com.levnovikov.postbus.root.di.DaggerAppComponent
8 | import com.levnovikov.system_base.base_di.ComponentBuilder
9 | import com.levnovikov.system_base.base_di.SubComponentProvider
10 |
11 | /**
12 | * Author: lev.novikov
13 | * Date: 20/11/17.
14 | */
15 |
16 | class Application : android.app.Application(), SubComponentProvider {
17 |
18 | lateinit var appComponent: AppComponent
19 |
20 | override fun onCreate() {
21 | super.onCreate()
22 | injectDependencies()
23 | }
24 |
25 | private fun injectDependencies() {
26 | appComponent = DaggerAppComponent.builder()
27 | .appModule(AppModule(this))
28 | .build()
29 | }
30 |
31 | @Suppress("UNCHECKED_CAST")
32 | override fun provide(key: Class): C =
33 | appComponent.subComponentBuilders()[key] as C
34 |
35 | override fun attachBaseContext(base: Context) {
36 | super.attachBaseContext(base)
37 | MultiDex.install(this)
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/deeplinks/DeeplinkParser.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.deeplinks
2 |
3 | import com.levnovikov.postbus.root.home.HomeInteractor
4 | import com.levnovikov.postbus.root.home.HomeRouter
5 | import com.levnovikov.postbus.root.home.prebooking.PrebookingNodeHolder
6 | import com.levnovikov.postbus.root.home.prebooking.PrebookingRouter
7 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.BookingExtraNodeHolder
8 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.BookingExtraRouter
9 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.options.OptionsNodeHolder
10 | import com.levnovikov.postbus.root.home.prebooking.car_type_selector.CarTypeSelectorNodeHolder
11 | import com.levnovikov.postbus.root.home.prebooking.car_type_selector.CarTypeSelectorRouter
12 | import com.levnovikov.postbus.root.home.prebooking.car_type_selector.car_type_list.CarTypeListNodeHolder
13 | import com.levnovikov.stream_state.AppState
14 | import com.levnovikov.system_base.node_state.ActivityState
15 | import com.levnovikov.system_base.node_state.NodeState
16 | import java.net.URI
17 | import javax.inject.Inject
18 |
19 | /**
20 | * Created by lev.novikov
21 | * Date: 1/3/18.
22 | */
23 |
24 | interface DeeplinkParser {
25 | fun parseDeeplink(deeplink: URI): ActivityState?
26 | }
27 |
28 | class DeeplinkParserImpl @Inject constructor() : DeeplinkParser {
29 |
30 | private val deeplinkCases = setOf(PromoDeeplink())
31 |
32 | override fun parseDeeplink(deeplink: URI): ActivityState? =
33 | deeplinkCases.firstOrNull { it.validateLink(deeplink) }?.parseState()
34 | }
35 |
36 | interface DeeplinkCase {
37 | fun validateLink(deeplink: URI): Boolean
38 | fun parseState(): ActivityState
39 | }
40 |
41 | class PromoDeeplink : DeeplinkCase {
42 | override fun validateLink(deeplink: URI) =
43 | deeplink.path == "/prebooking/extra/options"
44 |
45 | override fun parseState(): ActivityState =
46 | ActivityState(stateMap = mapOf(
47 | className() to NodeState(HomeInteractor.HomeData(AppState.PREBOOKING), setOf(className())),
48 | className() to NodeState(null, setOf(
49 | className(), className())),
50 | className() to NodeState(null, setOf(
51 | className())),
52 | className() to NodeState(null, setOf(className()))))
53 |
54 |
55 | inline fun className() = T::class.java.simpleName
56 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/di/AppComponent.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.di
2 |
3 | import com.levnovikov.core_profile.di.ProfileModule
4 | import com.levnovikov.postbus.root.home.di.HomeComponentBuilder
5 | import com.levnovikov.system_base.base_di.ComponentBuilder
6 | import dagger.Component
7 | import javax.inject.Singleton
8 |
9 | /**
10 | * Author: lev.novikov
11 | * Date: 20/11/17.
12 | */
13 |
14 | @Singleton
15 | @Component(modules = [(AppModule::class), (ProfileModule::class), (HomeComponentBuilder::class)])
16 | interface AppComponent {
17 |
18 | fun subComponentBuilders(): Map, ComponentBuilder>
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/di/AppModule.java:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.di;
2 |
3 | import android.content.Context;
4 |
5 | import javax.inject.Named;
6 | import javax.inject.Singleton;
7 |
8 | import dagger.Module;
9 | import dagger.Provides;
10 |
11 | /**
12 | * Created by lev.novikov
13 | * Date: 21/11/17.
14 | */
15 |
16 | @Module
17 | public class AppModule {
18 |
19 | private final Context appContext;
20 |
21 | public AppModule(Context appContext) {
22 | this.appContext = appContext;
23 | }
24 |
25 | @Provides
26 | @Singleton
27 | @Named("AppContext")
28 | Context provideContext() {
29 | return appContext;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/HomeRouter.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home
2 |
3 | import com.levnovikov.feature_map.MapNodeHolder
4 | import com.levnovikov.postbus.root.home.allocating.AllocatingNodeHolder
5 | import com.levnovikov.postbus.root.home.di.HomeScope
6 | import com.levnovikov.postbus.root.home.prebooking.PrebookingNodeHolder
7 | import com.levnovikov.system_base.NodeHolder
8 | import com.levnovikov.system_base.Router
9 | import javax.inject.Inject
10 |
11 | /**
12 | * Author: lev.novikov
13 | * Date: 14/12/17.
14 | */
15 |
16 | @HomeScope
17 | class HomeRouter @Inject
18 | constructor(
19 | private val prebookingHolder: PrebookingNodeHolder,
20 | private val allocatingHolder: AllocatingNodeHolder,
21 | private val mapHolder: MapNodeHolder) : Router() {
22 |
23 | fun startPrebooking() {
24 | detachNode(allocatingHolder)
25 | attachNode(prebookingHolder)
26 | }
27 |
28 | fun startAllocating() {
29 | detachNode(prebookingHolder)
30 | attachNode(allocatingHolder)
31 | }
32 |
33 | fun loadMap() {
34 | attachNode(mapHolder)
35 | }
36 |
37 | fun startTracking() {
38 | detachNode(allocatingHolder)
39 | detachNode(prebookingHolder)
40 | }
41 |
42 | override val holders: Set> = setOf(mapHolder, prebookingHolder, allocatingHolder)
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/HomeView.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 | import android.widget.FrameLayout
6 |
7 | /**
8 | * Author: lev.novikov
9 | * Date: 14/12/17.
10 | */
11 |
12 | class HomeView : FrameLayout {
13 |
14 | constructor(context: Context) : super(context) {}
15 |
16 | constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {}
17 |
18 | constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {}
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/allocating/AllocatingInteractor.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.allocating
2 |
3 | import com.levnovikov.postbus.root.home.allocating.di.AllocatingScope
4 |
5 | import javax.inject.Inject
6 |
7 | /**
8 | * Created by lev.novikov
9 | * Date: 23/12/17.
10 | */
11 |
12 | @AllocatingScope
13 | class AllocatingInteractor @Inject
14 | internal constructor()
15 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/allocating/AllocatingNodeHolder.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.allocating
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 |
6 | import com.levnovikov.postbus.R
7 | import com.levnovikov.postbus.root.home.allocating.di.AllocatingComponent
8 | import com.levnovikov.postbus.root.home.allocating.di.DaggerAllocatingComponent
9 | import com.levnovikov.postbus.root.home.di.HomeComponent
10 | import com.levnovikov.system_base.ViewNodeHolder
11 |
12 | /**
13 | * Created by lev.novikov
14 | * Date: 23/12/17.
15 | */
16 |
17 | class AllocatingNodeHolder(inflater: LayoutInflater, parent: ViewGroup, private val parentComponent: HomeComponent) : ViewNodeHolder(inflater, parent) {
18 |
19 | override val layout: Int
20 | get() = R.layout.alloc_view
21 |
22 | override fun build(): AllocatingRouter {
23 | val view = buildView()
24 | val component = DaggerAllocatingComponent.builder()
25 | .homeComponent(parentComponent)
26 | .allocatingModule(AllocatingComponent.AllocatingModule(view))
27 | .build()
28 | component.inject(view)
29 | component.inject(this)
30 | attachView()
31 | return component.router()
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/allocating/AllocatingRouter.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.allocating
2 |
3 | import com.levnovikov.postbus.root.home.allocating.di.AllocatingScope
4 | import com.levnovikov.system_base.NodeHolder
5 | import com.levnovikov.system_base.Router
6 | import com.levnovikov.system_base.node_state.NodeState
7 |
8 | import javax.inject.Inject
9 |
10 | /**
11 | * Created by lev.novikov
12 | * Date: 23/12/17.
13 | */
14 |
15 | @AllocatingScope
16 | class AllocatingRouter @Inject
17 | internal constructor() : Router() {
18 | override val holders: Set>
19 | get() = emptySet()
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/allocating/AllocatingView.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.allocating
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 | import android.widget.LinearLayout
6 |
7 | /**
8 | * Created by lev.novikov
9 | * Date: 23/12/17.
10 | */
11 |
12 | class AllocatingView : LinearLayout {
13 | constructor(context: Context) : super(context) {}
14 |
15 | constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {}
16 |
17 | constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {}
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/allocating/di/AllocatingComponent.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.allocating.di
2 |
3 | import com.levnovikov.postbus.root.home.allocating.AllocatingNodeHolder
4 | import com.levnovikov.postbus.root.home.allocating.AllocatingRouter
5 | import com.levnovikov.postbus.root.home.allocating.AllocatingView
6 | import com.levnovikov.postbus.root.home.di.HomeComponent
7 |
8 | import dagger.Component
9 | import dagger.Module
10 | import dagger.Provides
11 |
12 | /**
13 | * Created by lev.novikov
14 | * Date: 23/12/17.
15 | */
16 |
17 | @AllocatingScope
18 | @Component(dependencies = [(HomeComponent::class)], modules = [(AllocatingComponent.AllocatingModule::class)])
19 | interface AllocatingComponent {
20 |
21 | fun inject(view: AllocatingView)
22 |
23 | fun router(): AllocatingRouter
24 |
25 | fun inject(allocatingBuilder: AllocatingNodeHolder)
26 |
27 | @Module
28 | class AllocatingModule(private val view: AllocatingView) {
29 |
30 | @AllocatingScope
31 | @Provides
32 | internal fun provideView(): AllocatingView {
33 | return view
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/allocating/di/AllocatingScope.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.allocating.di
2 |
3 | import javax.inject.Scope
4 |
5 | /**
6 | * Created by lev.novikov
7 | * Date: 23/12/17.
8 | */
9 |
10 | @Scope
11 | @Retention(AnnotationRetention.RUNTIME)
12 | annotation class AllocatingScope
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/di/HomeComponent.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.di
2 |
3 | import android.view.LayoutInflater
4 |
5 | import com.levnovikov.feature_map.dependency.MapDependency
6 | import com.levnovikov.feature_map.dependency.MapProvider
7 | import com.levnovikov.feature_map.dependency.MapSetter
8 | import com.levnovikov.postbus.root.home.HomeActivity
9 | import com.levnovikov.postbus.root.home.HomeView
10 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.BookingExtraInteractor
11 | import com.levnovikov.system_base.base_di.ActivityComponent
12 | import com.levnovikov.system_base.base_di.ComponentBuilder
13 |
14 | import dagger.Subcomponent
15 |
16 | /**
17 | * Author: lev.novikov
18 | * Date: 14/12/17.
19 | */
20 |
21 | @HomeScope
22 | @Subcomponent(modules = [(HomeModule::class)])
23 | interface HomeComponent : ActivityComponent, MapDependency {
24 |
25 | fun inject(homeActivity: HomeActivity)
26 |
27 | @Subcomponent.Builder
28 | interface Builder : ComponentBuilder {
29 | fun homeModule(module: HomeModule): HomeComponent.Builder
30 | fun build(): HomeComponent
31 | }
32 |
33 | fun inflater(): LayoutInflater
34 | fun homeView(): HomeView
35 | fun bookingListener(): BookingExtraInteractor.Listener
36 | override fun mapSetter(): MapSetter
37 | fun mapProvider(): MapProvider
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/di/HomeComponentBuilder.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.di
2 |
3 | import com.levnovikov.system_base.base_di.ComponentBuilder
4 | import com.levnovikov.system_base.base_di.ComponentKey
5 |
6 | import dagger.Binds
7 | import dagger.Module
8 | import dagger.multibindings.IntoMap
9 |
10 | /**
11 | * Created by lev.novikov
12 | * Date: 2/12/17.
13 | */
14 |
15 | @Module(subcomponents = [(HomeComponent::class)])
16 | interface HomeComponentBuilder {
17 |
18 | @Binds
19 | @IntoMap
20 | @ComponentKey(HomeComponent.Builder::class)
21 | fun mainActivityComponentBuilder(impl: HomeComponent.Builder): ComponentBuilder
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/di/HomeScope.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.di
2 |
3 | import javax.inject.Scope
4 |
5 | /**
6 | * Author: lev.novikov
7 | * Date: 14/12/17.
8 | */
9 |
10 | @Scope
11 | @Retention(AnnotationRetention.RUNTIME)
12 | annotation class HomeScope
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/PrebookingNodeHolder.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking
2 |
3 | import com.levnovikov.postbus.root.home.di.HomeComponent
4 | import com.levnovikov.postbus.root.home.prebooking.di.DaggerPrebookingComponent
5 | import com.levnovikov.system_base.NodeHolder
6 |
7 | /**
8 | * Author: lev.novikov
9 | * Date: 17/12/17.
10 | */
11 |
12 | class PrebookingNodeHolder(private val component: HomeComponent) : NodeHolder() {
13 |
14 | override fun build(): PrebookingRouter {
15 | val cmp = DaggerPrebookingComponent.builder()
16 | .homeComponent(component)
17 | .build()
18 | cmp.inject(this) //TODO add lint checking
19 | cmp.interactor().restoreState()
20 | return cmp.getRouter()
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/PrebookingRouter.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking
2 |
3 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.BookingExtraNodeHolder
4 | import com.levnovikov.postbus.root.home.prebooking.car_type_selector.CarTypeSelectorNodeHolder
5 | import com.levnovikov.postbus.root.home.prebooking.di.PrebookingScope
6 | import com.levnovikov.postbus.root.home.prebooking.poi_selector.PoiSelectorNodeHolder
7 | import com.levnovikov.postbus.root.home.prebooking.poi_widget.PoiWidgetNodeHolder
8 | import com.levnovikov.system_base.NodeHolder
9 | import com.levnovikov.system_base.Router
10 | import com.levnovikov.system_base.node_state.NodeState
11 |
12 | import javax.inject.Inject
13 |
14 | /**
15 | * Author: lev.novikov
16 | * Date: 17/12/17.
17 | */
18 |
19 | @PrebookingScope
20 | class PrebookingRouter @Inject
21 | internal constructor(
22 | private val poiWidgetHolder: PoiWidgetNodeHolder,
23 | private val poiSelectorHolder: PoiSelectorNodeHolder,
24 | private val carTypeSelectorHolder: CarTypeSelectorNodeHolder,
25 | private val bookingExtraHolder: BookingExtraNodeHolder) : Router() {
26 |
27 | override val holders: Set> = setOf(poiWidgetHolder, poiSelectorHolder, carTypeSelectorHolder, bookingExtraHolder)
28 |
29 | fun showPoiWidget() {
30 | attachNode(poiWidgetHolder)
31 | }
32 |
33 | fun startServiceType() {
34 | detachNode(poiSelectorHolder)
35 | detachNode(poiWidgetHolder)
36 |
37 | attachNode(carTypeSelectorHolder)
38 | }
39 |
40 | fun startBookingExtra() {
41 | attachNode(bookingExtraHolder)
42 | }
43 |
44 | fun startPoiChoice() {
45 | attachNode(poiSelectorHolder)
46 | }
47 |
48 | fun hidePoiChoice() {
49 | detachNode(poiSelectorHolder)
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/booking_extra_widget/BookingExtraInteractor.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.booking_extra_widget
2 |
3 | import com.levnovikov.feature_promo.domain.Promo
4 | import com.levnovikov.feature_promo.promo_list.dependency.OnPromoSelectedListener
5 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.di.BookingExtraScope
6 | import com.levnovikov.system_base.Interactor
7 | import com.levnovikov.system_base.node_state.ActivityState
8 | import javax.inject.Inject
9 |
10 | /**
11 | * Created by lev.novikov
12 | * Date: 23/12/17.
13 | */
14 |
15 | @BookingExtraScope
16 | class BookingExtraInteractor @Inject
17 | constructor(
18 | private val listener: Listener,
19 | router: BookingExtraRouter,
20 | activityState: ActivityState) : Interactor(router, activityState), OnPromoSelectedListener {
21 |
22 | override fun onPromoSelected(promo: Promo) {
23 | router.detachPromoList()
24 | router.getState()
25 | }
26 |
27 | override fun onCancel() {
28 | router.detachPromoList()
29 | }
30 |
31 | fun onBookClick() {
32 | listener.onBookClick()
33 | }
34 |
35 | fun showPromo() {
36 | router.showOptions()
37 | }
38 |
39 | interface Listener {
40 | fun onBookClick()
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/booking_extra_widget/BookingExtraNodeHolder.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.booking_extra_widget
2 |
3 | import android.view.Gravity
4 | import android.view.LayoutInflater
5 | import android.view.ViewGroup
6 | import android.widget.FrameLayout
7 |
8 | import com.levnovikov.postbus.R
9 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.di.BookingExtraComponent
10 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.di.DaggerBookingExtraComponent
11 | import com.levnovikov.postbus.root.home.prebooking.di.PrebookingComponent
12 | import com.levnovikov.system_base.ViewNodeHolder
13 |
14 | /**
15 | * Created by lev.novikov
16 | * Date: 23/12/17.
17 | */
18 |
19 | class BookingExtraNodeHolder(inflater: LayoutInflater, parent: ViewGroup, private val parentComponent: PrebookingComponent) : ViewNodeHolder(inflater, parent) {
20 |
21 | override val layout: Int
22 | get() = R.layout.booking_extra_widget
23 |
24 | override fun build(): BookingExtraRouter {
25 | val view = buildView()
26 | val params = view.layoutParams as FrameLayout.LayoutParams
27 | params.gravity = Gravity.BOTTOM
28 | view.layoutParams = params
29 |
30 | val component = DaggerBookingExtraComponent
31 | .builder()
32 | .prebookingComponent(parentComponent)
33 | .bookingExtraModule(BookingExtraComponent.BookingExtraModule(view))
34 | .build()
35 | component.inject(view)
36 | component.inject(this)
37 | attachView()
38 | return component.router()
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/booking_extra_widget/BookingExtraRouter.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.booking_extra_widget
2 |
3 | import com.levnovikov.feature_promo.promo_list.PromoListNodeHolder
4 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.di.BookingExtraScope
5 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.extra.ExtraNodeHolder
6 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.options.OptionsNodeHolder
7 | import com.levnovikov.system_base.NodeHolder
8 | import com.levnovikov.system_base.Router
9 | import com.levnovikov.system_base.node_state.NodeState
10 |
11 | import javax.inject.Inject
12 |
13 | /**
14 | * Created by lev.novikov
15 | * Date: 23/12/17.
16 | */
17 |
18 | @BookingExtraScope
19 | class BookingExtraRouter @Inject
20 | constructor(
21 | private val promoListBuilder: PromoListNodeHolder,
22 | private val extraNodeHolder: ExtraNodeHolder,
23 | private val optionsNodeHolder: OptionsNodeHolder) : Router() {
24 |
25 | override val holders: Set> = setOf(promoListBuilder, extraNodeHolder, optionsNodeHolder)
26 |
27 | fun detachPromoList() {
28 | detachNode(promoListBuilder)
29 | }
30 |
31 | fun attachPromoList() {
32 | attachNode(promoListBuilder)
33 | }
34 |
35 | fun attachExtra() {
36 | attachNode(extraNodeHolder)
37 | }
38 |
39 | fun detachExtra() {
40 | detachNode(extraNodeHolder)
41 | }
42 |
43 | fun showOptions() {
44 | attachNode(optionsNodeHolder)
45 | }
46 |
47 | fun hideOptions() {
48 | detachNode(optionsNodeHolder)
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/booking_extra_widget/BookingExtraVM.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.booking_extra_widget
2 |
3 | import javax.inject.Inject
4 |
5 | /**
6 | * Author: lev.novikov
7 | * Date: 3/3/18.
8 | */
9 | class BookingExtraVM @Inject constructor(
10 | private val interactor: BookingExtraInteractor
11 | ) {
12 |
13 | init {
14 | if (interactor.hasSavedState()) interactor.restoreState()
15 | }
16 |
17 | fun onPaymentClick() {
18 |
19 | }
20 |
21 | fun onPromoClick() {
22 | interactor.showPromo()
23 | }
24 |
25 | fun onOptionsClick() {
26 |
27 | }
28 |
29 | fun onBookClick() {
30 | interactor.onBookClick()
31 | }
32 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/booking_extra_widget/BookingExtraView.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.booking_extra_widget
2 |
3 | import android.content.Context
4 | import android.databinding.DataBindingUtil
5 | import android.util.AttributeSet
6 | import android.widget.LinearLayout
7 | import com.levnovikov.postbus.databinding.BookingExtraWidgetBinding
8 | import javax.inject.Inject
9 |
10 | /**
11 | * Created by lev.novikov
12 | * Date: 23/12/17.
13 | */
14 |
15 | class BookingExtraView @JvmOverloads constructor(
16 | context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
17 | ) : LinearLayout(context, attrs, defStyleAttr) {
18 |
19 | @Inject
20 | lateinit var vm: BookingExtraVM
21 |
22 | override fun onAttachedToWindow() {
23 | super.onAttachedToWindow()
24 | setupBinding()
25 | }
26 |
27 |
28 | private fun setupBinding() {
29 | DataBindingUtil.bind(this).vm = vm
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/booking_extra_widget/di/BookingExtraScope.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.di
2 |
3 | import javax.inject.Scope
4 |
5 | /**
6 | * Created by lev.novikov
7 | * Date: 23/12/17.
8 | */
9 |
10 | @Scope
11 | @Retention(AnnotationRetention.RUNTIME)
12 | annotation class BookingExtraScope
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/booking_extra_widget/extra/ExtraInteractor.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.extra
2 |
3 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.extra.di.ExtraScope
4 | import com.levnovikov.system_base.Interactor
5 | import com.levnovikov.system_base.node_state.ActivityState
6 | import javax.inject.Inject
7 |
8 | /**
9 | * Created by lev.novikov
10 | * Date: 3/2/18.
11 | */
12 |
13 | @ExtraScope
14 | class ExtraInteractor @Inject constructor(
15 | router: ExtraRouter,
16 | activityState: ActivityState) : Interactor(router, activityState) {
17 |
18 | init {
19 | restoreState()
20 | }
21 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/booking_extra_widget/extra/ExtraNodeHolder.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.extra
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import com.levnovikov.postbus.R
6 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.di.BookingExtraComponent
7 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.extra.di.DaggerExtraComponent
8 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.extra.di.ExtraComponent
9 | import com.levnovikov.system_base.ViewNodeHolder
10 |
11 | /**
12 | * Created by lev.novikov
13 | * Date: 3/2/18.
14 | */
15 | class ExtraNodeHolder(layoutInflater: LayoutInflater, parent: ViewGroup, private val dependency: BookingExtraComponent)
16 | : ViewNodeHolder(layoutInflater, parent) {
17 |
18 | override fun build(): ExtraRouter {
19 | val view = buildView()
20 | val component = DaggerExtraComponent.builder()
21 | .bookingExtraComponent(dependency)
22 | .extraModule(ExtraComponent.ExtraModule(view))
23 | .build()
24 | component.inject(view)
25 | component.inject(this)
26 | attachView()
27 | return component.router()
28 | }
29 |
30 | override val layout: Int = R.layout.extra_view
31 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/booking_extra_widget/extra/ExtraRouter.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.extra
2 |
3 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.extra.di.ExtraScope
4 | import com.levnovikov.system_base.NodeHolder
5 | import com.levnovikov.system_base.Router
6 | import javax.inject.Inject
7 |
8 | /**
9 | * Created by lev.novikov
10 | * Date: 3/2/18.
11 | */
12 |
13 | @ExtraScope
14 | class ExtraRouter @Inject constructor() : Router() {
15 | override val holders: Set>
16 | get() = emptySet()
17 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/booking_extra_widget/extra/ExtraView.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.extra
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 | import android.widget.FrameLayout
6 | import javax.inject.Inject
7 |
8 | /**
9 | * Created by lev.novikov
10 | * Date: 3/2/18.
11 | */
12 | class ExtraView : FrameLayout {
13 | constructor(context: Context?) : super(context)
14 | constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
15 | constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
16 |
17 | @Inject
18 | lateinit var interactor: ExtraInteractor
19 |
20 | override fun onAttachedToWindow() {
21 | super.onAttachedToWindow()
22 | interactor.restoreState()
23 | }
24 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/booking_extra_widget/extra/di/ExtraComponent.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.extra.di
2 |
3 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.di.BookingExtraComponent
4 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.extra.ExtraNodeHolder
5 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.extra.ExtraRouter
6 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.extra.ExtraView
7 | import com.levnovikov.system_base.base_di.ActivityComponent
8 | import dagger.Component
9 | import dagger.Module
10 | import dagger.Provides
11 |
12 | /**
13 | * Created by lev.novikov
14 | * Date: 3/2/18.
15 | */
16 |
17 | @ExtraScope
18 | @Component(dependencies = [BookingExtraComponent::class], modules = [ExtraComponent.ExtraModule::class])
19 | interface ExtraComponent : ActivityComponent {
20 |
21 | @Module
22 | class ExtraModule(private val view: ExtraView) {
23 | @Provides
24 | fun provideView() = view
25 | }
26 |
27 | fun router(): ExtraRouter
28 | fun inject(view: ExtraView)
29 | fun inject(view: ExtraNodeHolder)
30 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/booking_extra_widget/extra/di/ExtraScope.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.extra.di
2 |
3 | import javax.inject.Scope
4 |
5 | /**
6 | * Created by lev.novikov
7 | * Date: 3/2/18.
8 | */
9 | @Scope
10 | @Retention(AnnotationRetention.RUNTIME)
11 | annotation class ExtraScope
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/booking_extra_widget/options/OptionsInteractor.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.options
2 |
3 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.options.di.OptionsScope
4 | import com.levnovikov.system_base.Interactor
5 | import com.levnovikov.system_base.node_state.ActivityState
6 | import javax.inject.Inject
7 |
8 | /**
9 | * Created by lev.novikov
10 | * Date: 1/3/18.
11 | */
12 |
13 | @OptionsScope
14 | class OptionsInteractor @Inject constructor(router: OptionsRouter, activityState: ActivityState) : Interactor(router, activityState) {
15 |
16 | fun showSubOptions() {
17 | router.showSubOptions()
18 | }
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/booking_extra_widget/options/OptionsNodeHolder.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.options
2 |
3 | import android.view.LayoutInflater
4 | import com.levnovikov.postbus.R
5 | import com.levnovikov.postbus.root.home.HomeView
6 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.options.di.DaggerOptionsComponent
7 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.options.di.OptionsDependencies
8 | import com.levnovikov.system_base.ViewNodeHolder
9 | import javax.inject.Inject
10 |
11 | /**
12 | * Created by lev.novikov
13 | * Date: 1/3/18.
14 | */
15 |
16 | class OptionsNodeHolder @Inject constructor(
17 | inflater: LayoutInflater,
18 | parent: HomeView,
19 | private val dependencies: OptionsDependencies) : ViewNodeHolder(inflater, parent) {
20 |
21 | override val layout: Int
22 | get() = R.layout.options_view
23 |
24 | override fun build(): OptionsRouter {
25 | val view = buildView()
26 | val component = DaggerOptionsComponent.builder()
27 | .dependencies(dependencies)
28 | .view(view)
29 | .build()
30 | component.inject(this)
31 | component.inject(view)
32 | attachView()
33 | return component.router()
34 | }
35 |
36 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/booking_extra_widget/options/OptionsRouter.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.options
2 |
3 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.options.di.OptionsScope
4 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.options.sub_options.SubOptionsNodeHolder
5 | import com.levnovikov.system_base.NodeHolder
6 | import com.levnovikov.system_base.Router
7 | import javax.inject.Inject
8 |
9 | /**
10 | * Created by lev.novikov
11 | * Date: 1/3/18.
12 | */
13 |
14 | @OptionsScope
15 | class OptionsRouter @Inject constructor(private val subOptionsNodeHolder: SubOptionsNodeHolder) : Router() {
16 | override val holders: Set> = setOf(subOptionsNodeHolder)
17 |
18 | fun showSubOptions() {
19 | attachNode(subOptionsNodeHolder)
20 | }
21 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/booking_extra_widget/options/OptionsVM.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.options
2 |
3 | import javax.inject.Inject
4 |
5 | /**
6 | * Author: lev.novikov
7 | * Date: 4/3/18.
8 | */
9 | class OptionsVM @Inject constructor(
10 | interactor: OptionsInteractor
11 | ) {
12 |
13 | init {
14 | if (interactor.hasSavedState()) {
15 | interactor.restoreState()
16 | } else {
17 | interactor.showSubOptions()
18 | }
19 | }
20 |
21 |
22 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/booking_extra_widget/options/OptionsView.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.options
2 |
3 | import android.content.Context
4 | import android.databinding.DataBindingUtil
5 | import android.util.AttributeSet
6 | import android.widget.FrameLayout
7 | import com.levnovikov.postbus.databinding.OptionsViewBinding
8 | import dagger.Lazy
9 | import javax.inject.Inject
10 |
11 | /**
12 | * Created by lev.novikov
13 | * Date: 1/3/18.
14 | */
15 | class OptionsView @JvmOverloads constructor(
16 | context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
17 | ) : FrameLayout(context, attrs, defStyleAttr) {
18 |
19 | @Inject
20 | lateinit var vm: Lazy
21 |
22 | override fun onAttachedToWindow() {
23 | super.onAttachedToWindow()
24 | setupBinding()
25 | }
26 |
27 | private fun setupBinding() {
28 | DataBindingUtil.bind(this).vm = vm.get()
29 | }
30 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/booking_extra_widget/options/di/OptionsComponent.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.options.di
2 |
3 | import android.view.LayoutInflater
4 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.options.OptionsNodeHolder
5 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.options.OptionsRouter
6 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.options.OptionsView
7 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.options.sub_options.SubOptionsNodeHolder
8 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.options.sub_options.di.SubOptionsDependencies
9 | import com.levnovikov.system_base.base_di.ActivityComponent
10 | import dagger.BindsInstance
11 | import dagger.Component
12 | import dagger.Module
13 | import dagger.Provides
14 | import javax.inject.Scope
15 |
16 | /**
17 | * Created by lev.novikov
18 | * Date: 1/3/18.
19 | */
20 |
21 | @Scope
22 | @Retention(AnnotationRetention.RUNTIME)
23 | annotation class OptionsScope
24 |
25 | interface OptionsDependencies : ActivityComponent {
26 | fun inflater(): LayoutInflater
27 | }
28 |
29 | @OptionsScope
30 | @Component(dependencies = [OptionsDependencies::class], modules = [OptionsComponent.OptionsModule::class])
31 | interface OptionsComponent : SubOptionsDependencies, ActivityComponent {
32 |
33 | @Module
34 | class OptionsModule {
35 | @Provides
36 | fun subOptionsNodeHolder(view: OptionsView, layoutInflater: LayoutInflater, component: OptionsComponent): SubOptionsNodeHolder =
37 | SubOptionsNodeHolder(view, layoutInflater, component)
38 | }
39 |
40 | @Component.Builder
41 | interface Builder {
42 | fun build(): OptionsComponent
43 | fun dependencies(dependencies: OptionsDependencies): Builder
44 | @BindsInstance
45 | fun view(view: OptionsView): Builder
46 | }
47 |
48 | fun inject(view: OptionsView)
49 | fun inject(view: OptionsNodeHolder)
50 | fun router(): OptionsRouter
51 | fun dependencies(): OptionsDependencies
52 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/booking_extra_widget/options/sub_options/SubOptionsNodeHolder.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.options.sub_options
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import com.levnovikov.postbus.R
6 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.options.sub_options.di.DaggerSubOptionsComponent
7 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.options.sub_options.di.SubOptionsDependencies
8 | import com.levnovikov.system_base.ViewNodeHolder
9 |
10 |
11 | /**
12 | * Created by stepan.goncharov on 1/3/18.
13 | */
14 | class SubOptionsNodeHolder constructor(parent: ViewGroup, inflater: LayoutInflater, val dependencies: SubOptionsDependencies) :
15 | ViewNodeHolder(inflater, parent) {
17 |
18 | override val layout: Int = R.layout.sub_options_view
19 |
20 | override fun build(): SubOptionsRouter {
21 | val view = buildView()
22 | val component = DaggerSubOptionsComponent.builder()
23 | .dependencies(dependencies)
24 | .view(view)
25 | .build()
26 | component.inject(this)
27 | component.inject(view)
28 | attachView()
29 | return component.router()
30 | }
31 |
32 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/booking_extra_widget/options/sub_options/SubOptionsRouter.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.options.sub_options
2 |
3 | import com.levnovikov.system_base.NodeHolder
4 | import com.levnovikov.system_base.Router
5 | import com.levnovikov.system_base.node_state.NodeState
6 | import javax.inject.Inject
7 |
8 | /**
9 | * Created by stepan.goncharov on 1/3/18.
10 | */
11 | class SubOptionsRouter @Inject constructor(): Router() {
12 | override val holders: Set> = emptySet()
13 |
14 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/booking_extra_widget/options/sub_options/SubOptionsView.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.options.sub_options
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 | import android.widget.FrameLayout
6 |
7 | /**
8 | * Created by stepan.goncharov on 1/3/18.
9 | */
10 | class SubOptionsView @JvmOverloads constructor(
11 | context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
12 | ) : FrameLayout(context, attrs, defStyleAttr){
13 |
14 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/booking_extra_widget/options/sub_options/di/SubOptionsComponent.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.options.sub_options.di
2 |
3 | import android.view.LayoutInflater
4 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.options.sub_options.SubOptionsNodeHolder
5 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.options.sub_options.SubOptionsRouter
6 | import com.levnovikov.postbus.root.home.prebooking.booking_extra_widget.options.sub_options.SubOptionsView
7 | import dagger.BindsInstance
8 | import dagger.Component
9 | import dagger.Module
10 | import javax.inject.Scope
11 |
12 | /**
13 | * Created by stepan.goncharov on 1/3/18.
14 | */
15 |
16 | @Scope
17 | @Retention(AnnotationRetention.RUNTIME)
18 | annotation class SubOptionsScope
19 |
20 | interface SubOptionsDependencies {
21 |
22 | }
23 |
24 | @SubOptionsScope
25 | @Component(dependencies = [SubOptionsDependencies::class], modules = [SubOptionsComponent.OptionsModule::class])
26 | interface SubOptionsComponent {
27 |
28 | @Module
29 | class OptionsModule {
30 |
31 | }
32 |
33 | @Component.Builder
34 | interface Builder {
35 | fun build(): SubOptionsComponent
36 | fun dependencies(dependencies: SubOptionsDependencies): Builder
37 | @BindsInstance
38 | fun view(view: SubOptionsView): Builder
39 | }
40 |
41 | fun inject(view: SubOptionsView)
42 | fun inject(view: SubOptionsNodeHolder)
43 | fun router(): SubOptionsRouter
44 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/car_type_selector/CarTypeSelectorInteractor.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.car_type_selector
2 |
3 | import com.levnovikov.postbus.root.home.prebooking.car_type_selector.car_type_list.TypeListListener
4 | import com.levnovikov.postbus.root.home.prebooking.car_type_selector.di.CarTypeSelectorScope
5 | import com.levnovikov.system_base.Interactor
6 | import com.levnovikov.system_base.node_state.ActivityState
7 | import javax.inject.Inject
8 |
9 |
10 | /**
11 | * Created by lev.novikov
12 | * Date: 23/12/17.
13 | */
14 |
15 | @CarTypeSelectorScope
16 | class CarTypeSelectorInteractor @Inject constructor(
17 | private val listener: Listener,
18 | router: CarTypeSelectorRouter,
19 | activityState: ActivityState) : Interactor(router, activityState), TypeListListener {
20 |
21 | override fun onCancel() {
22 | router.detachTypeList()
23 | }
24 |
25 | interface Listener {
26 | fun onServiceSelected()
27 | }
28 |
29 | fun onServiceSelected() {
30 | router.attachTypeList()
31 | listener.onServiceSelected()
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/car_type_selector/CarTypeSelectorNodeHolder.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.car_type_selector
2 |
3 | import android.content.Context
4 | import android.view.LayoutInflater
5 | import android.view.ViewGroup
6 | import com.levnovikov.postbus.BR
7 | import com.levnovikov.postbus.R
8 | import com.levnovikov.postbus.databinding.CarTypeSelectorBinding
9 | import com.levnovikov.postbus.root.home.prebooking.car_type_selector.di.DaggerCarTypeSelectorComponent
10 | import com.levnovikov.postbus.root.home.prebooking.di.PrebookingComponent
11 | import com.levnovikov.system_base.BindingNodeHolder
12 | import javax.inject.Inject
13 |
14 | /**
15 | * Created by lev.novikov
16 | * Date: 23/12/17.
17 | */
18 |
19 | class CarTypeSelectorNodeHolder(
20 | inflater: LayoutInflater,
21 | parent: ViewGroup,
22 | private val parentComponent: PrebookingComponent
23 | ) : BindingNodeHolder(inflater, parent) {
24 |
25 | @Inject
26 | lateinit var vm: CarTypeSelectorVM
27 |
28 | override val layout: Int
29 | get() = R.layout.car_type_selector
30 |
31 | override fun build(): CarTypeSelectorRouter {
32 | // val view = buildView()
33 | // val params = view.layoutParams as FrameLayout.LayoutParams
34 | // params.gravity = Gravity.BOTTOM
35 | // params.setMargins(0, 0, 0, getDp(view.context, 180))
36 | // view.layoutParams = params
37 |
38 | val component = DaggerCarTypeSelectorComponent.builder()
39 | .prebookingComponent(parentComponent)
40 | .build()
41 | component.inject(this)
42 | buildAndAttachView(vm, BR.vm)
43 | return component.router()
44 | }
45 |
46 | //TODO move to utils
47 | private fun getDp(context: Context, dps: Int): Int {
48 | val scale = context.resources.displayMetrics.density
49 | return (dps * scale + 0.5f).toInt()
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/car_type_selector/CarTypeSelectorRouter.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.car_type_selector
2 |
3 | import com.levnovikov.postbus.root.home.prebooking.car_type_selector.car_type_list.CarTypeListNodeHolder
4 | import com.levnovikov.postbus.root.home.prebooking.car_type_selector.di.CarTypeSelectorScope
5 | import com.levnovikov.system_base.NodeHolder
6 | import com.levnovikov.system_base.Router
7 | import com.levnovikov.system_base.node_state.NodeState
8 |
9 | import javax.inject.Inject
10 |
11 | /**
12 | * Created by lev.novikov
13 | * Date: 23/12/17.
14 | */
15 |
16 | @CarTypeSelectorScope
17 | class CarTypeSelectorRouter @Inject
18 | internal constructor(private val carTypeListBuilder: CarTypeListNodeHolder) : Router() {
19 | override val holders: Set> = setOf(carTypeListBuilder)
20 |
21 | internal fun attachTypeList() {
22 | attachNode(carTypeListBuilder)
23 | }
24 |
25 | internal fun detachTypeList() {
26 | detachNode(carTypeListBuilder)
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/car_type_selector/CarTypeSelectorVM.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.car_type_selector
2 |
3 | import com.levnovikov.postbus.root.home.prebooking.car_type_selector.di.CarTypeSelectorScope
4 | import javax.inject.Inject
5 |
6 | /**
7 | * Author: lev.novikov
8 | * Date: 2/3/18.
9 | */
10 |
11 | @CarTypeSelectorScope
12 | class CarTypeSelectorVM @Inject constructor(
13 | private val interactor: CarTypeSelectorInteractor
14 | ) {
15 |
16 | init {
17 | if (interactor.hasSavedState()) interactor.restoreState()
18 | }
19 |
20 | fun onClick() {
21 | interactor.onServiceSelected()
22 | }
23 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/car_type_selector/car_type_list/CarTypeListInteractor.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.car_type_selector.car_type_list
2 |
3 | import android.os.Parcelable
4 |
5 | import com.levnovikov.postbus.root.home.prebooking.car_type_selector.car_type_list.di.CarTypeListScope
6 | import com.levnovikov.system_base.BackStateInteractor
7 | import com.levnovikov.system_base.node_state.ActivityState
8 |
9 | import javax.inject.Inject
10 |
11 | /**
12 | * Created by lev.novikov
13 | * Date: 25/12/17.
14 | */
15 |
16 | @CarTypeListScope
17 | class CarTypeListInteractor @Inject
18 | constructor(router: CarTypeListRouter, activityState: ActivityState, private val listener: TypeListListener) : BackStateInteractor(router, activityState) {
19 |
20 | override fun onSaveData(): Parcelable? = null
21 |
22 | override fun onBackPressed(): Boolean {
23 | listener.onCancel()
24 | return true
25 | }
26 | }
27 |
28 | interface TypeListListener {
29 | fun onCancel()
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/car_type_selector/car_type_list/CarTypeListNodeHolder.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.car_type_selector.car_type_list
2 |
3 | import android.content.Context
4 | import android.view.LayoutInflater
5 | import android.view.ViewGroup
6 | import android.widget.FrameLayout
7 |
8 | import com.levnovikov.postbus.R
9 | import com.levnovikov.postbus.root.home.prebooking.car_type_selector.car_type_list.di.CarTypeListComponent
10 | import com.levnovikov.postbus.root.home.prebooking.car_type_selector.car_type_list.di.DaggerCarTypeListComponent
11 | import com.levnovikov.postbus.root.home.prebooking.car_type_selector.di.CarTypeSelectorComponent
12 | import com.levnovikov.system_base.ViewNodeHolder
13 |
14 | /**
15 | * Created by lev.novikov
16 | * Date: 25/12/17.
17 | */
18 |
19 | class CarTypeListNodeHolder(inflater: LayoutInflater, parent: ViewGroup, private val parentComponent: CarTypeSelectorComponent) : ViewNodeHolder(inflater, parent) {
20 |
21 | override val layout: Int
22 | get() = R.layout.car_type_list_view
23 |
24 | override fun build(): CarTypeListRouter {
25 | val view = buildView()
26 | val params = view.layoutParams as FrameLayout.LayoutParams
27 | params.bottomMargin = getDp(view.context, 280)
28 | view.layoutParams = params
29 |
30 | val component = DaggerCarTypeListComponent.builder()
31 | .carTypeSelectorComponent(parentComponent)
32 | .carTypeListModule(CarTypeListComponent.CarTypeListModule(view))
33 | .build()
34 | component.inject(view)
35 | component.inject(this)
36 | attachView()
37 | return component.router()
38 | }
39 |
40 | //TODO move to utils
41 | private fun getDp(context: Context, dps: Int): Int {
42 | val scale = context.resources.displayMetrics.density
43 | return (dps * scale + 0.5f).toInt()
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/car_type_selector/car_type_list/CarTypeListRouter.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.car_type_selector.car_type_list
2 |
3 | import com.levnovikov.postbus.root.home.prebooking.car_type_selector.car_type_list.di.CarTypeListScope
4 | import com.levnovikov.system_base.NodeHolder
5 | import com.levnovikov.system_base.Router
6 | import com.levnovikov.system_base.node_state.NodeState
7 |
8 | import javax.inject.Inject
9 |
10 | /**
11 | * Created by lev.novikov
12 | * Date: 25/12/17.
13 | */
14 |
15 | @CarTypeListScope
16 | class CarTypeListRouter @Inject
17 | internal constructor() : Router() {
18 |
19 | override val holders: Set> = setOf()
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/car_type_selector/car_type_list/CarTypeListView.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.car_type_selector.car_type_list
2 |
3 | import android.content.Context
4 | import android.support.constraint.ConstraintLayout
5 | import android.util.AttributeSet
6 | import javax.inject.Inject
7 |
8 | /**
9 | * Created by lev.novikov
10 | * Date: 25/12/17.
11 | */
12 |
13 | class CarTypeListView @JvmOverloads constructor(
14 | context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
15 | ) : ConstraintLayout(context, attrs, defStyleAttr) {
16 |
17 | @Inject
18 | lateinit var interactor: CarTypeListInteractor
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/car_type_selector/car_type_list/di/CarTypeListComponent.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.car_type_selector.car_type_list.di
2 |
3 | import com.levnovikov.postbus.root.home.prebooking.car_type_selector.car_type_list.CarTypeListNodeHolder
4 | import com.levnovikov.postbus.root.home.prebooking.car_type_selector.car_type_list.CarTypeListRouter
5 | import com.levnovikov.postbus.root.home.prebooking.car_type_selector.car_type_list.CarTypeListView
6 | import com.levnovikov.postbus.root.home.prebooking.car_type_selector.di.CarTypeSelectorComponent
7 | import com.levnovikov.system_base.base_di.ActivityComponent
8 |
9 | import dagger.Component
10 | import dagger.Module
11 | import dagger.Provides
12 |
13 | /**
14 | * Created by lev.novikov
15 | * Date: 25/12/17.
16 | */
17 |
18 | @CarTypeListScope
19 | @Component(dependencies = [(CarTypeSelectorComponent::class)], modules = [(CarTypeListComponent.CarTypeListModule::class)])
20 | interface CarTypeListComponent : ActivityComponent {
21 |
22 | fun inject(view: CarTypeListView)
23 |
24 | fun inject(carTypeListBuilder: CarTypeListNodeHolder)
25 |
26 | fun router(): CarTypeListRouter
27 |
28 | @Module
29 | class CarTypeListModule(private val view: CarTypeListView) {
30 |
31 | @CarTypeListScope
32 | @Provides
33 | internal fun provideView(): CarTypeListView {
34 | return view
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/car_type_selector/car_type_list/di/CarTypeListScope.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.car_type_selector.car_type_list.di
2 |
3 | import javax.inject.Scope
4 |
5 | /**
6 | * Created by lev.novikov
7 | * Date: 25/12/17.
8 | */
9 |
10 | @Scope
11 | @Retention(AnnotationRetention.RUNTIME)
12 | annotation class CarTypeListScope
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/car_type_selector/di/CarTypeSelectorComponent.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.car_type_selector.di
2 |
3 | import android.view.LayoutInflater
4 | import com.levnovikov.postbus.root.home.HomeView
5 | import com.levnovikov.postbus.root.home.prebooking.car_type_selector.CarTypeSelectorInteractor
6 | import com.levnovikov.postbus.root.home.prebooking.car_type_selector.CarTypeSelectorNodeHolder
7 | import com.levnovikov.postbus.root.home.prebooking.car_type_selector.CarTypeSelectorRouter
8 | import com.levnovikov.postbus.root.home.prebooking.car_type_selector.car_type_list.CarTypeListNodeHolder
9 | import com.levnovikov.postbus.root.home.prebooking.car_type_selector.car_type_list.TypeListListener
10 | import com.levnovikov.postbus.root.home.prebooking.di.PrebookingComponent
11 | import com.levnovikov.system_base.base_di.ActivityComponent
12 | import dagger.Component
13 | import dagger.Module
14 | import dagger.Provides
15 |
16 | /**
17 | * Created by lev.novikov
18 | * Date: 23/12/17.
19 | */
20 |
21 | @CarTypeSelectorScope
22 | @Component(dependencies = [(PrebookingComponent::class)], modules = [(CarTypeSelectorComponent.CarTypeModule::class)])
23 | interface CarTypeSelectorComponent : ActivityComponent {
24 |
25 | fun router(): CarTypeSelectorRouter
26 |
27 | fun typeListListener(): TypeListListener
28 |
29 | fun inject(carTypeSelectorBuilder: CarTypeSelectorNodeHolder)
30 |
31 | @Module
32 | class CarTypeModule {
33 |
34 | @CarTypeSelectorScope
35 | @Provides
36 | internal fun provideTypeListListener(interactor: CarTypeSelectorInteractor): TypeListListener {
37 | return interactor
38 | }
39 |
40 | @CarTypeSelectorScope
41 | @Provides
42 | internal fun provideListBuilder(
43 | inflater: LayoutInflater,
44 | homeScreen: HomeView,
45 | parentComponent: CarTypeSelectorComponent): CarTypeListNodeHolder {
46 | return CarTypeListNodeHolder(inflater, homeScreen, parentComponent)
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/car_type_selector/di/CarTypeSelectorScope.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.car_type_selector.di
2 |
3 | import javax.inject.Scope
4 |
5 | /**
6 | * Created by lev.novikov
7 | * Date: 23/12/17.
8 | */
9 |
10 | @Scope
11 | @kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
12 | annotation class CarTypeSelectorScope
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/di/PrebookingScope.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.di
2 |
3 | import javax.inject.Scope
4 |
5 |
6 | /**
7 | * Author: lev.novikov
8 | * Date: 17/12/17.
9 | */
10 |
11 | @Scope
12 | @Retention(AnnotationRetention.RUNTIME)
13 | annotation class PrebookingScope
14 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/poi_selector/PoiSelectorInteractor.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.poi_selector
2 |
3 | import android.os.Parcelable
4 | import com.example.core_geo.Point
5 | import com.example.core_location.PoiSuggestionProvider
6 | import com.levnovikov.postbus.root.home.prebooking.poi_selector.di.PoiSelectorScope
7 | import com.levnovikov.system_base.BackStateInteractor
8 | import com.levnovikov.system_base.lifecycle.Lifecycle
9 | import com.levnovikov.system_base.node_state.ActivityState
10 | import io.reactivex.Observable
11 | import javax.inject.Inject
12 |
13 | /**
14 | * Created by lev.novikov
15 | * Date: 20/12/17.
16 | */
17 |
18 | @PoiSelectorScope
19 | class PoiSelectorInteractor @Inject
20 | constructor(
21 | private val poiProvider: PoiSuggestionProvider,
22 | private val presenter: Presenter,
23 | router: PoiSelectorRouter,
24 | activityState: ActivityState,
25 | private val listener: PoiSelectionListener,
26 | private val lifecycle: Lifecycle) : BackStateInteractor(router, activityState) {
27 | override fun onSaveData(): Parcelable? = null
28 |
29 | interface PoiSelectionListener {
30 | fun onPoiSelected(point: Point)
31 | fun onPoiSelectionCanceled()
32 | }
33 |
34 | override fun restoreState() {
35 | super.restoreState()
36 | lifecycle.subscribeUntilDestroy(presenter.placeTitleStream()
37 | .subscribe({ title -> poiProvider.updatePlace(title) }
38 | ) { /*handle error*/ error -> })
39 |
40 | lifecycle.subscribeUntilDestroy(poiProvider.poiStream
41 | .subscribe({ poiList -> presenter.updateSuggestions(poiList) }
42 | ) { /*handle error*/ error -> })
43 |
44 | lifecycle.subscribeUntilDestroy(presenter.selectedPoi()
45 | .subscribe({ point -> listener.onPoiSelected(point) }) { error -> })
46 | }
47 |
48 | override fun onBackPressed(): Boolean {
49 | listener.onPoiSelectionCanceled()
50 | return true
51 | }
52 |
53 | interface Presenter {
54 | fun selectedPoi(): Observable
55 | fun placeTitleStream(): Observable
56 | fun updateSuggestions(poiList: List)
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/poi_selector/PoiSelectorNodeHolder.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.poi_selector
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 |
6 | import com.levnovikov.postbus.R
7 | import com.levnovikov.postbus.root.home.prebooking.di.PrebookingComponent
8 | import com.levnovikov.postbus.root.home.prebooking.poi_selector.di.DaggerPoiSelectorComponent
9 | import com.levnovikov.postbus.root.home.prebooking.poi_selector.di.PoiSelectorComponent
10 | import com.levnovikov.system_base.ViewNodeHolder
11 |
12 | /**
13 | * Created by lev.novikov
14 | * Date: 20/12/17.
15 | */
16 |
17 | class PoiSelectorNodeHolder(inflater: LayoutInflater, parent: ViewGroup, private val parentComponent: PrebookingComponent) : ViewNodeHolder(inflater, parent) {
18 |
19 | override val layout: Int
20 | get() = R.layout.poi_selector
21 |
22 | override fun build(): PoiSelectorRouter {
23 | val view = buildView()
24 | val component = DaggerPoiSelectorComponent.builder()
25 | .prebookingComponent(parentComponent)
26 | .poiSelectorModule(PoiSelectorComponent.PoiSelectorModule(view))
27 | .build()
28 | component.inject(view)
29 | component.inject(this)
30 | attachView()
31 | return component.router()
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/poi_selector/PoiSelectorRouter.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.poi_selector
2 |
3 | import com.levnovikov.postbus.root.home.prebooking.poi_selector.di.PoiSelectorScope
4 | import com.levnovikov.system_base.NodeHolder
5 | import com.levnovikov.system_base.Router
6 | import com.levnovikov.system_base.node_state.NodeState
7 |
8 | import javax.inject.Inject
9 |
10 | /**
11 | * Created by lev.novikov
12 | * Date: 20/12/17.
13 | */
14 |
15 | @PoiSelectorScope
16 | class PoiSelectorRouter @Inject
17 | constructor() : Router() {
18 |
19 | override val holders: Set> = setOf()
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/poi_selector/di/PoiSelectorScope.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.poi_selector.di
2 |
3 | import javax.inject.Scope
4 |
5 | /**
6 | * Created by lev.novikov
7 | * Date: 20/12/17.
8 | */
9 |
10 | @Scope
11 | @Retention(AnnotationRetention.RUNTIME)
12 | annotation class PoiSelectorScope
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/poi_widget/PoiWidgetInteractor.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.poi_widget
2 |
3 | import com.example.core_geo.Point
4 | import com.levnovikov.feature_ride.ride.RidePrebookingRepo
5 | import com.levnovikov.postbus.root.home.prebooking.poi_widget.di.PoiWidgetScope
6 | import com.levnovikov.system_base.Interactor
7 | import com.levnovikov.system_base.node_state.ActivityState
8 | import io.reactivex.Observable
9 | import javax.inject.Inject
10 |
11 | /**
12 | * Author: lev.novikov
13 | * Date: 19/12/17.
14 | */
15 |
16 | @PoiWidgetScope
17 | class PoiWidgetInteractor @Inject
18 | constructor(
19 | private val poiSelectionListener: PoiClickListener,
20 | router: PoiWidgetRouter,
21 | activityState: ActivityState,
22 | private val prebookingRepo: RidePrebookingRepo) : Interactor(router, activityState) {
23 |
24 | interface PoiClickListener {
25 | fun onPickUpSelected()
26 | fun onDropOffSelected()
27 | }
28 |
29 | fun getPickupPointStream(): Observable {
30 | return prebookingRepo.pickupPoint.stream()
31 | }
32 |
33 | fun getDropOffPointStream(): Observable {
34 | return prebookingRepo.dropOffPoint.stream()
35 | }
36 |
37 | fun selectPickUp() {
38 | poiSelectionListener.onPickUpSelected()
39 | }
40 |
41 | fun selectDropOff() {
42 | poiSelectionListener.onDropOffSelected()
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/poi_widget/PoiWidgetNodeHolder.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.poi_widget
2 |
3 | import android.view.Gravity
4 | import android.view.LayoutInflater
5 | import android.view.ViewGroup
6 | import android.widget.FrameLayout
7 |
8 | import com.levnovikov.postbus.R
9 | import com.levnovikov.postbus.root.home.prebooking.di.PrebookingComponent
10 | import com.levnovikov.postbus.root.home.prebooking.poi_widget.di.DaggerPoiWidgetComponent
11 | import com.levnovikov.postbus.root.home.prebooking.poi_widget.di.PoiWidgetComponent
12 | import com.levnovikov.system_base.ViewNodeHolder
13 |
14 | /**
15 | * Author: lev.novikov
16 | * Date: 19/12/17.
17 | */
18 |
19 | class PoiWidgetNodeHolder(inflater: LayoutInflater, parent: ViewGroup, private val parentComponent: PrebookingComponent) : ViewNodeHolder(inflater, parent) {
20 |
21 | override val layout: Int
22 | get() = R.layout.poi_widget
23 |
24 | override fun build(): PoiWidgetRouter {
25 | val view = buildView()
26 | val params = view.layoutParams as FrameLayout.LayoutParams
27 | params.gravity = Gravity.BOTTOM
28 | view.layoutParams = params
29 |
30 | val component = DaggerPoiWidgetComponent.builder()
31 | .prebookingComponent(parentComponent)
32 | .poiWidgetModule(PoiWidgetComponent.PoiWidgetModule(view))
33 | .build()
34 | component.inject(this)
35 | component.inject(view)
36 | attachView()
37 | return component.router()
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/poi_widget/PoiWidgetRouter.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.poi_widget
2 |
3 | import com.levnovikov.postbus.root.home.prebooking.poi_widget.di.PoiWidgetScope
4 | import com.levnovikov.system_base.NodeHolder
5 | import com.levnovikov.system_base.Router
6 | import com.levnovikov.system_base.node_state.NodeState
7 |
8 | import javax.inject.Inject
9 |
10 | /**
11 | * Author: lev.novikov
12 | * Date: 19/12/17.
13 | */
14 |
15 | @PoiWidgetScope
16 | class PoiWidgetRouter @Inject
17 | constructor() : Router() {
18 |
19 | override val holders: Set> = setOf()
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/poi_widget/PoiWidgetVM.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.poi_widget
2 |
3 | import android.databinding.ObservableField
4 | import javax.inject.Inject
5 |
6 | /**
7 | * Author: lev.novikov
8 | * Date: 3/3/18.
9 | */
10 | class PoiWidgetVM @Inject constructor(
11 | private val interactor: PoiWidgetInteractor
12 | ) {
13 |
14 | val pickUpPoint = ObservableField("Select pick-up")
15 | val dropOffPoint = ObservableField("Select drop-off")
16 |
17 | init {
18 | interactor.getPickupPointStream()
19 | .subscribe({ (_, title) -> pickUpPoint.set(title) }) { /*handle*/ e -> }
20 |
21 | interactor.getDropOffPointStream()
22 | .subscribe({ (_, title) -> dropOffPoint.set(title) }) { /*handle*/ e -> }
23 |
24 | if (interactor.hasSavedState()) interactor.restoreState()
25 | }
26 |
27 | fun onPickupSelected() {
28 | interactor.selectPickUp()
29 | }
30 |
31 | fun onDropOffSelected() {
32 | interactor.selectDropOff()
33 | }
34 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/poi_widget/PoiWidgetView.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.poi_widget
2 |
3 | import android.content.Context
4 | import android.databinding.DataBindingUtil
5 | import android.util.AttributeSet
6 | import android.widget.LinearLayout
7 | import com.levnovikov.postbus.databinding.PoiWidgetBinding
8 | import javax.inject.Inject
9 |
10 | /**
11 | * Author: lev.novikov
12 | * Date: 19/12/17.
13 | */
14 |
15 | class PoiWidgetView @JvmOverloads constructor(
16 | context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
17 | ) : LinearLayout(context, attrs, defStyleAttr) {
18 |
19 | @Inject
20 | lateinit var vm: PoiWidgetVM
21 |
22 | override fun onAttachedToWindow() {
23 | super.onAttachedToWindow()
24 | setupBinding()
25 | }
26 |
27 | private fun setupBinding() {
28 | DataBindingUtil.bind(this).vm = vm
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/poi_widget/di/PoiWidgetComponent.java:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.poi_widget.di;
2 |
3 | import com.levnovikov.postbus.root.home.prebooking.di.PrebookingComponent;
4 | import com.levnovikov.postbus.root.home.prebooking.poi_widget.PoiWidgetNodeHolder;
5 | import com.levnovikov.postbus.root.home.prebooking.poi_widget.PoiWidgetRouter;
6 | import com.levnovikov.postbus.root.home.prebooking.poi_widget.PoiWidgetView;
7 | import com.levnovikov.system_base.base_di.ActivityComponent;
8 |
9 | import dagger.Component;
10 | import dagger.Module;
11 | import dagger.Provides;
12 |
13 | /**
14 | * Author: lev.novikov
15 | * Date: 19/12/17.
16 | */
17 |
18 | @PoiWidgetScope
19 | @Component(dependencies = PrebookingComponent.class, modules = PoiWidgetComponent.PoiWidgetModule.class)
20 | public interface PoiWidgetComponent extends ActivityComponent {
21 |
22 | void inject(PoiWidgetNodeHolder poiWidgetBuilder);
23 |
24 | PoiWidgetRouter router();
25 |
26 | void inject(PoiWidgetView view);
27 |
28 | @Module
29 | class PoiWidgetModule {
30 |
31 | private PoiWidgetView view;
32 |
33 | public PoiWidgetModule(PoiWidgetView view) {
34 | this.view = view;
35 | }
36 |
37 | @PoiWidgetScope
38 | @Provides
39 | PoiWidgetView provideView() {
40 | return view;
41 | }
42 |
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/main/java/com/levnovikov/postbus/root/home/prebooking/poi_widget/di/PoiWidgetScope.java:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus.root.home.prebooking.poi_widget.di;
2 |
3 | import java.lang.annotation.Retention;
4 | import java.lang.annotation.RetentionPolicy;
5 |
6 | import javax.inject.Scope;
7 |
8 | /**
9 | * Author: lev.novikov
10 | * Date: 19/12/17.
11 | */
12 |
13 | @Scope
14 | @Retention(RetentionPolicy.RUNTIME)
15 | public @interface PoiWidgetScope {
16 | }
17 |
--------------------------------------------------------------------------------
/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/ic_attach_money_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_directions_car_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_more_horiz_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_receipt_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_splash.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/alloc_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
14 |
15 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/booking_extra_widget.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
9 |
10 |
11 |
12 |
18 |
19 |
23 |
24 |
31 |
32 |
39 |
40 |
47 |
48 |
49 |
58 |
59 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/car_type_list_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/car_type_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
10 |
11 |
12 |
18 |
19 |
31 |
32 |
48 |
49 |
61 |
62 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/extra_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/home_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/options_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/poi_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/poi_selector_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
21 |
22 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/poi_widget.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
10 |
14 |
15 |
16 |
24 |
25 |
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/sub_options_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/template_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
10 |
11 |
12 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/test_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
13 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/wtf_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/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/LevNovikov92/Node-architecture-prototype/79d3328d11b95c193510552f729665ade74eb2e0/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LevNovikov92/Node-architecture-prototype/79d3328d11b95c193510552f729665ade74eb2e0/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LevNovikov92/Node-architecture-prototype/79d3328d11b95c193510552f729665ade74eb2e0/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LevNovikov92/Node-architecture-prototype/79d3328d11b95c193510552f729665ade74eb2e0/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LevNovikov92/Node-architecture-prototype/79d3328d11b95c193510552f729665ade74eb2e0/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LevNovikov92/Node-architecture-prototype/79d3328d11b95c193510552f729665ade74eb2e0/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LevNovikov92/Node-architecture-prototype/79d3328d11b95c193510552f729665ade74eb2e0/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LevNovikov92/Node-architecture-prototype/79d3328d11b95c193510552f729665ade74eb2e0/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LevNovikov92/Node-architecture-prototype/79d3328d11b95c193510552f729665ade74eb2e0/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LevNovikov92/Node-architecture-prototype/79d3328d11b95c193510552f729665ade74eb2e0/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | PostBus
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/com/levnovikov/postbus/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.levnovikov.postbus;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext.kotlin_version = '1.2.21'
5 | apply from: 'dependency.gradle'
6 |
7 | repositories {
8 | google()
9 | jcenter()
10 | }
11 | dependencies {
12 | classpath "com.android.tools.build:gradle:$gradlePluginVersion"
13 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
14 | }
15 |
16 | }
17 |
18 | allprojects {
19 | repositories {
20 | google()
21 | jcenter()
22 | }
23 | }
24 |
25 | ext {
26 | androidConfiguration = {
27 |
28 | compileSdkVersion androidCompileSdkVersion
29 | buildToolsVersion androidBuildToolsVersion
30 |
31 | defaultConfig {
32 |
33 | vectorDrawables.useSupportLibrary = true
34 |
35 | minSdkVersion androidMinSdkVersion
36 | targetSdkVersion androidTargetSdkVersion
37 |
38 | multiDexEnabled true
39 |
40 | resValue "string", "google_maps_key", (project.findProperty("GOOGLE_MAPS_API_KEY") ?: "")
41 | }
42 |
43 | compileOptions {
44 | sourceCompatibility JavaVersion.VERSION_1_8
45 | targetCompatibility JavaVersion.VERSION_1_8
46 | }
47 | }
48 | }
49 |
50 | task clean(type: Delete) {
51 | delete rootProject.buildDir
52 | }
53 |
--------------------------------------------------------------------------------
/core-auth/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/core-auth/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | apply plugin: 'kotlin-kapt'
5 |
6 | android androidConfiguration
7 |
8 | androidExtensions {
9 | experimental = true
10 | }
11 |
12 | dependencies {
13 | implementation libs.kotlin
14 | implementation libs.rxJava
15 | implementation libs.rxAndroid
16 | implementation libs.dagger
17 |
18 | //retrofit
19 | api (libs.retrofit){
20 | exclude group: 'com.squareup.okhttp3', module: 'okhttp'
21 | }
22 | implementation libs.retrofitRxjavaAdapter
23 | implementation libs.retrofitConverterGson
24 | implementation libs.okHttp
25 | implementation (libs.okhttpUrlconnection){
26 | exclude group: 'com.squareup.okhttp3', module: 'okhttp'
27 | }
28 | implementation libs.okhttpLoggingInterceptor
29 | }
30 |
31 | dependencies {
32 | kapt libs.daggerCompiler
33 | }
34 |
35 | dependencies {
36 | testImplementation testLibs.jUnit
37 | testImplementation testLibs.mockito
38 | testImplementation testLibs.mockito_inline
39 | testImplementation testLibs.mockitoKotlin
40 | testImplementation testLibs.mockWebServer
41 | }
42 |
--------------------------------------------------------------------------------
/core-auth/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 |
--------------------------------------------------------------------------------
/core-auth/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/core-auth/src/main/java/com/example/core_auth/di/AuthProviderModule.java:
--------------------------------------------------------------------------------
1 | package com.example.core_auth.di;
2 |
3 | import com.example.core_auth.provider.AuthProvider;
4 | import com.example.core_auth.provider.FacebookAuthProvider;
5 | import com.example.core_auth.provider.GoogleAuthProvider;
6 |
7 | import javax.inject.Named;
8 |
9 | import dagger.Module;
10 | import dagger.Provides;
11 |
12 | /**
13 | * Created by lev.novikov
14 | * Date: 25/11/17.
15 | */
16 |
17 | @Module
18 | public class AuthProviderModule {
19 |
20 | public static final String GOOGLE_AUTH_PROVIDER = "GOOGLE_AUTH_PROVIDER";
21 | public static final String FACEBOOK_AUTH_PROVIDER = "FACEBOOK_AUTH_PROVIDER";
22 |
23 | @Provides
24 | @Named(GOOGLE_AUTH_PROVIDER)
25 | AuthProvider provideGoogleAuthProvider() {
26 | return new GoogleAuthProvider();
27 | }
28 |
29 | @Provides
30 | @Named(FACEBOOK_AUTH_PROVIDER)
31 | AuthProvider provideFacebookAuthProvider() {
32 | return new FacebookAuthProvider();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/core-auth/src/main/java/com/example/core_auth/provider/AuthProvider.java:
--------------------------------------------------------------------------------
1 | package com.example.core_auth.provider;
2 |
3 | import io.reactivex.Single;
4 |
5 | /**
6 | * Created by lev.novikov
7 | * Date: 23/11/17.
8 | */
9 |
10 | public interface AuthProvider {
11 |
12 | class Info {
13 | public final String token;
14 | public final String providerId;
15 |
16 | public Info(String token, String providerId) {
17 | this.token = token;
18 | this.providerId = providerId;
19 | }
20 | }
21 |
22 | Single login();
23 | }
24 |
--------------------------------------------------------------------------------
/core-auth/src/main/java/com/example/core_auth/provider/FacebookAuthProvider.java:
--------------------------------------------------------------------------------
1 | package com.example.core_auth.provider;
2 |
3 | import io.reactivex.Single;
4 |
5 | /**
6 | * Created by lev.novikov
7 | * Date: 23/11/17.
8 | */
9 |
10 | public class FacebookAuthProvider implements AuthProvider {
11 |
12 | private final static String FB_PROVIDER_ID = "FB_PROVIDER_ID";
13 |
14 | @Override
15 | public Single login() {
16 | return Single.just(new Info("fb_token", FB_PROVIDER_ID));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/core-auth/src/main/java/com/example/core_auth/provider/GoogleAuthProvider.java:
--------------------------------------------------------------------------------
1 | package com.example.core_auth.provider;
2 |
3 | import io.reactivex.Single;
4 |
5 | /**
6 | * Created by lev.novikov
7 | * Date: 23/11/17.
8 | */
9 |
10 | public class GoogleAuthProvider implements AuthProvider {
11 |
12 | private final static String GOOGLE_PROVIDER_ID = "GOOGLE_PROVIDER_ID";
13 |
14 | @Override
15 | public Single login() {
16 | return Single.just(new Info("google_token", GOOGLE_PROVIDER_ID));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/core-auth/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | feature-car-animation
3 |
4 |
--------------------------------------------------------------------------------
/core-auth/src/test/java/com/example/core_auth/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.example.core_auth;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/core-booking/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/core-booking/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | apply plugin: 'kotlin-kapt'
5 |
6 | android androidConfiguration
7 |
8 | androidExtensions {
9 | experimental = true
10 | }
11 |
12 | dependencies {
13 | implementation libs.kotlin
14 | implementation libs.rxJava
15 | implementation libs.rxAndroid
16 | implementation libs.dagger
17 | }
18 |
19 | dependencies {
20 | kapt libs.daggerCompiler
21 | }
22 |
23 | dependencies {
24 | testImplementation testLibs.jUnit
25 | testImplementation testLibs.mockito
26 | testImplementation testLibs.mockito_inline
27 | testImplementation testLibs.mockitoKotlin
28 | }
29 |
30 | dependencies {
31 | implementation project(path: ':core-geo')
32 | }
--------------------------------------------------------------------------------
/core-booking/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 |
--------------------------------------------------------------------------------
/core-booking/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/core-booking/src/main/java/com/example/core_booking/PrebookingRepo.java:
--------------------------------------------------------------------------------
1 | package com.example.core_booking;
2 |
3 | /**
4 | * Created by lev.novikov
5 | * Date: 18/12/17.
6 | */
7 |
8 | public abstract class PrebookingRepo {
9 |
10 | protected abstract Data getData();
11 | }
12 |
--------------------------------------------------------------------------------
/core-booking/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | core-booking
3 |
4 |
--------------------------------------------------------------------------------
/core-booking/src/test/java/com/example/core_booking/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.example.core_booking;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/core-geo/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/core-geo/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | apply plugin: 'kotlin-kapt'
5 |
6 | android androidConfiguration
7 |
8 | androidExtensions {
9 | experimental = true
10 | }
11 |
12 | dependencies {
13 | implementation libs.kotlin
14 | implementation libs.rxJava
15 | implementation libs.rxAndroid
16 | implementation libs.dagger
17 | }
18 |
19 | dependencies {
20 | kapt libs.daggerCompiler
21 | }
22 |
23 | dependencies {
24 | testImplementation testLibs.jUnit
25 | testImplementation testLibs.mockito
26 | testImplementation testLibs.mockito_inline
27 | testImplementation testLibs.mockitoKotlin
28 | }
29 |
30 | dependencies {
31 | testImplementation 'junit:junit:4.12'
32 | }
33 |
--------------------------------------------------------------------------------
/core-geo/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 |
--------------------------------------------------------------------------------
/core-geo/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/core-geo/src/main/java/com/example/core_geo/Coordinates.kt:
--------------------------------------------------------------------------------
1 | package com.example.core_geo
2 |
3 | import android.annotation.SuppressLint
4 | import android.os.Parcelable
5 | import kotlinx.android.parcel.Parcelize
6 |
7 | /**
8 | * Created by lev.novikov
9 | * Date: 20/12/17.
10 | */
11 |
12 | @SuppressLint("ParcelCreator")
13 | @Parcelize
14 | data class Coordinates(val x: Double, val y: Double) : Parcelable
15 |
--------------------------------------------------------------------------------
/core-geo/src/main/java/com/example/core_geo/Point.kt:
--------------------------------------------------------------------------------
1 | package com.example.core_geo
2 |
3 | import android.annotation.SuppressLint
4 | import android.os.Parcelable
5 | import kotlinx.android.parcel.Parcelize
6 |
7 | /**
8 | * Created by lev.novikov
9 | * Date: 18/12/17.
10 | */
11 |
12 | @SuppressLint("ParcelCreator")
13 | @Parcelize
14 | data class Point(val coordinates: Coordinates, val title: String) : Parcelable
--------------------------------------------------------------------------------
/core-geo/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | core-geo
3 |
4 |
--------------------------------------------------------------------------------
/core-geo/src/test/java/com/example/core_geo/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.example.core_geo;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/core-location/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/core-location/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | apply plugin: 'kotlin-kapt'
5 |
6 | android androidConfiguration
7 |
8 | androidExtensions {
9 | experimental = true
10 | }
11 |
12 | dependencies {
13 | implementation libs.kotlin
14 | implementation libs.rxJava
15 | implementation libs.rxAndroid
16 | implementation libs.dagger
17 | }
18 |
19 | dependencies {
20 | kapt libs.daggerCompiler
21 | }
22 |
23 | dependencies {
24 | testImplementation testLibs.jUnit
25 | testImplementation testLibs.mockito
26 | testImplementation testLibs.mockito_inline
27 | testImplementation testLibs.mockitoKotlin
28 | }
29 |
30 | dependencies {
31 | implementation project(path: ':core-geo')
32 | }
--------------------------------------------------------------------------------
/core-location/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 |
--------------------------------------------------------------------------------
/core-location/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/core-location/src/main/java/com/example/core_location/PoiSuggestionProvider.java:
--------------------------------------------------------------------------------
1 | package com.example.core_location;
2 |
3 | import com.example.core_geo.Point;
4 |
5 | import java.util.List;
6 |
7 | import io.reactivex.Observable;
8 |
9 | /**
10 | * Created by lev.novikov
11 | * Date: 20/12/17.
12 | */
13 |
14 | public interface PoiSuggestionProvider {
15 |
16 | Observable> getPoiStream();
17 |
18 | void updatePlace(String placeName);
19 | }
20 |
--------------------------------------------------------------------------------
/core-location/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | core-location
3 |
4 |
--------------------------------------------------------------------------------
/core-location/src/test/java/com/example/core_location/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.example.core_location;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/core-profile/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/core-profile/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | apply plugin: 'kotlin-kapt'
5 |
6 | android androidConfiguration
7 |
8 | androidExtensions {
9 | experimental = true
10 | }
11 |
12 | dependencies {
13 | implementation libs.kotlin
14 | implementation libs.rxJava
15 | implementation libs.rxAndroid
16 | implementation libs.dagger
17 | }
18 |
19 | dependencies {
20 | kapt libs.daggerCompiler
21 | }
22 |
23 | dependencies {
24 | testImplementation testLibs.jUnit
25 | testImplementation testLibs.mockito
26 | testImplementation testLibs.mockito_inline
27 | testImplementation testLibs.mockitoKotlin
28 | }
29 |
--------------------------------------------------------------------------------
/core-profile/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 |
--------------------------------------------------------------------------------
/core-profile/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/core-profile/src/main/java/com/levnovikov/core_profile/UserRepository.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.core_profile
2 |
3 | import com.levnovikov.core_profile.model.UserProfile
4 |
5 | import io.reactivex.Single
6 |
7 | /**
8 | * Author: lev.novikov
9 | * Date: 20/11/17.
10 | */
11 |
12 | interface UserRepository {
13 |
14 | val isUserLoggedIn: Single
15 |
16 | fun updateUserProfile(): Single
17 | }
18 |
--------------------------------------------------------------------------------
/core-profile/src/main/java/com/levnovikov/core_profile/di/ProfileComponent.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.core_profile.di
2 |
3 | import dagger.Component
4 |
5 |
6 | /**
7 | * Created by lev.novikov
8 | * Date: 21/11/17.
9 | */
10 |
11 | @Component(modules = [(ProfileModule::class)])
12 | interface ProfileComponent
13 |
--------------------------------------------------------------------------------
/core-profile/src/main/java/com/levnovikov/core_profile/di/ProfileModule.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.core_profile.di
2 |
3 | import com.levnovikov.core_profile.UserRepository
4 | import com.levnovikov.core_profile.di.stubs.UserRepoStub
5 |
6 | import dagger.Module
7 | import dagger.Provides
8 |
9 | /**
10 | * Created by lev.novikov
11 | * Date: 21/11/17.
12 | */
13 | @Module
14 | class ProfileModule {
15 |
16 | @Provides
17 | internal fun provideUserRepo(): UserRepository {
18 | return UserRepoStub()
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/core-profile/src/main/java/com/levnovikov/core_profile/di/stubs/UserRepoStub.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.core_profile.di.stubs
2 |
3 | import com.levnovikov.core_profile.UserRepository
4 | import com.levnovikov.core_profile.model.UserProfile
5 |
6 | import io.reactivex.Single
7 |
8 | /**
9 | * Created by lev.novikov
10 | * Date: 21/11/17.
11 | */
12 |
13 | class UserRepoStub : UserRepository {
14 | override val isUserLoggedIn: Single
15 | get() = Single.just(true)
16 |
17 | override fun updateUserProfile(): Single {
18 | return Single.just(UserProfile(1, "John", "Doe")).map({ profile ->
19 | Thread.sleep(2000)
20 | profile
21 | })
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/core-profile/src/main/java/com/levnovikov/core_profile/model/UserProfile.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.core_profile.model
2 |
3 | /**
4 | * Created by lev.novikov
5 | * Date: 21/11/17.
6 | */
7 |
8 | data class UserProfile(val id: Int, val name: String, val surname: String)
--------------------------------------------------------------------------------
/core-profile/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | core-profile
3 |
4 |
--------------------------------------------------------------------------------
/feature-auth/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/feature-auth/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | apply plugin: 'kotlin-kapt'
5 |
6 | android androidConfiguration
7 |
8 | androidExtensions {
9 | experimental = true
10 | }
11 |
12 | dependencies {
13 | implementation libs.kotlin
14 | implementation libs.rxJava
15 | implementation libs.rxAndroid
16 | implementation libs.dagger
17 | implementation libs.constraintLayout
18 | implementation libs.recyclerView
19 | implementation libs.appcompatV7
20 | }
21 |
22 | dependencies {
23 | kapt libs.daggerCompiler
24 | }
25 |
26 | dependencies {
27 | testImplementation testLibs.jUnit
28 | testImplementation testLibs.mockito
29 | testImplementation testLibs.mockito_inline
30 | testImplementation testLibs.mockitoKotlin
31 | }
32 |
33 | dependencies {
34 | implementation project(path: ':system-base')
35 | implementation project(path: ':core-auth')
36 | }
37 |
--------------------------------------------------------------------------------
/feature-auth/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 |
--------------------------------------------------------------------------------
/feature-auth/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/feature-auth/src/main/java/com/levnovikov/feature_auth/AuthInteractor.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_auth
2 |
3 | import com.levnovikov.feature_auth.di.AuthScope
4 | import com.levnovikov.system_base.Interactor
5 | import com.levnovikov.system_base.node_state.ActivityState
6 |
7 | import javax.inject.Inject
8 |
9 | /**
10 | * Created by lev.novikov
11 | * Date: 29/1/18.
12 | */
13 |
14 | @AuthScope
15 | class AuthInteractor @Inject
16 | constructor(router: AuthRouter, activityState: ActivityState) : Interactor(router, activityState) {
17 |
18 | override fun onGetActive() {
19 | super.onGetActive()
20 |
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/feature-auth/src/main/java/com/levnovikov/feature_auth/AuthNodeHolder.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_auth
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 |
6 | import com.levnovikov.feature_auth.dependency.AuthDependency
7 | import com.levnovikov.feature_auth.di.AuthComponent
8 | import com.levnovikov.feature_auth.di.DaggerAuthComponent
9 | import com.levnovikov.system_base.ViewNodeHolder
10 |
11 | /**
12 | * Created by lev.novikov
13 | * Date: 29/1/18.
14 | */
15 |
16 | class AuthNodeHolder(inflater: LayoutInflater, parent: ViewGroup, private val authDependency: AuthDependency) : ViewNodeHolder(inflater, parent) {
17 |
18 | override val layout: Int
19 | get() = R.layout.auth_view
20 |
21 | override fun build(): AuthRouter {
22 | val view = buildView()
23 | val component = DaggerAuthComponent.builder()
24 | .authDependency(authDependency)
25 | .authModule(AuthComponent.AuthModule(view))
26 | .build()
27 | component.inject(this)
28 | component.inject(view)
29 | attachView()
30 | return component.router()
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/feature-auth/src/main/java/com/levnovikov/feature_auth/AuthRouter.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_auth
2 |
3 | import com.levnovikov.feature_auth.di.AuthScope
4 | import com.levnovikov.system_base.Router
5 | import com.levnovikov.system_base.node_state.NodeState
6 |
7 | import javax.inject.Inject
8 |
9 | /**
10 | * Created by lev.novikov
11 | * Date: 29/1/18.
12 | */
13 |
14 | @AuthScope
15 | class AuthRouter @Inject
16 | constructor() : Router() {
17 |
18 | override val holders: Set> = setOf()
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/feature-auth/src/main/java/com/levnovikov/feature_auth/AuthView.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_auth
2 |
3 | import android.content.Context
4 | import android.support.constraint.ConstraintLayout
5 | import android.util.AttributeSet
6 |
7 | import com.levnovikov.feature_auth.view_model.AuthActions
8 | import com.levnovikov.feature_auth.view_model.AuthViewModel
9 |
10 | import javax.inject.Inject
11 |
12 | /**
13 | * Created by lev.novikov
14 | * Date: 29/1/18.
15 | */
16 |
17 | class AuthView : ConstraintLayout {
18 |
19 | @Inject
20 | lateinit var vmActions: AuthActions
21 |
22 | @Inject
23 | lateinit var vm: AuthViewModel
24 |
25 | constructor(context: Context) : super(context)
26 |
27 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
28 |
29 | constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
30 |
31 | override fun onAttachedToWindow() {
32 | super.onAttachedToWindow()
33 | vmActions.onGetActive()
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/feature-auth/src/main/java/com/levnovikov/feature_auth/dependency/AuthDependency.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_auth.dependency
2 |
3 | import com.levnovikov.system_base.base_di.ActivityComponent
4 |
5 | /**
6 | * Created by lev.novikov
7 | * Date: 29/1/18.
8 | */
9 |
10 | interface AuthDependency : ActivityComponent
11 |
--------------------------------------------------------------------------------
/feature-auth/src/main/java/com/levnovikov/feature_auth/di/AuthComponent.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_auth.di
2 |
3 | import com.levnovikov.feature_auth.AuthNodeHolder
4 | import com.levnovikov.feature_auth.AuthRouter
5 | import com.levnovikov.feature_auth.AuthView
6 | import com.levnovikov.feature_auth.dependency.AuthDependency
7 | import com.levnovikov.feature_auth.view_model.AuthActions
8 | import com.levnovikov.feature_auth.view_model.AuthViewModel
9 | import com.levnovikov.feature_auth.view_model.AuthViewModelImpl
10 | import com.levnovikov.system_base.base_di.ActivityComponent
11 |
12 | import dagger.Binds
13 | import dagger.Component
14 | import dagger.Module
15 |
16 | /**
17 | * Created by lev.novikov
18 | * Date: 29/1/18.
19 | */
20 |
21 | @AuthScope
22 | @Component(dependencies = [(AuthDependency::class)], modules = [(AuthComponent.AuthModule::class)])
23 | interface AuthComponent : ActivityComponent {
24 |
25 | fun inject(view: AuthView)
26 |
27 | fun router(): AuthRouter
28 |
29 | @Module(includes = [(AuthModule.AuthBinders::class)])
30 | class AuthModule(private val view: AuthView) {
31 |
32 | @Module
33 | interface AuthBinders {
34 | @Binds
35 | fun bindViewModel(impl: AuthViewModelImpl): AuthViewModel
36 |
37 | @Binds
38 | fun bindViewModelActions(impl: AuthViewModelImpl): AuthActions
39 | }
40 | }
41 |
42 | fun inject(view: AuthNodeHolder)
43 | }
44 |
--------------------------------------------------------------------------------
/feature-auth/src/main/java/com/levnovikov/feature_auth/di/AuthScope.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_auth.di
2 |
3 | import javax.inject.Scope
4 |
5 | /**
6 | * Created by lev.novikov
7 | * Date: 29/1/18.
8 | */
9 |
10 | @Retention(AnnotationRetention.RUNTIME)
11 | @Scope
12 | annotation class AuthScope
13 |
--------------------------------------------------------------------------------
/feature-auth/src/main/java/com/levnovikov/feature_auth/view_model/AuthActions.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_auth.view_model
2 |
3 | /**
4 | * Author: lev.novikov
5 | * Date: 29/1/18.
6 | */
7 |
8 | interface AuthActions {
9 | fun onGetActive()
10 | }
11 |
--------------------------------------------------------------------------------
/feature-auth/src/main/java/com/levnovikov/feature_auth/view_model/AuthViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_auth.view_model
2 |
3 | /**
4 | * Author: lev.novikov
5 | * Date: 29/1/18.
6 | */
7 |
8 | interface AuthViewModel
9 |
--------------------------------------------------------------------------------
/feature-auth/src/main/java/com/levnovikov/feature_auth/view_model/AuthViewModelImpl.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_auth.view_model
2 |
3 | import com.levnovikov.feature_auth.di.AuthScope
4 |
5 | import javax.inject.Inject
6 |
7 | /**
8 | * Created by lev.novikov
9 | * Date: 29/1/18.
10 | */
11 |
12 | @AuthScope
13 | class AuthViewModelImpl @Inject
14 | internal constructor() : AuthActions, AuthViewModel {
15 |
16 | override fun onGetActive() {
17 |
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/feature-auth/src/main/res/layout/auth_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/feature-auth/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | feature-auth
3 |
4 |
--------------------------------------------------------------------------------
/feature-map/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/feature-map/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | apply plugin: 'kotlin-kapt'
5 |
6 | android androidConfiguration
7 |
8 | androidExtensions {
9 | experimental = true
10 | }
11 |
12 | dependencies {
13 | implementation libs.kotlin
14 | implementation libs.rxJava
15 | implementation libs.rxAndroid
16 | implementation libs.dagger
17 | implementation libs.map
18 | }
19 |
20 | dependencies {
21 | kapt libs.daggerCompiler
22 | }
23 |
24 | dependencies {
25 | testImplementation testLibs.jUnit
26 | testImplementation testLibs.mockito
27 | testImplementation testLibs.mockito_inline
28 | testImplementation testLibs.mockitoKotlin
29 | }
30 |
31 | dependencies {
32 | implementation project(path: ':system-base')
33 | implementation project(path: ':core-geo')
34 | }
35 |
--------------------------------------------------------------------------------
/feature-map/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 |
--------------------------------------------------------------------------------
/feature-map/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/feature-map/src/main/java/com/levnovikov/feature_map/MapInteractor.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_map
2 |
3 | import com.google.android.gms.maps.GoogleMap
4 | import com.google.android.gms.maps.OnMapReadyCallback
5 | import com.levnovikov.feature_map.dependency.MapSetter
6 | import com.levnovikov.feature_map.di.MapScope
7 | import com.levnovikov.system_base.Interactor
8 | import com.levnovikov.system_base.node_state.ActivityState
9 | import javax.inject.Inject
10 |
11 | /**
12 | * Author: lev.novikov
13 | * Date: 2/1/18.
14 | */
15 |
16 | @MapScope
17 | class MapInteractor @Inject constructor(
18 | router: MapRouter,
19 | activityState: ActivityState,
20 | private val mapSetter: MapSetter) : Interactor(router, activityState), OnMapReadyCallback {
21 |
22 | init {
23 | restoreState()
24 | }
25 |
26 | override fun onMapReady(googleMap: GoogleMap) {
27 | mapSetter.setMap(googleMap)
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/feature-map/src/main/java/com/levnovikov/feature_map/MapNodeHolder.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_map
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 |
6 | import com.levnovikov.feature_map.dependency.MapDependency
7 | import com.levnovikov.feature_map.di.DaggerMapComponent
8 | import com.levnovikov.feature_map.di.MapComponent
9 | import com.levnovikov.system_base.ViewNodeHolder
10 |
11 | /**
12 | * Author: lev.novikov
13 | * Date: 2/1/18.
14 | */
15 |
16 | class MapNodeHolder(inflater: LayoutInflater, parent: ViewGroup, private val parentComponent: MapDependency) : ViewNodeHolder(inflater, parent) {
17 |
18 | override val layout: Int
19 | get() = R.layout.map_view
20 |
21 | override fun build(): MapRouter {
22 | val view = buildView()
23 | val component = DaggerMapComponent
24 | .builder()
25 | .mapDependency(parentComponent)
26 | .mapModule(MapComponent.MapModule(view))
27 | .build()
28 | component.inject(view)
29 | component.inject(this)
30 | attachView()
31 | return component.router()
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/feature-map/src/main/java/com/levnovikov/feature_map/MapRouter.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_map
2 |
3 | import com.levnovikov.feature_map.di.MapScope
4 | import com.levnovikov.system_base.NodeHolder
5 | import com.levnovikov.system_base.Router
6 | import com.levnovikov.system_base.node_state.NodeState
7 |
8 | import javax.inject.Inject
9 |
10 | /**
11 | * Author: lev.novikov
12 | * Date: 2/1/18.
13 | */
14 |
15 | @MapScope
16 | class MapRouter @Inject constructor() : Router() {
17 |
18 | override val holders: Set> = setOf()
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/feature-map/src/main/java/com/levnovikov/feature_map/MapView.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_map
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 | import com.levnovikov.feature_map.lifecycle.MapLifecycleEvent
6 | import com.levnovikov.feature_map.lifecycle.MapLifecycleListener
7 | import io.reactivex.Observable
8 | import javax.inject.Inject
9 |
10 | /**
11 | * Author: lev.novikov
12 | * Date: 2/1/18.
13 | */
14 |
15 | class MapView : com.google.android.gms.maps.MapView, MapLifecycleListener {
16 |
17 | @Inject
18 | lateinit var interactor: MapInteractor
19 |
20 | @Inject
21 | lateinit var mapLifecycleStream: Observable
22 |
23 | constructor(context: Context) : super(context) {}
24 |
25 | constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {}
26 |
27 | constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {}
28 |
29 | override fun onAttachedToWindow() {
30 | super.onAttachedToWindow()
31 | interactor.restoreState()
32 | initMap()
33 | }
34 |
35 | private fun initMap() {
36 | getMapAsync(interactor)
37 | mapLifecycleStream //TODO unsubscribe
38 | .subscribe({ event ->
39 | when (event) {
40 | MapLifecycleEvent.CREATE -> onCreate(event.bundle)
41 | MapLifecycleEvent.RESUME -> onResume()
42 | MapLifecycleEvent.PAUSE -> onPause()
43 | MapLifecycleEvent.DESTROY -> onDestroy()
44 | }
45 | }) { e -> }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/feature-map/src/main/java/com/levnovikov/feature_map/dependency/MapDependency.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_map.dependency
2 |
3 | import com.levnovikov.feature_map.lifecycle.MapLifecycleEvent
4 | import com.levnovikov.system_base.base_di.ActivityComponent
5 |
6 | import io.reactivex.Observable
7 |
8 | /**
9 | * Author: lev.novikov
10 | * Date: 6/1/18.
11 | */
12 |
13 | interface MapDependency : ActivityComponent {
14 | fun mapLifecycle(): Observable
15 | fun mapSetter(): MapSetter
16 | }
17 |
--------------------------------------------------------------------------------
/feature-map/src/main/java/com/levnovikov/feature_map/dependency/MapProvider.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_map.dependency
2 |
3 | import com.google.android.gms.maps.GoogleMap
4 |
5 | import io.reactivex.Maybe
6 |
7 | /**
8 | * Author: lev.novikov
9 | * Date: 27/1/18.
10 | */
11 |
12 | interface MapProvider {
13 | val map: Maybe
14 | }
15 |
--------------------------------------------------------------------------------
/feature-map/src/main/java/com/levnovikov/feature_map/dependency/MapSetter.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_map.dependency
2 |
3 | import com.google.android.gms.maps.GoogleMap
4 |
5 | /**
6 | * Author: lev.novikov
7 | * Date: 27/1/18.
8 | */
9 |
10 | interface MapSetter {
11 | fun setMap(map: GoogleMap)
12 | }
13 |
--------------------------------------------------------------------------------
/feature-map/src/main/java/com/levnovikov/feature_map/di/MapComponent.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_map.di
2 |
3 | import com.levnovikov.feature_map.MapNodeHolder
4 | import com.levnovikov.feature_map.MapRouter
5 | import com.levnovikov.feature_map.MapView
6 | import com.levnovikov.feature_map.dependency.MapDependency
7 |
8 | import dagger.Component
9 | import dagger.Module
10 | import dagger.Provides
11 |
12 | /**
13 | * Author: lev.novikov
14 | * Date: 2/1/18.
15 | */
16 |
17 | @MapScope
18 | @Component(dependencies = [(MapDependency::class)], modules = [(MapComponent.MapModule::class)])
19 | interface MapComponent {
20 |
21 | fun router(): MapRouter
22 |
23 | fun inject(view: MapView)
24 |
25 | @Module
26 | class MapModule(private val view: MapView) {
27 |
28 | @MapScope
29 | @Provides
30 | internal fun provideView(): MapView {
31 | return view
32 | }
33 | }
34 |
35 | fun inject(view: MapNodeHolder)
36 | }
37 |
--------------------------------------------------------------------------------
/feature-map/src/main/java/com/levnovikov/feature_map/di/MapScope.java:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_map.di;
2 |
3 | import java.lang.annotation.Retention;
4 | import java.lang.annotation.RetentionPolicy;
5 |
6 | import javax.inject.Scope;
7 |
8 | /**
9 | * Author: lev.novikov
10 | * Date: 2/1/18.
11 | */
12 |
13 | @Scope
14 | @Retention(RetentionPolicy.RUNTIME)
15 | public @interface MapScope {
16 | }
17 |
--------------------------------------------------------------------------------
/feature-map/src/main/java/com/levnovikov/feature_map/lifecycle/MapLifecycleEvent.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_map.lifecycle
2 |
3 | import android.os.Bundle
4 |
5 | /**
6 | * Author: lev.novikov
7 | * Date: 2/1/18.
8 | */
9 |
10 | enum class MapLifecycleEvent constructor(val bundle: Bundle?) {
11 | CREATE(Bundle()), //TODO refactor it
12 | RESUME(null),
13 | PAUSE(null),
14 | DESTROY(null),
15 | ON_SAVE_INSTANCE(null),
16 | ON_LOW_MEMORY(null)
17 | }
18 |
--------------------------------------------------------------------------------
/feature-map/src/main/java/com/levnovikov/feature_map/lifecycle/MapLifecycleListener.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_map.lifecycle
2 |
3 | import android.os.Bundle
4 |
5 | /**
6 | * Author: lev.novikov
7 | * Date: 2/1/18.
8 | */
9 |
10 | interface MapLifecycleListener {
11 | fun onCreate(bundle: Bundle)
12 |
13 | //TODO add all lifecycle methods
14 | }
15 |
--------------------------------------------------------------------------------
/feature-map/src/main/java/com/levnovikov/feature_map/map_wrapper/MapInterface.java:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_map.map_wrapper;
2 |
3 | import com.example.core_geo.Point;
4 |
5 | /**
6 | * Author: lev.novikov
7 | * Date: 3/1/18.
8 | */
9 |
10 | public interface MapInterface {
11 |
12 | void setPickUp(Point point);
13 | void setDropOff(Point point);
14 | void clear();
15 | }
16 |
--------------------------------------------------------------------------------
/feature-map/src/main/java/com/levnovikov/feature_map/map_wrapper/MapWrapper.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_map.map_wrapper
2 |
3 | import com.example.core_geo.Point
4 | import com.google.android.gms.maps.CameraUpdateFactory
5 | import com.google.android.gms.maps.GoogleMap
6 | import com.google.android.gms.maps.model.LatLng
7 | import com.google.android.gms.maps.model.Marker
8 | import com.google.android.gms.maps.model.MarkerOptions
9 |
10 | /**
11 | * Author: lev.novikov
12 | * Date: 3/1/18.
13 | */
14 |
15 | class MapWrapper(private val map: GoogleMap //TODO remove link onDestroy
16 | ) : MapInterface {
17 |
18 | private var pickUpMarker: Marker? = null
19 |
20 | private var dropOffMarker: Marker? = null
21 |
22 | override fun setPickUp(point: Point) {
23 | pickUpMarker = setMarker(point)
24 | }
25 |
26 | override fun setDropOff(point: Point) {
27 | dropOffMarker = setMarker(point)
28 | }
29 |
30 | private fun setMarker(point: Point): Marker {
31 | val coordinates = LatLng(
32 | point.coordinates.x,
33 | point.coordinates.y)
34 | map.moveCamera(CameraUpdateFactory.newLatLngZoom(coordinates, 6f))
35 | return map.addMarker(
36 | MarkerOptions()
37 | .position(coordinates)
38 | .title(point.title))
39 | }
40 |
41 | override fun clear() {
42 | if (pickUpMarker != null) {
43 | pickUpMarker!!.remove()
44 | pickUpMarker = null
45 | }
46 |
47 | if (dropOffMarker != null) {
48 | dropOffMarker!!.remove()
49 | dropOffMarker = null
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/feature-map/src/main/res/layout/map_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
--------------------------------------------------------------------------------
/feature-map/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | feature-map
3 |
4 |
--------------------------------------------------------------------------------
/feature-promo/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/feature-promo/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | apply plugin: 'kotlin-kapt'
5 |
6 | android androidConfiguration
7 |
8 | androidExtensions {
9 | experimental = true
10 | }
11 |
12 | dependencies {
13 | implementation libs.kotlin
14 | implementation libs.rxJava
15 | implementation libs.rxAndroid
16 | implementation libs.dagger
17 | implementation libs.constraintLayout
18 | implementation libs.recyclerView
19 | implementation libs.appcompatV7
20 | }
21 |
22 | dependencies {
23 | kapt libs.daggerCompiler
24 | }
25 |
26 | dependencies {
27 | testImplementation testLibs.jUnit
28 | testImplementation testLibs.mockito
29 | testImplementation testLibs.mockito_inline
30 | testImplementation testLibs.mockitoKotlin
31 | }
32 |
33 | dependencies {
34 | implementation project(path: ':system-base')
35 | implementation project(path: ':core-auth')
36 | }
37 |
--------------------------------------------------------------------------------
/feature-promo/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 |
--------------------------------------------------------------------------------
/feature-promo/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/feature-promo/src/main/java/com/levnovikov/feature_promo/domain/Promo.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_promo.domain
2 |
3 | /**
4 | * Author: lev.novikov
5 | * Date: 4/1/18.
6 | */
7 |
8 | data class Promo(val title: String, val priceOff: Int)
9 |
--------------------------------------------------------------------------------
/feature-promo/src/main/java/com/levnovikov/feature_promo/promo_list/PromoListInteractor.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_promo.promo_list
2 |
3 | import android.os.Parcelable
4 | import com.levnovikov.feature_promo.domain.Promo
5 | import com.levnovikov.feature_promo.promo_list.dependency.OnPromoSelectedListener
6 | import com.levnovikov.feature_promo.promo_list.di.PromoListScope
7 | import com.levnovikov.system_base.BackStateInteractor
8 | import com.levnovikov.system_base.node_state.ActivityState
9 | import java.util.*
10 | import javax.inject.Inject
11 |
12 | /**
13 | * Author: lev.novikov
14 | * Date: 4/1/18.
15 | */
16 |
17 | @PromoListScope
18 | class PromoListInteractor @Inject constructor(
19 | router: PromoListRouter,
20 | activityState: ActivityState,
21 | private val presenter: PromoListPresenter,
22 | private val listener: OnPromoSelectedListener) : BackStateInteractor(router, activityState) {
23 |
24 | private//Hardcoded data
25 | val promoList: List
26 | get() {
27 | val promoList = ArrayList()
28 | for (i in 0..4) {
29 | promoList.add(Promo("Promo", i + 1))
30 | }
31 | return promoList
32 | }
33 |
34 | override fun restoreState() {
35 | super.restoreState()
36 | presenter.setData(promoList)
37 | }
38 |
39 | override fun onBackPressed(): Boolean {
40 | listener.onCancel()
41 | return true
42 | }
43 |
44 | override fun onSaveData(): Parcelable? = null
45 | }
46 |
--------------------------------------------------------------------------------
/feature-promo/src/main/java/com/levnovikov/feature_promo/promo_list/PromoListNodeHolder.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_promo.promo_list
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 |
6 | import com.levnovikov.feature_promo.R
7 | import com.levnovikov.feature_promo.promo_list.dependency.PromoListDependency
8 | import com.levnovikov.feature_promo.promo_list.di.DaggerPromoListComponent
9 | import com.levnovikov.feature_promo.promo_list.di.PromoListComponent
10 | import com.levnovikov.system_base.ViewNodeHolder
11 |
12 | /**
13 | * Author: lev.novikov
14 | * Date: 4/1/18.
15 | */
16 |
17 | class PromoListNodeHolder(inflater: LayoutInflater, parent: ViewGroup, private val parentComponent: PromoListDependency) : ViewNodeHolder(inflater, parent) {
18 |
19 | override val layout: Int
20 | get() = R.layout.promo_list_view
21 |
22 | override fun build(): PromoListRouter {
23 | val view = buildView()
24 | val component = DaggerPromoListComponent.builder()
25 | .promoListDependency(parentComponent)
26 | .promoListModule(PromoListComponent.PromoListModule(view))
27 | .build()
28 | component.inject(this) //TODO check that called in every node
29 | component.inject(view)
30 | attachView()
31 | return component.router()
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/feature-promo/src/main/java/com/levnovikov/feature_promo/promo_list/PromoListPresenter.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_promo.promo_list
2 |
3 | import com.levnovikov.feature_promo.domain.Promo
4 |
5 | /**
6 | * Author: lev.novikov
7 | * Date: 4/1/18.
8 | */
9 |
10 | interface PromoListPresenter {
11 |
12 | fun setData(promoList: List)
13 | }
14 |
--------------------------------------------------------------------------------
/feature-promo/src/main/java/com/levnovikov/feature_promo/promo_list/PromoListRouter.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_promo.promo_list
2 |
3 | import com.levnovikov.feature_promo.promo_list.di.PromoListScope
4 | import com.levnovikov.system_base.NodeHolder
5 | import com.levnovikov.system_base.Router
6 | import com.levnovikov.system_base.node_state.NodeState
7 |
8 | import javax.inject.Inject
9 |
10 | /**
11 | * Author: lev.novikov
12 | * Date: 4/1/18.
13 | */
14 |
15 | @PromoListScope
16 | class PromoListRouter @Inject constructor() : Router() {
17 |
18 | override val holders: Set> = emptySet()
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/feature-promo/src/main/java/com/levnovikov/feature_promo/promo_list/dependency/OnPromoSelectedListener.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_promo.promo_list.dependency
2 |
3 | import com.levnovikov.feature_promo.domain.Promo
4 |
5 | /**
6 | * Author: lev.novikov
7 | * Date: 4/1/18.
8 | */
9 |
10 | interface OnPromoSelectedListener {
11 |
12 | fun onPromoSelected(promo: Promo)
13 |
14 | fun onCancel()
15 | }
16 |
--------------------------------------------------------------------------------
/feature-promo/src/main/java/com/levnovikov/feature_promo/promo_list/dependency/PromoListDependency.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_promo.promo_list.dependency
2 |
3 | import com.levnovikov.system_base.base_di.ActivityComponent
4 |
5 | /**
6 | * Author: lev.novikov
7 | * Date: 4/1/18.
8 | */
9 |
10 | interface PromoListDependency : ActivityComponent {
11 |
12 | fun onPromoSelectedListener(): OnPromoSelectedListener
13 | }
14 |
--------------------------------------------------------------------------------
/feature-promo/src/main/java/com/levnovikov/feature_promo/promo_list/di/PromoListComponent.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_promo.promo_list.di
2 |
3 | import com.levnovikov.feature_promo.promo_list.PromoListNodeHolder
4 | import com.levnovikov.feature_promo.promo_list.PromoListPresenter
5 | import com.levnovikov.feature_promo.promo_list.PromoListRouter
6 | import com.levnovikov.feature_promo.promo_list.PromoListView
7 | import com.levnovikov.feature_promo.promo_list.dependency.PromoListDependency
8 |
9 | import dagger.Component
10 | import dagger.Module
11 | import dagger.Provides
12 |
13 | /**
14 | * Author: lev.novikov
15 | * Date: 4/1/18.
16 | */
17 |
18 | @PromoListScope
19 | @Component(dependencies = [(PromoListDependency::class)], modules = [(PromoListComponent.PromoListModule::class)])
20 | interface PromoListComponent {
21 |
22 | fun inject(view: PromoListView)
23 |
24 | fun router(): PromoListRouter
25 |
26 | fun inject(promoListBuilder: PromoListNodeHolder)
27 |
28 | @Module
29 | class PromoListModule(private val view: PromoListView) {
30 |
31 | @Provides
32 | @PromoListScope
33 | internal fun provideView(): PromoListView {
34 | return view
35 | }
36 |
37 | @Provides
38 | @PromoListScope
39 | internal fun providePresenter(): PromoListPresenter {
40 | return view
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/feature-promo/src/main/java/com/levnovikov/feature_promo/promo_list/di/PromoListScope.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_promo.promo_list.di
2 |
3 | import javax.inject.Scope
4 |
5 | /**
6 | * Author: lev.novikov
7 | * Date: 4/1/18.
8 | */
9 |
10 | @Scope
11 | @Retention(AnnotationRetention.RUNTIME)
12 | annotation class PromoListScope
13 |
--------------------------------------------------------------------------------
/feature-promo/src/main/res/layout/promo_list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
17 |
--------------------------------------------------------------------------------
/feature-promo/src/main/res/layout/promo_list_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
--------------------------------------------------------------------------------
/feature-promo/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | feature-promo
3 |
4 |
--------------------------------------------------------------------------------
/feature-ride/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/feature-ride/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | apply plugin: 'kotlin-kapt'
5 |
6 | android androidConfiguration
7 |
8 | androidExtensions {
9 | experimental = true
10 | }
11 |
12 | dependencies {
13 | implementation libs.kotlin
14 | implementation libs.rxJava
15 | implementation libs.rxAndroid
16 | implementation libs.dagger
17 | implementation libs.constraintLayout
18 | implementation libs.appcompatV7
19 | implementation libs.map
20 | }
21 |
22 | dependencies {
23 | kapt libs.daggerCompiler
24 | }
25 |
26 | dependencies {
27 | testImplementation testLibs.jUnit
28 | testImplementation testLibs.mockito
29 | testImplementation testLibs.mockito_inline
30 | testImplementation testLibs.mockitoKotlin
31 | }
32 |
33 | dependencies {
34 | implementation project(path: ':system-base')
35 | implementation project(path: ':core-auth')
36 | implementation project(path: ':core-booking')
37 | implementation project(path: ':core-geo')
38 | }
39 |
--------------------------------------------------------------------------------
/feature-ride/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 |
--------------------------------------------------------------------------------
/feature-ride/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/feature-ride/src/main/java/com/levnovikov/feature_ride/ride/BehaviorField.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_ride.ride
2 |
3 | import io.reactivex.Observable
4 | import io.reactivex.subjects.BehaviorSubject
5 |
6 | /**
7 | * Created by lev.novikov
8 | * Date: 19/12/17.
9 | */
10 |
11 | abstract class BehaviorField {
12 |
13 | private val field = BehaviorSubject.create()
14 | fun stream(): Observable = field.distinctUntilChanged()
15 |
16 | fun set(entity: T) {
17 | save(entity)
18 | field.onNext(entity)
19 | }
20 |
21 | internal abstract fun save(entity: T)
22 | }
23 |
--------------------------------------------------------------------------------
/feature-ride/src/main/java/com/levnovikov/feature_ride/ride/RidePrebookingData.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_ride.ride
2 |
3 |
4 | import android.annotation.SuppressLint
5 | import android.os.Parcelable
6 | import com.example.core_geo.Point
7 | import kotlinx.android.parcel.Parcelize
8 |
9 | /**
10 | * Created by lev.novikov
11 | * Date: 18/12/17.
12 | */
13 |
14 | @SuppressLint("ParcelCreator")
15 | @Parcelize
16 | data class RidePrebookingData(
17 | val carType: Int,
18 | val promoCode: String,
19 | val pickUpPoint: Point?,
20 | val dropOffPoint: Point?) : Parcelable
--------------------------------------------------------------------------------
/feature-ride/src/main/java/com/levnovikov/feature_ride/ride/RidePrebookingRepo.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_ride.ride
2 |
3 | import com.example.core_booking.PrebookingRepo
4 | import com.example.core_geo.Point
5 |
6 | /**
7 | * Created by lev.novikov
8 | * Date: 18/12/17.
9 | */
10 |
11 | class RidePrebookingRepo(private var data: RidePrebookingData) : PrebookingRepo() {
12 |
13 | var pickupPoint: BehaviorField = object : BehaviorField() {
14 | internal override fun save(entity: Point) {
15 | data = data.copy(pickUpPoint = entity)
16 | }
17 | }
18 |
19 | var dropOffPoint: BehaviorField = object : BehaviorField() {
20 | internal override fun save(entity: Point) {
21 | data = data.copy(dropOffPoint = entity)
22 | }
23 | }
24 |
25 | var carType: BehaviorField = object : BehaviorField() {
26 | internal override fun save(entity: Int) {
27 | data = data.copy(carType = entity)
28 | }
29 | }
30 |
31 | var promo: BehaviorField = object : BehaviorField() {
32 | internal override fun save(entity: String) {
33 | data = data.copy(promoCode = entity)
34 | }
35 | }
36 |
37 | public override fun getData(): RidePrebookingData {
38 | return data.copy()
39 | }
40 |
41 | fun setData(data: RidePrebookingData) {
42 | this.data = data
43 | data.pickUpPoint?.let { pickupPoint.set(it) }
44 | data.dropOffPoint?.let { dropOffPoint.set(it) }
45 | carType.set(data.carType)
46 | promo.set(data.promoCode)
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/feature-ride/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | feature-ride
3 |
4 |
--------------------------------------------------------------------------------
/feature-ride/src/test/java/com/levnovikov/feature_ride/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.levnovikov.feature_ride;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/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:decouspled_projects
17 | # org.gradle.parallel=true
18 | GOOGLE_MAPS_API_KEY=AIzaSyD3-dSaUprVpb3LmJLjGXY_aGqEaztOpEc
19 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LevNovikov92/Node-architecture-prototype/79d3328d11b95c193510552f729665ade74eb2e0/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Nov 20 21:02:20 SGT 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.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', ':system-base', ':core-profile', ':core-auth', ':stream-state', ':core-booking', ':feature-ride', ':core-location', ':core-geo', ':feature-promo', ':feature-map'
2 |
--------------------------------------------------------------------------------
/stream-state/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/stream-state/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | apply plugin: 'kotlin-kapt'
5 |
6 | android androidConfiguration
7 |
8 | androidExtensions {
9 | experimental = true
10 | }
11 |
12 | dependencies {
13 | implementation libs.kotlin
14 | implementation libs.rxJava
15 | implementation libs.rxAndroid
16 | implementation libs.dagger
17 | }
18 |
19 | dependencies {
20 | kapt libs.daggerCompiler
21 | }
22 |
23 | dependencies {
24 | testImplementation testLibs.jUnit
25 | testImplementation testLibs.mockito
26 | testImplementation testLibs.mockito_inline
27 | testImplementation testLibs.mockitoKotlin
28 | }
--------------------------------------------------------------------------------
/stream-state/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 |
--------------------------------------------------------------------------------
/stream-state/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/stream-state/src/main/java/com/levnovikov/stream_state/AppState.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.stream_state
2 |
3 | /**
4 | * Author: lev.novikov
5 | * Date: 14/12/17.
6 | */
7 |
8 | enum class AppState {
9 | PREBOOKING,
10 | ALLOCATING,
11 | TRACKING
12 | }
13 |
--------------------------------------------------------------------------------
/stream-state/src/main/java/com/levnovikov/stream_state/AppStateStreamProvider.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.stream_state
2 |
3 | import io.reactivex.Observable
4 | import io.reactivex.subjects.BehaviorSubject
5 | import javax.inject.Inject
6 |
7 | /**
8 | * Author: lev.novikov
9 | * Date: 14/12/17.
10 | */
11 |
12 | class AppStateStreamProvider @Inject
13 | constructor() {
14 |
15 | private val appStateSubject = BehaviorSubject.createDefault(AppState.PREBOOKING)
16 | fun provideAppStateStream(): Observable {
17 | return appStateSubject.distinctUntilChanged() //TODO stub
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/stream-state/src/main/java/com/levnovikov/stream_state/PrebookingState.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.stream_state
2 |
3 | /**
4 | * Created by lev.novikov
5 | * Date: 18/12/17.
6 | */
7 |
8 | enum class PrebookingState {
9 | INITIAL,
10 | PICK_UP_SELECTION,
11 | DROP_OFF_SELECTION,
12 | SET_SERVICE_TYPE,
13 | APPLY_PROMO
14 | }
15 |
--------------------------------------------------------------------------------
/stream-state/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | stream-state
3 |
4 |
--------------------------------------------------------------------------------
/system-base/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/system-base/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | apply plugin: 'kotlin-kapt'
5 |
6 | android androidConfiguration
7 |
8 | androidExtensions {
9 | experimental = true
10 | }
11 |
12 | android {
13 | dataBinding {
14 | enabled = true
15 | }
16 | }
17 |
18 | dependencies {
19 | implementation libs.kotlin
20 | implementation libs.rxJava
21 | implementation libs.rxAndroid
22 | implementation libs.dagger
23 | implementation libs.appcompatV7
24 | implementation libs.timber
25 | }
26 |
27 | dependencies {
28 | kapt libs.daggerCompiler
29 | kapt aptLibs.databinding
30 | }
31 |
32 | dependencies {
33 | testImplementation testLibs.jUnit
34 | testImplementation testLibs.mockito
35 | testImplementation testLibs.mockito_inline
36 | testImplementation testLibs.mockitoKotlin
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/system-base/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 |
--------------------------------------------------------------------------------
/system-base/readme-structure/Node architecture - communiacation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LevNovikov92/Node-architecture-prototype/79d3328d11b95c193510552f729665ade74eb2e0/system-base/readme-structure/Node architecture - communiacation.png
--------------------------------------------------------------------------------
/system-base/readme-structure/Node architecture - node structure.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LevNovikov92/Node-architecture-prototype/79d3328d11b95c193510552f729665ade74eb2e0/system-base/readme-structure/Node architecture - node structure.png
--------------------------------------------------------------------------------
/system-base/readme-structure/Node architecture overview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LevNovikov92/Node-architecture-prototype/79d3328d11b95c193510552f729665ade74eb2e0/system-base/readme-structure/Node architecture overview.png
--------------------------------------------------------------------------------
/system-base/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/system-base/src/main/java/com/levnovikov/system_base/BackStateInteractor.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.system_base
2 |
3 | /**
4 | * Author: lev.novikov
5 | * Date: 6/1/18.
6 | */
7 |
8 | import com.levnovikov.system_base.back_handling.BackHandler
9 | import com.levnovikov.system_base.node_state.ActivityState
10 |
11 | abstract class BackStateInteractor(
12 | router: R, activityState: ActivityState
13 | ) : StateInteractor(router, activityState), BackHandler {
14 |
15 | init {
16 | /*
17 | * If interactor need to handle onBackPressed
18 | */
19 | @Suppress("LeakingThis")
20 | router.setBackHandler(this)
21 | activityState.addToBackStack(router.javaClass)
22 | }
23 |
24 | override fun isLastInBackStack(_class: Class): Boolean {
25 | return activityState.isLastInBackStack(_class)
26 | }
27 |
28 | override fun popLastInBackStack() {
29 | activityState.popLastInBackStack()
30 | }
31 |
32 | override fun removeFromBackStack(_class: Class) {
33 | activityState.removeFromBackStack(_class)
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/system-base/src/main/java/com/levnovikov/system_base/BindingNodeHolder.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.system_base
2 |
3 | import android.databinding.DataBindingUtil
4 | import android.databinding.ViewDataBinding
5 | import android.util.Log
6 | import android.view.LayoutInflater
7 | import android.view.View
8 | import android.view.ViewGroup
9 | import com.levnovikov.system_base.exceptions.ViewIsAlreadyAttachedException
10 |
11 | /**
12 | * Created by lev.novikov
13 | * Date: 30/11/17.
14 | */
15 |
16 | abstract class BindingNodeHolder(
17 | private val inflater: LayoutInflater,
18 | protected val parent: ViewGroup
19 | ) : NodeHolder() {
20 |
21 | private var view: View? = null
22 |
23 | abstract val layout: Int
24 |
25 | private fun destroyView() {
26 | if (view != null) {
27 | parent.removeView(view)
28 | view = null
29 | }
30 | }
31 |
32 | override fun destroy() {
33 | super.destroy()
34 | destroyView()
35 | }
36 |
37 | @Suppress("UNCHECKED_CAST")
38 | private fun buildView(): View {
39 | if (view != null) {
40 | throw ViewIsAlreadyAttachedException(this)
41 | }
42 | Log.i(">>>>", "buildView " + this.javaClass.simpleName)
43 | val v = inflater.inflate(layout, parent, false)
44 | view = v
45 | return v
46 | }
47 |
48 | private fun setupDataBinding(v: View, vm: Any, brId: Int) {
49 | val binding: B = DataBindingUtil.bind(v)
50 | binding.setVariable(brId, vm)
51 | }
52 |
53 | private fun attachView(vm: Any, brId: Int) {
54 | Log.i(">>>>", "attachView " + this.javaClass.simpleName)
55 | view?.let { setupDataBinding(it, vm, brId) }
56 | parent.addView(view)
57 | }
58 |
59 | protected fun buildAndAttachView(vm: Any, brId: Int) {
60 | buildView()
61 | attachView(vm, brId)
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/system-base/src/main/java/com/levnovikov/system_base/Interactor.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.system_base
2 |
3 | import android.os.Parcelable
4 |
5 | import com.levnovikov.system_base.node_state.ActivityState
6 | import com.levnovikov.system_base.node_state.NodeState
7 |
8 | abstract class Interactor(
9 | protected var router: R,
10 | protected var activityState: ActivityState) {
11 |
12 | protected val nodeState: NodeState? = activityState.findNodeState(router.javaClass)
13 |
14 | protected val nodeStateData: Parcelable? = nodeState?.data
15 |
16 | open fun restoreState() {
17 | nodeState?.let { router.setState(it) }
18 | }
19 |
20 | fun hasSavedState(): Boolean {
21 | return activityState.findNodeState(router.javaClass) != null
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/system-base/src/main/java/com/levnovikov/system_base/NodeHolder.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.system_base
2 |
3 | import android.util.Log
4 |
5 | import javax.inject.Inject
6 |
7 | /**
8 | * Author: lev.novikov
9 | * Date: 17/12/17.
10 | *
11 | * NodeHolder
12 | */
13 |
14 | abstract class NodeHolder {
15 |
16 | @JvmField
17 | @Inject
18 | internal var router: R? = null
19 |
20 | internal fun isActive(): Boolean = router != null
21 |
22 | abstract fun build(): R
23 |
24 | open fun destroy() {
25 | Log.i(">>>>", "destroy " + this.javaClass.simpleName)
26 | router?.run {
27 | detachAllChildren()
28 | removeFromBackStack()
29 | this.setBackHandler(null)
30 | router = null
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/system-base/src/main/java/com/levnovikov/system_base/StateDataProvider.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.system_base
2 |
3 | import android.os.Parcelable
4 |
5 | /**
6 | * Created by lev.novikov
7 | * Date: 29/12/17.
8 | */
9 |
10 | interface StateDataProvider {
11 | fun onSaveData(): Parcelable?
12 | }
13 |
--------------------------------------------------------------------------------
/system-base/src/main/java/com/levnovikov/system_base/StateInteractor.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.system_base
2 |
3 | import com.levnovikov.system_base.node_state.ActivityState
4 |
5 | abstract class StateInteractor(router: R, activityState: ActivityState) : Interactor(router, activityState), StateDataProvider {
6 |
7 | init {
8 | /*
9 | * If interactor need to store data after Activity recreation, we can set data source to router.
10 | * Router will get and save data when Activity will call onSaveInstanceState.
11 | */
12 | @Suppress("LeakingThis")
13 | router.setStateDataProvider(this)
14 | }
15 |
16 | override fun restoreState() {
17 | val state = nodeState
18 | if (state != null) {
19 | router.setState(state)
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/system-base/src/main/java/com/levnovikov/system_base/ViewNodeHolder.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.system_base
2 |
3 | import android.util.Log
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import com.levnovikov.system_base.exceptions.ViewIsAlreadyAttachedException
8 |
9 | /**
10 | * Created by lev.novikov
11 | * Date: 30/11/17.
12 | */
13 |
14 | abstract class ViewNodeHolder(
15 | private val inflater: LayoutInflater,
16 | protected val parent: ViewGroup
17 | ) : NodeHolder() {
18 |
19 | private var view: V? = null
20 |
21 | abstract val layout: Int
22 |
23 | private fun destroyView() {
24 | if (view != null) {
25 | parent.removeView(view)
26 | view = null
27 | }
28 | }
29 |
30 | override fun destroy() {
31 | super.destroy()
32 | destroyView()
33 | }
34 |
35 | @Suppress("UNCHECKED_CAST")
36 | protected fun buildView(): V {
37 | if (view != null) {
38 | throw ViewIsAlreadyAttachedException(this)
39 | }
40 | Log.i(">>>>", "buildView " + this.javaClass.simpleName)
41 | val v = inflater.inflate(layout, parent, false) as V
42 | view = v
43 | return v
44 | }
45 |
46 | protected fun attachView() {
47 | Log.i(">>>>", "attachView " + this.javaClass.simpleName)
48 | parent.addView(view)
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/system-base/src/main/java/com/levnovikov/system_base/back_handling/BackHandler.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.system_base.back_handling
2 |
3 | import com.levnovikov.system_base.Router
4 |
5 | /**
6 | * Created by lev.novikov
7 | * Date: 1/1/18.
8 | */
9 |
10 | internal interface BackHandler {
11 | fun onBackPressed(): Boolean
12 | fun isLastInBackStack(_class: Class): Boolean
13 | fun popLastInBackStack()
14 | fun removeFromBackStack(_class: Class)
15 | }
16 |
--------------------------------------------------------------------------------
/system-base/src/main/java/com/levnovikov/system_base/base_di/ActivityComponent.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.system_base.base_di
2 |
3 | import android.content.Context
4 |
5 | import com.levnovikov.system_base.lifecycle.Lifecycle
6 | import com.levnovikov.system_base.node_state.ActivityState
7 |
8 | /**
9 | * Created by lev.novikov
10 | * Date: 29/12/17.
11 | */
12 |
13 | interface ActivityComponent {
14 | fun activityState(): ActivityState
15 | fun lifecycle(): Lifecycle
16 | fun activity(): Context
17 | }
18 |
--------------------------------------------------------------------------------
/system-base/src/main/java/com/levnovikov/system_base/base_di/ComponentBuilder.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.system_base.base_di
2 |
3 | /**
4 | * Created by lev.novikov
5 | * Date: 2/12/17.
6 | */
7 |
8 | interface ComponentBuilder
9 |
--------------------------------------------------------------------------------
/system-base/src/main/java/com/levnovikov/system_base/base_di/ComponentKey.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.system_base.base_di
2 |
3 | import dagger.MapKey
4 | import kotlin.reflect.KClass
5 |
6 | /**
7 | * Created by lev.novikov
8 | * Date: 2/12/17.
9 | */
10 |
11 | @MapKey
12 | @Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
13 | @Retention(AnnotationRetention.RUNTIME)
14 | annotation class ComponentKey(val value: KClass)
15 |
--------------------------------------------------------------------------------
/system-base/src/main/java/com/levnovikov/system_base/base_di/SubComponentProvider.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.system_base.base_di
2 |
3 | /**
4 | * Created by lev.novikov
5 | * Date: 2/12/17.
6 | */
7 |
8 | interface SubComponentProvider {
9 | fun provide(key: Class): ComponentBuilder
10 | }
11 |
--------------------------------------------------------------------------------
/system-base/src/main/java/com/levnovikov/system_base/exceptions/RouterAlreadyAttachedException.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.system_base.exceptions
2 |
3 | import com.levnovikov.system_base.Router
4 |
5 | /**
6 | * Author: lev.novikov
7 | * Date: 3/3/18.
8 | */
9 | class RouterAlreadyAttachedException(private val router: Router) : Exception() {
10 |
11 | override val message: String?
12 | get() = "Router ${router.javaClass.simpleName} is already attached"
13 | }
--------------------------------------------------------------------------------
/system-base/src/main/java/com/levnovikov/system_base/exceptions/ViewIsAlreadyAttachedException.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.system_base.exceptions
2 |
3 | import com.levnovikov.system_base.NodeHolder
4 |
5 | /**
6 | * Author: lev.novikov
7 | * Date: 3/3/18.
8 | */
9 | class ViewIsAlreadyAttachedException(private val nodeHolder: NodeHolder<*>) : Exception() {
10 |
11 | override val message: String?
12 | get() = "ViewNodeHolder ${nodeHolder.javaClass.simpleName} is already attached"
13 | }
--------------------------------------------------------------------------------
/system-base/src/main/java/com/levnovikov/system_base/lifecycle/Lifecycle.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.system_base.lifecycle
2 |
3 | import io.reactivex.disposables.Disposable
4 |
5 | /**
6 | * Author: lev.novikov
7 | * Date: 2/1/18.
8 | */
9 |
10 | interface Lifecycle {
11 |
12 | fun subscribeUntil(event: LifecycleEvent, disposable: Disposable)
13 |
14 | fun subscribeUntilDestroy(disposable: Disposable)
15 | }
16 |
--------------------------------------------------------------------------------
/system-base/src/main/java/com/levnovikov/system_base/lifecycle/LifecycleActivity.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.system_base.lifecycle
2 |
3 | import android.os.Bundle
4 | import android.os.PersistableBundle
5 | import android.support.v7.app.AppCompatActivity
6 | import io.reactivex.disposables.CompositeDisposable
7 | import io.reactivex.disposables.Disposable
8 | import io.reactivex.subjects.BehaviorSubject
9 | import java.util.*
10 |
11 | /**
12 | * Author: lev.novikov
13 | * Date: 7/1/18.
14 | */
15 |
16 | open class LifecycleActivity : AppCompatActivity(), Lifecycle {
17 |
18 | private val lifecycleStream = BehaviorSubject.create()
19 | private val disposableMap = HashMap()
20 |
21 | override fun subscribeUntil(event: LifecycleEvent, disposable: Disposable) {
22 | val compositeDisposable = disposableMap[event]
23 | if (compositeDisposable != null) {
24 | disposableMap[event] = CompositeDisposable()
25 | }
26 |
27 | disposableMap[event]?.add(disposable)
28 | }
29 |
30 | override fun subscribeUntilDestroy(disposable: Disposable) {
31 | val compositeDisposable = disposableMap[LifecycleEvent.DESTROY]
32 | if (compositeDisposable == null) {
33 | disposableMap[LifecycleEvent.DESTROY] = CompositeDisposable()
34 | }
35 |
36 | disposableMap[LifecycleEvent.DESTROY]?.add(disposable)
37 | }
38 |
39 | override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
40 | super.onCreate(savedInstanceState, persistentState)
41 | lifecycleStream.onNext(LifecycleEvent.CREATE)
42 | }
43 |
44 | override fun onStart() {
45 | super.onStart()
46 | lifecycleStream.onNext(LifecycleEvent.START)
47 | dispose(LifecycleEvent.START)
48 | }
49 |
50 | override fun onResume() {
51 | super.onResume()
52 | lifecycleStream.onNext(LifecycleEvent.RESUME)
53 | dispose(LifecycleEvent.RESUME)
54 | }
55 |
56 | override fun onPause() {
57 | super.onPause()
58 | lifecycleStream.onNext(LifecycleEvent.PAUSE)
59 | dispose(LifecycleEvent.PAUSE)
60 | }
61 |
62 | override fun onStop() {
63 | super.onStop()
64 | lifecycleStream.onNext(LifecycleEvent.STOP)
65 | dispose(LifecycleEvent.STOP)
66 | }
67 |
68 | override fun onDestroy() {
69 | lifecycleStream.onNext(LifecycleEvent.DESTROY)
70 | dispose(LifecycleEvent.DESTROY)
71 | super.onDestroy()
72 | }
73 |
74 | private fun dispose(event: LifecycleEvent) {
75 | val disposable = disposableMap[event]
76 | if (disposable != null) {
77 | disposable.dispose()
78 | disposableMap.remove(event)
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/system-base/src/main/java/com/levnovikov/system_base/lifecycle/LifecycleEvent.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.system_base.lifecycle
2 |
3 | /**
4 | * Author: lev.novikov
5 | * Date: 2/1/18.
6 | */
7 |
8 | enum class LifecycleEvent {
9 | CREATE,
10 | START,
11 | RESUME,
12 | PAUSE,
13 | STOP,
14 | DESTROY
15 | }
16 |
--------------------------------------------------------------------------------
/system-base/src/main/java/com/levnovikov/system_base/node_state/ActivityState.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.system_base.node_state
2 |
3 | import android.annotation.SuppressLint
4 | import android.os.Parcelable
5 | import com.levnovikov.system_base.Router
6 | import kotlinx.android.parcel.Parcelize
7 | import java.util.*
8 |
9 | /**
10 | * Created by lev.novikov
11 | * Date: 29/12/17.
12 | */
13 |
14 | @SuppressLint("ParcelCreator")
15 | @Parcelize
16 | data class ActivityState(
17 | private val backStack: Stack = Stack(),
18 | private val stateMap: Map = mapOf()) : Parcelable {
19 |
20 |
21 | fun findNodeState(routerClass: Class): NodeState? = stateMap[routerClass.simpleName]
22 |
23 | fun addToBackStack(_class: Class) = backStack.add(_class.simpleName) //TODO replace to canonical name after testing
24 |
25 | fun isLastInBackStack(_class: Class): Boolean =
26 | !backStack.isEmpty() && backStack.peek() == _class.simpleName //TODO replace to canonical name after testing
27 |
28 | fun popLastInBackStack() {
29 | backStack.pop()
30 | }
31 |
32 | fun removeFromBackStack(_class: Class) {
33 | backStack.remove(_class.simpleName) //TODO replace to canonical name after testing
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/system-base/src/main/java/com/levnovikov/system_base/node_state/NodeState.kt:
--------------------------------------------------------------------------------
1 | package com.levnovikov.system_base.node_state
2 |
3 | import android.annotation.SuppressLint
4 | import android.os.Parcelable
5 | import kotlinx.android.parcel.Parcelize
6 |
7 | /**
8 | * Created by lev.novikov
9 | * Date: 27/12/17.
10 | */
11 |
12 | @SuppressLint("ParcelCreator")
13 | @Parcelize
14 | data class NodeState(
15 | val data: Parcelable?,
16 | private val activeNodes: Set = emptySet()) : Parcelable {
17 |
18 | fun contains(_class: Class<*>): Boolean {
19 | return activeNodes.contains(_class.simpleName) //TODO change to canonical after testing
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/system-base/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | system-base
3 |
4 |
--------------------------------------------------------------------------------
/system-base/src/test/java/com/example/system_base/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.example.system_base;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/template/NewNode_MVP/globals.xml.ftl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/template/NewNode_MVP/recipe.xml.ftl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/template/NewNode_MVP/root/res/layout/fragment_blank.xml.ftl:
--------------------------------------------------------------------------------
1 |
2 | <${packageName}.${className}View xmlns:android="http://schemas.android.com/apk/res/android"
3 | xmlns:tools="http://schemas.android.com/tools"
4 | android:layout_width="match_parent"
5 | android:layout_height="match_parent">
6 |
7 |
8 |
9 | ${packageName}.${className}View>
10 |
--------------------------------------------------------------------------------
/template/NewNode_MVP/template.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
14 |
15 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/template/NewNode_MVVM/globals.xml.ftl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/template/NewNode_MVVM/recipe.xml.ftl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/template/NewNode_MVVM/root/res/layout/fragment_blank.xml.ftl:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
10 |
11 |
12 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/template/NewNode_MVVM/template.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
14 |
15 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/template/NewNode_MVVM_custom_view/globals.xml.ftl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/template/NewNode_MVVM_custom_view/recipe.xml.ftl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/template/NewNode_MVVM_custom_view/root/res/layout/fragment_blank.xml.ftl:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
10 |
11 |
12 | <${packageName}.${className}View
13 | android:layout_width="match_parent"
14 | android:layout_height="match_parent">
15 |
16 |
17 |
18 | ${packageName}.${className}View>
19 |
--------------------------------------------------------------------------------
/template/NewNode_MVVM_custom_view/template.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
14 |
15 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/template/README.MD:
--------------------------------------------------------------------------------
1 | ### New Node template v1.0
2 |
3 | Run sync_templates.sh to update templates
4 |
5 | or
6 |
7 | Pls copy `NewNode` folder to `/Applications/Android Studio.app/Contents/plugins/android/lib/templates/other/`
--------------------------------------------------------------------------------
/template/sync_templates.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | find . -mindepth 1 -maxdepth 1 -type d | while read line; do
3 | cp -R "$line" /Applications/Android\ Studio.app/Contents/plugins/android/lib/templates/other
4 | done
5 |
--------------------------------------------------------------------------------