Skip to content

Commit 7a498d8

Browse files
committed
changed a bit the components to make the screen stable for compose
1 parent 91af8b0 commit 7a498d8

9 files changed

Lines changed: 375 additions & 213 deletions

File tree

app/src/main/java/org/schabi/newpipe/settings/components/switch_preference/SwitchPreference.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ fun SwitchPreferenceComponent(
3131
horizontalArrangement = Arrangement.SpaceBetween,
3232
verticalAlignment = Alignment.CenterVertically
3333
) {
34-
3534
Column(
3635
horizontalAlignment = Alignment.Start,
3736
verticalArrangement = Arrangement.Center,

app/src/main/java/org/schabi/newpipe/settings/presentation/history_cache/HistoryCacheEvent.kt

Lines changed: 0 additions & 12 deletions
This file was deleted.

app/src/main/java/org/schabi/newpipe/settings/presentation/history_cache/HistoryCacheSettingsScreen.kt

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,45 +7,75 @@ import androidx.compose.foundation.layout.fillMaxWidth
77
import androidx.compose.foundation.layout.padding
88
import androidx.compose.foundation.rememberScrollState
99
import androidx.compose.foundation.verticalScroll
10+
import androidx.compose.material3.HorizontalDivider
1011
import androidx.compose.material3.Scaffold
1112
import androidx.compose.material3.SnackbarHost
1213
import androidx.compose.material3.SnackbarHostState
1314
import androidx.compose.material3.Surface
1415
import androidx.compose.runtime.Composable
16+
import androidx.compose.runtime.LaunchedEffect
1517
import androidx.compose.runtime.collectAsState
1618
import androidx.compose.runtime.getValue
1719
import androidx.compose.runtime.mutableStateOf
1820
import androidx.compose.runtime.remember
19-
import androidx.compose.runtime.rememberCoroutineScope
2021
import androidx.compose.ui.Alignment
2122
import androidx.compose.ui.Modifier
23+
import androidx.compose.ui.res.stringResource
2224
import androidx.compose.ui.tooling.preview.Preview
2325
import androidx.hilt.navigation.compose.hiltViewModel
24-
import kotlinx.coroutines.launch
26+
import org.schabi.newpipe.R
2527
import org.schabi.newpipe.settings.presentation.history_cache.components.CachePreferencesComponent
2628
import org.schabi.newpipe.settings.presentation.history_cache.components.HistoryPreferencesComponent
29+
import org.schabi.newpipe.settings.presentation.history_cache.events.HistoryCacheEvent
30+
import org.schabi.newpipe.settings.presentation.history_cache.events.HistoryCacheUiEvent.ShowClearWatchHistorySnackbar
31+
import org.schabi.newpipe.settings.presentation.history_cache.events.HistoryCacheUiEvent.ShowDeletePlaybackSnackbar
32+
import org.schabi.newpipe.settings.presentation.history_cache.events.HistoryCacheUiEvent.ShowDeleteSearchHistorySnackbar
33+
import org.schabi.newpipe.settings.presentation.history_cache.events.HistoryCacheUiEvent.ShowReCaptchaCookiesSnackbar
34+
import org.schabi.newpipe.settings.presentation.history_cache.events.HistoryCacheUiEvent.ShowWipeCachedMetadataSnackbar
2735
import org.schabi.newpipe.ui.theme.AppTheme
2836

2937
@Composable
30-
fun HistoryCacheScreen(
38+
fun HistoryCacheSettingsScreen(
3139
modifier: Modifier = Modifier,
3240
viewModel: HistoryCacheSettingsViewModel = hiltViewModel(),
3341
) {
42+
val snackBarHostState = remember { SnackbarHostState() }
43+
val playBackPositionsDeleted = stringResource(R.string.watch_history_states_deleted)
44+
val watchHistoryDeleted = stringResource(R.string.watch_history_deleted)
45+
val wipeCachedMetadataSnackbar = stringResource(R.string.metadata_cache_wipe_complete_notice)
46+
val deleteSearchHistory = stringResource(R.string.search_history_deleted)
47+
val clearReCaptchaCookiesSnackbar = stringResource(R.string.recaptcha_cookies_cleared)
48+
49+
LaunchedEffect(key1 = true) {
50+
viewModel.eventFlow.collect { event ->
51+
val message = when (event) {
52+
is ShowDeletePlaybackSnackbar -> playBackPositionsDeleted
53+
is ShowClearWatchHistorySnackbar -> watchHistoryDeleted
54+
is ShowWipeCachedMetadataSnackbar -> wipeCachedMetadataSnackbar
55+
is ShowDeleteSearchHistorySnackbar -> deleteSearchHistory
56+
is ShowReCaptchaCookiesSnackbar -> clearReCaptchaCookiesSnackbar
57+
}
58+
59+
snackBarHostState.showSnackbar(message)
60+
}
61+
}
62+
3463
val state by viewModel.state.collectAsState()
3564
HistoryCacheComponent(
3665
state = state,
3766
onEvent = viewModel::onEvent,
67+
snackBarHostState = snackBarHostState,
3868
modifier = modifier
3969
)
4070
}
4171

4272
@Composable
4373
fun HistoryCacheComponent(
44-
state: HistoryCacheUiState,
74+
state: SwitchPreferencesUiState,
4575
onEvent: (HistoryCacheEvent) -> Unit,
76+
snackBarHostState: SnackbarHostState,
4677
modifier: Modifier = Modifier,
4778
) {
48-
val snackBarHostState = remember { SnackbarHostState() }
4979
Scaffold(
5080
modifier = modifier,
5181
snackbarHost = {
@@ -61,18 +91,15 @@ fun HistoryCacheComponent(
6191
verticalArrangement = Arrangement.Center,
6292
) {
6393
HistoryPreferencesComponent(
64-
state = state.switchPreferencesUiState,
65-
onEvent = onEvent,
66-
modifier = Modifier.fillMaxWidth()
94+
state = state,
95+
onEvent = { key, value ->
96+
onEvent(HistoryCacheEvent.OnUpdateBooleanPreference(key, value))
97+
},
98+
modifier = Modifier.fillMaxWidth(),
6799
)
68-
val coroutineScope = rememberCoroutineScope()
100+
HorizontalDivider(Modifier.fillMaxWidth())
69101
CachePreferencesComponent(
70-
onEvent = onEvent,
71-
onShowSnackbar = {
72-
coroutineScope.launch {
73-
snackBarHostState.showSnackbar(it)
74-
}
75-
},
102+
onEvent = { onEvent(it) },
76103
modifier = Modifier.fillMaxWidth()
77104
)
78105
}
@@ -84,7 +111,7 @@ fun HistoryCacheComponent(
84111
private fun HistoryCacheComponentPreview() {
85112
val state by remember {
86113
mutableStateOf(
87-
HistoryCacheUiState()
114+
SwitchPreferencesUiState()
88115
)
89116
}
90117
AppTheme(
@@ -95,6 +122,7 @@ private fun HistoryCacheComponentPreview() {
95122
state = state,
96123
onEvent = {
97124
},
125+
snackBarHostState = SnackbarHostState(),
98126
modifier = Modifier.fillMaxSize()
99127
)
100128
}
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
package org.schabi.newpipe.settings.presentation.history_cache
2+
3+
import androidx.lifecycle.ViewModel
4+
import androidx.lifecycle.viewModelScope
5+
import dagger.hilt.android.lifecycle.HiltViewModel
6+
import kotlinx.coroutines.Dispatchers
7+
import kotlinx.coroutines.flow.MutableSharedFlow
8+
import kotlinx.coroutines.flow.MutableStateFlow
9+
import kotlinx.coroutines.flow.StateFlow
10+
import kotlinx.coroutines.flow.asSharedFlow
11+
import kotlinx.coroutines.flow.asStateFlow
12+
import kotlinx.coroutines.flow.update
13+
import kotlinx.coroutines.launch
14+
import org.schabi.newpipe.DownloaderImpl
15+
import org.schabi.newpipe.R
16+
import org.schabi.newpipe.error.ErrorInfo
17+
import org.schabi.newpipe.error.ReCaptchaActivity
18+
import org.schabi.newpipe.error.UserAction
19+
import org.schabi.newpipe.error.usecases.OpenErrorActivity
20+
import org.schabi.newpipe.settings.domain.usecases.DeleteCompleteSearchHistory
21+
import org.schabi.newpipe.settings.domain.usecases.DeleteCompleteStreamStateHistory
22+
import org.schabi.newpipe.settings.domain.usecases.DeleteWatchHistory
23+
import org.schabi.newpipe.settings.domain.usecases.get_preference.GetPreference
24+
import org.schabi.newpipe.settings.domain.usecases.update_boolean_preference.UpdatePreference
25+
import org.schabi.newpipe.settings.presentation.history_cache.events.HistoryCacheEvent
26+
import org.schabi.newpipe.settings.presentation.history_cache.events.HistoryCacheEvent.OnClickClearSearchHistory
27+
import org.schabi.newpipe.settings.presentation.history_cache.events.HistoryCacheEvent.OnClickClearWatchHistory
28+
import org.schabi.newpipe.settings.presentation.history_cache.events.HistoryCacheEvent.OnClickDeletePlaybackPositions
29+
import org.schabi.newpipe.settings.presentation.history_cache.events.HistoryCacheEvent.OnClickReCaptchaCookies
30+
import org.schabi.newpipe.settings.presentation.history_cache.events.HistoryCacheEvent.OnClickWipeCachedMetadata
31+
import org.schabi.newpipe.settings.presentation.history_cache.events.HistoryCacheEvent.OnUpdateBooleanPreference
32+
import org.schabi.newpipe.settings.presentation.history_cache.events.HistoryCacheUiEvent
33+
import org.schabi.newpipe.settings.presentation.history_cache.events.HistoryCacheUiEvent.ShowClearWatchHistorySnackbar
34+
import org.schabi.newpipe.settings.presentation.history_cache.events.HistoryCacheUiEvent.ShowDeletePlaybackSnackbar
35+
import org.schabi.newpipe.settings.presentation.history_cache.events.HistoryCacheUiEvent.ShowDeleteSearchHistorySnackbar
36+
import org.schabi.newpipe.settings.presentation.history_cache.events.HistoryCacheUiEvent.ShowWipeCachedMetadataSnackbar
37+
import org.schabi.newpipe.util.InfoCache
38+
import javax.inject.Inject
39+
40+
@HiltViewModel
41+
class HistoryCacheSettingsViewModel @Inject constructor(
42+
private val updateBooleanPreference: UpdatePreference<Boolean>,
43+
private val updateStringPreference: UpdatePreference<String>,
44+
private val getBooleanPreference: GetPreference<Boolean>,
45+
private val deleteWatchHistory: DeleteWatchHistory,
46+
private val deleteCompleteStreamStateHistory: DeleteCompleteStreamStateHistory,
47+
private val deleteCompleteSearchHistory: DeleteCompleteSearchHistory,
48+
private val openErrorActivity: OpenErrorActivity,
49+
) : ViewModel() {
50+
private val _state = MutableStateFlow(SwitchPreferencesUiState())
51+
val state: StateFlow<SwitchPreferencesUiState> = _state.asStateFlow()
52+
53+
private val _eventFlow = MutableSharedFlow<HistoryCacheUiEvent>()
54+
val eventFlow = _eventFlow.asSharedFlow()
55+
56+
init {
57+
viewModelScope.launch {
58+
getBooleanPreference(R.string.enable_watch_history_key, true).collect { preference ->
59+
_state.update { oldState ->
60+
oldState.copy(
61+
watchHistoryEnabled = preference
62+
)
63+
}
64+
}
65+
}
66+
67+
viewModelScope.launch {
68+
getBooleanPreference(R.string.enable_playback_resume_key, true).collect { preference ->
69+
_state.update { oldState ->
70+
oldState.copy(
71+
resumePlaybackEnabled = preference
72+
)
73+
}
74+
}
75+
}
76+
77+
viewModelScope.launch {
78+
getBooleanPreference(
79+
R.string.enable_playback_state_lists_key,
80+
true
81+
).collect { preference ->
82+
_state.update { oldState ->
83+
oldState.copy(
84+
positionsInListsEnabled = preference
85+
)
86+
}
87+
}
88+
}
89+
viewModelScope.launch {
90+
getBooleanPreference(R.string.enable_search_history_key, true).collect { preference ->
91+
_state.update { oldState ->
92+
oldState.copy(
93+
searchHistoryEnabled = preference
94+
)
95+
}
96+
}
97+
}
98+
}
99+
100+
fun onEvent(event: HistoryCacheEvent) {
101+
when (event) {
102+
is OnUpdateBooleanPreference -> {
103+
viewModelScope.launch {
104+
updateBooleanPreference(event.key, event.isEnabled)
105+
}
106+
}
107+
108+
is OnClickWipeCachedMetadata -> {
109+
InfoCache.getInstance().clearCache()
110+
viewModelScope.launch {
111+
_eventFlow.emit(ShowWipeCachedMetadataSnackbar)
112+
}
113+
}
114+
115+
is OnClickClearWatchHistory -> {
116+
viewModelScope.launch {
117+
deleteWatchHistory(
118+
onDeletePlaybackStates = {
119+
viewModelScope.launch {
120+
_eventFlow.emit(ShowDeletePlaybackSnackbar)
121+
}
122+
},
123+
onDeleteWholeStreamHistory = {
124+
viewModelScope.launch {
125+
_eventFlow.emit(ShowClearWatchHistorySnackbar)
126+
}
127+
},
128+
onRemoveOrphanedRecords = {
129+
// TODO: ask why original did nothing
130+
}
131+
)
132+
}
133+
}
134+
135+
is OnClickDeletePlaybackPositions -> {
136+
viewModelScope.launch {
137+
deleteCompleteStreamStateHistory(
138+
Dispatchers.IO,
139+
onError = { error ->
140+
openErrorActivity(
141+
ErrorInfo(
142+
error,
143+
UserAction.DELETE_FROM_HISTORY,
144+
"Delete playback states"
145+
)
146+
)
147+
},
148+
onSuccess = {
149+
viewModelScope.launch {
150+
_eventFlow.emit(ShowDeletePlaybackSnackbar)
151+
}
152+
}
153+
)
154+
}
155+
}
156+
157+
is OnClickClearSearchHistory -> {
158+
viewModelScope.launch {
159+
deleteCompleteSearchHistory(
160+
dispatcher = Dispatchers.IO,
161+
onError = { error ->
162+
openErrorActivity(
163+
ErrorInfo(
164+
error,
165+
UserAction.DELETE_FROM_HISTORY,
166+
"Delete search history"
167+
)
168+
)
169+
},
170+
onSuccess = {
171+
viewModelScope.launch {
172+
_eventFlow.emit(ShowDeleteSearchHistorySnackbar)
173+
}
174+
}
175+
)
176+
}
177+
}
178+
179+
is OnClickReCaptchaCookies -> {
180+
viewModelScope.launch {
181+
updateStringPreference(event.key, "")
182+
DownloaderImpl.getInstance()
183+
.setCookie(ReCaptchaActivity.RECAPTCHA_COOKIES_KEY, "")
184+
_eventFlow.emit(HistoryCacheUiEvent.ShowWipeCachedMetadataSnackbar)
185+
}
186+
}
187+
}
188+
}
189+
}

app/src/main/java/org/schabi/newpipe/settings/presentation/history_cache/HistoryCacheUiState.kt renamed to app/src/main/java/org/schabi/newpipe/settings/presentation/history_cache/SwitchPreferencesUiState.kt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
package org.schabi.newpipe.settings.presentation.history_cache
22

3-
data class HistoryCacheUiState(
4-
val switchPreferencesUiState: SwitchPreferencesUiState = SwitchPreferencesUiState()
5-
)
6-
3+
import androidx.compose.runtime.Stable
4+
@Stable
75
data class SwitchPreferencesUiState(
86
val watchHistoryEnabled: Boolean = false,
97
val resumePlaybackEnabled: Boolean = false,

0 commit comments

Comments
 (0)