diff --git a/app/src/main/java/app/pachli/components/notifications/NotificationsViewModel.kt b/app/src/main/java/app/pachli/components/notifications/NotificationsViewModel.kt index d0a5f0579..fcdab59b2 100644 --- a/app/src/main/java/app/pachli/components/notifications/NotificationsViewModel.kt +++ b/app/src/main/java/app/pachli/components/notifications/NotificationsViewModel.kt @@ -33,6 +33,7 @@ import app.pachli.appstore.MuteEvent import app.pachli.components.timeline.FilterKind import app.pachli.components.timeline.FiltersRepository import app.pachli.core.accounts.AccountManager +import app.pachli.core.common.extensions.throttleFirst import app.pachli.core.data.repository.StatusDisplayOptionsRepository import app.pachli.core.network.model.Filter import app.pachli.core.network.model.FilterContext @@ -44,13 +45,11 @@ import app.pachli.network.FilterModel import app.pachli.usecase.TimelineCases import app.pachli.util.deserialize import app.pachli.util.serialize -import app.pachli.util.throttleFirst import app.pachli.viewdata.NotificationViewData import app.pachli.viewdata.StatusViewData import at.connyduck.calladapter.networkresult.getOrThrow import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject -import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.Flow @@ -416,7 +415,7 @@ class NotificationsViewModel @Inject constructor( // Handle NotificationAction.* viewModelScope.launch { uiAction.filterIsInstance() - .throttleFirst(THROTTLE_TIMEOUT) + .throttleFirst() .collect { action -> try { when (action) { @@ -435,7 +434,7 @@ class NotificationsViewModel @Inject constructor( // Handle StatusAction.* viewModelScope.launch { uiAction.filterIsInstance() - .throttleFirst(THROTTLE_TIMEOUT) // avoid double-taps + .throttleFirst() // avoid double-taps .collect { action -> try { when (action) { @@ -568,8 +567,4 @@ class NotificationsViewModel @Inject constructor( private fun toPrefs() = UiPrefs( showFabWhileScrolling = !sharedPreferencesRepository.getBoolean(PrefKeys.FAB_HIDE, false), ) - - companion object { - private val THROTTLE_TIMEOUT = 500.milliseconds - } } diff --git a/app/src/main/java/app/pachli/components/timeline/viewmodel/TimelineViewModel.kt b/app/src/main/java/app/pachli/components/timeline/viewmodel/TimelineViewModel.kt index 50fc97363..24c900477 100644 --- a/app/src/main/java/app/pachli/components/timeline/viewmodel/TimelineViewModel.kt +++ b/app/src/main/java/app/pachli/components/timeline/viewmodel/TimelineViewModel.kt @@ -44,6 +44,7 @@ import app.pachli.appstore.UnfollowEvent import app.pachli.components.timeline.FilterKind import app.pachli.components.timeline.FiltersRepository import app.pachli.core.accounts.AccountManager +import app.pachli.core.common.extensions.throttleFirst import app.pachli.core.data.repository.StatusDisplayOptionsRepository import app.pachli.core.model.Timeline import app.pachli.core.network.model.Filter @@ -54,10 +55,8 @@ import app.pachli.core.preferences.PrefKeys import app.pachli.core.preferences.SharedPreferencesRepository import app.pachli.network.FilterModel import app.pachli.usecase.TimelineCases -import app.pachli.util.throttleFirst import app.pachli.viewdata.StatusViewData import at.connyduck.calladapter.networkresult.getOrThrow -import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow @@ -329,7 +328,7 @@ abstract class TimelineViewModel( // Handle StatusAction.* viewModelScope.launch { uiAction.filterIsInstance() - .throttleFirst(THROTTLE_TIMEOUT) // avoid double-taps + .throttleFirst() // avoid double-taps .collect { action -> try { when (action) { @@ -623,8 +622,6 @@ abstract class TimelineViewModel( } companion object { - private val THROTTLE_TIMEOUT = 500.milliseconds - /** Tag for the timelineKind in `savedStateHandle` */ @VisibleForTesting(VisibleForTesting.PRIVATE) const val TIMELINE_TAG = "timeline" diff --git a/app/src/main/java/app/pachli/components/trending/viewmodel/TrendingLinksViewModel.kt b/app/src/main/java/app/pachli/components/trending/viewmodel/TrendingLinksViewModel.kt index d93beaf71..083aff201 100644 --- a/app/src/main/java/app/pachli/components/trending/viewmodel/TrendingLinksViewModel.kt +++ b/app/src/main/java/app/pachli/components/trending/viewmodel/TrendingLinksViewModel.kt @@ -21,15 +21,14 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import app.pachli.components.trending.TrendingLinksRepository import app.pachli.core.accounts.AccountManager +import app.pachli.core.common.extensions.throttleFirst import app.pachli.core.data.repository.StatusDisplayOptionsRepository import app.pachli.core.network.model.TrendsLink import app.pachli.core.preferences.PrefKeys import app.pachli.core.preferences.SharedPreferencesRepository -import app.pachli.util.throttleFirst import at.connyduck.calladapter.networkresult.fold import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject -import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted @@ -84,7 +83,7 @@ class TrendingLinksViewModel @Inject constructor( init { viewModelScope.launch { uiAction - .throttleFirst(THROTTLE_TIMEOUT) + .throttleFirst() .filterIsInstance() .onEach { invalidate() } .collect() @@ -99,8 +98,4 @@ class TrendingLinksViewModel @Inject constructor( { throwable -> _loadState.update { LoadState.Error(throwable) } }, ) } - - companion object { - private val THROTTLE_TIMEOUT = 500.milliseconds - } } diff --git a/app/src/main/java/app/pachli/util/FlowExtensions.kt b/core/common/src/main/kotlin/app/pachli/core/common/extensions/FlowExtensions.kt similarity index 86% rename from app/src/main/java/app/pachli/util/FlowExtensions.kt rename to core/common/src/main/kotlin/app/pachli/core/common/extensions/FlowExtensions.kt index a887f0435..5d470f71d 100644 --- a/app/src/main/java/app/pachli/util/FlowExtensions.kt +++ b/core/common/src/main/kotlin/app/pachli/core/common/extensions/FlowExtensions.kt @@ -15,9 +15,10 @@ * see . */ -package app.pachli.util +package app.pachli.core.common.extensions import kotlin.time.Duration +import kotlin.time.Duration.Companion.milliseconds import kotlin.time.TimeMark import kotlin.time.TimeSource import kotlinx.coroutines.flow.Flow @@ -50,11 +51,12 @@ import kotlinx.coroutines.flow.flow * ``` * * @see kotlinx.coroutines.flow.debounce(Duration) - * @param timeout Emissions within this duration of the last emission are filtered + * @param timeout Emissions within this duration of the last emission are filtered. + * Defaults to [DEFAULT_THROTTLE_FIRST_TIMEOUT] if omitted. * @param timeSource Used to measure elapsed time. Normally only overridden in tests */ fun Flow.throttleFirst( - timeout: Duration, + timeout: Duration = DEFAULT_THROTTLE_FIRST_TIMEOUT, timeSource: TimeSource = TimeSource.Monotonic, ) = flow { var marker: TimeMark? = null @@ -65,3 +67,5 @@ fun Flow.throttleFirst( } } } + +private val DEFAULT_THROTTLE_FIRST_TIMEOUT = 500.milliseconds diff --git a/app/src/test/java/app/pachli/util/FlowExtensionsTest.kt b/core/common/src/test/kotlin/app/pachli/core/common/extensions/FlowExtensionsTest.kt similarity index 97% rename from app/src/test/java/app/pachli/util/FlowExtensionsTest.kt rename to core/common/src/test/kotlin/app/pachli/core/common/extensions/FlowExtensionsTest.kt index 01b3a9679..bdd005bd5 100644 --- a/app/src/test/java/app/pachli/util/FlowExtensionsTest.kt +++ b/core/common/src/test/kotlin/app/pachli/core/common/extensions/FlowExtensionsTest.kt @@ -15,7 +15,7 @@ * see . */ -package app.pachli.util +package app.pachli.core.common.extensions import app.cash.turbine.test import com.google.common.truth.Truth.assertThat