Save progress

This commit is contained in:
Ivan Agosto
2025-02-07 18:25:23 -06:00
parent 10836f538d
commit cbbc15d9fb
6 changed files with 75 additions and 26 deletions

View File

@@ -22,6 +22,7 @@ import org.libre.agosto.p2play.ui.bars.SearchTopBar
import org.libre.agosto.p2play.ui.views.SearchView
import org.libre.agosto.p2play.ui.views.SubscriptionsView
import org.libre.agosto.p2play.ui.views.VideosView
import org.libre.agosto.p2play.viewModels.SubscriptionsViewModel
class MainActivity : ComponentActivity() {
@@ -30,6 +31,7 @@ class MainActivity : ComponentActivity() {
enableEdgeToEdge()
setContent {
val videoViewModel: VideosViewModel = viewModel()
val subscriptionsViewModel: SubscriptionsViewModel = viewModel()
val navController = rememberNavController()
val currentRoute = navController.currentBackStackEntryAsState().value?.destination?.route
P2playTheme {
@@ -46,7 +48,7 @@ class MainActivity : ComponentActivity() {
) { innerPadding ->
NavHost(navController, startDestination = Routes.Videos.route, modifier = Modifier.padding(innerPadding)) {
composable(Routes.Videos.route) { VideosView(videoViewModel) }
composable(Routes.Subscriptions.route) { SubscriptionsView() }
composable(Routes.Subscriptions.route) { SubscriptionsView(subscriptionsViewModel) }
composable(Routes.Search.route) { SearchView() }
}
}

View File

@@ -1,7 +1,9 @@
package org.libre.agosto.p2play.ui
sealed class Routes (val route: String) {
data object Videos: Routes("videos")
data object Subscriptions: Routes("subscriptions")
data object Search: Routes("search")
import org.libre.agosto.p2play.R
sealed class Routes (val route: String, val title: Int?) {
data object Videos: Routes("videos", R.string.app_name)
data object Subscriptions: Routes("subscriptions", R.string.title_subscriptions)
data object Search: Routes("search", null)
}

View File

@@ -22,7 +22,7 @@ import org.libre.agosto.p2play.ui.Routes
fun MainNavigationBar (navController: NavController) {
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
currentDestination?.route
NavigationBar {
NavigationBarItem(
icon = { Icon(Icons.Filled.Home, "home") },

View File

@@ -21,6 +21,7 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.navigation.NavController
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.compose.currentBackStackEntryAsState
import org.libre.agosto.p2play.AboutActivity
import org.libre.agosto.p2play.LoginActivity
import org.libre.agosto.p2play.ManagerSingleton
@@ -33,8 +34,17 @@ import org.libre.agosto.p2play.SettingsActivity2
fun MainTopAppBar(navController: NavController, modifier: Modifier = Modifier) {
var isMenuOpen by remember { mutableStateOf(false) }
val context = LocalContext.current
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
val title = when (currentDestination?.route) {
Routes.Subscriptions.route -> stringResource(Routes.Subscriptions.title!!)
else -> stringResource(R.string.app_name)
}
TopAppBar(
{ Text(stringResource(R.string.nav_menu_videos)) },
{ Text(title) },
modifier,
actions = {
IconButton({

View File

@@ -7,6 +7,7 @@ import androidx.compose.material.icons.filled.Star
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@@ -25,27 +26,18 @@ import org.libre.agosto.p2play.ui.components.molecules.ChipSelector
import org.libre.agosto.p2play.ui.components.molecules.ChipValues
import org.libre.agosto.p2play.helpers.TaskManager
import org.libre.agosto.p2play.models.VideoModel
import org.libre.agosto.p2play.viewModels.SubscriptionsViewModel
import java.util.ArrayList
@SuppressLint("MutableCollectionMutableState")
@Composable
fun SubscriptionsView (modifier: Modifier = Modifier) {
val videos by rememberSaveable { mutableStateOf(mutableListOf<VideoModel>()) }
var isLoading by rememberSaveable { mutableStateOf(true) }
fun SubscriptionsView (subscriptionsViewModel: SubscriptionsViewModel, modifier: Modifier = Modifier) {
val videos by subscriptionsViewModel.videos.observeAsState(initial = listOf())
val isLoading: Boolean by subscriptionsViewModel.isLoading.observeAsState(initial = false)
LaunchedEffect(isLoading) {
if (isLoading) {
val task = TaskManager<List<VideoModel>>()
task.runTask(
{
val client = Videos()
client.getTrendingVideos(videos.size)
},
{
videos.addAll(it)
isLoading = false
}
)
LaunchedEffect(Unit) {
if (videos.isEmpty()) {
subscriptionsViewModel.loadVideos()
}
}
@@ -55,13 +47,12 @@ fun SubscriptionsView (modifier: Modifier = Modifier) {
isLoading = isLoading,
onRefresh = {
if (!isLoading) {
videos.clear()
isLoading = true
subscriptionsViewModel.refresh()
}
},
onLoadMore = {
if (!isLoading) {
isLoading = true
subscriptionsViewModel.loadVideos()
}
}
)

View File

@@ -0,0 +1,44 @@
package org.libre.agosto.p2play.viewModels
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.libre.agosto.p2play.ManagerSingleton
import org.libre.agosto.p2play.ajax.Videos
import org.libre.agosto.p2play.models.VideoModel
class SubscriptionsViewModel(savedStateHandle: SavedStateHandle) : ViewModel() {
val client = Videos()
private val _videos = MutableLiveData<List<VideoModel>>()
val videos: LiveData<List<VideoModel>> = _videos
private val _isLoading = MutableLiveData<Boolean>()
val isLoading: LiveData<Boolean> = _isLoading
fun loadVideos() {
_isLoading.value = true
viewModelScope.launch {
val result = withContext(Dispatchers.IO) {
client.videoSubscriptions(ManagerSingleton.token.token, videos.value?.size ?: 0)
}
val data = if (videos.value !== null)
ArrayList(videos.value!!)
else
ArrayList()
data.addAll(result)
_videos.postValue(data)
_isLoading.value = false
}
}
fun refresh() {
_videos.value = arrayListOf()
loadVideos()
}
}