diff --git a/app/src/main/java/com/aurora/store/compose/ui/dev/DevProfileScreen.kt b/app/src/main/java/com/aurora/store/compose/ui/dev/DevProfileScreen.kt index ef68ca797..ec976565e 100644 --- a/app/src/main/java/com/aurora/store/compose/ui/dev/DevProfileScreen.kt +++ b/app/src/main/java/com/aurora/store/compose/ui/dev/DevProfileScreen.kt @@ -15,6 +15,8 @@ import androidx.compose.material3.adaptive.WindowAdaptiveInfo import androidx.compose.material3.adaptive.currentWindowAdaptiveInfoV2 import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.livedata.observeAsState import androidx.compose.ui.Modifier import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.painterResource @@ -30,14 +32,19 @@ import androidx.paging.compose.collectAsLazyPagingItems import androidx.paging.compose.itemKey import com.aurora.extensions.adaptiveNavigationIcon import com.aurora.gplayapi.data.models.App +import com.aurora.gplayapi.data.models.StreamBundle +import com.aurora.gplayapi.data.models.StreamCluster +import com.aurora.gplayapi.data.models.details.DevStream import com.aurora.store.R import com.aurora.store.compose.composable.ContainedLoadingIndicator import com.aurora.store.compose.composable.Placeholder +import com.aurora.store.compose.composable.StreamCarousel import com.aurora.store.compose.composable.TopAppBar import com.aurora.store.compose.composable.app.LargeAppListItem import com.aurora.store.compose.navigation.Destination import com.aurora.store.compose.preview.AppPreviewProvider import com.aurora.store.compose.preview.ThemePreviewProvider +import com.aurora.store.data.model.ViewState import com.aurora.store.viewmodel.details.DevProfileViewModel import com.aurora.store.viewmodel.search.SearchViewModel import kotlin.random.Random @@ -53,7 +60,61 @@ fun DevProfileScreen( onNavigateTo: (Destination) -> Unit, viewModel: DevProfileViewModel = hiltViewModel() ) { - // TODO: Implement when migrating logic for current DevProfileFragment + val state by viewModel.liveData.observeAsState() + + LaunchedEffect(developerId) { viewModel.getStreamBundle(developerId) } + + val devStream = (state as? ViewState.Success<*>)?.data as? DevStream + + DevStreamContent( + title = devStream?.title?.takeIf { it.isNotBlank() } ?: developerId, + streamBundle = devStream?.streamBundle, + isError = state is ViewState.Error, + onRetry = { viewModel.getStreamBundle(developerId) }, + onClusterScrolled = viewModel::observeCluster, + onNavigateTo = onNavigateTo + ) +} + +@Composable +private fun DevStreamContent( + title: String, + streamBundle: StreamBundle?, + isError: Boolean, + onRetry: () -> Unit = {}, + onClusterScrolled: (StreamCluster) -> Unit = {}, + onNavigateTo: (Destination) -> Unit = {}, + windowAdaptiveInfo: WindowAdaptiveInfo = currentWindowAdaptiveInfoV2() +) { + Scaffold( + topBar = { + TopAppBar( + title = title, + navigationIcon = windowAdaptiveInfo.adaptiveNavigationIcon + ) + } + ) { paddingValues -> + if (isError) { + Placeholder( + modifier = Modifier.padding(paddingValues), + painter = painterResource(R.drawable.ic_refresh), + message = stringResource(R.string.error), + actionLabel = stringResource(R.string.action_retry), + onAction = onRetry + ) + } else { + // A null bundle renders the loading shimmer until the stream resolves + StreamCarousel( + modifier = Modifier + .padding(paddingValues) + .fillMaxSize(), + streamBundle = streamBundle, + onHeaderClick = { onNavigateTo(Destination.StreamBrowse(it)) }, + onAppClick = { onNavigateTo(Destination.AppDetails(it.packageName)) }, + onClusterScrolled = onClusterScrolled + ) + } + } } /**