compose: details: Initial DevProfileScreen implementation

Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
Aayush Gupta
2025-05-16 21:07:09 +08:00
parent 3a23088525
commit f868a0f505
3 changed files with 84 additions and 19 deletions

View File

@@ -309,9 +309,8 @@ private fun ScreenContentApp(
index = screen.index,
onNavigateUp = ::showMainPane
)
// TODO: Pass the real developerId
is Screen.DevProfile -> DevProfileScreen(
developerId = app.developerName,
publisherId = app.developerName,
onNavigateUp = ::showMainPane,
onNavigateToAppDetails = { onNavigateToAppDetails(it) }
)

View File

@@ -5,35 +5,71 @@
package com.aurora.store.compose.ui.dev
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.Scaffold
import androidx.compose.material3.adaptive.WindowAdaptiveInfo
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.paging.LoadState
import androidx.paging.PagingData
import androidx.paging.compose.LazyPagingItems
import androidx.paging.compose.collectAsLazyPagingItems
import androidx.paging.compose.itemKey
import coil3.annotation.ExperimentalCoilApi
import coil3.compose.LocalAsyncImagePreviewHandler
import com.aurora.extensions.adaptiveNavigationIcon
import com.aurora.gplayapi.data.models.App
import com.aurora.store.R
import com.aurora.store.compose.composables.TopAppBarComposable
import com.aurora.store.compose.composables.app.AppListComposable
import com.aurora.store.compose.composables.preview.AppPreviewProvider
import com.aurora.store.compose.composables.preview.coilPreviewProvider
import com.aurora.store.viewmodel.details.DevProfileViewModel
import com.aurora.store.viewmodel.search.SearchResultViewModel
import kotlinx.coroutines.flow.flowOf
import kotlin.random.Random
/**
* Screen to display apps from a developer using the developerId
* for e.g. https://play.google.com/store/apps/dev?id=5700313618786177705
*/
@Composable
fun DevProfileScreen(
developerId: String,
onNavigateUp: () -> Unit,
onNavigateToAppDetails: (packageName: String) -> Unit,
devProfileViewModel: DevProfileViewModel = hiltViewModel()
viewModel: DevProfileViewModel = hiltViewModel()
) {
// TODO: Implement when migrating logic for current DevProfileFragment
}
/**
* Screen to display apps from a developer by searching using the publisherId
* for e.g. https://play.google.com/store/apps/developer?id=The+Tor+Project
*/
@Composable
fun DevProfileScreen(
publisherId: String,
onNavigateUp: () -> Unit,
onNavigateToAppDetails: (packageName: String) -> Unit,
viewModel: SearchResultViewModel = hiltViewModel()
) {
val apps = viewModel.apps.collectAsLazyPagingItems()
LaunchedEffect(key1 = Unit) { viewModel.search("pub:$publisherId") }
ScreenContent(
topAppBarTitle = "",
apps = apps,
topAppBarTitle = publisherId,
onNavigateUp = onNavigateUp,
onNavigateToAppDetails = onNavigateToAppDetails
)
@@ -41,7 +77,8 @@ fun DevProfileScreen(
@Composable
private fun ScreenContent(
topAppBarTitle: String? = null,
apps: LazyPagingItems<App>,
topAppBarTitle: String,
onNavigateUp: () -> Unit = {},
onNavigateToAppDetails: (packageName: String) -> Unit = {},
windowAdaptiveInfo: WindowAdaptiveInfo = currentWindowAdaptiveInfo()
@@ -55,21 +92,43 @@ private fun ScreenContent(
)
}
) { paddingValues ->
Column(
modifier = Modifier
.padding(paddingValues)
.fillMaxSize()
.verticalScroll(rememberScrollState())
.padding(dimensionResource(R.dimen.padding_medium)),
verticalArrangement = Arrangement.spacedBy(dimensionResource(R.dimen.margin_medium))
) {
when (apps.loadState.refresh) {
is LoadState.Loading -> {}
is LoadState.Error -> {}
else -> {
LazyColumn(
modifier = Modifier
.padding(paddingValues)
.fillMaxSize()
.padding(vertical = dimensionResource(R.dimen.padding_medium))
) {
items(count = apps.itemCount, key = apps.itemKey { it.id }) { index ->
apps[index]?.let { app ->
AppListComposable(
app = app,
onClick = { onNavigateToAppDetails(app.packageName) }
)
}
}
}
}
}
}
}
@Preview
@Composable
private fun DevProfileScreenPreview() {
ScreenContent()
@OptIn(ExperimentalCoilApi::class)
private fun DevProfileScreenPreview(@PreviewParameter(AppPreviewProvider::class) app: App) {
CompositionLocalProvider(LocalAsyncImagePreviewHandler provides coilPreviewProvider) {
val apps = List(10) { app.copy(id = Random.nextInt()) }
val pagedApps = flowOf(PagingData.from(apps)).collectAsLazyPagingItems()
ScreenContent(
topAppBarTitle = app.developerName,
apps = pagedApps
)
}
}

View File

@@ -23,6 +23,8 @@ import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.PagingData
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.helpers.SearchHelper
@@ -33,6 +35,8 @@ import com.aurora.store.data.model.ViewState
import com.aurora.store.data.providers.AuthProvider
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
@@ -54,6 +58,9 @@ class SearchResultViewModel @Inject constructor(
private val contract: SearchContract
get() = if (authProvider.isAnonymous) webSearchHelper else searchHelper
private val _apps = MutableStateFlow<PagingData<App>>(PagingData.empty())
val apps = _apps.asStateFlow()
private val stashMutex = Mutex()
@Synchronized