compose: details: Initial DevProfileScreen implementation
Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
@@ -309,9 +309,8 @@ private fun ScreenContentApp(
|
|||||||
index = screen.index,
|
index = screen.index,
|
||||||
onNavigateUp = ::showMainPane
|
onNavigateUp = ::showMainPane
|
||||||
)
|
)
|
||||||
// TODO: Pass the real developerId
|
|
||||||
is Screen.DevProfile -> DevProfileScreen(
|
is Screen.DevProfile -> DevProfileScreen(
|
||||||
developerId = app.developerName,
|
publisherId = app.developerName,
|
||||||
onNavigateUp = ::showMainPane,
|
onNavigateUp = ::showMainPane,
|
||||||
onNavigateToAppDetails = { onNavigateToAppDetails(it) }
|
onNavigateToAppDetails = { onNavigateToAppDetails(it) }
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,35 +5,71 @@
|
|||||||
|
|
||||||
package com.aurora.store.compose.ui.dev
|
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.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.verticalScroll
|
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.adaptive.WindowAdaptiveInfo
|
import androidx.compose.material3.adaptive.WindowAdaptiveInfo
|
||||||
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
|
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.dimensionResource
|
import androidx.compose.ui.res.dimensionResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
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.extensions.adaptiveNavigationIcon
|
||||||
|
import com.aurora.gplayapi.data.models.App
|
||||||
import com.aurora.store.R
|
import com.aurora.store.R
|
||||||
import com.aurora.store.compose.composables.TopAppBarComposable
|
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.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
|
@Composable
|
||||||
fun DevProfileScreen(
|
fun DevProfileScreen(
|
||||||
developerId: String,
|
developerId: String,
|
||||||
onNavigateUp: () -> Unit,
|
onNavigateUp: () -> Unit,
|
||||||
onNavigateToAppDetails: (packageName: String) -> 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(
|
ScreenContent(
|
||||||
topAppBarTitle = "",
|
apps = apps,
|
||||||
|
topAppBarTitle = publisherId,
|
||||||
onNavigateUp = onNavigateUp,
|
onNavigateUp = onNavigateUp,
|
||||||
onNavigateToAppDetails = onNavigateToAppDetails
|
onNavigateToAppDetails = onNavigateToAppDetails
|
||||||
)
|
)
|
||||||
@@ -41,7 +77,8 @@ fun DevProfileScreen(
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun ScreenContent(
|
private fun ScreenContent(
|
||||||
topAppBarTitle: String? = null,
|
apps: LazyPagingItems<App>,
|
||||||
|
topAppBarTitle: String,
|
||||||
onNavigateUp: () -> Unit = {},
|
onNavigateUp: () -> Unit = {},
|
||||||
onNavigateToAppDetails: (packageName: String) -> Unit = {},
|
onNavigateToAppDetails: (packageName: String) -> Unit = {},
|
||||||
windowAdaptiveInfo: WindowAdaptiveInfo = currentWindowAdaptiveInfo()
|
windowAdaptiveInfo: WindowAdaptiveInfo = currentWindowAdaptiveInfo()
|
||||||
@@ -55,21 +92,43 @@ private fun ScreenContent(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
Column(
|
when (apps.loadState.refresh) {
|
||||||
modifier = Modifier
|
is LoadState.Loading -> {}
|
||||||
.padding(paddingValues)
|
|
||||||
.fillMaxSize()
|
|
||||||
.verticalScroll(rememberScrollState())
|
|
||||||
.padding(dimensionResource(R.dimen.padding_medium)),
|
|
||||||
verticalArrangement = Arrangement.spacedBy(dimensionResource(R.dimen.margin_medium))
|
|
||||||
) {
|
|
||||||
|
|
||||||
|
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
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
private fun DevProfileScreenPreview() {
|
@OptIn(ExperimentalCoilApi::class)
|
||||||
ScreenContent()
|
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
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ import android.util.Log
|
|||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
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.StreamBundle
|
||||||
import com.aurora.gplayapi.data.models.StreamCluster
|
import com.aurora.gplayapi.data.models.StreamCluster
|
||||||
import com.aurora.gplayapi.helpers.SearchHelper
|
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 com.aurora.store.data.providers.AuthProvider
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import kotlinx.coroutines.sync.withLock
|
import kotlinx.coroutines.sync.withLock
|
||||||
@@ -54,6 +58,9 @@ class SearchResultViewModel @Inject constructor(
|
|||||||
private val contract: SearchContract
|
private val contract: SearchContract
|
||||||
get() = if (authProvider.isAnonymous) webSearchHelper else searchHelper
|
get() = if (authProvider.isAnonymous) webSearchHelper else searchHelper
|
||||||
|
|
||||||
|
private val _apps = MutableStateFlow<PagingData<App>>(PagingData.empty())
|
||||||
|
val apps = _apps.asStateFlow()
|
||||||
|
|
||||||
private val stashMutex = Mutex()
|
private val stashMutex = Mutex()
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
|
|||||||
Reference in New Issue
Block a user