diff --git a/.gitignore b/.gitignore index aa724b7..1bc29aa 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ /.idea/workspace.xml /.idea/navEditor.xml /.idea/assetWizardSettings.xml +/.idea .DS_Store /build /captures diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 26d3352..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/.idea/.name b/.idea/.name deleted file mode 100644 index 3a3df10..0000000 --- a/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -Ribs-Demo-Android \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index 61a9130..0000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml deleted file mode 100644 index fd81426..0000000 --- a/.idea/gradle.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index d5d35ec..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 56aa021..c149ca6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,7 +8,7 @@ android { compileSdk 32 defaultConfig { - applicationId "com.example.ribs_demo_android" + applicationId "com.solacestudios.ribs_demo_android" minSdk 23 targetSdk 32 versionCode 1 @@ -61,15 +61,14 @@ dependencies { def retrofit_version = "2.9.0" implementation "com.squareup.retrofit2:retrofit:$retrofit_version" implementation "com.squareup.retrofit2:converter-gson:$retrofit_version" + implementation "com.squareup.retrofit2:adapter-rxjava3:$retrofit_version" + + implementation 'com.jakewharton.rxbinding4:rxbinding-core:4.0.0' def glide_version = "4.11.0" implementation "com.github.bumptech.glide:glide:$glide_version" kapt "com.github.bumptech.glide:compiler:$glide_version" - implementation 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0' - implementation 'io.reactivex.rxjava2:rxandroid:2.1.0' - implementation 'io.reactivex.rxjava2:rxjava:2.2.4' - testImplementation 'junit:junit:4.12' testImplementation "org.mockito:mockito-core:3.10.0" testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0" @@ -77,4 +76,6 @@ dependencies { testImplementation "com.google.testing.compile:compile-testing:0.17" //testImplementation "org.mockito:mockito-all:1.10.19" testImplementation 'org.mockito:mockito-inline:2.13.0' + + implementation 'com.squareup.okhttp3:logging-interceptor:4.2.1' } \ No newline at end of file diff --git a/app/src/androidTest/java/com/example/ribs_demo_android/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/solacestudios/ribs_demo_android/ExampleInstrumentedTest.kt similarity index 81% rename from app/src/androidTest/java/com/example/ribs_demo_android/ExampleInstrumentedTest.kt rename to app/src/androidTest/java/com/solacestudios/ribs_demo_android/ExampleInstrumentedTest.kt index 255d0b0..945ec7b 100644 --- a/app/src/androidTest/java/com/example/ribs_demo_android/ExampleInstrumentedTest.kt +++ b/app/src/androidTest/java/com/solacestudios/ribs_demo_android/ExampleInstrumentedTest.kt @@ -1,4 +1,4 @@ -package com.example.ribs_demo_android +package com.solacestudios.ribs_demo_android import androidx.test.platform.app.InstrumentationRegistry import androidx.test.ext.junit.runners.AndroidJUnit4 @@ -19,6 +19,6 @@ class ExampleInstrumentedTest { fun useAppContext() { // Context of the app under test. val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("com.example.ribs_demo_android", appContext.packageName) + assertEquals("com.solacestudios.ribs_demo_android", appContext.packageName) } } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3b071d4..36ee150 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,11 +1,11 @@ + package="com.solacestudios.ribs_demo_android"> diff --git a/app/src/main/java/com/example/ribs_demo_android/network/repository/CatalogueRepositoryImpl.kt b/app/src/main/java/com/example/ribs_demo_android/network/repository/CatalogueRepositoryImpl.kt deleted file mode 100644 index f8966c3..0000000 --- a/app/src/main/java/com/example/ribs_demo_android/network/repository/CatalogueRepositoryImpl.kt +++ /dev/null @@ -1,65 +0,0 @@ -package com.example.ribs_demo_android.network.repository - -import com.example.ribs_demo_android.models.CatalogueDetail -import com.example.ribs_demo_android.models.CatalogueResponse -import com.example.ribs_demo_android.network.CatalogueService -import com.example.ribs_demo_android.ribs.root.home.catalogue.CatalogueScheduler -import com.example.ribs_demo_android.ribs.root.repository.CatalogueRepository -import com.example.ribs_demo_android.util.Resource -import io.reactivex.Observable -import io.reactivex.Observer -import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.functions.Consumer -import io.reactivex.schedulers.Schedulers - -class CatalogueRepositoryImpl( - private val catalogueService: CatalogueService, - private val scheduler: CatalogueScheduler -) : CatalogueRepository { - - override fun getAll(page: Int): Observable> { - return object : Observable>() { - override fun subscribeActual(observer: Observer>?) { - observer?.onNext(Resource.Loading()) - catalogueService.getAll(page) - .subscribeOn(scheduler.io) - .observeOn(scheduler.main) - .subscribe( - object : Consumer { - override fun accept(t: CatalogueResponse?) { - t?.let { - observer?.onNext(Resource.Success(it)) - } - } - }, - { - observer?.onNext(Resource.Error(it.message.toString())) - } - ) - } - } - } - - override fun getDetail(name: String): Observable> { - return object : Observable>() { - override fun subscribeActual(observer: Observer>?) { - observer?.onNext(Resource.Loading()) - catalogueService.getDetail(name) - .subscribeOn(scheduler.io) - .observeOn(scheduler.main) - .subscribe( - object : Consumer { - override fun accept(t: CatalogueDetail?) { - t?.let { - observer?.onNext(Resource.Success(it)) - } - } - }, - { - observer?.onNext(Resource.Error(it.message.toString())) - } - ) - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/example/ribs_demo_android/network/repository/CategoryRepositoryImpl.kt b/app/src/main/java/com/example/ribs_demo_android/network/repository/CategoryRepositoryImpl.kt deleted file mode 100644 index fa3d077..0000000 --- a/app/src/main/java/com/example/ribs_demo_android/network/repository/CategoryRepositoryImpl.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.example.ribs_demo_android.network.repository - -import com.example.ribs_demo_android.models.CatalogueResponse -import com.example.ribs_demo_android.network.CategoryService -import com.example.ribs_demo_android.ribs.root.category.CategoryScheduler -import com.example.ribs_demo_android.ribs.root.repository.CategoryRepository -import com.example.ribs_demo_android.util.Resource -import io.reactivex.Observable -import io.reactivex.Observer -import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.functions.Consumer -import io.reactivex.schedulers.Schedulers - -class CategoryRepositoryImpl( - private val categoryService: CategoryService, - private val categoryScheduler: CategoryScheduler -) : CategoryRepository { - - override fun getByRarity(rarity: String): Observable> { - return object : Observable>() { - override fun subscribeActual(observer: Observer>?) { - observer?.onNext(Resource.Loading()) - categoryService.getByRarity(rarity) - .subscribeOn(categoryScheduler.io) - .observeOn(categoryScheduler.main) - .subscribe( - object : Consumer { - override fun accept(t: CatalogueResponse?) { - t?.let { - observer?.onNext(Resource.Success(it)) - } - } - }, - { - observer?.onNext(Resource.Error(it.message.toString())) - } - ) - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/example/ribs_demo_android/network/repository/DetailsRepositoryImpl.kt b/app/src/main/java/com/example/ribs_demo_android/network/repository/DetailsRepositoryImpl.kt deleted file mode 100644 index 143917f..0000000 --- a/app/src/main/java/com/example/ribs_demo_android/network/repository/DetailsRepositoryImpl.kt +++ /dev/null @@ -1,39 +0,0 @@ -package com.example.ribs_demo_android.network.repository - -import com.example.ribs_demo_android.models.CatalogueDetail -import com.example.ribs_demo_android.network.DetailsService -import com.example.ribs_demo_android.ribs.root.home.catalogue.details.DetailsScheduler -import com.example.ribs_demo_android.ribs.root.repository.DetailsRepository -import com.example.ribs_demo_android.util.Resource -import io.reactivex.Observable -import io.reactivex.Observer -import io.reactivex.functions.Consumer - -class DetailsRepositoryImpl( - private val detailsService: DetailsService, - private val detailsScheduler: DetailsScheduler -) : DetailsRepository { - - override fun getDetail(name: String): Observable> { - return object : Observable>() { - override fun subscribeActual(observer: Observer>?) { - observer?.onNext(Resource.Loading()) - detailsService.getDetail(name) - .subscribeOn(detailsScheduler.io) - .observeOn(detailsScheduler.main) - .subscribe( - object : Consumer { - override fun accept(t: CatalogueDetail?) { - t?.let { - observer?.onNext(Resource.Success(it)) - } - } - }, - { - observer?.onNext(Resource.Error(it.message.toString())) - } - ) - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/MainActivity.kt b/app/src/main/java/com/example/ribs_demo_android/ribs/MainActivity.kt deleted file mode 100644 index 33c33ad..0000000 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/MainActivity.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.example.ribs_demo_android.ribs - -import androidx.appcompat.app.AppCompatActivity -import android.os.Bundle -import android.view.ViewGroup -import com.example.ribs_demo_android.ribs.root.RootBuilder -import com.uber.rib.core.RibActivity -import com.uber.rib.core.ViewRouter - -class MainActivity : RibActivity() { - - override fun createRouter(parentViewGroup: ViewGroup): ViewRouter<*, *> { - val rootBuilder: RootBuilder = RootBuilder(object : RootBuilder.ParentComponent{}) - return rootBuilder.build(parentViewGroup) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/RootBuilder.kt b/app/src/main/java/com/example/ribs_demo_android/ribs/root/RootBuilder.kt deleted file mode 100644 index c689d4f..0000000 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/RootBuilder.kt +++ /dev/null @@ -1,136 +0,0 @@ -package com.example.ribs_demo_android.ribs.root - -import android.view.LayoutInflater -import android.view.ViewGroup -import com.example.ribs_demo_android.R -import com.example.ribs_demo_android.ribs.root.category.CategoryBuilder -import com.example.ribs_demo_android.ribs.root.category.CategoryInteractor -import com.example.ribs_demo_android.ribs.root.home.HomeBuilder -import com.example.ribs_demo_android.ribs.root.home.HomeInteractor -import com.uber.rib.core.InteractorBaseComponent -import com.uber.rib.core.ViewBuilder -import dagger.Binds -import dagger.BindsInstance -import dagger.Provides -import java.lang.annotation.Retention -import java.lang.annotation.RetentionPolicy.CLASS -import javax.inject.Qualifier -import javax.inject.Scope - -/** - * Builder for the {@link RootScope}. - * - * TODO describe this scope's responsibility as a whole. - */ -class RootBuilder(dependency: ParentComponent) : - ViewBuilder(dependency) { - - /** - * Builds a new [RootRouter]. - * - * @param parentViewGroup parent view group that this router's view will be added to. - * @return a new [RootRouter]. - */ - fun build(parentViewGroup: ViewGroup): RootRouter { - val view = createView(parentViewGroup) - val interactor = RootInteractor() - val component = DaggerRootBuilder_Component.builder() - .parentComponent(dependency) - .view(view) - .interactor(interactor) - .build() - return component.rootRouter() - } - - override fun inflateView(inflater: LayoutInflater, parentViewGroup: ViewGroup): RootView { - // TODO: Inflate a new view using the provided inflater, or create a new view programatically using the - // provided context from the parentViewGroup. - return inflater.inflate(R.layout.root_rib, parentViewGroup, false) as RootView - } - - interface ParentComponent { - // TODO: Define dependencies required from your parent interactor here. - } - - @dagger.Module - abstract class Module { - - @RootScope - @Binds - internal abstract fun presenter(view: RootView): RootInteractor.RootPresenter - - @dagger.Module - companion object { - - @RootScope - @Provides - @JvmStatic - internal fun provideHomeListener( - interactor: RootInteractor - ): HomeInteractor.HomeToggleListener { - return interactor.RootListener() - } - - @RootScope - @Provides - @JvmStatic - internal fun provideCategoryListener( - interactor: RootInteractor - ): CategoryInteractor.CategoryToggleListener { - return interactor.RootCategoryListener() - } - - @RootScope - @Provides - @JvmStatic - internal fun router( - component: Component, - view: RootView, - interactor: RootInteractor - ): RootRouter { - return RootRouter( - view, - interactor, - component, - HomeBuilder(component), - CategoryBuilder(component) - ) - } - } - - // TODO: Create provider methods for dependencies created by this Rib. These should be static. - } - - @RootScope - @dagger.Component( - modules = arrayOf(Module::class), - dependencies = arrayOf(ParentComponent::class) - ) - interface Component : InteractorBaseComponent, HomeBuilder.ParentComponent, CategoryBuilder.ParentComponent, - BuilderComponent { - - @dagger.Component.Builder - interface Builder { - @BindsInstance - fun interactor(interactor: RootInteractor): Builder - - @BindsInstance - fun view(view: RootView): Builder - - fun parentComponent(component: ParentComponent): Builder - fun build(): Component - } - } - - interface BuilderComponent { - fun rootRouter(): RootRouter - } - - @Scope - @Retention(CLASS) - internal annotation class RootScope - - @Qualifier - @Retention(CLASS) - internal annotation class RootInternal -} diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/category/CategoryBuilder.kt b/app/src/main/java/com/example/ribs_demo_android/ribs/root/category/CategoryBuilder.kt deleted file mode 100644 index 3d9e938..0000000 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/category/CategoryBuilder.kt +++ /dev/null @@ -1,164 +0,0 @@ -package com.example.ribs_demo_android.ribs.root.category - -import android.view.LayoutInflater -import android.view.ViewGroup -import com.example.ribs_demo_android.R -import com.example.ribs_demo_android.network.CategoryService -import com.example.ribs_demo_android.network.repository.CategoryRepositoryImpl -import com.example.ribs_demo_android.ribs.root.RootBuilder -import com.example.ribs_demo_android.ribs.root.home.HomeBuilder -import com.example.ribs_demo_android.ribs.root.repository.CategoryRepository -import com.example.ribs_demo_android.util.Constants -import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory -import com.uber.rib.core.InteractorBaseComponent -import com.uber.rib.core.ViewBuilder -import dagger.Binds -import dagger.BindsInstance -import dagger.Provides -import retrofit2.Retrofit -import retrofit2.converter.gson.GsonConverterFactory -import java.lang.annotation.Retention -import java.lang.annotation.RetentionPolicy.CLASS -import javax.inject.Named -import javax.inject.Qualifier -import javax.inject.Scope - -/** - * Builder for the {@link CategoryScope}. - * - * TODO describe this scope's responsibility as a whole. - */ -class CategoryBuilder(dependency: ParentComponent) : - ViewBuilder(dependency) { - - /** - * Builds a new [CategoryRouter]. - * - * @param parentViewGroup parent view group that this router's view will be added to. - * @return a new [CategoryRouter]. - */ - fun build(parentViewGroup: ViewGroup): CategoryRouter { - val view = createView(parentViewGroup) - val interactor = CategoryInteractor() - val component = DaggerCategoryBuilder_Component.builder() - .parentComponent(dependency) - .view(view) - .interactor(interactor) - .build() - return component.categoryRouter() - } - - override fun inflateView(inflater: LayoutInflater, parentViewGroup: ViewGroup): CategoryView { - // TODO: Inflate a new view using the provided inflater, or create a new view programatically using the - // provided context from the parentViewGroup. - return inflater.inflate(R.layout.category_rib, parentViewGroup, false) as CategoryView - } - - interface ParentComponent { - // TODO: Define dependencies required from your parent interactor here. - fun categoryToggleListener(): CategoryInteractor.CategoryToggleListener - } - - @dagger.Module - abstract class Module { - - @CategoryScope - @Binds - internal abstract fun presenter(view: CategoryView): CategoryInteractor.CategoryPresenter - - @dagger.Module - companion object { - - @Provides - fun providesGsonConverterFactory(): GsonConverterFactory { - return GsonConverterFactory.create() - } - - @CategoryScope - @Provides - @JvmStatic - internal fun provideRetrofit( - gsonConverterFactory: GsonConverterFactory - ): Retrofit { - return Retrofit.Builder() - .baseUrl(Constants.BASE_URL) - .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) - .addConverterFactory(gsonConverterFactory) - .build() - } - - @CategoryScope - @Provides - @JvmStatic - internal fun provideCategoryService( - retrofit: Retrofit - ): CategoryService { - return retrofit.create(CategoryService::class.java) - } - - @CategoryScope - @Provides - @JvmStatic - @Named("category") - internal fun provideCategorySchedulers(): CategoryScheduler { - return CategorySchedulerImpl() - } - -// @CategoryScope -// @Provides -// @JvmStatic -// @Named("categoryRepo") -// internal fun provideCategoryRepository( -// service: CategoryService, -// categoryScheduler: CategoryScheduler -// ): CategoryRepository { -// return CategoryRepositoryImpl(service, categoryScheduler) -// } - - @CategoryScope - @Provides - @JvmStatic - internal fun router( - component: Component, - view: CategoryView, - interactor: CategoryInteractor - ): CategoryRouter { - return CategoryRouter(view, interactor, component) - } - } - - // TODO: Create provider methods for dependencies created by this Rib. These should be static. - } - - @CategoryScope - @dagger.Component( - modules = arrayOf(Module::class), - dependencies = arrayOf(ParentComponent::class) - ) - interface Component : InteractorBaseComponent, BuilderComponent { - - @dagger.Component.Builder - interface Builder { - @BindsInstance - fun interactor(interactor: CategoryInteractor): Builder - - @BindsInstance - fun view(view: CategoryView): Builder - - fun parentComponent(component: ParentComponent): Builder - fun build(): Component - } - } - - interface BuilderComponent { - fun categoryRouter(): CategoryRouter - } - - @Scope - @Retention(CLASS) - internal annotation class CategoryScope - - @Qualifier - @Retention(CLASS) - internal annotation class CategoryInternal -} diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/category/CategoryInteractor.kt b/app/src/main/java/com/example/ribs_demo_android/ribs/root/category/CategoryInteractor.kt deleted file mode 100644 index a008efa..0000000 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/category/CategoryInteractor.kt +++ /dev/null @@ -1,141 +0,0 @@ -package com.example.ribs_demo_android.ribs.root.category - -import androidx.annotation.VisibleForTesting -import com.example.ribs_demo_android.models.Catalogue -import com.example.ribs_demo_android.models.CatalogueResponse -import com.example.ribs_demo_android.network.CategoryService -import com.example.ribs_demo_android.network.repository.CategoryRepositoryImpl -import com.example.ribs_demo_android.ribs.root.repository.CategoryRepository -import com.example.ribs_demo_android.util.Resource -import com.uber.rib.core.Bundle -import com.uber.rib.core.Interactor -import com.uber.rib.core.RibInteractor -import io.reactivex.Observable -import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.functions.Consumer -import io.reactivex.schedulers.Schedulers -import javax.inject.Inject -import javax.inject.Named - -/** - * Coordinates Business Logic for [CategoryScope]. - * - * TODO describe the logic of this scope. - */ -@RibInteractor -class CategoryInteractor : Interactor() { - - @Inject - lateinit var presenter: CategoryPresenter - - @Inject - lateinit var categoryService: CategoryService - - @Inject - lateinit var categoryToggleListener: CategoryToggleListener - - @Inject - @Named("category") - lateinit var categoryScheduler: CategoryScheduler - -// @Inject -// @Named("categoryRepo") -// lateinit var categoryRepository: CategoryRepository - - lateinit var categoryRepository: CategoryRepository - - override fun didBecomeActive(savedInstanceState: Bundle?) { - super.didBecomeActive(savedInstanceState) - - // TODO: Add attachment logic here (RxSubscriptions, etc.). - init() - - getByRarity("chromatic") - - handleToggle() - - getChip() - } - - fun init() { - categoryRepository = CategoryRepositoryImpl(categoryService, categoryScheduler) - } - - fun handleToggle() { - presenter.toggle() - .subscribeOn(categoryScheduler.io) - .observeOn(categoryScheduler.main) - .subscribe(object : Consumer { - override fun accept(t: Boolean?) { - t?.let { - categoryToggleListener.toggleCategory() - } - } - }) - } - - fun getChip() { - presenter.getChip() - .subscribeOn(categoryScheduler.io) - .observeOn(categoryScheduler.main) - .subscribe(object : Consumer { - override fun accept(t: String?) { - t?.let { - getByRarity(it) - } - } - }, - { - it.printStackTrace() - }) - } - - fun getByRarity(rarity: String) { - categoryRepository.getByRarity(rarity) - .subscribeOn(categoryScheduler.io) - .observeOn(categoryScheduler.main) - .subscribe( - object : Consumer> { - override fun accept(t: Resource?) { - t?.let { - when (it) { - is Resource.Loading -> { - presenter.updateProgressbarState(true) - } - is Resource.Success -> { - presenter.setup(it.data?.brawlers!!) - presenter.updateProgressbarState(false) - } - is Resource.Error -> { - presenter.updateProgressbarState(false) - } - } - } - } - }, - { - it.printStackTrace() - } - ) - } - - override fun willResignActive() { - super.willResignActive() - - // TODO: Perform any required clean up here, or delete this method entirely if not needed. - } - - /** - * Presenter interface implemented by this RIB's view. - */ - interface CategoryPresenter { - fun setup(items: List) - fun toggle(): Observable - fun getChip(): Observable - fun updateProgressbarState(isVisible: Boolean) - } - - interface CategoryToggleListener { - fun toggleCategory() - } -} diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/category/CategoryScheduler.kt b/app/src/main/java/com/example/ribs_demo_android/ribs/root/category/CategoryScheduler.kt deleted file mode 100644 index e3dd17a..0000000 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/category/CategoryScheduler.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.example.ribs_demo_android.ribs.root.category - -import io.reactivex.Scheduler -import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.schedulers.Schedulers - -interface CategoryScheduler { - val io: Scheduler - val main: Scheduler - val compute: Scheduler -} - -class CategorySchedulerImpl(): CategoryScheduler { - override val io: Scheduler - get() = Schedulers.io() - override val main: Scheduler - get() = AndroidSchedulers.mainThread() - override val compute: Scheduler - get() = Schedulers.computation() -} \ No newline at end of file diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/category/CategoryView.kt b/app/src/main/java/com/example/ribs_demo_android/ribs/root/category/CategoryView.kt deleted file mode 100644 index 9c72f77..0000000 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/category/CategoryView.kt +++ /dev/null @@ -1,71 +0,0 @@ -package com.example.ribs_demo_android.ribs.root.category - -import android.content.Context -import android.util.AttributeSet -import android.view.View -import android.widget.LinearLayout -import android.widget.ProgressBar -import android.widget.RelativeLayout -import android.widget.TextView -import androidx.core.view.forEach -import androidx.core.view.forEachIndexed -import androidx.core.view.get -import androidx.core.view.isVisible -import androidx.recyclerview.widget.RecyclerView -import com.example.ribs_demo_android.R -import com.example.ribs_demo_android.models.Catalogue -import com.example.ribs_demo_android.ribs.root.category.adapter.CategoryAdapter -import com.google.android.material.chip.Chip -import com.google.android.material.chip.ChipGroup -import io.reactivex.Observable -import io.reactivex.Observer - -/** - * Top level view for {@link CategoryBuilder.CategoryScope}. - */ -class CategoryView @JvmOverloads constructor( - context: Context, - attrs: AttributeSet? = null, - defStyle: Int = 0 -) : RelativeLayout(context, attrs, defStyle), CategoryInteractor.CategoryPresenter { - - private var adapter: CategoryAdapter? = null - - override fun setup(items: List) { - adapter = CategoryAdapter(items) { - - } - - findViewById(R.id.rvCategory).adapter = adapter - } - - override fun toggle(): Observable { - return object : Observable() { - override fun subscribeActual(observer: Observer?) { - findViewById(R.id.home).setOnClickListener { - observer?.onNext(true) - } - } - } - } - - override fun getChip(): Observable { - return object : Observable() { - override fun subscribeActual(observer: Observer?) { - findViewById(R.id.chipgroup).setOnCheckedChangeListener { group, checkedId -> - group.forEachIndexed { index, view -> - if (view.id == checkedId) { - val chip = group[index] as Chip - val query = chip.text.toString().toLowerCase() - observer?.onNext(query) - } - } - } - } - } - } - - override fun updateProgressbarState(isVisible: Boolean) { - findViewById(R.id.progressbar_category).isVisible = isVisible - } -} diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/HomeBuilder.kt b/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/HomeBuilder.kt deleted file mode 100644 index 668df78..0000000 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/HomeBuilder.kt +++ /dev/null @@ -1,180 +0,0 @@ -package com.example.ribs_demo_android.ribs.root.home - -import android.view.LayoutInflater -import android.view.ViewGroup -import com.example.ribs_demo_android.R -import com.example.ribs_demo_android.network.CatalogueService -import com.example.ribs_demo_android.network.repository.CatalogueRepositoryImpl -import com.example.ribs_demo_android.ribs.root.category.CategoryInteractor -import com.example.ribs_demo_android.ribs.root.home.catalogue.CatalogueBuilder -import com.example.ribs_demo_android.ribs.root.home.catalogue.CatalogueInteractor -import com.example.ribs_demo_android.ribs.root.home.catalogue.CatalogueScheduler -import com.example.ribs_demo_android.ribs.root.home.catalogue.CatalogueSchedulerImpl -import com.example.ribs_demo_android.ribs.root.repository.CatalogueRepository -import com.example.ribs_demo_android.util.Constants -import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory -import com.uber.rib.core.InteractorBaseComponent -import com.uber.rib.core.ViewBuilder -import dagger.Binds -import dagger.BindsInstance -import dagger.Provides -import retrofit2.Retrofit -import retrofit2.converter.gson.GsonConverterFactory -import java.lang.annotation.Retention -import java.lang.annotation.RetentionPolicy.CLASS -import javax.inject.Qualifier -import javax.inject.Scope - -/** - * Builder for the {@link LogoutScope}. - * - * TODO describe this scope's responsibility as a whole. - */ -class HomeBuilder(dependency: ParentComponent) : - ViewBuilder(dependency) { - - /** - * Builds a new [LogoutRouter]. - * - * @param parentViewGroup parent view group that this router's view will be added to. - * @return a new [LogoutRouter]. - */ - fun build(parentViewGroup: ViewGroup): HomeRouter { - val view = createView(parentViewGroup) - val interactor = HomeInteractor() - val component = DaggerHomeBuilder_Component.builder() - .parentComponent(dependency) - .view(view) - .interactor(interactor) - .build() - return component.logoutRouter() - } - - override fun inflateView(inflater: LayoutInflater, parentViewGroup: ViewGroup): HomeView { - // TODO: Inflate a new view using the provided inflater, or create a new view programatically using the - // provided context from the parentViewGroup. - return inflater.inflate(R.layout.home_rib, parentViewGroup, false) as HomeView - } - - interface ParentComponent { - // TODO: Define dependencies required from your parent interactor here. - //fun logoutListener(): LogoutInteractor.LogoutListener - fun homeToggleListener(): HomeInteractor.HomeToggleListener - } - - @dagger.Module - abstract class Module { - - @HomeScope - @Binds - internal abstract fun presenter(view: HomeView): HomeInteractor.HomePresenter - - @dagger.Module - companion object { - - @HomeScope - @Provides - @JvmStatic - internal fun provideCatalogueListener( - interactor: HomeInteractor - ): CatalogueInteractor.CatalogueListener { - return interactor.HomeListener() - } - - @HomeScope - @Provides - @JvmStatic - internal fun provideRetrofit( - gsonConverterFactory: GsonConverterFactory - ): Retrofit { - return Retrofit.Builder() - .baseUrl(Constants.BASE_URL) - .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) - .addConverterFactory(gsonConverterFactory) - .build() - } - - @HomeScope - @Provides - @JvmStatic - internal fun provideService( - retrofit: Retrofit - ): CatalogueService { - return retrofit.create(CatalogueService::class.java) - } - - @HomeScope - @Provides - @JvmStatic - internal fun provideCatalogueRepository( - service: CatalogueService, - scheduler: CatalogueScheduler - ): CatalogueRepository { - return CatalogueRepositoryImpl(service, scheduler) - } - - @Provides - fun providesGsonConverterFactory(): GsonConverterFactory { - return GsonConverterFactory.create() - } - - @HomeScope - @Provides - @JvmStatic - internal fun router( - component: Component, - view: HomeView, - interactor: HomeInteractor, - service: CatalogueService - ): HomeRouter { - return HomeRouter( - view, - interactor, - component, - CatalogueBuilder(component) - ) - } - - @HomeScope - @Provides - @JvmStatic - internal fun provideCatalogueSchedulers(): CatalogueScheduler { - return CatalogueSchedulerImpl() - } - // TODO: Create provider methods for dependencies created by this Rib. These should be static. - } - } - - @HomeScope - @dagger.Component( - modules = arrayOf(Module::class), - dependencies = arrayOf(ParentComponent::class) - ) - interface Component : InteractorBaseComponent, CatalogueBuilder.ParentComponent, - BuilderComponent { - - @dagger.Component.Builder - interface Builder { - @BindsInstance - fun interactor(interactor: HomeInteractor): Builder - - @BindsInstance - fun view(view: HomeView): Builder - - fun parentComponent(component: ParentComponent): Builder - fun build(): Component - } - } - - interface BuilderComponent { - fun logoutRouter(): HomeRouter - } - - @Scope - @Retention(CLASS) - internal annotation class HomeScope - - @Qualifier - @Retention(CLASS) - internal annotation class LogoutInternal -} diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/CatalogueBuilder.kt b/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/CatalogueBuilder.kt deleted file mode 100644 index a7c3d48..0000000 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/CatalogueBuilder.kt +++ /dev/null @@ -1,199 +0,0 @@ -package com.example.ribs_demo_android.ribs.root.home.catalogue - -import android.view.LayoutInflater -import android.view.ViewGroup -import com.example.ribs_demo_android.R -import com.example.ribs_demo_android.network.CatalogueService -import com.example.ribs_demo_android.network.DetailsService -import com.example.ribs_demo_android.network.repository.DetailsRepositoryImpl -import com.example.ribs_demo_android.ribs.root.home.HomeBuilder -import com.example.ribs_demo_android.ribs.root.home.catalogue.details.DetailsBuilder -import com.example.ribs_demo_android.ribs.root.home.catalogue.details.DetailsInteractor -import com.example.ribs_demo_android.ribs.root.home.catalogue.details.DetailsScheduler -import com.example.ribs_demo_android.ribs.root.home.catalogue.details.DetailsSchedulerImpl -import com.example.ribs_demo_android.ribs.root.repository.CatalogueRepository -import com.example.ribs_demo_android.ribs.root.repository.DetailsRepository -import com.example.ribs_demo_android.util.Constants -import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory -import com.uber.rib.core.InteractorBaseComponent -import com.uber.rib.core.ViewBuilder -import dagger.Binds -import dagger.BindsInstance -import dagger.Provides -import retrofit2.Retrofit -import retrofit2.converter.gson.GsonConverterFactory -import java.lang.annotation.Retention -import java.lang.annotation.RetentionPolicy.CLASS -import javax.inject.Named -import javax.inject.Qualifier -import javax.inject.Scope - -/** - * Builder for the {@link CatalogueScope}. - * - * TODO describe this scope's responsibility as a whole. - */ -class CatalogueBuilder(dependency: ParentComponent) : - ViewBuilder(dependency) { - - /** - * Builds a new [CatalogueRouter]. - * - * @param parentViewGroup parent view group that this router's view will be added to. - * @return a new [CatalogueRouter]. - */ - fun build(parentViewGroup: ViewGroup): CatalogueRouter { - val view = createView(parentViewGroup) - val interactor = CatalogueInteractor() - val component = DaggerCatalogueBuilder_Component.builder() - .parentComponent(dependency) - .view(view) - .interactor(interactor) - .build() - return component.catalogueRouter() - } - - override fun inflateView(inflater: LayoutInflater, parentViewGroup: ViewGroup): CatalogueView { - // TODO: Inflate a new view using the provided inflater, or create a new view programatically using the - // provided context from the parentViewGroup. - return inflater.inflate(R.layout.catalogue_rib, parentViewGroup, false) as CatalogueView - } - - interface ParentComponent { - // TODO: Define dependencies required from your parent interactor here. - fun service(): CatalogueService - fun catalogueListener(): CatalogueInteractor.CatalogueListener - fun catalogueRepository(): CatalogueRepository - fun catalogueSchedulers(): CatalogueScheduler - } - - @dagger.Module - abstract class Module { - - @CatalogueScope - @Binds - internal abstract fun presenter(view: CatalogueView): CatalogueInteractor.CataloguePresenter - - @dagger.Module - companion object { - - @CatalogueScope - @Provides - @JvmStatic - internal fun provideDetailsListener( - interactor: CatalogueInteractor - ): DetailsInteractor.DetailsListener { - return interactor.DetailsListener() - } - - @CatalogueScope - @CatalogueInternal - @Provides - internal fun provideMutableDataStream(): MutableDataStream { - return MutableDataStream("initial") - } - - @CatalogueScope - @Provides - fun provideDataStream(@CatalogueInternal mutableDataStream: MutableDataStream): DataStream { - return mutableDataStream - } - - @CatalogueScope - @Provides - @JvmStatic - internal fun router( - component: Component, - view: CatalogueView, - interactor: CatalogueInteractor - ): CatalogueRouter { - return CatalogueRouter( - view, - interactor, - component, - DetailsBuilder(component) - ) - } - - @Provides - @Named("gson") - fun providesGsonConverterFactory(): GsonConverterFactory { - return GsonConverterFactory.create() - } - - @CatalogueScope - @Provides - @JvmStatic - @Named("catalogue_retrofit") - internal fun provideRetrofit( - @Named("gson") gsonConverterFactory: GsonConverterFactory - ): Retrofit { - return Retrofit.Builder() - .baseUrl(Constants.BASE_URL) - .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) - .addConverterFactory(gsonConverterFactory) - .build() - } - - @CatalogueScope - @Provides - @JvmStatic - internal fun provideService( - @Named("catalogue_retrofit") retrofit: Retrofit - ): DetailsService { - return retrofit.create(DetailsService::class.java) - } - - @CatalogueScope - @Provides - @JvmStatic - internal fun provideDetailsRepository( - service: DetailsService, - scheduler: DetailsScheduler - ): DetailsRepository { - return DetailsRepositoryImpl(service, scheduler) - } - - @CatalogueScope - @Provides - @JvmStatic - internal fun provideDetailsScheduler(): DetailsScheduler { - return DetailsSchedulerImpl() - } - } - - // TODO: Create provider methods for dependencies created by this Rib. These should be static. - } - - @CatalogueScope - @dagger.Component( - modules = arrayOf(Module::class), - dependencies = arrayOf(ParentComponent::class) - ) - interface Component : InteractorBaseComponent, DetailsBuilder.ParentComponent, BuilderComponent { - - @dagger.Component.Builder - interface Builder { - @BindsInstance - fun interactor(interactor: CatalogueInteractor): Builder - - @BindsInstance - fun view(view: CatalogueView): Builder - - fun parentComponent(component: ParentComponent): Builder - fun build(): Component - } - } - - interface BuilderComponent { - fun catalogueRouter(): CatalogueRouter - } - - @Scope - @Retention(CLASS) - internal annotation class CatalogueScope - - @Qualifier - @Retention(CLASS) - internal annotation class CatalogueInternal -} diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/CatalogueInteractor.kt b/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/CatalogueInteractor.kt deleted file mode 100644 index c48756a..0000000 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/CatalogueInteractor.kt +++ /dev/null @@ -1,138 +0,0 @@ -package com.example.ribs_demo_android.ribs.root.home.catalogue - -import com.example.ribs_demo_android.models.Catalogue -import com.example.ribs_demo_android.models.CatalogueResponse -import com.example.ribs_demo_android.network.CatalogueService -import com.example.ribs_demo_android.ribs.root.home.catalogue.details.DetailsInteractor -import com.example.ribs_demo_android.ribs.root.repository.CatalogueRepository -import com.example.ribs_demo_android.util.Resource -import com.uber.rib.core.Bundle -import com.uber.rib.core.Interactor -import com.uber.rib.core.RibInteractor -import io.reactivex.Observable -import io.reactivex.Scheduler -import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.functions.Consumer -import io.reactivex.schedulers.Schedulers -import javax.inject.Inject -import javax.inject.Named - -/** - * Coordinates Business Logic for [CatalogueScope]. - * - * TODO describe the logic of this scope. - */ -@RibInteractor -class CatalogueInteractor : Interactor() { - - @Inject - lateinit var presenter: CataloguePresenter - - @Inject - lateinit var catalogueService: CatalogueService - - @Inject - lateinit var catalogueListener: CatalogueListener - - @Inject - lateinit var catalogueRepository: CatalogueRepository - - @Inject @CatalogueBuilder.CatalogueInternal - lateinit var dataStream: MutableDataStream - - @Inject - lateinit var catalogueScheduler: CatalogueScheduler - - override fun didBecomeActive(savedInstanceState: Bundle?) { - super.didBecomeActive(savedInstanceState) - - // TODO: Add attachment logic here (RxSubscriptions, etc.). - - getInitialData(1) - .subscribeOn(catalogueScheduler.io) - .observeOn(catalogueScheduler.main) - .subscribe( - object : Consumer> { - override fun accept(t: Resource?) { - t?.let { state -> - when(state) { - is Resource.Loading -> { - presenter.updateProgressbarState(true) - } - is Resource.Success -> { - presenter.updateProgressbarState(false) - presenter.setupUI(state.data!!.brawlers) - .subscribeOn(catalogueScheduler.io) - .observeOn(catalogueScheduler.main) - .subscribe( - object : Consumer { - override fun accept(t: String?) { - t?.let { - router.attachDetails() - dataStream.setData(it) - } - } - }, - { - it.printStackTrace() - } - ) - } - is Resource.Error -> { - presenter.updateProgressbarState(false) - } - else -> Unit - } - } - } - }, - { - it.printStackTrace() - } - ) - - handleCategoryToggle() - } - - fun getInitialData(page: Int): Observable> { - return catalogueRepository.getAll(1) - } - - fun handleCategoryToggle() { - presenter.onCategoryToggle() - .subscribeOn(catalogueScheduler.io) - .observeOn(catalogueScheduler.main) - .subscribe(object: Consumer { - override fun accept(t: Boolean?) { - t?.let { - catalogueListener.onClick() - } - } - }) - } - - override fun willResignActive() { - super.willResignActive() - - // TODO: Perform any required clean up here, or delete this method entirely if not needed. - } - - /** - * Presenter interface implemented by this RIB's view. - */ - interface CataloguePresenter { - fun setupUI(items: List): Observable - fun updateProgressbarState(isVisible: Boolean) - fun onCategoryToggle(): Observable - } - - interface CatalogueListener { - fun onClick() - } - - inner class DetailsListener: DetailsInteractor.DetailsListener { - override fun onBackPress() { - router.detachDetails() - } - } -} diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/CatalogueScheduler.kt b/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/CatalogueScheduler.kt deleted file mode 100644 index c789320..0000000 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/CatalogueScheduler.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.example.ribs_demo_android.ribs.root.home.catalogue - -import io.reactivex.Scheduler -import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.schedulers.Schedulers - -interface CatalogueScheduler { - val io: Scheduler - val main: Scheduler - val compute: Scheduler -} - -class CatalogueSchedulerImpl(): CatalogueScheduler { - override val io: Scheduler - get() = Schedulers.io() - override val main: Scheduler - get() = AndroidSchedulers.mainThread() - override val compute: Scheduler - get() = Schedulers.computation() -} \ No newline at end of file diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/CatalogueView.kt b/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/CatalogueView.kt deleted file mode 100644 index 47ef2cc..0000000 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/CatalogueView.kt +++ /dev/null @@ -1,57 +0,0 @@ -package com.example.ribs_demo_android.ribs.root.home.catalogue - -import android.content.Context -import android.util.AttributeSet -import android.widget.LinearLayout -import android.widget.ProgressBar -import android.widget.TextView -import androidx.constraintlayout.widget.ConstraintLayout -import androidx.core.view.isVisible -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView -import com.example.ribs_demo_android.R -import com.example.ribs_demo_android.ribs.root.home.catalogue.adapter.CatalogueAdapter.CatalogueAdapter -import com.example.ribs_demo_android.models.Catalogue -import io.reactivex.Observable -import io.reactivex.Observer - -/** - * Top level view for {@link CatalogueBuilder.CatalogueScope}. - */ -class CatalogueView @JvmOverloads constructor( - context: Context, - attrs: AttributeSet? = null, - defStyle: Int = 0 -) : ConstraintLayout(context, attrs, defStyle), CatalogueInteractor.CataloguePresenter { - - private var adapter: CatalogueAdapter? = null - private var listener: ((String) -> Unit)? = null - - override fun setupUI(items: List): Observable { - adapter = CatalogueAdapter(items) { name -> - listener?.invoke(name) - } - findViewById(R.id.rv).adapter = adapter - return object : Observable() { - override fun subscribeActual(observer: Observer?) { - listener = { name -> - observer?.onNext(name) - } - } - } - } - - override fun updateProgressbarState(isVisible: Boolean) { - findViewById(R.id.progressbar_catalogue).isVisible = isVisible - } - - override fun onCategoryToggle(): Observable { - return object : Observable() { - override fun subscribeActual(observer: Observer?) { - findViewById(R.id.filters).setOnClickListener { - observer?.onNext(true) - } - } - } - } -} diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/MutableDataStream.kt b/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/MutableDataStream.kt deleted file mode 100644 index 493f8ec..0000000 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/MutableDataStream.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.example.ribs_demo_android.ribs.root.home.catalogue - -import com.jakewharton.rxrelay2.BehaviorRelay -import io.reactivex.Observable - -/** - * Created by Mehul Bisht on 05-01-2022 - */ - -class MutableDataStream(data: String): DataStream { - - private val behaviorRelay: BehaviorRelay = BehaviorRelay.create() - - init { - behaviorRelay.accept(data) - } - - fun setData(data: String) { - behaviorRelay.accept(data) - } - - override fun data(): Observable { - return behaviorRelay.hide() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/details/DetailsBuilder.kt b/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/details/DetailsBuilder.kt deleted file mode 100644 index ae304ce..0000000 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/details/DetailsBuilder.kt +++ /dev/null @@ -1,117 +0,0 @@ -package com.example.ribs_demo_android.ribs.root.home.catalogue.details - -import android.view.LayoutInflater -import android.view.ViewGroup -import com.example.ribs_demo_android.R -import com.example.ribs_demo_android.network.CatalogueService -import com.example.ribs_demo_android.network.DetailsService -import com.example.ribs_demo_android.ribs.root.home.catalogue.DataStream -import com.example.ribs_demo_android.ribs.root.repository.DetailsRepository -import com.uber.rib.core.InteractorBaseComponent -import com.uber.rib.core.ViewBuilder -import dagger.Binds -import dagger.BindsInstance -import dagger.Provides -import java.lang.annotation.Retention -import java.lang.annotation.RetentionPolicy.CLASS -import javax.inject.Named -import javax.inject.Qualifier -import javax.inject.Scope - -/** - * Builder for the {@link DetailsScope}. - * - * TODO describe this scope's responsibility as a whole. - */ -class DetailsBuilder(dependency: ParentComponent) : - ViewBuilder(dependency) { - - /** - * Builds a new [DetailsRouter]. - * - * @param parentViewGroup parent view group that this router's view will be added to. - * @return a new [DetailsRouter]. - */ - fun build(parentViewGroup: ViewGroup): DetailsRouter { - val view = createView(parentViewGroup) - val interactor = DetailsInteractor() - val component = DaggerDetailsBuilder_Component.builder() - .parentComponent(dependency) - .view(view) - .interactor(interactor) - .build() - return component.detailsRouter() - } - - override fun inflateView(inflater: LayoutInflater, parentViewGroup: ViewGroup): DetailsView { - // TODO: Inflate a new view using the provided inflater, or create a new view programatically using the - // provided context from the parentViewGroup. - return inflater.inflate(R.layout.details_rib, parentViewGroup, false) as DetailsView - } - - interface ParentComponent { - // TODO: Define dependencies required from your parent interactor here. - fun detailsListener(): DetailsInteractor.DetailsListener - fun service(): DetailsService - fun dataSteam(): DataStream - fun detailsRepository(): DetailsRepository - fun detailsScheduler(): DetailsScheduler - } - - @dagger.Module - abstract class Module { - - @DetailsScope - @Binds - internal abstract fun presenter(view: DetailsView): DetailsInteractor.DetailsPresenter - - @dagger.Module - companion object { - - @DetailsScope - @Provides - @JvmStatic - internal fun router( - component: Component, - view: DetailsView, - interactor: DetailsInteractor - ): DetailsRouter { - return DetailsRouter(view, interactor, component) - } - } - - // TODO: Create provider methods for dependencies created by this Rib. These should be static. - } - - @DetailsScope - @dagger.Component( - modules = arrayOf(Module::class), - dependencies = arrayOf(ParentComponent::class) - ) - interface Component : InteractorBaseComponent, BuilderComponent { - - @dagger.Component.Builder - interface Builder { - @BindsInstance - fun interactor(interactor: DetailsInteractor): Builder - - @BindsInstance - fun view(view: DetailsView): Builder - - fun parentComponent(component: ParentComponent): Builder - fun build(): Component - } - } - - interface BuilderComponent { - fun detailsRouter(): DetailsRouter - } - - @Scope - @Retention(CLASS) - internal annotation class DetailsScope - - @Qualifier - @Retention(CLASS) - internal annotation class DetailsInternal -} diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/details/DetailsInteractor.kt b/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/details/DetailsInteractor.kt deleted file mode 100644 index cc6096b..0000000 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/details/DetailsInteractor.kt +++ /dev/null @@ -1,136 +0,0 @@ -package com.example.ribs_demo_android.ribs.root.home.catalogue.details - -import android.util.Log -import com.example.ribs_demo_android.models.CatalogueDetail -import com.example.ribs_demo_android.network.CatalogueService -import com.example.ribs_demo_android.network.DetailsService -import com.example.ribs_demo_android.ribs.root.home.catalogue.CatalogueScheduler -import com.example.ribs_demo_android.ribs.root.home.catalogue.DataStream -import com.example.ribs_demo_android.ribs.root.repository.CatalogueRepository -import com.example.ribs_demo_android.ribs.root.repository.DetailsRepository -import com.example.ribs_demo_android.util.Resource -import com.uber.autodispose.AutoDispose -import com.uber.rib.core.Bundle -import com.uber.rib.core.Interactor -import com.uber.rib.core.RibInteractor -import io.reactivex.Observable -import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.functions.Consumer -import io.reactivex.schedulers.Schedulers -import javax.inject.Inject -import javax.inject.Named - -/** - * Coordinates Business Logic for [DetailsScope]. - * - * TODO describe the logic of this scope. - */ -@RibInteractor -class DetailsInteractor : Interactor() { - - @Inject - lateinit var presenter: DetailsPresenter - - @Inject - lateinit var service: DetailsService - - @Inject - lateinit var detailsListener: DetailsListener - - @Inject - lateinit var dataStream: DataStream - - @Inject - lateinit var detailsScheduler: DetailsScheduler - - @Inject - lateinit var detailsRepository: DetailsRepository - - override fun didBecomeActive(savedInstanceState: Bundle?) { - super.didBecomeActive(savedInstanceState) - - // TODO: Add attachment logic here (RxSubscriptions, etc.). - setupUI() - - onBack() - } - - fun setupUI() { - dataStream.data() - .`as`(AutoDispose.autoDisposable(this)) - .subscribe( - object : Consumer { - override fun accept(t: String?) { - t?.let { - detailsRepository.getDetail(it) - .subscribeOn(detailsScheduler.io) - .observeOn(detailsScheduler.main) - .subscribe( - object : Consumer> { - override fun accept(t: Resource?) { - t?.let { - when (it) { - is Resource.Loading -> { - presenter.updateProgressbarState(true) - } - is Resource.Success -> { - presenter.setData(it.data!!) - presenter.updateProgressbarState(false) - } - is Resource.Error -> { - presenter.updateProgressbarState(false) - } - } - } - } - }, - { e -> - e.printStackTrace() - } - ) - } - } - }, - { - it.printStackTrace() - } - ) - } - - fun onBack() { - presenter.onBack() - .subscribeOn(detailsScheduler.io) - .observeOn(detailsScheduler.main) - .subscribe( - object : Consumer { - override fun accept(t: Boolean?) { - t?.let { - detailsListener.onBackPress() - } - } - }, - { - it.printStackTrace() - } - ) - } - - override fun willResignActive() { - super.willResignActive() - - // TODO: Perform any required clean up here, or delete this method entirely if not needed. - } - - /** - * Presenter interface implemented by this RIB's view. - */ - interface DetailsPresenter { - fun onBack(): Observable - fun setData(data: CatalogueDetail) - fun updateProgressbarState(isVisible: Boolean) - } - - interface DetailsListener { - fun onBackPress() - } -} diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/details/DetailsView.kt b/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/details/DetailsView.kt deleted file mode 100644 index 97c4806..0000000 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/details/DetailsView.kt +++ /dev/null @@ -1,56 +0,0 @@ -package com.example.ribs_demo_android.ribs.root.home.catalogue.details - -import android.content.Context -import android.util.AttributeSet -import android.widget.ImageView -import android.widget.LinearLayout -import android.widget.ProgressBar -import android.widget.TextView -import androidx.constraintlayout.widget.ConstraintLayout -import androidx.core.view.isVisible -import com.bumptech.glide.Glide -import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions -import com.example.ribs_demo_android.R -import com.example.ribs_demo_android.models.CatalogueDetail -import io.reactivex.Observable -import io.reactivex.Observer - -/** - * Top level view for {@link DetailsBuilder.DetailsScope}. - */ -class DetailsView @JvmOverloads constructor( - context: Context, - attrs: AttributeSet? = null, - defStyle: Int = 0 -) : ConstraintLayout(context, attrs, defStyle), DetailsInteractor.DetailsPresenter { - - override fun onBack(): Observable { - return object : Observable() { - override fun subscribeActual(observer: Observer?) { - findViewById(R.id.back).setOnClickListener { - observer?.onNext(true) - } - } - } - } - - override fun setData(data: CatalogueDetail) { - findViewById(R.id.name).text = data.name - findViewById(R.id.rarity).text = data.rarity - findViewById(R.id.hp).text = data.hp - findViewById(R.id.type).text = data.type - - Glide.with(context) - .load(data.imageUrl) - .transition(DrawableTransitionOptions.withCrossFade()) - .into(findViewById(R.id.icon_detail)) - } - - override fun updateProgressbarState(isVisible: Boolean) { - findViewById(R.id.progressbar_details).isVisible = isVisible - findViewById(R.id.name_label).isVisible = !isVisible - findViewById(R.id.hp_label).isVisible = !isVisible - findViewById(R.id.rarity_label).isVisible = !isVisible - findViewById(R.id.type_label).isVisible = !isVisible - } -} diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/repository/CatalogueRepository.kt b/app/src/main/java/com/example/ribs_demo_android/ribs/root/repository/CatalogueRepository.kt deleted file mode 100644 index fbec933..0000000 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/repository/CatalogueRepository.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.example.ribs_demo_android.ribs.root.repository - -import com.example.ribs_demo_android.models.CatalogueDetail -import com.example.ribs_demo_android.models.CatalogueResponse -import com.example.ribs_demo_android.util.Resource -import io.reactivex.Observable - -interface CatalogueRepository { - - fun getAll(page: Int): Observable> - - fun getDetail(name: String): Observable> -} \ No newline at end of file diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/repository/CategoryRepository.kt b/app/src/main/java/com/example/ribs_demo_android/ribs/root/repository/CategoryRepository.kt deleted file mode 100644 index 7057d7d..0000000 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/repository/CategoryRepository.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.example.ribs_demo_android.ribs.root.repository - -import com.example.ribs_demo_android.models.CatalogueResponse -import com.example.ribs_demo_android.util.Resource -import io.reactivex.Observable - -interface CategoryRepository { - - fun getByRarity(rarity: String): Observable> -} \ No newline at end of file diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/repository/DetailsRepository.kt b/app/src/main/java/com/example/ribs_demo_android/ribs/root/repository/DetailsRepository.kt deleted file mode 100644 index f486758..0000000 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/repository/DetailsRepository.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.example.ribs_demo_android.ribs.root.repository - -import com.example.ribs_demo_android.models.CatalogueDetail -import com.example.ribs_demo_android.util.Resource -import io.reactivex.Observable - -interface DetailsRepository { - - fun getDetail(name: String): Observable> -} \ No newline at end of file diff --git a/app/src/main/java/com/example/ribs_demo_android/App.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/App.kt similarity index 65% rename from app/src/main/java/com/example/ribs_demo_android/App.kt rename to app/src/main/java/com/solacestudios/ribs_demo_android/App.kt index 18b2575..65569bd 100644 --- a/app/src/main/java/com/example/ribs_demo_android/App.kt +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/App.kt @@ -1,7 +1,6 @@ -package com.example.ribs_demo_android +package com.solacestudios.ribs_demo_android import android.app.Application -import androidx.annotation.VisibleForTesting class App: Application() { diff --git a/app/src/main/java/com/example/ribs_demo_android/models/Catalogue.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/models/Catalogue.kt similarity index 81% rename from app/src/main/java/com/example/ribs_demo_android/models/Catalogue.kt rename to app/src/main/java/com/solacestudios/ribs_demo_android/models/Catalogue.kt index 432156e..ce8da34 100644 --- a/app/src/main/java/com/example/ribs_demo_android/models/Catalogue.kt +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/models/Catalogue.kt @@ -1,4 +1,4 @@ -package com.example.ribs_demo_android.models +package com.solacestudios.ribs_demo_android.models import com.google.gson.annotations.SerializedName diff --git a/app/src/main/java/com/example/ribs_demo_android/models/CatalogueDetail.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/models/CatalogueDetail.kt similarity index 86% rename from app/src/main/java/com/example/ribs_demo_android/models/CatalogueDetail.kt rename to app/src/main/java/com/solacestudios/ribs_demo_android/models/CatalogueDetail.kt index c15638a..c184e5e 100644 --- a/app/src/main/java/com/example/ribs_demo_android/models/CatalogueDetail.kt +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/models/CatalogueDetail.kt @@ -1,4 +1,4 @@ -package com.example.ribs_demo_android.models +package com.solacestudios.ribs_demo_android.models import com.google.gson.annotations.SerializedName diff --git a/app/src/main/java/com/example/ribs_demo_android/models/CatalogueResponse.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/models/CatalogueResponse.kt similarity index 85% rename from app/src/main/java/com/example/ribs_demo_android/models/CatalogueResponse.kt rename to app/src/main/java/com/solacestudios/ribs_demo_android/models/CatalogueResponse.kt index 751fcd7..f4f84cb 100644 --- a/app/src/main/java/com/example/ribs_demo_android/models/CatalogueResponse.kt +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/models/CatalogueResponse.kt @@ -1,4 +1,4 @@ -package com.example.ribs_demo_android.models +package com.solacestudios.ribs_demo_android.models import com.google.gson.annotations.SerializedName diff --git a/app/src/main/java/com/solacestudios/ribs_demo_android/network/ApiCallUtils.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/network/ApiCallUtils.kt new file mode 100644 index 0000000..cad241e --- /dev/null +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/network/ApiCallUtils.kt @@ -0,0 +1,19 @@ +package com.solacestudios.ribs_demo_android.network + +import com.solacestudios.ribs_demo_android.util.Resource +import io.reactivex.rxjava3.core.Observable +import io.reactivex.rxjava3.schedulers.Schedulers + +fun createResult(apiObserver: Observable): Observable> { + return Observable.create { emitter -> + emitter.onNext(Resource.Loading()) + + apiObserver + .subscribeOn(Schedulers.io()) + .subscribe ({ + if (!emitter.isDisposed) { + emitter.onNext(Resource.Success(it)) + } + }){emitter.onNext(Resource.Error(it.message.toString()))} + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/ribs_demo_android/network/CatalogueService.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/network/CatalogueService.kt similarity index 59% rename from app/src/main/java/com/example/ribs_demo_android/network/CatalogueService.kt rename to app/src/main/java/com/solacestudios/ribs_demo_android/network/CatalogueService.kt index 8e9add5..fbdeab9 100644 --- a/app/src/main/java/com/example/ribs_demo_android/network/CatalogueService.kt +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/network/CatalogueService.kt @@ -1,8 +1,8 @@ -package com.example.ribs_demo_android.network +package com.solacestudios.ribs_demo_android.network -import com.example.ribs_demo_android.models.CatalogueDetail -import com.example.ribs_demo_android.models.CatalogueResponse -import io.reactivex.Observable +import com.solacestudios.ribs_demo_android.models.CatalogueDetail +import com.solacestudios.ribs_demo_android.models.CatalogueResponse +import io.reactivex.rxjava3.core.Observable import retrofit2.http.GET import retrofit2.http.Path import retrofit2.http.Query diff --git a/app/src/main/java/com/example/ribs_demo_android/network/CategoryService.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/network/CategoryService.kt similarity index 60% rename from app/src/main/java/com/example/ribs_demo_android/network/CategoryService.kt rename to app/src/main/java/com/solacestudios/ribs_demo_android/network/CategoryService.kt index af80094..5cc026c 100644 --- a/app/src/main/java/com/example/ribs_demo_android/network/CategoryService.kt +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/network/CategoryService.kt @@ -1,8 +1,8 @@ -package com.example.ribs_demo_android.network +package com.solacestudios.ribs_demo_android.network -import com.example.ribs_demo_android.models.CatalogueDetail -import com.example.ribs_demo_android.models.CatalogueResponse -import io.reactivex.Observable +import com.solacestudios.ribs_demo_android.models.CatalogueDetail +import com.solacestudios.ribs_demo_android.models.CatalogueResponse +import io.reactivex.rxjava3.core.Observable import retrofit2.http.GET import retrofit2.http.Path diff --git a/app/src/main/java/com/example/ribs_demo_android/network/DetailsService.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/network/DetailsService.kt similarity index 54% rename from app/src/main/java/com/example/ribs_demo_android/network/DetailsService.kt rename to app/src/main/java/com/solacestudios/ribs_demo_android/network/DetailsService.kt index 6c1840e..f491926 100644 --- a/app/src/main/java/com/example/ribs_demo_android/network/DetailsService.kt +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/network/DetailsService.kt @@ -1,7 +1,7 @@ -package com.example.ribs_demo_android.network +package com.solacestudios.ribs_demo_android.network -import com.example.ribs_demo_android.models.CatalogueDetail -import io.reactivex.Observable +import com.solacestudios.ribs_demo_android.models.CatalogueDetail +import io.reactivex.rxjava3.core.Observable import retrofit2.http.GET import retrofit2.http.Path diff --git a/app/src/main/java/com/solacestudios/ribs_demo_android/repository/CatalogueRepository.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/repository/CatalogueRepository.kt new file mode 100644 index 0000000..32f3986 --- /dev/null +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/repository/CatalogueRepository.kt @@ -0,0 +1,28 @@ +package com.solacestudios.ribs_demo_android.repository + +import com.solacestudios.ribs_demo_android.models.CatalogueDetail +import com.solacestudios.ribs_demo_android.models.CatalogueResponse +import com.solacestudios.ribs_demo_android.network.CatalogueService +import com.solacestudios.ribs_demo_android.network.createResult +import com.solacestudios.ribs_demo_android.util.Resource +import io.reactivex.rxjava3.core.Observable + +interface CatalogueRepository { + + fun getAll(page: Int): Observable> + + fun getDetail(name: String): Observable> +} + +class CatalogueRepositoryImpl( + private val catalogueService: CatalogueService +) : CatalogueRepository { + + override fun getAll(page: Int): Observable> { + return createResult(catalogueService.getAll(page)) + } + + override fun getDetail(name: String): Observable> { + return createResult(catalogueService.getDetail(name)) + } +} diff --git a/app/src/main/java/com/solacestudios/ribs_demo_android/repository/CategoryRepository.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/repository/CategoryRepository.kt new file mode 100644 index 0000000..1bc52ac --- /dev/null +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/repository/CategoryRepository.kt @@ -0,0 +1,22 @@ +package com.solacestudios.ribs_demo_android.repository + +import com.solacestudios.ribs_demo_android.models.CatalogueResponse +import com.solacestudios.ribs_demo_android.network.CategoryService +import com.solacestudios.ribs_demo_android.network.createResult +import com.solacestudios.ribs_demo_android.util.Resource +import io.reactivex.rxjava3.core.Observable + + +interface CategoryRepository { + + fun getByRarity(rarity: String): Observable> +} + +class CategoryRepositoryImpl( + private val categoryService: CategoryService, +) : CategoryRepository { + + override fun getByRarity(rarity: String): Observable> { + return createResult(categoryService.getByRarity(rarity)) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/solacestudios/ribs_demo_android/repository/DetailsRepository.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/repository/DetailsRepository.kt new file mode 100644 index 0000000..fb435b5 --- /dev/null +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/repository/DetailsRepository.kt @@ -0,0 +1,19 @@ +package com.solacestudios.ribs_demo_android.repository + +import com.solacestudios.ribs_demo_android.models.CatalogueDetail +import com.solacestudios.ribs_demo_android.network.DetailsService +import com.solacestudios.ribs_demo_android.network.createResult +import com.solacestudios.ribs_demo_android.util.Resource +import io.reactivex.rxjava3.core.Observable + +interface DetailsRepository { + fun getDetail(name: String): Observable> +} + +class DetailsRepositoryImpl( + private val detailsService: DetailsService +) : DetailsRepository { + override fun getDetail(name: String): Observable> { + return createResult(detailsService.getDetail(name)) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/MainActivity.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/MainActivity.kt new file mode 100644 index 0000000..4a14f07 --- /dev/null +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/MainActivity.kt @@ -0,0 +1,50 @@ +package com.solacestudios.ribs_demo_android.ribs + +import android.util.Log +import android.view.ViewGroup +import com.solacestudios.ribs_demo_android.ribs.root.RootBuilder +import com.solacestudios.ribs_demo_android.ribs.root.RootInteractor +import com.solacestudios.ribs_demo_android.ribs.root.RootView +import com.solacestudios.ribscodegen.root.RootComponent +import com.uber.rib.core.RibActivity +import com.uber.rib.core.ViewRouter +import io.reactivex.exceptions.UndeliverableException +import io.reactivex.plugins.RxJavaPlugins +import java.io.IOException +import java.net.SocketException + +class MainActivity : RibActivity() { + + override fun createRouter(parentViewGroup: ViewGroup): ViewRouter { + RxJavaPlugins.setErrorHandler { e: Throwable -> + var x = e + if (x is UndeliverableException) { + //x = e.cause!! + return@setErrorHandler + } + if (e is IOException || e is SocketException) { + // fine, irrelevant network problem or API that throws on cancellation + return@setErrorHandler + } + if (e is InterruptedException) { + // fine, some blocking code was interrupted by a dispose call + return@setErrorHandler + } + if (e is NullPointerException || e is IllegalArgumentException) { + // that's likely a bug in the application + Thread.currentThread().uncaughtExceptionHandler + .uncaughtException(Thread.currentThread(), e) + return@setErrorHandler + } + if (e is IllegalStateException) { + // that's a bug in RxJava or in a custom operator + Thread.currentThread().uncaughtExceptionHandler + .uncaughtException(Thread.currentThread(), e) + return@setErrorHandler + } + Log.println(Log.WARN,"Undeliverable exception received, not sure what to do", x.message!!) + } + + return RootBuilder(object : RootComponent.ParentComponent {}).build(parentViewGroup) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/catalogue/CatalogueBuilder.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/catalogue/CatalogueBuilder.kt new file mode 100644 index 0000000..00342a9 --- /dev/null +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/catalogue/CatalogueBuilder.kt @@ -0,0 +1,40 @@ +package com.solacestudios.ribs_demo_android.ribs.catalogue + +import android.view.LayoutInflater +import android.view.ViewGroup +import com.solacestudios.ribs_demo_android.R +import com.uber.rib.core.ViewBuilder + +/** + * Builder for the {@link CatalogueScope}. + * + * TODO describe this scope's responsibility as a whole. + */ +class CatalogueBuilder(dependency: CatalogueComponent.ParentComponent) : + ViewBuilder(dependency) { + + /** + * Builds a new [CatalogueRouter]. + * + * @param parentViewGroup parent view group that this router's view will be added to. + * @return a new [CatalogueRouter]. + */ + fun build(parentViewGroup: ViewGroup): CatalogueRouter { + val view = createView(parentViewGroup) + view.initViewIds() + val interactor = CatalogueInteractor() + val component = DaggerCatalogueComponent.builder() + .parentComponent(dependency) + .view(view) + .interactor(interactor) + .build() + return component.getCatalogueRouter() + } + + override fun inflateView(inflater: LayoutInflater, parentViewGroup: ViewGroup): CatalogueView { + // TODO: Inflate a new view using the provided inflater, or create a new view programatically using the + // provided context from the parentViewGroup. + return inflater.inflate(R.layout.catalogue_rib, parentViewGroup, false) as CatalogueView + } + +} diff --git a/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/catalogue/CatalogueComponent.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/catalogue/CatalogueComponent.kt new file mode 100644 index 0000000..87e82a1 --- /dev/null +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/catalogue/CatalogueComponent.kt @@ -0,0 +1,156 @@ +package com.solacestudios.ribs_demo_android.ribs.catalogue + +import android.view.ViewGroup +import com.solacestudios.ribs_demo_android.network.CatalogueService +import com.solacestudios.ribs_demo_android.network.DetailsService +import com.solacestudios.ribs_demo_android.repository.CatalogueRepository +import com.solacestudios.ribs_demo_android.repository.DetailsRepository +import com.solacestudios.ribs_demo_android.repository.DetailsRepositoryImpl +import com.solacestudios.ribs_demo_android.ribs.details.DetailsBuilder +import com.solacestudios.ribs_demo_android.ribs.details.DetailsInteractor +import com.solacestudios.ribs_demo_android.util.Constants +import com.solacestudios.ribs_demo_android.ribs.details.DetailsComponent +import com.solacestudios.ribs_demo_android.util.DataStream +import com.solacestudios.ribs_demo_android.util.MutableDataStream +import com.uber.rib.core.InteractorBaseComponent +import dagger.* +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory +import retrofit2.converter.gson.GsonConverterFactory +import java.lang.annotation.Retention +import java.lang.annotation.RetentionPolicy +import javax.inject.Named +import javax.inject.Qualifier +import javax.inject.Scope + +@CatalogueScope +@Component( + modules = [CatalogueModule::class], + dependencies = [CatalogueComponent.ParentComponent::class] +) +interface CatalogueComponent : InteractorBaseComponent, DetailsComponent.ParentComponent { + fun getCatalogueRouter(): CatalogueRouter + + interface ParentComponent { + fun service(): CatalogueService + fun catalogueListener(): CatalogueInteractor.Listener + fun catalogueRepository(): CatalogueRepository + } + + @Component.Builder + interface Builder { + @BindsInstance + fun interactor(interactor: CatalogueInteractor): Builder + + @BindsInstance + fun view(view: CatalogueView): Builder + + fun parentComponent(component: ParentComponent): Builder + + fun build(): CatalogueComponent + } +} + +@Module +abstract class CatalogueModule { + @Binds + @CatalogueScope + internal abstract fun buildPresenter(view: CatalogueView): CatalogueInteractor.Presenter + + @Binds + @CatalogueScope + internal abstract fun buildContainerView(view: CatalogueView): ViewGroup + + @Module + companion object { + var logging : HttpLoggingInterceptor = run { + val httpLoggingInterceptor = HttpLoggingInterceptor() + httpLoggingInterceptor.apply { + httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY + } + } + var clientCatalogue : OkHttpClient = OkHttpClient.Builder().addInterceptor(logging).build() + + @CatalogueScope + @Provides + @JvmStatic + internal fun router(view: CatalogueView, + component: CatalogueComponent, + interactor: CatalogueInteractor): CatalogueRouter = + CatalogueRouter(view, interactor, component, DetailsBuilder(component)) + + + //Provide Details Interactor's Listener to DetailsParent Catalogue + @CatalogueScope + @Provides + @JvmStatic + internal fun provideDetailsParentListener(interactor: CatalogueInteractor): DetailsInteractor.Listener = + interactor.DetailsParentListener() + + + //Provide Mutable Data Stream + @CatalogueScope + @CatalogueInternal + @Provides + internal fun provideMutableDataStream(): MutableDataStream { + return MutableDataStream("initial") + } + + @CatalogueScope + @Provides + fun provideDataStream(@CatalogueInternal mutableDataStream: MutableDataStream): DataStream { + return mutableDataStream + } + + + @Provides + @Named("gson") + fun providesGsonConverterFactory(): GsonConverterFactory { + return GsonConverterFactory.create() + } + + @CatalogueScope + @Provides + @JvmStatic + @Named("catalogue_retrofit") + internal fun provideRetrofit( + @Named("gson") gsonConverterFactory: GsonConverterFactory + ): Retrofit { + return Retrofit.Builder() + .baseUrl(Constants.BASE_URL) + .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) + .addConverterFactory(gsonConverterFactory) + .client(clientCatalogue) + .build() + } + + @CatalogueScope + @Provides + @JvmStatic + internal fun provideService( + @Named("catalogue_retrofit") retrofit: Retrofit + ): DetailsService { + return retrofit.create(DetailsService::class.java) + } + + @CatalogueScope + @Provides + @JvmStatic + internal fun provideDetailsRepository( + service: DetailsService, + ): DetailsRepository { + return DetailsRepositoryImpl(service) + } + + } +} + +@Scope +@Retention(RetentionPolicy.CLASS) +internal annotation class CatalogueScope + +@Qualifier +@Retention(RetentionPolicy.CLASS) +internal annotation class CatalogueInternal \ No newline at end of file diff --git a/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/catalogue/CatalogueInteractor.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/catalogue/CatalogueInteractor.kt new file mode 100644 index 0000000..a812fed --- /dev/null +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/catalogue/CatalogueInteractor.kt @@ -0,0 +1,144 @@ +package com.solacestudios.ribs_demo_android.ribs.catalogue + +import android.util.Log +import com.solacestudios.ribs_demo_android.models.Catalogue +import com.solacestudios.ribs_demo_android.models.CatalogueResponse +import com.solacestudios.ribs_demo_android.network.CatalogueService +import com.solacestudios.ribs_demo_android.ribs.details.DetailsInteractor +import com.solacestudios.ribs_demo_android.repository.CatalogueRepository +import com.solacestudios.ribs_demo_android.util.MutableDataStream +import com.solacestudios.ribs_demo_android.util.Resource +import com.solacestudios.ribs_demo_android.util.RibsScheduler +import com.solacestudios.ribs_demo_android.util.RibsSchedulerImpl +import com.uber.rib.core.Bundle +import com.uber.rib.core.Interactor +import com.uber.rib.core.RibInteractor +import io.reactivex.rxjava3.core.Observable +import io.reactivex.rxjava3.disposables.CompositeDisposable +import javax.inject.Inject + +/** + * Coordinates Business Logic for [CatalogueScope]. + * + * TODO describe the logic of this scope. + */ +@RibInteractor +class CatalogueInteractor : Interactor() { + companion object { + const val TAG = "CatalogueInteractor" + var catalogueScheduler: RibsScheduler = RibsSchedulerImpl() + } + @Inject + lateinit var buildPresenter: Presenter + + @Inject + lateinit var catalogueService: CatalogueService + + @Inject + lateinit var catalogueListener: Listener + + @Inject + lateinit var catalogueRepository: CatalogueRepository + + @Inject @CatalogueInternal + lateinit var dataStream: MutableDataStream + + + private var disposables = CompositeDisposable() + + override fun didBecomeActive(savedInstanceState: Bundle?) { + super.didBecomeActive(savedInstanceState) + + // TODO: Add attachment logic here (RxSubscriptions, etc.). + + getInitialData(1) + .observeOn(catalogueScheduler.main) + .doOnSubscribe { disposables.add(it) } + .subscribe({result -> handleResult(result)}) { + Log.e(TAG, it.toString()) + } + + handleCategoryToggle() + handleCategoryTaps() + } + + private fun handleCategoryTaps() { + buildPresenter.categoryTaps() + .doOnSubscribe { disposables.add(it) } + .observeOn(catalogueScheduler.main) + .subscribe({ category -> + Log.e(this.javaClass.name, "itemClickedObserved: $category") + router.attachDetails() + dataStream.setData(category) + }) {Log.e(TAG, it.toString())} + } + + private fun handleResult(state: Resource) { + + when (state) { + is Resource.Loading -> { + Log.e(this.javaClass.name, "Handle Result: " + "Loading") + + buildPresenter.updateProgressbarState(true) + } + is Resource.Success -> { + Log.e(this.javaClass.name, "Handle Result: " + "Success") + + buildPresenter.updateProgressbarState(false) + buildPresenter.setupUI(state.data!!.brawlers) + } + is Resource.Error -> { + Log.e(this.javaClass.name, "Handle Result: " + "Error") + + buildPresenter.updateProgressbarState(false) + } + } + } + + fun getInitialData(page: Int): Observable> { + Log.e(this.javaClass.name, "getInitialData ") + + return catalogueRepository.getAll(1) + } + + fun handleCategoryToggle() { + buildPresenter.onCategoryToggle() + .subscribeOn(catalogueScheduler.io) + .observeOn(catalogueScheduler.main) + .doOnSubscribe { disposables.add(it) } + .subscribe({catalogueListener.onClick()}) { + Log.e(TAG, "handleCategoryToggle:: $it") + } + } + + override fun willResignActive() { + // TODO: Perform any required clean up here, or delete this method entirely if not needed. + super.willResignActive() + + if (!disposables.isDisposed){ + disposables.dispose() + disposables = CompositeDisposable() + } + } + + /** + * Presenter interface implemented by this RIB's view. + */ + interface Presenter { + fun setupUI(items: List) + fun updateProgressbarState(isVisible: Boolean) + fun onCategoryToggle(): Observable + fun categoryTaps(): Observable + } + + interface Listener { + fun onClick() + } + + + inner class DetailsParentListener: DetailsInteractor.Listener { + override fun onBackPress() { + router.detachDetails() + } + } +} diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/CatalogueRouter.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/catalogue/CatalogueRouter.kt similarity index 66% rename from app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/CatalogueRouter.kt rename to app/src/main/java/com/solacestudios/ribs_demo_android/ribs/catalogue/CatalogueRouter.kt index fa69c8c..2c0e773 100644 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/CatalogueRouter.kt +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/catalogue/CatalogueRouter.kt @@ -1,22 +1,21 @@ -package com.example.ribs_demo_android.ribs.root.home.catalogue +package com.solacestudios.ribs_demo_android.ribs.catalogue -import com.example.ribs_demo_android.ribs.root.home.catalogue.details.DetailsBuilder -import com.example.ribs_demo_android.ribs.root.home.catalogue.details.DetailsRouter +import com.solacestudios.ribs_demo_android.ribs.details.DetailsBuilder +import com.solacestudios.ribs_demo_android.ribs.details.DetailsRouter import com.uber.rib.core.ViewRouter /** - * Adds and removes children of {@link CatalogueBuilder.CatalogueScope}. + * Adds and removes children of {@link CatalogueScope}. * * TODO describe the possible child configurations of this scope. */ class CatalogueRouter( view: CatalogueView, interactor: CatalogueInteractor, - component: CatalogueBuilder.Component, + component: CatalogueComponent, private val detailsBuilder: DetailsBuilder ) : ViewRouter(view, interactor, component) { - private var detailsRouter: DetailsRouter? = null fun attachDetails() { diff --git a/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/catalogue/CatalogueView.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/catalogue/CatalogueView.kt new file mode 100644 index 0000000..e344dfb --- /dev/null +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/catalogue/CatalogueView.kt @@ -0,0 +1,60 @@ +package com.solacestudios.ribs_demo_android.ribs.catalogue + +import android.content.Context +import android.util.AttributeSet +import android.util.Log +import android.widget.ProgressBar +import android.widget.TextView +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.view.isVisible +import androidx.recyclerview.widget.RecyclerView +import com.solacestudios.ribs_demo_android.R +import com.solacestudios.ribs_demo_android.ribs.catalogue.adapter.CatalogueAdapter.CatalogueAdapter +import com.solacestudios.ribs_demo_android.models.Catalogue +import io.reactivex.rxjava3.core.Observable +import io.reactivex.rxjava3.subjects.PublishSubject + +/** + * Top level view for {@link CatalogueScope}. + */ +class CatalogueView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyle: Int = 0 +) : ConstraintLayout(context, attrs, defStyle), CatalogueInteractor.Presenter { + private lateinit var catalogueRecycler: RecyclerView + private lateinit var progressBar: ProgressBar + private lateinit var tvFilters: TextView + + private lateinit var adapter: CatalogueAdapter + private val itemTaps = PublishSubject.create() + private val filterTaps = PublishSubject.create() + + fun initViewIds() { + this.catalogueRecycler = findViewById(R.id.RecyclerView) + this.progressBar = findViewById(R.id.progressbar_catalogue) + this.tvFilters = findViewById(R.id.filters) + adapter = CatalogueAdapter { name -> + Log.e(this.javaClass.name, "itemClicked: $name") + itemTaps.onNext(name) + } + tvFilters.setOnClickListener { filterTaps.onNext(true) } + catalogueRecycler.adapter = adapter + } + + override fun setupUI(items: List) { + adapter.setItems(items) + } + + override fun categoryTaps(): Observable { + return itemTaps + } + + override fun updateProgressbarState(isVisible: Boolean) { + progressBar.isVisible = isVisible + } + + override fun onCategoryToggle(): Observable { + return filterTaps + } +} diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/adapter/CatalogueAdapter/CatalogueAdapter.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/catalogue/adapter/CatalogueAdapter/CatalogueAdapter.kt similarity index 70% rename from app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/adapter/CatalogueAdapter/CatalogueAdapter.kt rename to app/src/main/java/com/solacestudios/ribs_demo_android/ribs/catalogue/adapter/CatalogueAdapter/CatalogueAdapter.kt index d6eeb5b..53e478f 100644 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/adapter/CatalogueAdapter/CatalogueAdapter.kt +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/catalogue/adapter/CatalogueAdapter/CatalogueAdapter.kt @@ -1,29 +1,36 @@ -package com.example.ribs_demo_android.ribs.root.home.catalogue.adapter.CatalogueAdapter +package com.solacestudios.ribs_demo_android.ribs.catalogue.adapter.CatalogueAdapter import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions -import com.example.ribs_demo_android.R -import com.example.ribs_demo_android.databinding.ItemCatalogueBinding -import com.example.ribs_demo_android.models.Catalogue +import com.solacestudios.ribs_demo_android.R +import com.solacestudios.ribs_demo_android.databinding.ItemCatalogueBinding +import com.solacestudios.ribs_demo_android.models.Catalogue class CatalogueAdapter( - private val items: List, private val onClick: (String) -> Unit ) : RecyclerView.Adapter() { + private var items: List = emptyList() + fun setItems(items: List){ + this.items = items + notifyDataSetChanged() + } inner class ViewHolder(private val binding: ItemCatalogueBinding) : RecyclerView.ViewHolder(binding.root) { + init { + binding.root.setOnClickListener { v -> + onClick(items[adapterPosition].name) + } + } fun bind(item: Catalogue?) { item?.let { binding.name.text = it.name binding.rarity.text = it.rarity - binding.root.setOnClickListener { v -> - onClick(it.name) - } + Glide.with(binding.root) .load(it.imageUrl) diff --git a/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/category/CategoryBuilder.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/category/CategoryBuilder.kt new file mode 100644 index 0000000..6a36f08 --- /dev/null +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/category/CategoryBuilder.kt @@ -0,0 +1,33 @@ +package com.solacestudios.ribs_demo_android.ribs.category + +import android.view.LayoutInflater +import android.view.ViewGroup +import com.solacestudios.ribs_demo_android.R +import com.uber.rib.core.ViewBuilder + +/** + * Builder for the {@link CategoryScope}. + * + * TODO describe this scope's responsibility as a whole. + */ +class CategoryBuilder(dependency: CategoryComponent.ParentComponent) : + ViewBuilder(dependency) { + + fun build(parentViewGroup: ViewGroup): CategoryRouter { + val view = createView(parentViewGroup) + view.initViewIds() + val interactor = CategoryInteractor() + val component = DaggerCategoryComponent.builder() + .parentComponent(dependency) + .view(view) + .interactor(interactor) + .build() + return component.getCategoryRouter() + } + override fun inflateView(inflater: LayoutInflater, parentViewGroup: ViewGroup): CategoryView { + // TODO: Inflate a new view using the provided inflater, or create a new view programatically using the + // provided context from the parentViewGroup. + return inflater.inflate(R.layout.category_rib, parentViewGroup, false) as CategoryView + } + +} diff --git a/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/category/CategoryComponent.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/category/CategoryComponent.kt new file mode 100644 index 0000000..6848dde --- /dev/null +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/category/CategoryComponent.kt @@ -0,0 +1,102 @@ +package com.solacestudios.ribs_demo_android.ribs.category + +import android.view.ViewGroup +import com.solacestudios.ribs_demo_android.network.CategoryService +import com.solacestudios.ribs_demo_android.util.Constants +import com.uber.rib.core.InteractorBaseComponent +import dagger.* +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory +import retrofit2.converter.gson.GsonConverterFactory +import java.lang.annotation.Retention +import java.lang.annotation.RetentionPolicy +import javax.inject.Named +import javax.inject.Scope + +@CategoryScope +@Component( + modules = [CategoryModule::class], + dependencies = [CategoryComponent.ParentComponent::class] +) +interface CategoryComponent : InteractorBaseComponent { + fun getCategoryRouter(): CategoryRouter + + interface ParentComponent { + fun categoryListener(): CategoryInteractor.Listener + } + + @Component.Builder + interface Builder { + @BindsInstance + fun interactor(interactor: CategoryInteractor): Builder + + @BindsInstance + fun view(view: CategoryView): Builder + + fun parentComponent(component: ParentComponent): Builder + + fun build(): CategoryComponent + } +} + +@Module +abstract class CategoryModule { + @Binds + @CategoryScope + internal abstract fun buildPresenter(view: CategoryView): CategoryInteractor.Presenter + + @Binds + @CategoryScope + internal abstract fun buildContainerView(view: CategoryView): ViewGroup + + @Module + companion object { + var logging : HttpLoggingInterceptor = run { + val httpLoggingInterceptor = HttpLoggingInterceptor() + httpLoggingInterceptor.apply { + httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY + } + } + var client : OkHttpClient = OkHttpClient.Builder().addInterceptor(logging).build() + + @CategoryScope + @Provides + @JvmStatic + internal fun router(view: CategoryView, component: CategoryComponent, interactor: CategoryInteractor): CategoryRouter = + CategoryRouter(view, interactor, component) + + @Provides + fun providesGsonConverterFactory(): GsonConverterFactory { + return GsonConverterFactory.create() + } + + @CategoryScope + @Provides + @JvmStatic + internal fun provideRetrofit( + gsonConverterFactory: GsonConverterFactory + ): Retrofit { + return Retrofit.Builder() + .baseUrl(Constants.BASE_URL) + .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) + .addConverterFactory(gsonConverterFactory) + .client(client) + .build() + } + + @CategoryScope + @Provides + @JvmStatic + internal fun provideCategoryService( + retrofit: Retrofit + ): CategoryService { + return retrofit.create(CategoryService::class.java) + } + } +} + +@Scope +@Retention(RetentionPolicy.CLASS) +internal annotation class CategoryScope diff --git a/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/category/CategoryInteractor.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/category/CategoryInteractor.kt new file mode 100644 index 0000000..cfbd7aa --- /dev/null +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/category/CategoryInteractor.kt @@ -0,0 +1,134 @@ +package com.solacestudios.ribs_demo_android.ribs.category + +import android.util.Log +import com.solacestudios.ribs_demo_android.models.Catalogue +import com.solacestudios.ribs_demo_android.models.CatalogueResponse +import com.solacestudios.ribs_demo_android.network.CategoryService +import com.solacestudios.ribs_demo_android.repository.CategoryRepositoryImpl +import com.solacestudios.ribs_demo_android.repository.CategoryRepository +import com.solacestudios.ribs_demo_android.util.Resource +import com.solacestudios.ribs_demo_android.util.RibsScheduler +import com.solacestudios.ribs_demo_android.util.RibsSchedulerImpl +import com.uber.rib.core.Bundle +import com.uber.rib.core.Interactor +import com.uber.rib.core.RibInteractor +import io.reactivex.rxjava3.core.Observable +import io.reactivex.rxjava3.disposables.CompositeDisposable +import javax.inject.Inject +import javax.inject.Named + +/** + * Coordinates Business Logic for [CategoryScope]. + * + * TODO describe the logic of this scope. + */ +@RibInteractor +class CategoryInteractor : Interactor() { + companion object { + const val TAG = "CategoryInteractor" + var categoryScheduler: RibsScheduler = RibsSchedulerImpl() + } + @Inject + lateinit var buildPresenter: Presenter + + @Inject + lateinit var categoryService: CategoryService + + @Inject + lateinit var listener: Listener + +// @Inject +// @Named("categoryRepo") +// lateinit var categoryRepository: CategoryRepository + + lateinit var categoryRepository: CategoryRepository + private var disposables = CompositeDisposable() + + override fun didBecomeActive(savedInstanceState: Bundle?) { + super.didBecomeActive(savedInstanceState) + + // TODO: Add attachment logic here (RxSubscriptions, etc.). + init() + + getByRarity("chromatic") + + handleToggle() + + getChip() + } + + fun init() { + Log.e(TAG, "Entered init function") + + categoryRepository = CategoryRepositoryImpl(categoryService) + } + + fun handleToggle() { + buildPresenter.toggle() + .doOnSubscribe { disposables.add(it)} + .subscribe({ + listener.toggleCategory() + Log.e(TAG, "handleToggle::$it ::Thread:: ${Thread.currentThread().name}") + }) { + Log.e(TAG, "handleToggleFailed::$it ::Thread:: ${Thread.currentThread().name}") + } + } + + fun getChip() { + buildPresenter.getChip() + .doOnSubscribe { disposables.add(it)} + .subscribeOn(categoryScheduler.io) + .observeOn(categoryScheduler.main) + .subscribe({getByRarity(it)}){ + Log.e(TAG, "getChip$it") + } + } + + fun getByRarity(rarity: String) { + categoryRepository.getByRarity(rarity) + .subscribeOn(categoryScheduler.io) + .doOnSubscribe { disposables.add(it)} + .observeOn(categoryScheduler.main) + .subscribe({handleResult(it)}) { + Log.e(TAG, "getByRarity::$it") + } + } + + private fun handleResult(result: Resource) { + when (result) { + is Resource.Loading -> { + buildPresenter.updateProgressbarState(true) + } + is Resource.Success -> { + buildPresenter.setup(result.data?.brawlers!!) + buildPresenter.updateProgressbarState(false) + } + is Resource.Error -> { + buildPresenter.updateProgressbarState(false) + } + } + } + + override fun willResignActive() { + super.willResignActive() + if (!disposables.isDisposed) { + disposables.dispose() + disposables = CompositeDisposable() + } + // TODO: Perform any required clean up here, or delete this method entirely if not needed. + } + + /** + * Presenter interface implemented by this RIB's view. + */ + interface Presenter { + fun setup(items: List) + fun toggle(): Observable + fun getChip(): Observable + fun updateProgressbarState(isVisible: Boolean) + } + + interface Listener { + fun toggleCategory() + } +} diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/category/CategoryRouter.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/category/CategoryRouter.kt similarity index 57% rename from app/src/main/java/com/example/ribs_demo_android/ribs/root/category/CategoryRouter.kt rename to app/src/main/java/com/solacestudios/ribs_demo_android/ribs/category/CategoryRouter.kt index f0aa6de..41f63a9 100644 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/category/CategoryRouter.kt +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/category/CategoryRouter.kt @@ -1,6 +1,4 @@ -package com.example.ribs_demo_android.ribs.root.category - -import android.view.View +package com.solacestudios.ribs_demo_android.ribs.category import com.uber.rib.core.ViewRouter @@ -12,4 +10,5 @@ import com.uber.rib.core.ViewRouter class CategoryRouter( view: CategoryView, interactor: CategoryInteractor, - component: CategoryBuilder.Component) : ViewRouter(view, interactor, component) + component: CategoryComponent +) : ViewRouter(view, interactor, component) diff --git a/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/category/CategoryView.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/category/CategoryView.kt new file mode 100644 index 0000000..1c8fb71 --- /dev/null +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/category/CategoryView.kt @@ -0,0 +1,70 @@ +package com.solacestudios.ribs_demo_android.ribs.category + +import android.content.Context +import android.util.AttributeSet +import android.widget.ProgressBar +import android.widget.RelativeLayout +import android.widget.TextView +import androidx.core.view.forEachIndexed +import androidx.core.view.get +import androidx.core.view.isVisible +import androidx.recyclerview.widget.RecyclerView +import com.solacestudios.ribs_demo_android.R +import com.solacestudios.ribs_demo_android.models.Catalogue +import com.solacestudios.ribs_demo_android.ribs.category.adapter.CategoryAdapter +import com.google.android.material.chip.Chip +import com.google.android.material.chip.ChipGroup +import com.jakewharton.rxbinding4.view.clicks +import io.reactivex.rxjava3.core.Observable +import io.reactivex.rxjava3.subjects.PublishSubject + +/** + * Top level view for {@link CategoryBuilder.CategoryScope}. + */ +class CategoryView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyle: Int = 0 +) : RelativeLayout(context, attrs, defStyle), CategoryInteractor.Presenter { + private lateinit var categoryRecyclerView: RecyclerView + private lateinit var tvHome: TextView + private lateinit var chipGroup: ChipGroup + private lateinit var progressBar: ProgressBar + private val chipTaps = PublishSubject.create() + + private val adapter: CategoryAdapter = CategoryAdapter {} + + fun initViewIds() { + this.categoryRecyclerView = findViewById(R.id.rvCategory) + this.categoryRecyclerView.adapter = adapter + this.tvHome = findViewById(R.id.home) + this.chipGroup = findViewById(R.id.chipgroup) + this.progressBar = findViewById(R.id.progressbar_category) + + this.chipGroup.setOnCheckedChangeListener { group, checkedId -> + group.forEachIndexed { index, view -> + if (view.id == checkedId) { + val chip = group[index] as Chip + val query = chip.text.toString().toLowerCase() + chipTaps.onNext(query) + } + } + } + } + + override fun setup(items: List) { + adapter.setItems(items) + } + + override fun toggle(): Observable { + return tvHome.clicks().map { true } + } + + override fun getChip(): Observable { + return chipTaps + } + + override fun updateProgressbarState(isVisible: Boolean) { + findViewById(R.id.progressbar_category).isVisible = isVisible + } +} diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/category/adapter/CategoryAdapter.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/category/adapter/CategoryAdapter.kt similarity index 73% rename from app/src/main/java/com/example/ribs_demo_android/ribs/root/category/adapter/CategoryAdapter.kt rename to app/src/main/java/com/solacestudios/ribs_demo_android/ribs/category/adapter/CategoryAdapter.kt index 62316c7..90208f3 100644 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/category/adapter/CategoryAdapter.kt +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/category/adapter/CategoryAdapter.kt @@ -1,18 +1,23 @@ -package com.example.ribs_demo_android.ribs.root.category.adapter +package com.solacestudios.ribs_demo_android.ribs.category.adapter import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions -import com.example.ribs_demo_android.R -import com.example.ribs_demo_android.databinding.ItemCategoryBinding -import com.example.ribs_demo_android.models.Catalogue +import com.solacestudios.ribs_demo_android.R +import com.solacestudios.ribs_demo_android.databinding.ItemCategoryBinding +import com.solacestudios.ribs_demo_android.models.Catalogue class CategoryAdapter( - private val items: List, private val onClick: (String) -> Unit ) : RecyclerView.Adapter() { + private var items: List = emptyList() + + fun setItems(items:List){ + this.items = items + notifyDataSetChanged() + } inner class ViewHolder(private val binding: ItemCategoryBinding) : RecyclerView.ViewHolder(binding.root) { @@ -33,8 +38,7 @@ class CategoryAdapter( override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val binding = ItemCategoryBinding.inflate( - LayoutInflater.from(parent.context), parent, false - ) + LayoutInflater.from(parent.context), parent, false) return ViewHolder(binding) } diff --git a/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/details/DetailsBuilder.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/details/DetailsBuilder.kt new file mode 100644 index 0000000..c4d4720 --- /dev/null +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/details/DetailsBuilder.kt @@ -0,0 +1,43 @@ +package com.solacestudios.ribs_demo_android.ribs.details + +import android.view.LayoutInflater +import android.view.ViewGroup +import com.solacestudios.ribs_demo_android.R +import com.uber.rib.core.ViewBuilder + +/** + * Builder for the {@link DetailsScope}. + * + * TODO describe this scope's responsibility as a whole. + */ +class DetailsBuilder(dependency: DetailsComponent.ParentComponent) : + ViewBuilder(dependency) { + + /** + * Builds a new [DetailsRouter]. + * + * @param parentViewGroup parent view group that this router's view will be added to. + * @return a new [DetailsRouter]. + */ + fun build(parentViewGroup: ViewGroup): DetailsRouter { + val view = createView(parentViewGroup) + view.initViewIds() + val interactor = DetailsInteractor() + val component = DaggerDetailsComponent.builder() + .parentComponent(dependency) + .view(view) + .interactor(interactor) + .build() + return component.getDetailsRouter() + } + + override fun inflateView(inflater: LayoutInflater, parentViewGroup: ViewGroup): DetailsView { + // TODO: Inflate a new view using the provided inflater, or create a new view programatically using the + // provided context from the parentViewGroup. + return inflater.inflate(R.layout.details_rib, parentViewGroup, false) as DetailsView + } + + // TODO: Create provider methods for dependencies created by this Rib. These should be static. +} + + diff --git a/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/details/DetailsComponent.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/details/DetailsComponent.kt new file mode 100644 index 0000000..c579e13 --- /dev/null +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/details/DetailsComponent.kt @@ -0,0 +1,64 @@ +package com.solacestudios.ribs_demo_android.ribs.details + +import android.view.ViewGroup +import com.solacestudios.ribs_demo_android.network.DetailsService +import com.solacestudios.ribs_demo_android.repository.DetailsRepository +import com.solacestudios.ribs_demo_android.util.DataStream +import com.uber.rib.core.InteractorBaseComponent +import dagger.* +import java.lang.annotation.Retention +import java.lang.annotation.RetentionPolicy +import javax.inject.Scope + +@DetailsScope +@Component( + modules = [DetailsModule::class], + dependencies = [DetailsComponent.ParentComponent::class] +) +interface DetailsComponent : InteractorBaseComponent { + fun getDetailsRouter(): DetailsRouter + + interface ParentComponent { + fun detailsListener(): DetailsInteractor.Listener + fun service(): DetailsService + fun dataStream(): DataStream + fun detailsRepository(): DetailsRepository + } + + @Component.Builder + interface Builder { + @BindsInstance + fun interactor(interactor: DetailsInteractor): Builder + + @BindsInstance + fun view(view: DetailsView): Builder + + fun parentComponent(component: ParentComponent): Builder + + fun build(): DetailsComponent + } +} + +@Module +abstract class DetailsModule { + @Binds + @DetailsScope + internal abstract fun buildPresenter(view: DetailsView): DetailsInteractor.Presenter + + @Binds + @DetailsScope + internal abstract fun buildContainerView(view: DetailsView): ViewGroup + + @Module + companion object { + @DetailsScope + @Provides + @JvmStatic + internal fun router(view: DetailsView, component: DetailsComponent, interactor: DetailsInteractor): DetailsRouter = + DetailsRouter(view, interactor, component) + } +} + +@Scope +@Retention(RetentionPolicy.CLASS) +internal annotation class DetailsScope diff --git a/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/details/DetailsInteractor.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/details/DetailsInteractor.kt new file mode 100644 index 0000000..c55e2f4 --- /dev/null +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/details/DetailsInteractor.kt @@ -0,0 +1,127 @@ +package com.solacestudios.ribs_demo_android.ribs.details + +import android.util.Log +import com.solacestudios.ribs_demo_android.models.CatalogueDetail +import com.solacestudios.ribs_demo_android.network.DetailsService +import com.solacestudios.ribs_demo_android.util.DataStream +import com.solacestudios.ribs_demo_android.repository.DetailsRepository +import com.solacestudios.ribs_demo_android.util.Resource +import com.solacestudios.ribs_demo_android.util.RibsScheduler +import com.solacestudios.ribs_demo_android.util.RibsSchedulerImpl +import com.uber.rib.core.Bundle +import com.uber.rib.core.Interactor +import com.uber.rib.core.RibInteractor +import io.reactivex.rxjava3.core.Observable +import io.reactivex.rxjava3.disposables.CompositeDisposable +import javax.inject.Inject + +/** + * Coordinates Business Logic for [DetailsScope]. + * + * TODO describe the logic of this scope. + */ +@RibInteractor +class DetailsInteractor : Interactor() { + companion object { + const val TAG = "DetailsInteractor" + var detailsScheduler: RibsScheduler = RibsSchedulerImpl() + } + + @Inject + lateinit var buildPresenter: Presenter + + @Inject + lateinit var service: DetailsService + + @Inject + lateinit var detailsListener: Listener + + @Inject + lateinit var dataStream: DataStream + + @Inject + lateinit var detailsRepository: DetailsRepository + + private var disposables = CompositeDisposable() + + override fun didBecomeActive(savedInstanceState: Bundle?) { + super.didBecomeActive(savedInstanceState) + + // TODO: Add attachment logic here (RxSubscriptions, etc.). + setupUI() + + onBack() + } + + fun setupUI() { + dataStream.data() + .doOnSubscribe { disposables.add(it) } + .subscribe({fetchDetails(it)}) { + Log.e(TAG, it.toString()) + } + } + + private fun fetchDetails(detail: String) { + Log.e(this.javaClass.name, "fetchDetails::$detail") + detailsRepository.getDetail(detail) + .doOnSubscribe { disposables.add(it) } + .subscribeOn(detailsScheduler.io) + .observeOn(detailsScheduler.main) + .subscribe({ res -> handleResult(res) }) { + Log.e(TAG, it.toString()) + } + } + + private fun handleResult(result: Resource) { + when (result) { + is Resource.Loading -> { + buildPresenter.updateProgressbarState(true) + } + is Resource.Success -> { + buildPresenter.setData(result.data!!) + buildPresenter.updateProgressbarState(false) + } + is Resource.Error -> { + buildPresenter.updateProgressbarState(false) + } + } + } + + //subscribes to view click events + fun onBack() { + buildPresenter.onBack() + .subscribeOn(detailsScheduler.main) + .observeOn(detailsScheduler.main) + .doOnSubscribe { disposables.add(it) } + .subscribe({detailsListener.onBackPress()}) { + Log.e(TAG, it.toString()) + } + } + + override fun willResignActive() { + super.willResignActive() + if (!disposables.isDisposed) { + disposables.dispose() + disposables = CompositeDisposable() + } + // TODO: Perform any required clean up here, or delete this method entirely if not needed. + } + + /** + * Presenter interface implemented by this RIB's view. + * Declares functions to be defined in DetailsView + * Gives ability for details listener onBackPress to subscribe to click events emitted from Presenters onBack function + * onBack will emit when back button is clicked, onBackPress will receive that emission and do something + */ + interface Presenter { + fun onBack(): Observable + fun setData(data: CatalogueDetail) + fun updateProgressbarState(isVisible: Boolean) + } + + //Declares functions for details parent listener to define in catalogue interactor + // + interface Listener { + fun onBackPress() + } +} diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/details/DetailsRouter.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/details/DetailsRouter.kt similarity index 75% rename from app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/details/DetailsRouter.kt rename to app/src/main/java/com/solacestudios/ribs_demo_android/ribs/details/DetailsRouter.kt index 01d4ff6..1a2d7f9 100644 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/details/DetailsRouter.kt +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/details/DetailsRouter.kt @@ -1,4 +1,4 @@ -package com.example.ribs_demo_android.ribs.root.home.catalogue.details +package com.solacestudios.ribs_demo_android.ribs.details import com.uber.rib.core.ViewRouter @@ -10,5 +10,5 @@ import com.uber.rib.core.ViewRouter class DetailsRouter( view: DetailsView, interactor: DetailsInteractor, - component: DetailsBuilder.Component + component: DetailsComponent ) : ViewRouter(view, interactor, component) diff --git a/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/details/DetailsView.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/details/DetailsView.kt new file mode 100644 index 0000000..b9b6ab2 --- /dev/null +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/details/DetailsView.kt @@ -0,0 +1,61 @@ +package com.solacestudios.ribs_demo_android.ribs.details + +import android.content.Context +import android.util.AttributeSet +import android.widget.ImageView +import android.widget.ProgressBar +import android.widget.TextView +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.view.isVisible +import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions +import com.solacestudios.ribs_demo_android.R +import com.solacestudios.ribs_demo_android.models.CatalogueDetail +import com.jakewharton.rxbinding4.view.clicks +import io.reactivex.rxjava3.core.Observable + +/** + * Top level view for {@link DetailsBuilder.DetailsScope}. + */ +class DetailsView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyle: Int = 0 +) : ConstraintLayout(context, attrs, defStyle), DetailsInteractor.Presenter { + private lateinit var tvName: TextView + private lateinit var tvRarity: TextView + private lateinit var tvHp: TextView + private lateinit var tvType: TextView + private lateinit var progressDetails: ProgressBar + private lateinit var imgBack: ImageView + + fun initViewIds() { + tvName = findViewById(R.id.name) + tvRarity = findViewById(R.id.rarity) + tvHp = findViewById(R.id.hp) + tvType = findViewById(R.id.type) + progressDetails = findViewById(R.id.progressbar_details) + imgBack = findViewById(R.id.back) + } + + //Create an observable that emits on view click events + override fun onBack(): Observable { + return imgBack.clicks().map { true } + } + + override fun setData(data: CatalogueDetail) { + tvName.text = data.name + tvRarity.text = data.rarity + tvHp.text = data.hp + tvType.text = data.type + + Glide.with(context) + .load(data.imageUrl) + .transition(DrawableTransitionOptions.withCrossFade()) + .into(findViewById(R.id.icon_detail)) + } + + override fun updateProgressbarState(isVisible: Boolean) { + progressDetails.isVisible = isVisible + } +} diff --git a/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/home/HomeBuilder.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/home/HomeBuilder.kt new file mode 100644 index 0000000..695cf44 --- /dev/null +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/home/HomeBuilder.kt @@ -0,0 +1,38 @@ +package com.solacestudios.ribs_demo_android.ribs.home + +import android.view.LayoutInflater +import android.view.ViewGroup +import com.solacestudios.ribs_demo_android.R +import com.uber.rib.core.ViewBuilder + +/** + * Builder for the {@link LogoutScope}. + * + * TODO describe this scope's responsibility as a whole. + */ +class HomeBuilder(dependency: HomeComponent.ParentComponent) : + ViewBuilder(dependency) { + + /** + * Builds a new [LogoutRouter]. + * + * @param parentViewGroup parent view group that this router's view will be added to. + * @return a new [LogoutRouter]. + */ + fun build(parentViewGroup: ViewGroup): HomeRouter { + val view = createView(parentViewGroup) + val interactor = HomeInteractor() + val component = DaggerHomeComponent.builder() + .parentComponent(dependency) + .view(view) + .interactor(interactor) + .build() + return component.getHomeRouter() + } + + override fun inflateView(inflater: LayoutInflater, parentViewGroup: ViewGroup): HomeView { + // TODO: Inflate a new view using the provided inflater, or create a new view programatically using the + // provided context from the parentViewGroup. + return inflater.inflate(R.layout.home_rib, parentViewGroup, false) as HomeView + } +} diff --git a/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/home/HomeComponent.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/home/HomeComponent.kt new file mode 100644 index 0000000..b423207 --- /dev/null +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/home/HomeComponent.kt @@ -0,0 +1,121 @@ +package com.solacestudios.ribs_demo_android.ribs.home + +import android.view.ViewGroup +import com.solacestudios.ribs_demo_android.network.CatalogueService +import com.solacestudios.ribs_demo_android.repository.CatalogueRepository +import com.solacestudios.ribs_demo_android.repository.CatalogueRepositoryImpl +import com.solacestudios.ribs_demo_android.ribs.catalogue.* +import com.solacestudios.ribs_demo_android.util.Constants +import com.solacestudios.ribs_demo_android.util.RibsScheduler +import com.uber.rib.core.InteractorBaseComponent +import dagger.* +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory +import retrofit2.converter.gson.GsonConverterFactory +import java.lang.annotation.Retention +import java.lang.annotation.RetentionPolicy +import javax.inject.Scope + +@HomeScope +@Component( + modules = [HomeModule::class], + dependencies = [HomeComponent.ParentComponent::class] +) +interface HomeComponent : InteractorBaseComponent, CatalogueComponent.ParentComponent { + fun getHomeRouter(): HomeRouter + + interface ParentComponent { + fun homeListener(): HomeInteractor.Listener + } + + @Component.Builder + interface Builder { + @BindsInstance + fun interactor(interactor: HomeInteractor): Builder + + @BindsInstance + fun view(view: HomeView): Builder + + fun parentComponent(component: ParentComponent): Builder + + fun build(): HomeComponent + } +} + +@Module +abstract class HomeModule { + @Binds + @HomeScope + internal abstract fun buildPresenter(view: HomeView): HomeInteractor.Presenter + + @Binds + @HomeScope + internal abstract fun buildContainerView(view: HomeView): ViewGroup + + @Module + companion object { + + var logging : HttpLoggingInterceptor = run { + val httpLoggingInterceptor = HttpLoggingInterceptor() + httpLoggingInterceptor.apply { + httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY + } + } + var clientHome : OkHttpClient = OkHttpClient.Builder().addInterceptor(logging).build() + + @HomeScope + @Provides + @JvmStatic + internal fun router(view: HomeView, component: HomeComponent, interactor: HomeInteractor): HomeRouter = + HomeRouter(view, interactor, component, CatalogueBuilder(component)) + + @HomeScope + @Provides + @JvmStatic + internal fun provideCatalogueParentListener(interactor: HomeInteractor): CatalogueInteractor.Listener = + interactor.CatalogueParentListener() + + @HomeScope + @Provides + @JvmStatic + internal fun provideRetrofit( + gsonConverterFactory: GsonConverterFactory + ): Retrofit { + return Retrofit.Builder() + .baseUrl(Constants.BASE_URL) + .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) + .addConverterFactory(gsonConverterFactory) + .client(clientHome) + .build() + } + + @HomeScope + @Provides + @JvmStatic + internal fun provideService( + retrofit: Retrofit, + ): CatalogueService { + return retrofit.create(CatalogueService::class.java) + } + + @HomeScope + @Provides + @JvmStatic + internal fun provideCatalogueRepository( + service: CatalogueService + ): CatalogueRepository { + return CatalogueRepositoryImpl(service) + } + + @Provides + fun providesGsonConverterFactory(): GsonConverterFactory { + return GsonConverterFactory.create() + } + } +} + +@Scope +@Retention(RetentionPolicy.CLASS) +internal annotation class HomeScope diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/HomeInteractor.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/home/HomeInteractor.kt similarity index 66% rename from app/src/main/java/com/example/ribs_demo_android/ribs/root/home/HomeInteractor.kt rename to app/src/main/java/com/solacestudios/ribs_demo_android/ribs/home/HomeInteractor.kt index e1d3d03..7437b07 100644 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/HomeInteractor.kt +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/home/HomeInteractor.kt @@ -1,7 +1,7 @@ -package com.example.ribs_demo_android.ribs.root.home +package com.solacestudios.ribs_demo_android.ribs.home import android.util.Log -import com.example.ribs_demo_android.ribs.root.home.catalogue.CatalogueInteractor +import com.solacestudios.ribs_demo_android.ribs.catalogue.CatalogueInteractor import com.uber.rib.core.Bundle import com.uber.rib.core.Interactor import com.uber.rib.core.RibInteractor @@ -16,7 +16,7 @@ import javax.inject.Inject class HomeInteractor : Interactor() { @Inject - lateinit var homeToggleListener: HomeToggleListener + lateinit var listener: Listener override fun didBecomeActive(savedInstanceState: Bundle?) { super.didBecomeActive(savedInstanceState) @@ -31,15 +31,18 @@ class HomeInteractor : Interactor() { // TODO: Perform any required clean up here, or delete this method entirely if not needed. } - interface HomePresenter + interface Presenter - inner class HomeListener: CatalogueInteractor.CatalogueListener { + inner class CatalogueParentListener: CatalogueInteractor.Listener { override fun onClick() { - homeToggleListener.toggleHome() + Log.e(this.javaClass.name, "onClick, catalogue parent listener, toggling home") + + listener.toggleHome() } } - interface HomeToggleListener { + + interface Listener { fun toggleHome() } } diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/HomeRouter.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/home/HomeRouter.kt similarity index 69% rename from app/src/main/java/com/example/ribs_demo_android/ribs/root/home/HomeRouter.kt rename to app/src/main/java/com/solacestudios/ribs_demo_android/ribs/home/HomeRouter.kt index 03c9cd7..15b6c22 100644 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/HomeRouter.kt +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/home/HomeRouter.kt @@ -1,18 +1,18 @@ -package com.example.ribs_demo_android.ribs.root.home +package com.solacestudios.ribs_demo_android.ribs.home -import com.example.ribs_demo_android.ribs.root.home.catalogue.CatalogueBuilder -import com.example.ribs_demo_android.ribs.root.home.catalogue.CatalogueRouter +import com.solacestudios.ribs_demo_android.ribs.catalogue.CatalogueBuilder +import com.solacestudios.ribs_demo_android.ribs.catalogue.CatalogueRouter import com.uber.rib.core.ViewRouter /** - * Adds and removes children of {@link HomeBuilder.HomeScope}. + * Adds and removes children of {@link HomeScope}. * * TODO describe the possible child configurations of this scope. */ class HomeRouter( view: HomeView, interactor: HomeInteractor, - component: HomeBuilder.Component, + component: HomeComponent, private val catalogueBuilder: CatalogueBuilder ) : ViewRouter(view, interactor, component) { diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/HomeView.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/home/HomeView.kt similarity index 69% rename from app/src/main/java/com/example/ribs_demo_android/ribs/root/home/HomeView.kt rename to app/src/main/java/com/solacestudios/ribs_demo_android/ribs/home/HomeView.kt index 1b67c32..a6aee59 100644 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/HomeView.kt +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/home/HomeView.kt @@ -1,4 +1,4 @@ -package com.example.ribs_demo_android.ribs.root.home +package com.solacestudios.ribs_demo_android.ribs.home import android.content.Context import android.util.AttributeSet @@ -11,4 +11,4 @@ class HomeView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyle: Int = 0 -) : LinearLayout(context, attrs, defStyle), HomeInteractor.HomePresenter +) : LinearLayout(context, attrs, defStyle), HomeInteractor.Presenter diff --git a/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/root/RootBuilder.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/root/RootBuilder.kt new file mode 100644 index 0000000..ae4fea7 --- /dev/null +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/root/RootBuilder.kt @@ -0,0 +1,41 @@ +package com.solacestudios.ribs_demo_android.ribs.root + +import android.view.LayoutInflater +import android.view.ViewGroup +import com.solacestudios.ribs_demo_android.R +import com.solacestudios.ribscodegen.root.DaggerRootComponent +import com.solacestudios.ribscodegen.root.RootComponent +import com.uber.rib.core.ViewBuilder + +/** + * Builder for the {@link RootScope}. + * + * TODO describe this scope's responsibility as a whole. + */ +class RootBuilder(dependency: RootComponent.ParentComponent) : + ViewBuilder(dependency) { + + /** + * Builds a new [RootRouter]. + * + * @param parentViewGroup parent view group that this router's view will be added to. + * @return a new [RootRouter]. + */ + fun build(parentViewGroup: ViewGroup): RootRouter { + val view = createView(parentViewGroup) + val interactor = RootInteractor() + val component = DaggerRootComponent.builder() + .parentComponent(dependency) + .view(view) + .interactor(interactor) + .build() + return component.getRootRouter() + } + + override fun inflateView(inflater: LayoutInflater, parentViewGroup: ViewGroup): RootView { + // TODO: Inflate a new view using the provided inflater, or create a new view programatically using the + // provided context from the parentViewGroup. + return inflater.inflate(R.layout.root_rib, parentViewGroup, false) as RootView + } + +} diff --git a/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/root/RootComponent.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/root/RootComponent.kt new file mode 100644 index 0000000..688f35a --- /dev/null +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/root/RootComponent.kt @@ -0,0 +1,77 @@ +package com.solacestudios.ribscodegen.root + +import android.view.ViewGroup +import com.solacestudios.ribs_demo_android.ribs.root.RootInteractor +import com.solacestudios.ribs_demo_android.ribs.root.RootRouter +import com.solacestudios.ribs_demo_android.ribs.root.RootView +import com.solacestudios.ribs_demo_android.ribs.category.CategoryBuilder +import com.solacestudios.ribs_demo_android.ribs.category.CategoryComponent +import com.solacestudios.ribs_demo_android.ribs.category.CategoryInteractor +import com.solacestudios.ribs_demo_android.ribs.home.HomeBuilder +import com.solacestudios.ribs_demo_android.ribs.home.HomeComponent +import com.solacestudios.ribs_demo_android.ribs.home.HomeInteractor +import com.uber.rib.core.InteractorBaseComponent +import dagger.* +import java.lang.annotation.Retention +import java.lang.annotation.RetentionPolicy +import javax.inject.Scope + +@RootScope +@Component( + modules = [RootModule::class], + dependencies = [RootComponent.ParentComponent::class] +) +interface RootComponent : InteractorBaseComponent, CategoryComponent.ParentComponent, HomeComponent.ParentComponent { + fun getRootRouter(): RootRouter + + interface ParentComponent + + @Component.Builder + interface Builder { + @BindsInstance + fun interactor(interactor: RootInteractor): Builder + + @BindsInstance + fun view(view: RootView): Builder + + fun parentComponent(component: ParentComponent): Builder + + fun build(): RootComponent + } +} + +@Module +abstract class RootModule { + @Binds + @RootScope + internal abstract fun buildPresenter(view: RootView): RootInteractor.Presenter + + @Binds + @RootScope + internal abstract fun buildContainerView(view: RootView): ViewGroup + + @Module + companion object { + @RootScope + @Provides + @JvmStatic + internal fun router(view: RootView, component: RootComponent, interactor: RootInteractor): RootRouter = + RootRouter(view, interactor, component, CategoryBuilder(component), HomeBuilder(component)) + + @RootScope + @Provides + @JvmStatic + internal fun provideCategoryParentListener(interactor: RootInteractor): CategoryInteractor.Listener = + interactor.CategoryParentListener() + + @RootScope + @Provides + @JvmStatic + internal fun provideHomeParentListener(interactor: RootInteractor): HomeInteractor.Listener = + interactor.HomeParentListener() + } +} + +@Scope +@Retention(RetentionPolicy.CLASS) +internal annotation class RootScope diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/RootInteractor.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/root/RootInteractor.kt similarity index 59% rename from app/src/main/java/com/example/ribs_demo_android/ribs/root/RootInteractor.kt rename to app/src/main/java/com/solacestudios/ribs_demo_android/ribs/root/RootInteractor.kt index 06093ae..a32308f 100644 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/RootInteractor.kt +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/root/RootInteractor.kt @@ -1,10 +1,11 @@ -package com.example.ribs_demo_android.ribs.root +package com.solacestudios.ribs_demo_android.ribs.root import android.util.Log -import com.example.ribs_demo_android.ribs.root.category.CategoryInteractor -import com.example.ribs_demo_android.ribs.root.home.HomeInteractor +import com.solacestudios.ribs_demo_android.ribs.category.CategoryInteractor +import com.solacestudios.ribs_demo_android.ribs.home.HomeInteractor import com.uber.rib.core.Bundle import com.uber.rib.core.Interactor +import com.uber.rib.core.Presenter import com.uber.rib.core.RibInteractor import javax.inject.Inject @@ -14,10 +15,10 @@ import javax.inject.Inject * TODO describe the logic of this scope. */ @RibInteractor -class RootInteractor : Interactor() { +class RootInteractor : Interactor() { @Inject - lateinit var presenter: RootPresenter + lateinit var buildPresenter: Presenter override fun didBecomeActive(savedInstanceState: Bundle?) { super.didBecomeActive(savedInstanceState) @@ -35,19 +36,23 @@ class RootInteractor : Interactor() { /** * Presenter interface implemented by this RIB's view. */ - interface RootPresenter + interface Presenter - inner class RootListener: HomeInteractor.HomeToggleListener { + inner class HomeParentListener : HomeInteractor.Listener { override fun toggleHome() { + Log.e(this.javaClass.name, "toggleHome(), detaching home, attaching category") + router.detachHome() router.attachCategory() } } - - inner class RootCategoryListener: CategoryInteractor.CategoryToggleListener { + inner class CategoryParentListener : CategoryInteractor.Listener { override fun toggleCategory() { + Log.e(this.javaClass.name, "toggleCategory(), detaching category, attaching home") + router.detachCategory() router.attachHome() } } + } diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/RootRouter.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/root/RootRouter.kt similarity index 67% rename from app/src/main/java/com/example/ribs_demo_android/ribs/root/RootRouter.kt rename to app/src/main/java/com/solacestudios/ribs_demo_android/ribs/root/RootRouter.kt index 2e70e1c..a7b9221 100644 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/RootRouter.kt +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/root/RootRouter.kt @@ -1,9 +1,10 @@ -package com.example.ribs_demo_android.ribs.root +package com.solacestudios.ribs_demo_android.ribs.root -import com.example.ribs_demo_android.ribs.root.category.CategoryBuilder -import com.example.ribs_demo_android.ribs.root.category.CategoryRouter -import com.example.ribs_demo_android.ribs.root.home.HomeBuilder -import com.example.ribs_demo_android.ribs.root.home.HomeRouter +import com.solacestudios.ribs_demo_android.ribs.category.CategoryBuilder +import com.solacestudios.ribs_demo_android.ribs.category.CategoryRouter +import com.solacestudios.ribs_demo_android.ribs.home.HomeBuilder +import com.solacestudios.ribs_demo_android.ribs.home.HomeRouter +import com.solacestudios.ribscodegen.root.RootComponent import com.uber.rib.core.ViewRouter @@ -15,13 +16,12 @@ import com.uber.rib.core.ViewRouter class RootRouter( view: RootView, interactor: RootInteractor, - component: RootBuilder.Component, - private val homeBuilder: HomeBuilder, - private val categoryBuilder: CategoryBuilder + component: RootComponent, + private val categoryBuilder: CategoryBuilder, + private val homeBuilder: HomeBuilder ) : ViewRouter(view, interactor, component) { - - private var homeRouter: HomeRouter? = null private var categoryRouter: CategoryRouter? = null + private var homeRouter: HomeRouter? = null fun attachHome() { homeRouter = homeBuilder.build(view) diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/RootView.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/root/RootView.kt similarity index 65% rename from app/src/main/java/com/example/ribs_demo_android/ribs/root/RootView.kt rename to app/src/main/java/com/solacestudios/ribs_demo_android/ribs/root/RootView.kt index fdf02e6..0b04e26 100644 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/RootView.kt +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/ribs/root/RootView.kt @@ -1,8 +1,7 @@ -package com.example.ribs_demo_android.ribs.root +package com.solacestudios.ribs_demo_android.ribs.root import android.content.Context import android.util.AttributeSet -import android.view.View import android.widget.LinearLayout /** @@ -12,4 +11,4 @@ class RootView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyle: Int = 0 -) : LinearLayout(context, attrs, defStyle), RootInteractor.RootPresenter +) : LinearLayout(context, attrs, defStyle), RootInteractor.Presenter diff --git a/app/src/main/java/com/example/ribs_demo_android/util/Constants.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/util/Constants.kt similarity index 61% rename from app/src/main/java/com/example/ribs_demo_android/util/Constants.kt rename to app/src/main/java/com/solacestudios/ribs_demo_android/util/Constants.kt index c28ee87..4b39912 100644 --- a/app/src/main/java/com/example/ribs_demo_android/util/Constants.kt +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/util/Constants.kt @@ -1,4 +1,4 @@ -package com.example.ribs_demo_android.util +package com.solacestudios.ribs_demo_android.util object Constants { diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/DataStream.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/util/DataStream.kt similarity index 53% rename from app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/DataStream.kt rename to app/src/main/java/com/solacestudios/ribs_demo_android/util/DataStream.kt index 1ae4f6f..54c7202 100644 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/DataStream.kt +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/util/DataStream.kt @@ -1,6 +1,6 @@ -package com.example.ribs_demo_android.ribs.root.home.catalogue +package com.solacestudios.ribs_demo_android.util -import io.reactivex.Observable +import io.reactivex.rxjava3.core.Observable /** * Created by Mehul Bisht on 05-01-2022 diff --git a/app/src/main/java/com/solacestudios/ribs_demo_android/util/MutableDataStream.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/util/MutableDataStream.kt new file mode 100644 index 0000000..fd8f17a --- /dev/null +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/util/MutableDataStream.kt @@ -0,0 +1,25 @@ +package com.solacestudios.ribs_demo_android.util + +import io.reactivex.rxjava3.core.Observable +import io.reactivex.rxjava3.subjects.PublishSubject + +/** + * Created by Mehul Bisht on 05-01-2022 + */ + +class MutableDataStream(data: String): DataStream { + + private val behaviorRelay = PublishSubject.create() + + init { + behaviorRelay.onNext(data) + } + + fun setData(data: String) { + behaviorRelay.onNext(data) + } + + override fun data(): Observable { + return behaviorRelay + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/ribs_demo_android/util/Resource.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/util/Resource.kt similarity index 83% rename from app/src/main/java/com/example/ribs_demo_android/util/Resource.kt rename to app/src/main/java/com/solacestudios/ribs_demo_android/util/Resource.kt index d2ce046..c9cffed 100644 --- a/app/src/main/java/com/example/ribs_demo_android/util/Resource.kt +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/util/Resource.kt @@ -1,7 +1,8 @@ -package com.example.ribs_demo_android.util +package com.solacestudios.ribs_demo_android.util sealed class Resource(val data: T? = null, val message: String? = null) { class Success(data: T) : Resource(data) class Error(message: String, data: T? = null) : Resource(data, message) class Loading(data: T? = null) : Resource(data) -} \ No newline at end of file +} + diff --git a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/details/DetailsScheduler.kt b/app/src/main/java/com/solacestudios/ribs_demo_android/util/RibsScheduler.kt similarity index 51% rename from app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/details/DetailsScheduler.kt rename to app/src/main/java/com/solacestudios/ribs_demo_android/util/RibsScheduler.kt index 51e9afc..271e7ce 100644 --- a/app/src/main/java/com/example/ribs_demo_android/ribs/root/home/catalogue/details/DetailsScheduler.kt +++ b/app/src/main/java/com/solacestudios/ribs_demo_android/util/RibsScheduler.kt @@ -1,20 +1,20 @@ -package com.example.ribs_demo_android.ribs.root.home.catalogue.details +package com.solacestudios.ribs_demo_android.util -import io.reactivex.Scheduler -import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.schedulers.Schedulers +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers +import io.reactivex.rxjava3.core.Scheduler +import io.reactivex.rxjava3.schedulers.Schedulers -interface DetailsScheduler { +interface RibsScheduler { val io: Scheduler val main: Scheduler val compute: Scheduler } -class DetailsSchedulerImpl(): DetailsScheduler { +class RibsSchedulerImpl(): RibsScheduler { override val io: Scheduler get() = Schedulers.io() override val main: Scheduler get() = AndroidSchedulers.mainThread() override val compute: Scheduler get() = Schedulers.computation() -} \ No newline at end of file +} diff --git a/app/src/main/res/layout/catalogue_rib.xml b/app/src/main/res/layout/catalogue_rib.xml index 4c2ee98..10709b8 100644 --- a/app/src/main/res/layout/catalogue_rib.xml +++ b/app/src/main/res/layout/catalogue_rib.xml @@ -1,5 +1,5 @@ - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/category_rib.xml b/app/src/main/res/layout/category_rib.xml index e10bb87..c50fe52 100644 --- a/app/src/main/res/layout/category_rib.xml +++ b/app/src/main/res/layout/category_rib.xml @@ -1,5 +1,5 @@ - @@ -101,4 +102,4 @@ android:layout_centerInParent="true" android:visibility="gone"/> - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/details_rib.xml b/app/src/main/res/layout/details_rib.xml index a1cf63f..651a398 100644 --- a/app/src/main/res/layout/details_rib.xml +++ b/app/src/main/res/layout/details_rib.xml @@ -1,5 +1,5 @@ - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/home_rib.xml b/app/src/main/res/layout/home_rib.xml index 961d971..7397240 100644 --- a/app/src/main/res/layout/home_rib.xml +++ b/app/src/main/res/layout/home_rib.xml @@ -1,7 +1,8 @@ - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/item_catalogue.xml b/app/src/main/res/layout/item_catalogue.xml index 0178bbd..77f24dc 100644 --- a/app/src/main/res/layout/item_catalogue.xml +++ b/app/src/main/res/layout/item_catalogue.xml @@ -19,6 +19,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="16dp" + android:textColor="@color/purple_700" android:text="Name:" android:textStyle="bold" app:layout_constraintStart_toEndOf="@id/icon" @@ -29,6 +30,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="16dp" + android:textColor="@color/purple_700" app:layout_constraintStart_toEndOf="@id/name_label" app:layout_constraintTop_toTopOf="parent" tools:text="Amber" /> @@ -38,6 +40,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="16dp" + android:textColor="@color/purple_700" android:text="Rarity" android:textStyle="bold" app:layout_constraintStart_toEndOf="@id/icon" @@ -47,6 +50,7 @@ android:id="@+id/rarity" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:textColor="@color/purple_700" android:layout_margin="16dp" app:layout_constraintStart_toEndOf="@id/rarity_label" app:layout_constraintTop_toBottomOf="@id/name" diff --git a/app/src/main/res/layout/item_category.xml b/app/src/main/res/layout/item_category.xml index 9c8d487..41e953b 100644 --- a/app/src/main/res/layout/item_category.xml +++ b/app/src/main/res/layout/item_category.xml @@ -23,6 +23,7 @@ android:layout_height="wrap_content" android:layout_margin="8dp" android:textSize="20sp" + android:textColor="@color/purple_700" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/icon_category" diff --git a/app/src/main/res/layout/root_rib.xml b/app/src/main/res/layout/root_rib.xml index 1d4d61b..66bb49e 100644 --- a/app/src/main/res/layout/root_rib.xml +++ b/app/src/main/res/layout/root_rib.xml @@ -1,6 +1,6 @@ - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/test/java/com/example/ribs_demo_android/ExampleUnitTest.kt b/app/src/test/java/com/solacestudios/ribs_demo_android/ExampleUnitTest.kt similarity index 87% rename from app/src/test/java/com/example/ribs_demo_android/ExampleUnitTest.kt rename to app/src/test/java/com/solacestudios/ribs_demo_android/ExampleUnitTest.kt index 10c1c17..b6f2510 100644 --- a/app/src/test/java/com/example/ribs_demo_android/ExampleUnitTest.kt +++ b/app/src/test/java/com/solacestudios/ribs_demo_android/ExampleUnitTest.kt @@ -1,4 +1,4 @@ -package com.example.ribs_demo_android +package com.solacestudios.ribs_demo_android import org.junit.Test diff --git a/app/src/test/java/com/example/ribs_demo_android/network/FakeResponse.kt b/app/src/test/java/com/solacestudios/ribs_demo_android/network/FakeResponse.kt similarity index 78% rename from app/src/test/java/com/example/ribs_demo_android/network/FakeResponse.kt rename to app/src/test/java/com/solacestudios/ribs_demo_android/network/FakeResponse.kt index 7d30616..a3e5fb4 100644 --- a/app/src/test/java/com/example/ribs_demo_android/network/FakeResponse.kt +++ b/app/src/test/java/com/solacestudios/ribs_demo_android/network/FakeResponse.kt @@ -1,9 +1,9 @@ -package com.example.ribs_demo_android.network +package com.solacestudios.ribs_demo_android.network -import com.example.ribs_demo_android.models.Catalogue -import com.example.ribs_demo_android.models.CatalogueDetail -import com.example.ribs_demo_android.models.CatalogueResponse -import com.example.ribs_demo_android.util.Resource +import com.solacestudios.ribs_demo_android.models.Catalogue +import com.solacestudios.ribs_demo_android.models.CatalogueDetail +import com.solacestudios.ribs_demo_android.models.CatalogueResponse +import com.solacestudios.ribs_demo_android.util.Resource object FakeResponse { diff --git a/app/src/test/java/com/example/ribs_demo_android/network/repository/CatalogueRepositoryTest.kt b/app/src/test/java/com/solacestudios/ribs_demo_android/network/repository/CatalogueRepositoryTest.kt similarity index 85% rename from app/src/test/java/com/example/ribs_demo_android/network/repository/CatalogueRepositoryTest.kt rename to app/src/test/java/com/solacestudios/ribs_demo_android/network/repository/CatalogueRepositoryTest.kt index c9a2dee..1cbe9f8 100644 --- a/app/src/test/java/com/example/ribs_demo_android/network/repository/CatalogueRepositoryTest.kt +++ b/app/src/test/java/com/solacestudios/ribs_demo_android/network/repository/CatalogueRepositoryTest.kt @@ -1,9 +1,10 @@ -package com.example.ribs_demo_android.network.repository +package com.solacestudios.ribs_demo_android.network.repository -import com.example.ribs_demo_android.network.CatalogueService -import com.example.ribs_demo_android.network.FakeResponse -import com.example.ribs_demo_android.ribs.root.home.catalogue.FakeCatalogueScheduler -import com.example.ribs_demo_android.util.Resource +import com.solacestudios.ribs_demo_android.network.CatalogueService +import com.solacestudios.ribs_demo_android.network.FakeResponse +import com.solacestudios.ribs_demo_android.repository.CatalogueRepositoryImpl +import com.solacestudios.ribs_demo_android.ribs.root.home.catalogue.FakeCatalogueScheduler +import com.solacestudios.ribs_demo_android.util.Resource import io.reactivex.Observable import org.junit.Before import org.junit.Test diff --git a/app/src/test/java/com/example/ribs_demo_android/network/repository/FakeCatalogueRepository.kt b/app/src/test/java/com/solacestudios/ribs_demo_android/network/repository/FakeCatalogueRepository.kt similarity index 60% rename from app/src/test/java/com/example/ribs_demo_android/network/repository/FakeCatalogueRepository.kt rename to app/src/test/java/com/solacestudios/ribs_demo_android/network/repository/FakeCatalogueRepository.kt index 67e9f20..c503c17 100644 --- a/app/src/test/java/com/example/ribs_demo_android/network/repository/FakeCatalogueRepository.kt +++ b/app/src/test/java/com/solacestudios/ribs_demo_android/network/repository/FakeCatalogueRepository.kt @@ -1,11 +1,10 @@ -package com.example.ribs_demo_android.network.repository +package com.solacestudios.ribs_demo_android.network.repository -import com.example.ribs_demo_android.models.Catalogue -import com.example.ribs_demo_android.models.CatalogueDetail -import com.example.ribs_demo_android.models.CatalogueResponse -import com.example.ribs_demo_android.network.FakeResponse -import com.example.ribs_demo_android.ribs.root.repository.CatalogueRepository -import com.example.ribs_demo_android.util.Resource +import com.solacestudios.ribs_demo_android.models.CatalogueDetail +import com.solacestudios.ribs_demo_android.models.CatalogueResponse +import com.solacestudios.ribs_demo_android.network.FakeResponse +import com.solacestudios.ribs_demo_android.repository.CatalogueRepository +import com.solacestudios.ribs_demo_android.util.Resource import io.reactivex.Observable class FakeCatalogueRepository: CatalogueRepository { diff --git a/app/src/test/java/com/example/ribs_demo_android/ribs/root/category/CategoryInteractorTest.kt b/app/src/test/java/com/solacestudios/ribs_demo_android/ribs/root/category/CategoryInteractorTest.kt similarity index 86% rename from app/src/test/java/com/example/ribs_demo_android/ribs/root/category/CategoryInteractorTest.kt rename to app/src/test/java/com/solacestudios/ribs_demo_android/ribs/root/category/CategoryInteractorTest.kt index 5a24333..416e834 100644 --- a/app/src/test/java/com/example/ribs_demo_android/ribs/root/category/CategoryInteractorTest.kt +++ b/app/src/test/java/com/solacestudios/ribs_demo_android/ribs/root/category/CategoryInteractorTest.kt @@ -1,10 +1,11 @@ -package com.example.ribs_demo_android.ribs.root.category - -import com.example.ribs_demo_android.network.CategoryService -import com.example.ribs_demo_android.network.FakeResponse -import com.example.ribs_demo_android.network.repository.CategoryRepositoryImpl -import com.example.ribs_demo_android.ribs.root.repository.CategoryRepository -import com.example.ribs_demo_android.util.Resource +package com.solacestudios.ribs_demo_android.ribs.root.category + +import com.solacestudios.ribs_demo_android.network.CategoryService +import com.solacestudios.ribs_demo_android.network.FakeResponse +import com.solacestudios.ribs_demo_android.repository.CategoryRepositoryImpl +import com.solacestudios.ribs_demo_android.ribs.category.CategoryInteractor +import com.solacestudios.ribs_demo_android.repository.CategoryRepository +import com.solacestudios.ribs_demo_android.util.Resource import com.nhaarman.mockitokotlin2.verify import io.reactivex.Observable import org.junit.Before diff --git a/app/src/test/java/com/example/ribs_demo_android/ribs/root/category/FakeCategoryScheduler.kt b/app/src/test/java/com/solacestudios/ribs_demo_android/ribs/root/category/FakeCategoryScheduler.kt similarity index 71% rename from app/src/test/java/com/example/ribs_demo_android/ribs/root/category/FakeCategoryScheduler.kt rename to app/src/test/java/com/solacestudios/ribs_demo_android/ribs/root/category/FakeCategoryScheduler.kt index ab320af..d3bdd38 100644 --- a/app/src/test/java/com/example/ribs_demo_android/ribs/root/category/FakeCategoryScheduler.kt +++ b/app/src/test/java/com/solacestudios/ribs_demo_android/ribs/root/category/FakeCategoryScheduler.kt @@ -1,5 +1,6 @@ -package com.example.ribs_demo_android.ribs.root.category +package com.solacestudios.ribs_demo_android.ribs.root.category +import com.solacestudios.ribs_demo_android.ribs.category.CategoryScheduler import io.reactivex.Scheduler import io.reactivex.schedulers.Schedulers diff --git a/app/src/test/java/com/example/ribs_demo_android/ribs/root/home/catalogue/CatalogueInteractorTest.kt b/app/src/test/java/com/solacestudios/ribs_demo_android/ribs/root/home/catalogue/CatalogueInteractorTest.kt similarity index 84% rename from app/src/test/java/com/example/ribs_demo_android/ribs/root/home/catalogue/CatalogueInteractorTest.kt rename to app/src/test/java/com/solacestudios/ribs_demo_android/ribs/root/home/catalogue/CatalogueInteractorTest.kt index 53e5b4e..9281bac 100644 --- a/app/src/test/java/com/example/ribs_demo_android/ribs/root/home/catalogue/CatalogueInteractorTest.kt +++ b/app/src/test/java/com/solacestudios/ribs_demo_android/ribs/root/home/catalogue/CatalogueInteractorTest.kt @@ -1,20 +1,21 @@ -package com.example.ribs_demo_android - -import com.example.ribs_demo_android.network.CatalogueService -import com.example.ribs_demo_android.network.FakeResponse -import com.example.ribs_demo_android.network.repository.CatalogueRepositoryImpl -import com.example.ribs_demo_android.ribs.root.home.catalogue.* -import com.example.ribs_demo_android.ribs.root.repository.CatalogueRepository -import com.example.ribs_demo_android.util.Resource +package com.solacestudios.ribs_demo_android + +import com.solacestudios.ribs_demo_android.network.CatalogueService +import com.solacestudios.ribs_demo_android.network.FakeResponse +import com.solacestudios.ribs_demo_android.repository.CatalogueRepositoryImpl +import com.solacestudios.ribs_demo_android.ribs.catalogue.CatalogueInteractor +import com.solacestudios.ribs_demo_android.ribs.catalogue.CatalogueRouter +import com.solacestudios.ribs_demo_android.util.MutableDataStream +import com.solacestudios.ribs_demo_android.ribs.root.home.catalogue.* +import com.solacestudios.ribs_demo_android.repository.CatalogueRepository +import com.solacestudios.ribs_demo_android.util.Resource import com.google.common.truth.Truth.assertThat -import com.uber.rib.core.RibTestBasePlaceholder import io.reactivex.Observable import org.junit.Before import org.junit.Test import org.mockito.Mock import org.mockito.Mockito.* import org.mockito.MockitoAnnotations -import retrofit2.HttpException import java.io.IOException class CatalogueInteractorTest { @@ -43,7 +44,7 @@ class CatalogueInteractorTest { interactor = CatalogueInteractor() interactor.catalogueRepository = repository - interactor.presenter = presenter + interactor.buildPresenter = presenter interactor.catalogueScheduler = fakeScheduler interactor.catalogueListener = listener interactor.dataStream = dataStream diff --git a/app/src/test/java/com/example/ribs_demo_android/ribs/root/home/catalogue/FakeCatalogueScheduler.kt b/app/src/test/java/com/solacestudios/ribs_demo_android/ribs/root/home/catalogue/FakeCatalogueScheduler.kt similarity index 70% rename from app/src/test/java/com/example/ribs_demo_android/ribs/root/home/catalogue/FakeCatalogueScheduler.kt rename to app/src/test/java/com/solacestudios/ribs_demo_android/ribs/root/home/catalogue/FakeCatalogueScheduler.kt index 822ef1f..1e6da17 100644 --- a/app/src/test/java/com/example/ribs_demo_android/ribs/root/home/catalogue/FakeCatalogueScheduler.kt +++ b/app/src/test/java/com/solacestudios/ribs_demo_android/ribs/root/home/catalogue/FakeCatalogueScheduler.kt @@ -1,5 +1,6 @@ -package com.example.ribs_demo_android.ribs.root.home.catalogue +package com.solacestudios.ribs_demo_android.ribs.root.home.catalogue +import com.solacestudios.ribs_demo_android.ribs.catalogue.CatalogueScheduler import io.reactivex.Scheduler import io.reactivex.schedulers.Schedulers diff --git a/app/src/test/java/com/example/ribs_demo_android/ribs/root/home/catalogue/details/DetailsInteractorTest.kt b/app/src/test/java/com/solacestudios/ribs_demo_android/ribs/root/home/catalogue/details/DetailsInteractorTest.kt similarity index 83% rename from app/src/test/java/com/example/ribs_demo_android/ribs/root/home/catalogue/details/DetailsInteractorTest.kt rename to app/src/test/java/com/solacestudios/ribs_demo_android/ribs/root/home/catalogue/details/DetailsInteractorTest.kt index a411399..e1ccfc6 100644 --- a/app/src/test/java/com/example/ribs_demo_android/ribs/root/home/catalogue/details/DetailsInteractorTest.kt +++ b/app/src/test/java/com/solacestudios/ribs_demo_android/ribs/root/home/catalogue/details/DetailsInteractorTest.kt @@ -1,13 +1,12 @@ -package com.example.ribs_demo_android.ribs.root.home.catalogue.details - -import com.example.ribs_demo_android.network.CatalogueService -import com.example.ribs_demo_android.network.DetailsService -import com.example.ribs_demo_android.network.FakeResponse -import com.example.ribs_demo_android.network.repository.DetailsRepositoryImpl -import com.example.ribs_demo_android.ribs.root.home.catalogue.DataStream -import com.example.ribs_demo_android.ribs.root.repository.DetailsRepository -import com.example.ribs_demo_android.util.Resource -import com.google.common.truth.Truth.assertThat +package com.solacestudios.ribs_demo_android.ribs.root.home.catalogue.details + +import com.solacestudios.ribs_demo_android.network.DetailsService +import com.solacestudios.ribs_demo_android.network.FakeResponse +import com.solacestudios.ribs_demo_android.repository.DetailsRepositoryImpl +import com.solacestudios.ribs_demo_android.util.DataStream +import com.solacestudios.ribs_demo_android.ribs.details.DetailsInteractor +import com.solacestudios.ribs_demo_android.repository.DetailsRepository +import com.solacestudios.ribs_demo_android.util.Resource import com.nhaarman.mockitokotlin2.verify import io.reactivex.Observable import org.junit.Before @@ -40,7 +39,7 @@ class DetailsInteractorTest { interactor.detailsRepository = repository interactor.dataStream = datastream interactor.service = service - interactor.presenter = presenter + interactor.buildPresenter = presenter interactor.detailsListener = listener } diff --git a/app/src/test/java/com/example/ribs_demo_android/ribs/root/home/catalogue/details/FakeDetailsScheduler.kt b/app/src/test/java/com/solacestudios/ribs_demo_android/ribs/root/home/catalogue/details/FakeDetailsScheduler.kt similarity index 69% rename from app/src/test/java/com/example/ribs_demo_android/ribs/root/home/catalogue/details/FakeDetailsScheduler.kt rename to app/src/test/java/com/solacestudios/ribs_demo_android/ribs/root/home/catalogue/details/FakeDetailsScheduler.kt index b2af2df..8f7d3c1 100644 --- a/app/src/test/java/com/example/ribs_demo_android/ribs/root/home/catalogue/details/FakeDetailsScheduler.kt +++ b/app/src/test/java/com/solacestudios/ribs_demo_android/ribs/root/home/catalogue/details/FakeDetailsScheduler.kt @@ -1,5 +1,6 @@ -package com.example.ribs_demo_android.ribs.root.home.catalogue.details +package com.solacestudios.ribs_demo_android.ribs.root.home.catalogue.details +import com.solacestudios.ribs_demo_android.ribs.details.DetailsScheduler import io.reactivex.Scheduler import io.reactivex.schedulers.Schedulers