mirror of
https://github.com/melihaksoy/Android-Kotlin-Modulerized-CleanArchitecture.git
synced 2026-03-30 14:21:52 +02:00
Reducing complexity & duplication
Update README.md Update README.md
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
# Rocket Science
|
# Rocket Science
|
||||||
|
|
||||||
[](https://circleci.com/gh/melihaksoy/RocketScience/tree/master)
|
[](https://circleci.com/gh/melihaksoy/RocketScience/tree/master)
|
||||||
|
[](https://codebeat.co/a/melih-aksoy/projects/github-com-melihaksoy-rocketscience-master)
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ import androidx.databinding.ViewDataBinding
|
|||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import androidx.navigation.fragment.NavHostFragment
|
import androidx.navigation.fragment.NavHostFragment
|
||||||
|
import com.google.android.material.snackbar.Snackbar
|
||||||
|
import com.melih.repository.interactors.base.Reason
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parent of all fragments.
|
* Parent of all fragments.
|
||||||
@@ -38,6 +41,17 @@ abstract class BaseFragment<T : ViewDataBinding> : Fragment() {
|
|||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ExperimentalCoroutinesApi
|
||||||
|
protected fun showSnackbarWithAction(reason: Reason, block: () -> Unit) {
|
||||||
|
Snackbar.make(
|
||||||
|
binding.root,
|
||||||
|
resources.getString(reason.messageRes),
|
||||||
|
Snackbar.LENGTH_INDEFINITE
|
||||||
|
).setAction(com.melih.core.R.string.retry) {
|
||||||
|
block()
|
||||||
|
}.show()
|
||||||
|
}
|
||||||
|
|
||||||
@LayoutRes
|
@LayoutRes
|
||||||
abstract fun getLayoutId(): Int
|
abstract fun getLayoutId(): Int
|
||||||
// endregion
|
// endregion
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package com.melih.core.extensions
|
||||||
|
|
||||||
|
fun CharSequence.containsIgnoreCase(other: CharSequence) = contains(other, true)
|
||||||
@@ -4,7 +4,6 @@ import android.os.Bundle
|
|||||||
import android.text.method.ScrollingMovementMethod
|
import android.text.method.ScrollingMovementMethod
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
import com.google.android.material.snackbar.Snackbar
|
|
||||||
import com.melih.core.base.lifecycle.BaseDaggerFragment
|
import com.melih.core.base.lifecycle.BaseDaggerFragment
|
||||||
import com.melih.core.extensions.createFor
|
import com.melih.core.extensions.createFor
|
||||||
import com.melih.core.extensions.observe
|
import com.melih.core.extensions.observe
|
||||||
@@ -43,13 +42,9 @@ class DetailFragment : BaseDaggerFragment<DetailBinding>() {
|
|||||||
|
|
||||||
// Observing error to show toast with retry action
|
// Observing error to show toast with retry action
|
||||||
observe(viewModel.errorData) {
|
observe(viewModel.errorData) {
|
||||||
Snackbar.make(
|
showSnackbarWithAction(it) {
|
||||||
binding.root,
|
|
||||||
resources.getString(it.messageRes),
|
|
||||||
Snackbar.LENGTH_INDEFINITE
|
|
||||||
).setAction(com.melih.core.R.string.retry) {
|
|
||||||
viewModel.retry()
|
viewModel.retry()
|
||||||
}.show()
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
observe(viewModel.successData) {
|
observe(viewModel.successData) {
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import android.view.MenuInflater
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.appcompat.widget.SearchView
|
import androidx.appcompat.widget.SearchView
|
||||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
import com.google.android.material.snackbar.Snackbar
|
|
||||||
import com.melih.core.actions.Actions
|
import com.melih.core.actions.Actions
|
||||||
import com.melih.core.base.lifecycle.BaseDaggerFragment
|
import com.melih.core.base.lifecycle.BaseDaggerFragment
|
||||||
|
import com.melih.core.extensions.containsIgnoreCase
|
||||||
import com.melih.core.extensions.createFor
|
import com.melih.core.extensions.createFor
|
||||||
import com.melih.core.extensions.observe
|
import com.melih.core.extensions.observe
|
||||||
import com.melih.list.R
|
import com.melih.list.R
|
||||||
@@ -16,7 +16,6 @@ import com.melih.list.databinding.ListBinding
|
|||||||
import com.melih.repository.entities.LaunchEntity
|
import com.melih.repository.entities.LaunchEntity
|
||||||
import com.melih.repository.interactors.base.Result
|
import com.melih.repository.interactors.base.Result
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import timber.log.Timber
|
|
||||||
|
|
||||||
class LaunchesFragment : BaseDaggerFragment<ListBinding>(), SwipeRefreshLayout.OnRefreshListener {
|
class LaunchesFragment : BaseDaggerFragment<ListBinding>(), SwipeRefreshLayout.OnRefreshListener {
|
||||||
|
|
||||||
@@ -40,32 +39,7 @@ class LaunchesFragment : BaseDaggerFragment<ListBinding>(), SwipeRefreshLayout.O
|
|||||||
binding.rocketList.adapter = launchesAdapter
|
binding.rocketList.adapter = launchesAdapter
|
||||||
binding.swipeRefreshLayout.setOnRefreshListener(this)
|
binding.swipeRefreshLayout.setOnRefreshListener(this)
|
||||||
|
|
||||||
// Observing state to show loading
|
observeDataChanges()
|
||||||
observe(viewModel.stateData) {
|
|
||||||
binding.swipeRefreshLayout.isRefreshing = it is Result.State.Loading
|
|
||||||
}
|
|
||||||
|
|
||||||
// Observing error to show toast with retry action
|
|
||||||
observe(viewModel.errorData) {
|
|
||||||
Snackbar.make(
|
|
||||||
binding.root,
|
|
||||||
resources.getString(it.messageRes),
|
|
||||||
Snackbar.LENGTH_INDEFINITE
|
|
||||||
).setAction(com.melih.core.R.string.retry) {
|
|
||||||
viewModel.retry()
|
|
||||||
}.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
observe(viewModel.successData) {
|
|
||||||
itemList.addAll(it)
|
|
||||||
launchesAdapter.submitList(itemList)
|
|
||||||
binding.rocketList.scheduleLayoutAnimation()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun onItemSelected(item: LaunchEntity) {
|
|
||||||
Timber.i("${item.id}")
|
|
||||||
startActivity(Actions.openDetailFor(item.id))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||||
@@ -80,22 +54,7 @@ class LaunchesFragment : BaseDaggerFragment<ListBinding>(), SwipeRefreshLayout.O
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onQueryTextChange(newText: String?): Boolean {
|
override fun onQueryTextChange(newText: String?): Boolean {
|
||||||
launchesAdapter.submitList(
|
launchesAdapter.submitList(filterItemListBy(newText))
|
||||||
if (!newText.isNullOrBlank()) {
|
|
||||||
itemList.filter {
|
|
||||||
it.rocket.name.contains(
|
|
||||||
newText,
|
|
||||||
true
|
|
||||||
) || (it.missions.size > 0 && it.missions[0].description.contains(
|
|
||||||
newText,
|
|
||||||
true
|
|
||||||
))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
itemList
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -104,6 +63,41 @@ class LaunchesFragment : BaseDaggerFragment<ListBinding>(), SwipeRefreshLayout.O
|
|||||||
super.onCreateOptionsMenu(menu, inflater)
|
super.onCreateOptionsMenu(menu, inflater)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ExperimentalCoroutinesApi
|
||||||
|
private fun observeDataChanges() {
|
||||||
|
|
||||||
|
// Observing state to show loading
|
||||||
|
observe(viewModel.stateData) {
|
||||||
|
binding.swipeRefreshLayout.isRefreshing = it is Result.State.Loading
|
||||||
|
}
|
||||||
|
|
||||||
|
// Observing error to show toast with retry action
|
||||||
|
observe(viewModel.errorData) {
|
||||||
|
showSnackbarWithAction(it) {
|
||||||
|
viewModel.retry()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
observe(viewModel.successData) {
|
||||||
|
itemList.addAll(it)
|
||||||
|
launchesAdapter.submitList(itemList)
|
||||||
|
binding.rocketList.scheduleLayoutAnimation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onItemSelected(item: LaunchEntity) {
|
||||||
|
startActivity(Actions.openDetailFor(item.id))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun filterItemListBy(query: String?) =
|
||||||
|
if (!query.isNullOrBlank()) {
|
||||||
|
itemList.filter {
|
||||||
|
it.rocket.name.containsIgnoreCase(query) || it.missions.any { it.description.containsIgnoreCase(query) }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
itemList
|
||||||
|
}
|
||||||
|
|
||||||
@ExperimentalCoroutinesApi
|
@ExperimentalCoroutinesApi
|
||||||
override fun onRefresh() {
|
override fun onRefresh() {
|
||||||
viewModel.refresh()
|
viewModel.refresh()
|
||||||
|
|||||||
Reference in New Issue
Block a user