Skip to content

Commit

Permalink
Merge pull request #13721 from wordpress-mobile/issue/13268-activity-…
Browse files Browse the repository at this point in the history
…log-filters-visibility

Issue/13268 activity log filters visibility
  • Loading branch information
malinajirka authored Jan 7, 2021
2 parents e1b63df + 455e2b5 commit 4963e82
Show file tree
Hide file tree
Showing 7 changed files with 229 additions and 36 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.wordpress.android.ui.jetpack

import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.withContext
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.wordpress.android.fluxc.Dispatcher
import org.wordpress.android.fluxc.generated.SiteActionBuilder
import org.wordpress.android.fluxc.store.SiteStore
import org.wordpress.android.fluxc.store.SiteStore.FetchJetpackCapabilitiesPayload
import org.wordpress.android.fluxc.store.SiteStore.OnJetpackCapabilitiesFetched
import org.wordpress.android.modules.BG_THREAD
import javax.inject.Inject
import javax.inject.Named
import kotlin.coroutines.Continuation
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine

class FetchJetpackCapabilitiesUseCase @Inject constructor(
@Suppress("unused") private val siteStore: SiteStore,
private val dispatcher: Dispatcher,
@param:Named(BG_THREAD) private val bgDispatcher: CoroutineDispatcher
) {
private var continuation: Continuation<OnJetpackCapabilitiesFetched>? = null

suspend fun fetchJetpackCapabilities(remoteSiteId: Long): OnJetpackCapabilitiesFetched {
return withContext(bgDispatcher) {
if (continuation != null) {
throw IllegalStateException("Request already in progress.")
}

dispatcher.register(this@FetchJetpackCapabilitiesUseCase)
suspendCoroutine { cont ->
val payload = FetchJetpackCapabilitiesPayload(remoteSiteId)
continuation = cont
dispatcher.dispatch(SiteActionBuilder.newFetchJetpackCapabilitiesAction(payload))
}
}
}

@Subscribe(threadMode = ThreadMode.BACKGROUND)
@SuppressWarnings("unused")
fun onJetpackCapabilitiesFetched(event: OnJetpackCapabilitiesFetched) {
dispatcher.unregister(this@FetchJetpackCapabilitiesUseCase)
continuation?.resume(event)
continuation = null
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
package org.wordpress.android.util.config

import org.wordpress.android.BuildConfig
import org.wordpress.android.annotation.FeatureInDevelopment
import org.wordpress.android.annotation.Feature
import org.wordpress.android.util.config.ActivityLogFiltersFeatureConfig.Companion.ACTIVITY_LOG_FILTERS
import javax.inject.Inject

/**
* Configuration of the Activity Log Filters feature.
*/
@FeatureInDevelopment
@Feature(remoteField = ACTIVITY_LOG_FILTERS)
class ActivityLogFiltersFeatureConfig
@Inject constructor(appConfig: AppConfig) : FeatureConfig(
appConfig,
BuildConfig.ACTIVITY_LOG_FILTERS
)
BuildConfig.ACTIVITY_LOG_FILTERS,
ACTIVITY_LOG_FILTERS
) {
companion object {
const val ACTIVITY_LOG_FILTERS = "activity_log_filters_enabled"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import org.wordpress.android.R
import org.wordpress.android.fluxc.model.JetpackCapability.BACKUP
import org.wordpress.android.fluxc.model.JetpackCapability.BACKUP_DAILY
import org.wordpress.android.fluxc.model.JetpackCapability.BACKUP_REALTIME
import org.wordpress.android.fluxc.model.LocalOrRemoteId.RemoteId
import org.wordpress.android.fluxc.model.SiteModel
import org.wordpress.android.fluxc.model.activity.ActivityLogModel
Expand All @@ -27,6 +30,7 @@ import org.wordpress.android.ui.activitylog.list.ActivityLogListItem.Header
import org.wordpress.android.ui.activitylog.list.ActivityLogListItem.Loading
import org.wordpress.android.ui.activitylog.list.ActivityLogListItem.SecondaryAction.DOWNLOAD_BACKUP
import org.wordpress.android.ui.activitylog.list.ActivityLogListItem.SecondaryAction.RESTORE
import org.wordpress.android.ui.jetpack.FetchJetpackCapabilitiesUseCase
import org.wordpress.android.ui.jetpack.rewind.RewindStatusService
import org.wordpress.android.ui.jetpack.rewind.RewindStatusService.RewindProgress
import org.wordpress.android.ui.stats.refresh.utils.DateUtils
Expand Down Expand Up @@ -65,6 +69,7 @@ class ActivityLogViewModel @Inject constructor(
private val backupFeatureConfig: BackupFeatureConfig,
private val dateUtils: DateUtils,
private val activityLogTracker: ActivityLogTracker,
private val fetchJetpackCapabilitiesUseCase: FetchJetpackCapabilitiesUseCase,
@param:Named(UI_THREAD) private val uiDispatcher: CoroutineDispatcher
) : ScopedViewModel(uiDispatcher) {
enum class ActivityLogListStatus {
Expand All @@ -85,7 +90,7 @@ class ActivityLogViewModel @Inject constructor(
val eventListStatus: LiveData<ActivityLogListStatus>
get() = _eventListStatus

private val _filtersUiState = MutableLiveData<FiltersUiState>()
private val _filtersUiState = MutableLiveData<FiltersUiState>(FiltersHidden)
val filtersUiState: LiveData<FiltersUiState>
get() = _filtersUiState

Expand Down Expand Up @@ -167,11 +172,26 @@ class ActivityLogViewModel @Inject constructor(
reloadEvents(done = true)
requestEventsUpdate(false)

refreshFiltersUiState()
showFiltersIfSupported()

isStarted = true
}

private fun showFiltersIfSupported() {
when {
!activityLogFiltersFeatureConfig.isEnabled() -> return
!site.hasFreePlan -> refreshFiltersUiState()
else -> {
launch {
val result = fetchJetpackCapabilitiesUseCase.fetchJetpackCapabilities(site.siteId)
result.capabilities?.find { it == BACKUP || it == BACKUP_DAILY || it == BACKUP_REALTIME }?.let {
refreshFiltersUiState()
}
}
}
}
}

override fun onCleared() {
rewindStatusService.rewindAvailable.removeObserver(rewindAvailableObserver)
rewindStatusService.rewindProgress.removeObserver(rewindProgressObserver)
Expand All @@ -188,20 +208,16 @@ class ActivityLogViewModel @Inject constructor(
}

private fun refreshFiltersUiState() {
_filtersUiState.value = if (activityLogFiltersFeatureConfig.isEnabled()) {
val (activityTypeLabel, activityTypeLabelContentDescription) = createActivityTypeFilterLabel()
val (dateRangeLabel, dateRangeLabelContentDescription) = createDateRangeFilterLabel()
FiltersShown(
dateRangeLabel,
dateRangeLabelContentDescription,
activityTypeLabel,
activityTypeLabelContentDescription,
currentDateRangeFilter?.let { ::onClearDateRangeFilterClicked },
currentActivityTypeFilter.takeIf { it.isNotEmpty() }?.let { ::onClearActivityTypeFilterClicked }
)
} else {
FiltersHidden
}
val (activityTypeLabel, activityTypeLabelContentDescription) = createActivityTypeFilterLabel()
val (dateRangeLabel, dateRangeLabelContentDescription) = createDateRangeFilterLabel()
_filtersUiState.value = FiltersShown(
dateRangeLabel,
dateRangeLabelContentDescription,
activityTypeLabel,
activityTypeLabelContentDescription,
currentDateRangeFilter?.let { ::onClearDateRangeFilterClicked },
currentActivityTypeFilter.takeIf { it.isNotEmpty() }?.let { ::onClearActivityTypeFilterClicked }
)
}

private fun createDateRangeFilterLabel(): kotlin.Pair<UiString, UiString> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar_main"
android:animateLayoutChanges="true"
android:layout_width="match_parent"
android:layout_height="wrap_content">

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package org.wordpress.android.ui.jetpack

import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import com.nhaarman.mockitokotlin2.any
import com.nhaarman.mockitokotlin2.verify
import com.nhaarman.mockitokotlin2.whenever
import kotlinx.coroutines.InternalCoroutinesApi
import org.assertj.core.api.Assertions.assertThat
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.junit.MockitoJUnitRunner
import org.wordpress.android.TEST_DISPATCHER
import org.wordpress.android.fluxc.Dispatcher
import org.wordpress.android.fluxc.store.SiteStore
import org.wordpress.android.fluxc.store.SiteStore.OnJetpackCapabilitiesFetched
import org.wordpress.android.test

private const val SITE_ID = 1L
@InternalCoroutinesApi
@RunWith(MockitoJUnitRunner::class)
class FetchJetpackCapabilitiesUseCaseTest {
@Rule
@JvmField val rule = InstantTaskExecutorRule()

@Mock private lateinit var dispatcher: Dispatcher
@Mock private lateinit var store: SiteStore
private lateinit var useCase: FetchJetpackCapabilitiesUseCase
private lateinit var event: OnJetpackCapabilitiesFetched

@Before
fun setUp() {
useCase = FetchJetpackCapabilitiesUseCase(store, dispatcher, TEST_DISPATCHER)
event = OnJetpackCapabilitiesFetched(SITE_ID, listOf(), null)
}

@Test
fun `coroutine resumed, when result event dispatched`() = test {
whenever(dispatcher.dispatch(any())).then { useCase.onJetpackCapabilitiesFetched(event) }

val resultEvent = useCase.fetchJetpackCapabilities(SITE_ID)

assertThat(resultEvent).isEqualTo(event)
}

@Test
fun `useCase subscribes to event bus`() = test {
whenever(dispatcher.dispatch(any())).then { useCase.onJetpackCapabilitiesFetched(event) }

useCase.fetchJetpackCapabilities(SITE_ID)

verify(dispatcher).register(useCase)
}

@Test
fun `useCase unsubscribes from event bus`() = test {
whenever(dispatcher.dispatch(any())).then { useCase.onJetpackCapabilitiesFetched(event) }

useCase.fetchJetpackCapabilities(SITE_ID)

verify(dispatcher).unregister(useCase)
}
}
Loading

0 comments on commit 4963e82

Please sign in to comment.