Skip to content

Instantly share code, notes, and snippets.

@Vinny94051
Last active March 21, 2023 17:18
Show Gist options
  • Save Vinny94051/164108da870f3fd64933f47f390bf0f8 to your computer and use it in GitHub Desktop.
Save Vinny94051/164108da870f3fd64933f47f390bf0f8 to your computer and use it in GitHub Desktop.
Some code from my pet project
package applicationId.presentation.main
import android.os.Bundle
import android.view.View
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import org.koin.androidx.viewmodel.ext.android.viewModel
import androidx.lifecycle.lifecycleScope
import by.kirich1409.viewbindingdelegate.viewBinding
import com.kir.googlesheet.R
import com.kir.googlesheet.common_items.CommonViewHolderFactory
import com.kir.googlesheet.databinding.FragmentHomeBinding
import com.kir.googlesheet.presentation.main.HomeUiAction.ShowSnack
import com.kir.googlesheet.presentation.main.HomeUiEvents.OnInit
import com.kir.googlesheet.presentation.main.HomeUiEvents.OnSettingBtnClicked
import com.kir.googlesheet.presentation.main.HomeUiEvents.OnShareBtnClicked
import com.kir.googlesheet.utils.ext.showSnack
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapLatest
import ru.tinkoff.mobile.tech.ti_recycler.base.ViewTyped
import ru.tinkoff.mobile.tech.ti_recycler_coroutines.TiRecyclerCoroutines
class HomeFragment : Fragment(R.layout.fragment_home) {
companion object {
fun newInstance() = HomeFragment()
}
private val binding by viewBinding<FragmentHomeBinding>()
private val viewModel by viewModel<HomeViewModel>()
private val recycler: TiRecyclerCoroutines<ViewTyped> by lazy {
TiRecyclerCoroutines.invoke(
recyclerView = binding.content,
holderFactory = CommonViewHolderFactory()
)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.state.mapLatest(::onStateChanged).launchIn(lifecycleScope)
viewModel.sideEffects.mapLatest(::handleSideEffects).launchIn(lifecycleScope)
viewModel.send(OnInit)
initViews()
}
private fun onStateChanged(state: HomeUiState) {
binding.progressBar.isVisible = state.isLoading
recycler.setItems(state.content)
}
private fun handleSideEffects(sideEffects: List<HomeUiAction>) {
sideEffects.forEach { action ->
when (action) {
is ShowSnack -> showSnack(action.message)
}
}
}
private fun initViews() {
HomeRecyclerClicks(requireContext(), recycler)
.bind()
.map(viewModel::send)
.launchIn(lifecycleScope)
with(binding) {
settingsBtn.setOnClickListener {
viewModel.send(OnSettingBtnClicked)
}
shareBtn.setOnClickListener {
viewModel.send(OnShareBtnClicked)
}
}
}
}
package applicationId.presentation.main
import androidx.lifecycle.viewModelScope
import com.kir.googlesheet.R
import com.kir.googlesheet.common_mvi.MviViewModel
import com.kir.googlesheet.domain.GetMainInfo
import com.kir.googlesheet.old.presentation.ResourceProvider
import com.kir.googlesheet.presentation.main.HomeUiAction.ShowSnack
import com.kir.googlesheet.presentation.main.HomeUiEvents.OnFullReportClicked
import com.kir.googlesheet.presentation.main.HomeUiEvents.OnInit
import com.kir.googlesheet.presentation.main.HomeUiEvents.OnMonthChipsClicked
import com.kir.googlesheet.presentation.main.HomeUiEvents.OnPersonalReportClicked
import com.kir.googlesheet.presentation.main.HomeUiEvents.OnSettingBtnClicked
import com.kir.googlesheet.presentation.main.HomeUiEvents.OnShareBtnClicked
import com.kir.googlesheet.presentation.main.mapper.HomeUiMapper
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class HomeViewModel(
private val resourceProvider: ResourceProvider,
private val getMainInfo: GetMainInfo,
private val homeUiMapper: HomeUiMapper
) : MviViewModel<HomeUiState, HomeUiEvents, HomeUiAction>() {
override val mState = MutableStateFlow(HomeUiState())
override val mSideEffects = MutableStateFlow(emptyList<HomeUiAction>())
override fun send(event: HomeUiEvents) {
when (event) {
OnInit -> loadInfoByMonth("March") // todo: get current month
is OnMonthChipsClicked -> {
loadInfoByMonth(event.month)
}
OnSettingBtnClicked, OnShareBtnClicked -> {
val snackAction = ShowSnack(
resourceProvider.getString(R.string.snack_not_implemented_yet)
)
mSideEffects.value = listOf(snackAction)
}
OnFullReportClicked -> {
// TODO: remove stub
val snackAction = ShowSnack(
resourceProvider.getString(R.string.report_full)
)
mSideEffects.value = listOf(snackAction)
}
OnPersonalReportClicked -> {
// TODO: remove stub
val snackAction = ShowSnack(
resourceProvider.getString(R.string.report_by_person)
)
mSideEffects.value = listOf(snackAction)
}
}
}
private fun loadInfoByMonth(month: String) {
mState.change { copy(isLoading = true) }
viewModelScope.launch {
val mainScreenInfo = withContext(IO) {
delay(500)
val mainInfo = getMainInfo.getMainInfo(month)
homeUiMapper.map(mainInfo)
}
mState.change {
copy(isLoading = false, content = mainScreenInfo)
}
}
}
}
package applicationId.common_mvi
import androidx.lifecycle.ViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
abstract class MviViewModel<UiState, UiEvent, UiAction> : ViewModel() {
protected abstract val mState: MutableStateFlow<UiState>
val state: StateFlow<UiState> get() = mState
protected abstract val mSideEffects: MutableStateFlow<List<UiAction>>
val sideEffects: StateFlow<List<UiAction>> get() = mSideEffects
abstract fun send(event: UiEvent)
protected fun MutableStateFlow<UiState>.change(
action: UiState.() -> UiState
) {
value = mState.value.action()
}
}
## This is some code samples from my pet project
#### The code describes a main screen of my app.
In this snippet you can find such technologies as:
- Kotlin Coroutines,
- TiRecycler (due to in my pet project i need to do thinks faster, and I had a hands to this lib development)
- Koin for di - prefer it for a small project
- Mvi arcitecture
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment