Save progress
This commit is contained in:
@@ -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.SearchView
|
||||||
import org.libre.agosto.p2play.ui.views.SubscriptionsView
|
import org.libre.agosto.p2play.ui.views.SubscriptionsView
|
||||||
import org.libre.agosto.p2play.ui.views.VideosView
|
import org.libre.agosto.p2play.ui.views.VideosView
|
||||||
|
import org.libre.agosto.p2play.viewModels.SubscriptionsViewModel
|
||||||
|
|
||||||
class MainActivity : ComponentActivity() {
|
class MainActivity : ComponentActivity() {
|
||||||
|
|
||||||
@@ -30,6 +31,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
enableEdgeToEdge()
|
enableEdgeToEdge()
|
||||||
setContent {
|
setContent {
|
||||||
val videoViewModel: VideosViewModel = viewModel()
|
val videoViewModel: VideosViewModel = viewModel()
|
||||||
|
val subscriptionsViewModel: SubscriptionsViewModel = viewModel()
|
||||||
val navController = rememberNavController()
|
val navController = rememberNavController()
|
||||||
val currentRoute = navController.currentBackStackEntryAsState().value?.destination?.route
|
val currentRoute = navController.currentBackStackEntryAsState().value?.destination?.route
|
||||||
P2playTheme {
|
P2playTheme {
|
||||||
@@ -46,7 +48,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
) { innerPadding ->
|
) { innerPadding ->
|
||||||
NavHost(navController, startDestination = Routes.Videos.route, modifier = Modifier.padding(innerPadding)) {
|
NavHost(navController, startDestination = Routes.Videos.route, modifier = Modifier.padding(innerPadding)) {
|
||||||
composable(Routes.Videos.route) { VideosView(videoViewModel) }
|
composable(Routes.Videos.route) { VideosView(videoViewModel) }
|
||||||
composable(Routes.Subscriptions.route) { SubscriptionsView() }
|
composable(Routes.Subscriptions.route) { SubscriptionsView(subscriptionsViewModel) }
|
||||||
composable(Routes.Search.route) { SearchView() }
|
composable(Routes.Search.route) { SearchView() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,9 @@
|
|||||||
package org.libre.agosto.p2play.ui
|
package org.libre.agosto.p2play.ui
|
||||||
|
|
||||||
sealed class Routes (val route: String) {
|
import org.libre.agosto.p2play.R
|
||||||
data object Videos: Routes("videos")
|
|
||||||
data object Subscriptions: Routes("subscriptions")
|
sealed class Routes (val route: String, val title: Int?) {
|
||||||
data object Search: Routes("search")
|
data object Videos: Routes("videos", R.string.app_name)
|
||||||
|
data object Subscriptions: Routes("subscriptions", R.string.title_subscriptions)
|
||||||
|
data object Search: Routes("search", null)
|
||||||
}
|
}
|
@@ -22,7 +22,7 @@ import org.libre.agosto.p2play.ui.Routes
|
|||||||
fun MainNavigationBar (navController: NavController) {
|
fun MainNavigationBar (navController: NavController) {
|
||||||
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
||||||
val currentDestination = navBackStackEntry?.destination
|
val currentDestination = navBackStackEntry?.destination
|
||||||
currentDestination?.route
|
|
||||||
NavigationBar {
|
NavigationBar {
|
||||||
NavigationBarItem(
|
NavigationBarItem(
|
||||||
icon = { Icon(Icons.Filled.Home, "home") },
|
icon = { Icon(Icons.Filled.Home, "home") },
|
||||||
|
@@ -21,6 +21,7 @@ import androidx.compose.ui.platform.LocalContext
|
|||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import androidx.navigation.NavGraph.Companion.findStartDestination
|
import androidx.navigation.NavGraph.Companion.findStartDestination
|
||||||
|
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||||
import org.libre.agosto.p2play.AboutActivity
|
import org.libre.agosto.p2play.AboutActivity
|
||||||
import org.libre.agosto.p2play.LoginActivity
|
import org.libre.agosto.p2play.LoginActivity
|
||||||
import org.libre.agosto.p2play.ManagerSingleton
|
import org.libre.agosto.p2play.ManagerSingleton
|
||||||
@@ -33,8 +34,17 @@ import org.libre.agosto.p2play.SettingsActivity2
|
|||||||
fun MainTopAppBar(navController: NavController, modifier: Modifier = Modifier) {
|
fun MainTopAppBar(navController: NavController, modifier: Modifier = Modifier) {
|
||||||
var isMenuOpen by remember { mutableStateOf(false) }
|
var isMenuOpen by remember { mutableStateOf(false) }
|
||||||
val context = LocalContext.current
|
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(
|
TopAppBar(
|
||||||
{ Text(stringResource(R.string.nav_menu_videos)) },
|
{ Text(title) },
|
||||||
modifier,
|
modifier,
|
||||||
actions = {
|
actions = {
|
||||||
IconButton({
|
IconButton({
|
||||||
|
@@ -7,6 +7,7 @@ import androidx.compose.material.icons.filled.Star
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.livedata.observeAsState
|
||||||
import androidx.compose.runtime.mutableStateListOf
|
import androidx.compose.runtime.mutableStateListOf
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
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.ui.components.molecules.ChipValues
|
||||||
import org.libre.agosto.p2play.helpers.TaskManager
|
import org.libre.agosto.p2play.helpers.TaskManager
|
||||||
import org.libre.agosto.p2play.models.VideoModel
|
import org.libre.agosto.p2play.models.VideoModel
|
||||||
|
import org.libre.agosto.p2play.viewModels.SubscriptionsViewModel
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
|
|
||||||
@SuppressLint("MutableCollectionMutableState")
|
@SuppressLint("MutableCollectionMutableState")
|
||||||
@Composable
|
@Composable
|
||||||
fun SubscriptionsView (modifier: Modifier = Modifier) {
|
fun SubscriptionsView (subscriptionsViewModel: SubscriptionsViewModel, modifier: Modifier = Modifier) {
|
||||||
val videos by rememberSaveable { mutableStateOf(mutableListOf<VideoModel>()) }
|
val videos by subscriptionsViewModel.videos.observeAsState(initial = listOf())
|
||||||
var isLoading by rememberSaveable { mutableStateOf(true) }
|
val isLoading: Boolean by subscriptionsViewModel.isLoading.observeAsState(initial = false)
|
||||||
|
|
||||||
LaunchedEffect(isLoading) {
|
LaunchedEffect(Unit) {
|
||||||
if (isLoading) {
|
if (videos.isEmpty()) {
|
||||||
val task = TaskManager<List<VideoModel>>()
|
subscriptionsViewModel.loadVideos()
|
||||||
task.runTask(
|
|
||||||
{
|
|
||||||
val client = Videos()
|
|
||||||
client.getTrendingVideos(videos.size)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
videos.addAll(it)
|
|
||||||
isLoading = false
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,13 +47,12 @@ fun SubscriptionsView (modifier: Modifier = Modifier) {
|
|||||||
isLoading = isLoading,
|
isLoading = isLoading,
|
||||||
onRefresh = {
|
onRefresh = {
|
||||||
if (!isLoading) {
|
if (!isLoading) {
|
||||||
videos.clear()
|
subscriptionsViewModel.refresh()
|
||||||
isLoading = true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onLoadMore = {
|
onLoadMore = {
|
||||||
if (!isLoading) {
|
if (!isLoading) {
|
||||||
isLoading = true
|
subscriptionsViewModel.loadVideos()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@@ -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()
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user