diff --git a/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/filter/ActivityLogTypeFilterAdapter.kt b/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/filter/ActivityLogTypeFilterAdapter.kt index 09ff00a2337c..89e8ad4e0722 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/filter/ActivityLogTypeFilterAdapter.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/filter/ActivityLogTypeFilterAdapter.kt @@ -2,11 +2,11 @@ package org.wordpress.android.ui.activitylog.list.filter import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView.Adapter -import org.wordpress.android.ui.activitylog.list.filter.ActivityLogTypeFilterViewModel.ItemUiState +import org.wordpress.android.ui.activitylog.list.filter.ActivityLogTypeFilterViewModel.ListItemUiState import org.wordpress.android.ui.utils.UiHelpers class ActivityLogTypeFilterAdapter(private val uiHelpers: UiHelpers) : Adapter() { - private val items = mutableListOf() + private val items = mutableListOf() override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ActivityLogTypeFilterViewHolder { return ActivityLogTypeFilterViewHolder(parent, uiHelpers) @@ -18,7 +18,7 @@ class ActivityLogTypeFilterAdapter(private val uiHelpers: UiHelpers) : Adapter) { + fun update(newItems: List) { items.clear() items.addAll(newItems) notifyDataSetChanged() diff --git a/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/filter/ActivityLogTypeFilterViewHolder.kt b/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/filter/ActivityLogTypeFilterViewHolder.kt index 16645593e5d7..caed23f338d9 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/filter/ActivityLogTypeFilterViewHolder.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/filter/ActivityLogTypeFilterViewHolder.kt @@ -4,7 +4,7 @@ import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import org.wordpress.android.R -import org.wordpress.android.ui.activitylog.list.filter.ActivityLogTypeFilterViewModel.ItemUiState +import org.wordpress.android.ui.activitylog.list.filter.ActivityLogTypeFilterViewModel.ListItemUiState import org.wordpress.android.ui.utils.UiHelpers class ActivityLogTypeFilterViewHolder( @@ -13,6 +13,6 @@ class ActivityLogTypeFilterViewHolder( ) : RecyclerView.ViewHolder( LayoutInflater.from(parent.context).inflate(R.layout.activity_log_type_filter_item, parent, false) ) { - fun onBind(uiState: ItemUiState) { + fun onBind(uiState: ListItemUiState) { } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/filter/ActivityLogTypeFilterViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/filter/ActivityLogTypeFilterViewModel.kt index 8dc1464843b7..7bbca768371d 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/filter/ActivityLogTypeFilterViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/filter/ActivityLogTypeFilterViewModel.kt @@ -1,20 +1,118 @@ package org.wordpress.android.ui.activitylog.list.filter +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import org.wordpress.android.R +import org.wordpress.android.modules.BG_THREAD import org.wordpress.android.modules.UI_THREAD +import org.wordpress.android.ui.activitylog.list.filter.ActivityLogTypeFilterViewModel.ListItemUiState.SectionHeader +import org.wordpress.android.ui.activitylog.list.filter.ActivityLogTypeFilterViewModel.UiState.Content +import org.wordpress.android.ui.activitylog.list.filter.ActivityLogTypeFilterViewModel.UiState.FullscreenLoading +import org.wordpress.android.ui.utils.UiString +import org.wordpress.android.ui.utils.UiString.UiStringRes +import org.wordpress.android.ui.utils.UiString.UiStringText import org.wordpress.android.viewmodel.ScopedViewModel import javax.inject.Inject import javax.inject.Named class ActivityLogTypeFilterViewModel @Inject constructor( + @Named(BG_THREAD) private val bgDispatcher: CoroutineDispatcher, @Named(UI_THREAD) private val mainDispatcher: CoroutineDispatcher ) : ScopedViewModel(mainDispatcher) { private var isStarted = false + private val _uiState = MutableLiveData() + val uiState: LiveData = _uiState + fun start() { if (isStarted) return isStarted = true + + _uiState.value = FullscreenLoading + fetchAvailableActivityTypes() + } + + private fun fetchAvailableActivityTypes() { + launch { + // TODO malinjir initiate the fetch + onActivityTypesFetched(listOf(DummyActivityType, DummyActivityType, DummyActivityType)) + } + } + + private suspend fun onActivityTypesFetched(activityTypes: List) { + _uiState.value = buildContentUiState(activityTypes) + } + + private suspend fun buildContentUiState(activityTypes: List): Content { + return withContext(bgDispatcher) { + // TODO malinjir replace the hardcoded header title + val headerListItem = SectionHeader(UiStringText("Test")) + // TODO malinjir replace "it.toString()" with activity type name + val activityTypeListItems: List = activityTypes + .map { ListItemUiState.ActivityType(title = UiStringText(it.toString())) } + Content( + listOf(headerListItem) + activityTypeListItems, + primaryAction = Action(label = UiStringRes(R.string.activity_log_activity_type_filter_apply)) + .apply { action = ::onApplyClicked }, + secondaryAction = Action(label = UiStringRes(R.string.activity_log_activity_type_filter_clear)) + .apply { action = ::onClearClicked } + ) + } + } + + private fun onApplyClicked() { + // TODO malinjir save and dismiss + } + + private fun onClearClicked() { + (_uiState.value as? Content)?.let { it -> + _uiState.value = it.copy(items = getAllActivityTypeItemsUnchecked(it.items)) + } + } + + private fun getAllActivityTypeItemsUnchecked(listItemUiStates: List): List = + listItemUiStates.map { item -> + if (item is ListItemUiState.ActivityType) { + item.copy(checked = false) + } else { + item + } + } + + sealed class UiState { + open val contentVisibility = false + open val loadingVisibility = false + + object FullscreenLoading : UiState() { + override val loadingVisibility: Boolean = true + } + + data class Content( + val items: List, + val primaryAction: Action, + val secondaryAction: Action + ) : UiState() { + override val contentVisibility = true + } + } + + sealed class ListItemUiState { + data class SectionHeader( + val title: UiString + ) : ListItemUiState() + + data class ActivityType( + val title: UiString, + val checked: Boolean = false + ) : ListItemUiState() + } + + data class Action(val label: UiString) { + var action: (() -> Unit)? = null } - object ItemUiState + object DummyActivityType } diff --git a/WordPress/src/main/res/values/strings.xml b/WordPress/src/main/res/values/strings.xml index d7a506c47af7..d3dd077a6d5c 100644 --- a/WordPress/src/main/res/values/strings.xml +++ b/WordPress/src/main/res/values/strings.xml @@ -1026,6 +1026,8 @@ Rewind Site Are you sure you want to rewind your site back to %1$s at %2$s? This will remove all content and options created or changed since then. Since you\'re on a free plan, you\'ll see limited events in your activity. + Apply + Clear Scan diff --git a/WordPress/src/test/java/org/wordpress/android/ui/activitylog/list/filter/ActivityLogTypeFilterViewModelTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/activitylog/list/filter/ActivityLogTypeFilterViewModelTest.kt index 9cc956f02032..50888b363df8 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/activitylog/list/filter/ActivityLogTypeFilterViewModelTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/activitylog/list/filter/ActivityLogTypeFilterViewModelTest.kt @@ -1,10 +1,15 @@ package org.wordpress.android.ui.activitylog.list.filter import kotlinx.coroutines.InternalCoroutinesApi +import org.assertj.core.api.Assertions.assertThat import org.junit.Before import org.junit.Test import org.wordpress.android.BaseUnitTest import org.wordpress.android.TEST_DISPATCHER +import org.wordpress.android.test +import org.wordpress.android.ui.activitylog.list.filter.ActivityLogTypeFilterViewModel.ListItemUiState +import org.wordpress.android.ui.activitylog.list.filter.ActivityLogTypeFilterViewModel.UiState +import org.wordpress.android.ui.activitylog.list.filter.ActivityLogTypeFilterViewModel.UiState.Content @InternalCoroutinesApi class ActivityLogTypeFilterViewModelTest : BaseUnitTest() { @@ -12,11 +17,35 @@ class ActivityLogTypeFilterViewModelTest : BaseUnitTest() { @Before fun setUp() { - viewModel = ActivityLogTypeFilterViewModel(TEST_DISPATCHER) + viewModel = ActivityLogTypeFilterViewModel(TEST_DISPATCHER, TEST_DISPATCHER) } @Test - fun `skeleton test`() { - // Skeleton test. + fun `fullscreen loading shown, when screen initialized`() = test { + val uiStates = initObservers().uiStates + + viewModel.start() + + assertThat(uiStates[0]).isInstanceOf(UiState.FullscreenLoading::class.java) + } + + @Test + fun `section header gets added as first item in the list, when content shown`() { + initObservers() + + viewModel.start() + + assertThat((viewModel.uiState.value as Content).items[0]) + .isInstanceOf(ListItemUiState.SectionHeader::class.java) } + + private fun initObservers(): Observers { + val uiStates = mutableListOf() + viewModel.uiState.observeForever { + uiStates.add(it) + } + return Observers((uiStates)) + } + + private data class Observers(val uiStates: List) }