@@ -7,42 +7,26 @@ import androidx.compose.animation.fadeIn
77import androidx.compose.animation.fadeOut
88import androidx.compose.animation.togetherWith
99import androidx.compose.foundation.background
10- import androidx.compose.foundation.focusGroup
11- import androidx.compose.foundation.layout.Arrangement
1210import androidx.compose.foundation.layout.Box
13- import androidx.compose.foundation.layout.Column
14- import androidx.compose.foundation.layout.PaddingValues
1511import androidx.compose.foundation.layout.fillMaxSize
1612import androidx.compose.foundation.layout.fillMaxWidth
17- import androidx.compose.foundation.layout.padding
18- import androidx.compose.foundation.lazy.grid.GridCells
19- import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
20- import androidx.compose.foundation.lazy.grid.items
21- import androidx.compose.foundation.lazy.grid.rememberLazyGridState
2213import androidx.compose.runtime.Composable
23- import androidx.compose.runtime.LaunchedEffect
2414import androidx.compose.runtime.getValue
2515import androidx.compose.runtime.mutableStateOf
26- import androidx.compose.runtime.remember
2716import androidx.compose.runtime.saveable.listSaver
2817import androidx.compose.runtime.saveable.rememberSaveable
2918import androidx.compose.runtime.setValue
3019import androidx.compose.ui.Modifier
31- import androidx.compose.ui.focus.FocusRequester
32- import androidx.compose.ui.focus.focusProperties
33- import androidx.compose.ui.focus.focusRequester
34- import androidx.compose.ui.focus.onFocusChanged
3520import androidx.compose.ui.graphics.Color
3621import androidx.compose.ui.res.stringResource
3722import androidx.compose.ui.tooling.preview.Devices
3823import androidx.compose.ui.tooling.preview.Preview
39- import androidx.compose.ui.unit.dp
4024import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
4125import androidx.lifecycle.compose.collectAsStateWithLifecycle
4226import androidx.tv.material3.MaterialTheme
43- import androidx.tv.material3.Text
4427import au.com.shiftyjelly.pocketcasts.component.TvEmptyState
4528import au.com.shiftyjelly.pocketcasts.component.TvFolderCard
29+ import au.com.shiftyjelly.pocketcasts.component.TvPodcastGridScaffold
4630import au.com.shiftyjelly.pocketcasts.component.TvPodcastTile
4731import au.com.shiftyjelly.pocketcasts.compose.AppTheme
4832import au.com.shiftyjelly.pocketcasts.compose.loading.LoadingView
@@ -52,7 +36,6 @@ import au.com.shiftyjelly.pocketcasts.models.to.FolderItem
5236import au.com.shiftyjelly.pocketcasts.models.type.PodcastsSortType
5337import au.com.shiftyjelly.pocketcasts.repositories.images.PodcastImage
5438import au.com.shiftyjelly.pocketcasts.theme.TvColors
55- import au.com.shiftyjelly.pocketcasts.theme.TvTextStyles
5639import au.com.shiftyjelly.pocketcasts.ui.theme.Theme
5740import java.util.Date
5841import au.com.shiftyjelly.pocketcasts.localization.R as LR
@@ -81,7 +64,6 @@ fun TvYourPodcastsScreen(
8164 } else {
8265 TvYourPodcastsContent (
8366 uiState = uiState,
84- getFolderCoverUuids = viewModel::folderCoverUuids,
8567 onNavigateToHome = onNavigateToHome,
8668 onOpenFolder = { openedFolder = OpenedFolder (it.uuid, it.name) },
8769 modifier = modifier,
@@ -99,7 +81,6 @@ private val OpenedFolderSaver = listSaver<OpenedFolder?, String>(
9981@Composable
10082private fun TvYourPodcastsContent (
10183 uiState : TvYourPodcastsUiState ,
102- getFolderCoverUuids : suspend (String ) -> List <String >,
10384 onNavigateToHome : () -> Unit ,
10485 onOpenFolder : (Folder ) -> Unit ,
10586 modifier : Modifier = Modifier ,
@@ -130,7 +111,6 @@ private fun TvYourPodcastsContent(
130111
131112 is TvYourPodcastsUiState .Loaded -> TvYourPodcastsGrid (
132113 items = state.items,
133- getFolderCoverUuids = getFolderCoverUuids,
134114 onOpenFolder = onOpenFolder,
135115 modifier = Modifier .fillMaxSize(),
136116 )
@@ -141,7 +121,6 @@ private fun TvYourPodcastsContent(
141121@Composable
142122private fun TvYourPodcastsGrid (
143123 items : List <FolderItem >,
144- getFolderCoverUuids : suspend (String ) -> List <String >,
145124 onOpenFolder : (Folder ) -> Unit ,
146125 modifier : Modifier = Modifier ,
147126) {
@@ -159,98 +138,17 @@ private fun TvYourPodcastsGrid(
159138 modifier = itemModifier,
160139 )
161140
162- is FolderItem .Folder -> FolderGridItem (
141+ is FolderItem .Folder -> TvFolderCard (
163142 folder = item.folder,
164- getFolderCoverUuids = getFolderCoverUuids ,
165- onOpenFolder = onOpenFolder,
143+ coverUrls = item.podcasts.take( FOLDER_COVER_COUNT ).map { PodcastImage .getMediumArtworkUrl(it.uuid) } ,
144+ onClick = { onOpenFolder(item.folder) } ,
166145 modifier = itemModifier,
167146 )
168147 }
169148 }
170149}
171150
172- @Composable
173- private fun FolderGridItem (
174- folder : Folder ,
175- getFolderCoverUuids : suspend (String ) -> List <String >,
176- onOpenFolder : (Folder ) -> Unit ,
177- modifier : Modifier = Modifier ,
178- ) {
179- var coverUrls by remember(folder.uuid) { mutableStateOf(emptyList<String >()) }
180- LaunchedEffect (folder.uuid, getFolderCoverUuids) {
181- coverUrls = getFolderCoverUuids(folder.uuid).map(PodcastImage ::getMediumArtworkUrl)
182- }
183- TvFolderCard (
184- folder = folder,
185- coverUrls = coverUrls,
186- onClick = { onOpenFolder(folder) },
187- modifier = modifier,
188- )
189- }
190-
191- @Composable
192- internal fun TvPodcastGridScaffold (
193- title : String ,
194- itemKeys : List <Any >,
195- modifier : Modifier = Modifier ,
196- autoFocusFirstItem : Boolean = false,
197- itemContent : @Composable (index: Int , itemModifier: Modifier ) -> Unit ,
198- ) {
199- Column (modifier = modifier) {
200- Text (
201- text = title,
202- style = TvTextStyles .ScreenTitle ,
203- color = Color .White ,
204- modifier = Modifier .padding(start = 32 .dp, top = 8 .dp, bottom = 10 .dp),
205- )
206- val gridState = rememberLazyGridState()
207- var lastFocusedKey by rememberSaveable { mutableStateOf<String ?>(null ) }
208- val focusRequesters = remember(itemKeys.size) { List (itemKeys.size) { FocusRequester () } }
209-
210- if (autoFocusFirstItem) {
211- LaunchedEffect (focusRequesters) {
212- focusRequesters.firstOrNull()?.requestFocus()
213- }
214- }
215-
216- LazyVerticalGrid (
217- state = gridState,
218- columns = GridCells .Fixed (GRID_COLUMNS ),
219- horizontalArrangement = Arrangement .spacedBy(16 .dp),
220- verticalArrangement = Arrangement .spacedBy(16 .dp),
221- contentPadding = PaddingValues (start = 32 .dp, top = 16 .dp, end = 32 .dp, bottom = 32 .dp),
222- modifier = Modifier
223- .focusGroup()
224- .focusProperties {
225- onEnter = {
226- val visible = gridState.layoutInfo.visibleItemsInfo
227- val target = itemKeys.indexOfFirst { it.toString() == lastFocusedKey }
228- .takeIf { index -> index >= 0 && visible.any { it.index == index } }
229- ? : visible.firstOrNull()?.index
230- target?.let { focusRequesters.getOrNull(it)?.requestFocus() }
231- }
232- },
233- ) {
234- items(
235- count = itemKeys.size,
236- key = { index -> itemKeys[index] },
237- ) { index ->
238- itemContent(
239- index,
240- Modifier
241- .focusRequester(focusRequesters[index])
242- .onFocusChanged { focusState ->
243- if (focusState.hasFocus) {
244- lastFocusedKey = itemKeys[index].toString()
245- }
246- },
247- )
248- }
249- }
250- }
251- }
252-
253- private const val GRID_COLUMNS = 6
151+ private const val FOLDER_COVER_COUNT = 4
254152
255153@Preview(device = Devices .TV_1080p )
256154@Composable
@@ -273,15 +171,14 @@ private fun TvYourPodcastsGridPreview() {
273171 deleted = false ,
274172 syncModified = 0 ,
275173 ),
276- podcasts = emptyList() ,
174+ podcasts = List ( 4 ) { index -> Podcast (uuid = " cover- $index " ) } ,
277175 ),
278176 )
279177 repeat(11 ) { index ->
280178 add(FolderItem .Podcast (Podcast (uuid = " podcast-$index " , title = " Podcast $index " )))
281179 }
282180 },
283181 ),
284- getFolderCoverUuids = { emptyList() },
285182 onNavigateToHome = {},
286183 onOpenFolder = {},
287184 )
@@ -298,7 +195,6 @@ private fun TvYourPodcastsEmptyPreview() {
298195 Box (modifier = Modifier .background(TvColors .Dark )) {
299196 TvYourPodcastsContent (
300197 uiState = TvYourPodcastsUiState .Empty ,
301- getFolderCoverUuids = { emptyList() },
302198 onNavigateToHome = {},
303199 onOpenFolder = {},
304200 )
0 commit comments