[feat] UI optimization 3
This commit is contained in:
@@ -54,6 +54,8 @@ dependencies {
|
|||||||
implementation(libs.hilt.android)
|
implementation(libs.hilt.android)
|
||||||
implementation(libs.hilt.navigation.compose)
|
implementation(libs.hilt.navigation.compose)
|
||||||
implementation(libs.androidx.compose.material.core)
|
implementation(libs.androidx.compose.material.core)
|
||||||
|
implementation(libs.androidx.constraintlayout)
|
||||||
|
implementation(libs.androidx.compose.animation)
|
||||||
ksp(libs.hilt.android.compiler)
|
ksp(libs.hilt.android.compiler)
|
||||||
|
|
||||||
implementation(libs.androidx.room.runtime)
|
implementation(libs.androidx.room.runtime)
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ object Global {
|
|||||||
var sameClassVideos: List<Video>? = null
|
var sameClassVideos: List<Video>? = null
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
var isFullScreen by mutableStateOf(false)
|
||||||
fun updateRelate(v: List<Video>, s: Video)
|
fun updateRelate(v: List<Video>, s: Video)
|
||||||
{
|
{
|
||||||
sameClassVideos = if (v.contains(s)) {
|
sameClassVideos = if (v.contains(s)) {
|
||||||
|
|||||||
@@ -4,11 +4,15 @@ import android.app.Activity
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.activity.enableEdgeToEdge
|
import androidx.activity.enableEdgeToEdge
|
||||||
|
import androidx.compose.animation.AnimatedContentTransitionScope
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
|
import androidx.compose.animation.ExperimentalAnimationApi
|
||||||
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.animation.slideInVertically
|
import androidx.compose.animation.slideInVertically
|
||||||
import androidx.compose.animation.slideOutVertically
|
import androidx.compose.animation.slideOutVertically
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
@@ -95,22 +99,17 @@ class MainScreenActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
fun setFullScreen(view: View, isFullScreen: Boolean) {
|
||||||
fun ToggleFullScreen(isFullScreen: Boolean)
|
Global.isFullScreen = isFullScreen
|
||||||
{
|
val window = (view.context as Activity).window
|
||||||
val view = LocalView.current
|
val insetsController = WindowCompat.getInsetsController(window, view)
|
||||||
|
|
||||||
LaunchedEffect(isFullScreen) {
|
if (isFullScreen) {
|
||||||
val window = (view.context as Activity).window
|
insetsController.hide(WindowInsetsCompat.Type.systemBars())
|
||||||
val insetsController = WindowCompat.getInsetsController(window, view)
|
insetsController.systemBarsBehavior =
|
||||||
|
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
||||||
if (isFullScreen) {
|
} else {
|
||||||
insetsController.hide(WindowInsetsCompat.Type.systemBars())
|
insetsController.show(WindowInsetsCompat.Type.systemBars())
|
||||||
insetsController.systemBarsBehavior =
|
|
||||||
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
|
||||||
} else {
|
|
||||||
insetsController.show(WindowInsetsCompat.Type.systemBars())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,40 +135,64 @@ fun AppNavigation() {
|
|||||||
) {
|
) {
|
||||||
BottomNavigationBar(navController = navController)
|
BottomNavigationBar(navController = navController)
|
||||||
}
|
}
|
||||||
if(shouldShowBottomBar)
|
|
||||||
ToggleFullScreen(false)
|
|
||||||
}
|
}
|
||||||
) { innerPadding ->
|
) { innerPadding ->
|
||||||
NavHost(
|
NavHost(
|
||||||
navController = navController,
|
navController = navController,
|
||||||
startDestination = Screen.Me.route,
|
startDestination = Screen.Me.route,
|
||||||
modifier = if(shouldShowBottomBar)Modifier.padding(innerPadding) else Modifier.padding(0.dp)
|
modifier = if(!Global.isFullScreen) Modifier.padding(innerPadding) else Modifier.padding(0.dp)
|
||||||
) {
|
) {
|
||||||
composable(Screen.Home.route) {
|
composable(
|
||||||
|
Screen.Home.route,
|
||||||
|
enterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Start, animationSpec = tween(200)) },
|
||||||
|
exitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Start, animationSpec = tween(200)) },
|
||||||
|
popEnterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.End, animationSpec = tween(200)) },
|
||||||
|
popExitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.End, animationSpec = tween(200)) }
|
||||||
|
) {
|
||||||
CardPage(title = "Home") {
|
CardPage(title = "Home") {
|
||||||
HomeScreen(navController = navController)
|
HomeScreen(navController = navController)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
composable(Screen.Video.route) {
|
composable(Screen.Video.route,
|
||||||
|
enterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Start, animationSpec = tween(200)) },
|
||||||
|
exitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Start, animationSpec = tween(200)) },
|
||||||
|
popEnterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.End, animationSpec = tween(200)) },
|
||||||
|
popExitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.End, animationSpec = tween(200)) }) {
|
||||||
VideoScreen(navController = navController)
|
VideoScreen(navController = navController)
|
||||||
}
|
}
|
||||||
composable(Screen.Comic.route) {
|
composable(Screen.Comic.route,
|
||||||
|
enterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Start, animationSpec = tween(200)) },
|
||||||
|
exitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Start, animationSpec = tween(200)) },
|
||||||
|
popEnterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.End, animationSpec = tween(200)) },
|
||||||
|
popExitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.End, animationSpec = tween(200)) }) {
|
||||||
CardPage(title = "Comic") {
|
CardPage(title = "Comic") {
|
||||||
ComicScreen(navController = navController)
|
ComicScreen(navController = navController)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
composable(Screen.Transmission.route) {
|
composable(Screen.Transmission.route,
|
||||||
|
enterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Start, animationSpec = tween(200)) },
|
||||||
|
exitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Start, animationSpec = tween(200)) },
|
||||||
|
popEnterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.End, animationSpec = tween(200)) },
|
||||||
|
popExitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.End, animationSpec = tween(200)) }) {
|
||||||
CardPage(title = "Tasks") {
|
CardPage(title = "Tasks") {
|
||||||
TransmissionScreen(navigator = navController)
|
TransmissionScreen(navigator = navController)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
composable(Screen.Me.route) {
|
composable(Screen.Me.route,
|
||||||
|
enterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Start, animationSpec = tween(200)) },
|
||||||
|
exitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Start, animationSpec = tween(200)) },
|
||||||
|
popEnterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.End, animationSpec = tween(200)) },
|
||||||
|
popExitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.End, animationSpec = tween(200)) }) {
|
||||||
MeScreen();
|
MeScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
composable(
|
composable(
|
||||||
route = Screen.VideoPlayer.route,
|
route = Screen.VideoPlayer.route,
|
||||||
|
enterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Start, animationSpec = tween(200)) },
|
||||||
|
exitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Start, animationSpec = tween(200)) },
|
||||||
|
popEnterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.End, animationSpec = tween(200)) },
|
||||||
|
popExitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.End, animationSpec = tween(200)) },
|
||||||
arguments = listOf(navArgument("videoId") { type = NavType.StringType })
|
arguments = listOf(navArgument("videoId") { type = NavType.StringType })
|
||||||
) {
|
) {
|
||||||
backStackEntry ->
|
backStackEntry ->
|
||||||
@@ -181,6 +204,10 @@ fun AppNavigation() {
|
|||||||
|
|
||||||
composable(
|
composable(
|
||||||
route = Screen.ComicGrid.route,
|
route = Screen.ComicGrid.route,
|
||||||
|
enterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Start, animationSpec = tween(200)) },
|
||||||
|
exitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Start, animationSpec = tween(200)) },
|
||||||
|
popEnterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.End, animationSpec = tween(200)) },
|
||||||
|
popExitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.End, animationSpec = tween(200)) },
|
||||||
arguments = listOf(navArgument("comicId") { type = NavType.StringType })
|
arguments = listOf(navArgument("comicId") { type = NavType.StringType })
|
||||||
) {
|
) {
|
||||||
backStackEntry ->
|
backStackEntry ->
|
||||||
@@ -192,6 +219,10 @@ fun AppNavigation() {
|
|||||||
|
|
||||||
composable(
|
composable(
|
||||||
route = Screen.ComicPage.route,
|
route = Screen.ComicPage.route,
|
||||||
|
enterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Start, animationSpec = tween(200)) },
|
||||||
|
exitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Start, animationSpec = tween(200)) },
|
||||||
|
popEnterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.End, animationSpec = tween(200)) },
|
||||||
|
popExitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.End, animationSpec = tween(200)) },
|
||||||
arguments = listOf(navArgument("comicId") { type = NavType.StringType }, navArgument("page") { type = NavType.StringType })
|
arguments = listOf(navArgument("comicId") { type = NavType.StringType }, navArgument("page") { type = NavType.StringType })
|
||||||
) {
|
) {
|
||||||
backStackEntry ->
|
backStackEntry ->
|
||||||
@@ -199,7 +230,6 @@ fun AppNavigation() {
|
|||||||
val page = backStackEntry.arguments?.getString("page")
|
val page = backStackEntry.arguments?.getString("page")
|
||||||
if (comicId != null && page != null) {
|
if (comicId != null && page != null) {
|
||||||
ComicPageView(comicId = comicId, page = page, navController = navController)
|
ComicPageView(comicId = comicId, page = page, navController = navController)
|
||||||
ToggleFullScreen(true)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
package com.acitelight.aether.model
|
package com.acitelight.aether.model
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
data class BookMark(
|
data class BookMark(
|
||||||
val name: String,
|
val name: String,
|
||||||
val page: String
|
val page: String
|
||||||
|
|||||||
@@ -7,6 +7,19 @@ class Comic(
|
|||||||
val id: String
|
val id: String
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
fun getCover(api: ApiClient): String
|
||||||
|
{
|
||||||
|
if(id == "101")
|
||||||
|
print("")
|
||||||
|
|
||||||
|
if(comic.cover != "")
|
||||||
|
{
|
||||||
|
return "${api.getBase()}api/image/$id/${comic.cover}"
|
||||||
|
}
|
||||||
|
|
||||||
|
return "${api.getBase()}api/image/$id/${comic.list[0]}"
|
||||||
|
}
|
||||||
|
|
||||||
fun getPage(pageNumber: Int, api: ApiClient): String
|
fun getPage(pageNumber: Int, api: ApiClient): String
|
||||||
{
|
{
|
||||||
return "${api.getBase()}api/image/$id/${comic.list[pageNumber]}"
|
return "${api.getBase()}api/image/$id/${comic.list[pageNumber]}"
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
package com.acitelight.aether.model
|
package com.acitelight.aether.model
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
data class ComicResponse(
|
data class ComicResponse(
|
||||||
val comic_name: String,
|
val comic_name: String,
|
||||||
val page_count: Int,
|
val page_count: Int,
|
||||||
val bookmarks: List<BookMark>,
|
val bookmarks: List<BookMark>,
|
||||||
val list: List<String>,
|
val list: List<String>,
|
||||||
val tags: List<String>,
|
val tags: List<String>,
|
||||||
val author: String
|
val author: String,
|
||||||
|
val cover: String
|
||||||
)
|
)
|
||||||
@@ -219,6 +219,8 @@ class ApiClient @Inject constructor(
|
|||||||
|
|
||||||
suspend fun apply(context: Context, urls: String, crt: String): String? {
|
suspend fun apply(context: Context, urls: String, crt: String): String? {
|
||||||
try {
|
try {
|
||||||
|
client = createOkHttp()
|
||||||
|
|
||||||
val urlList = urls.split(";").map { it.trim() }
|
val urlList = urls.split(";").map { it.trim() }
|
||||||
|
|
||||||
var selectedUrl: String? = null
|
var selectedUrl: String? = null
|
||||||
@@ -231,7 +233,6 @@ class ApiClient @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (selectedUrl == null) {
|
if (selectedUrl == null) {
|
||||||
client = createOkHttp()
|
|
||||||
throw Exception("No reachable URL found")
|
throw Exception("No reachable URL found")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,9 +59,9 @@ fun ComicCard(
|
|||||||
Box(modifier = Modifier.fillMaxSize()) {
|
Box(modifier = Modifier.fillMaxSize()) {
|
||||||
AsyncImage(
|
AsyncImage(
|
||||||
model = ImageRequest.Builder(LocalContext.current)
|
model = ImageRequest.Builder(LocalContext.current)
|
||||||
.data(comic.getPage(0, comicScreenViewModel.apiClient))
|
.data(comic.getCover(comicScreenViewModel.apiClient))
|
||||||
.memoryCacheKey("${comic.id}/${0}")
|
.memoryCacheKey("${comic.id}/cover")
|
||||||
.diskCacheKey("${comic.id}/${0}")
|
.diskCacheKey("${comic.id}/cover")
|
||||||
.build(),
|
.build(),
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
imageLoader = comicScreenViewModel.imageLoader!!,
|
imageLoader = comicScreenViewModel.imageLoader!!,
|
||||||
@@ -115,14 +115,6 @@ fun ComicCard(
|
|||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
modifier = Modifier.align(Alignment.CenterStart)
|
modifier = Modifier.align(Alignment.CenterStart)
|
||||||
)
|
)
|
||||||
|
|
||||||
Text(
|
|
||||||
text = comic.comic.author,
|
|
||||||
fontSize = 12.sp,
|
|
||||||
lineHeight = 14.sp,
|
|
||||||
maxLines = 1,
|
|
||||||
modifier = Modifier.align(Alignment.CenterEnd)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ import androidx.compose.material3.IconButton
|
|||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.DisposableEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableFloatStateOf
|
import androidx.compose.runtime.mutableFloatStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
@@ -61,6 +62,7 @@ import androidx.compose.ui.graphics.Brush
|
|||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.input.pointer.pointerInput
|
import androidx.compose.ui.input.pointer.pointerInput
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.platform.LocalView
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
@@ -69,7 +71,7 @@ import androidx.lifecycle.viewModelScope
|
|||||||
import androidx.media3.common.util.UnstableApi
|
import androidx.media3.common.util.UnstableApi
|
||||||
import androidx.media3.exoplayer.ExoPlayer
|
import androidx.media3.exoplayer.ExoPlayer
|
||||||
import androidx.media3.ui.PlayerView
|
import androidx.media3.ui.PlayerView
|
||||||
import com.acitelight.aether.ToggleFullScreen
|
import com.acitelight.aether.setFullScreen
|
||||||
import com.acitelight.aether.view.pages.formatTime
|
import com.acitelight.aether.view.pages.formatTime
|
||||||
import com.acitelight.aether.view.pages.moveBrit
|
import com.acitelight.aether.view.pages.moveBrit
|
||||||
import com.acitelight.aether.viewModel.VideoPlayerViewModel
|
import com.acitelight.aether.viewModel.VideoPlayerViewModel
|
||||||
@@ -108,7 +110,14 @@ fun VideoPlayerLandscape(videoPlayerViewModel: VideoPlayerViewModel) {
|
|||||||
videoPlayerViewModel.isLandscape = false
|
videoPlayerViewModel.isLandscape = false
|
||||||
}
|
}
|
||||||
|
|
||||||
ToggleFullScreen(true)
|
val view = LocalView.current
|
||||||
|
DisposableEffect(Unit) {
|
||||||
|
setFullScreen(view, true)
|
||||||
|
onDispose {
|
||||||
|
setFullScreen(view, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Box(Modifier.fillMaxSize())
|
Box(Modifier.fillMaxSize())
|
||||||
{
|
{
|
||||||
Box(
|
Box(
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ import androidx.compose.ui.unit.dp
|
|||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import com.acitelight.aether.Global
|
import com.acitelight.aether.Global
|
||||||
import com.acitelight.aether.ToggleFullScreen
|
|
||||||
import com.acitelight.aether.view.pages.formatTime
|
import com.acitelight.aether.view.pages.formatTime
|
||||||
import com.acitelight.aether.view.pages.toHex
|
import com.acitelight.aether.view.pages.toHex
|
||||||
import com.acitelight.aether.viewModel.VideoPlayerViewModel
|
import com.acitelight.aether.viewModel.VideoPlayerViewModel
|
||||||
@@ -110,7 +109,6 @@ fun VideoPlayerPortal(
|
|||||||
val name by videoPlayerViewModel.currentName
|
val name by videoPlayerViewModel.currentName
|
||||||
val duration by videoPlayerViewModel.currentDuration
|
val duration by videoPlayerViewModel.currentDuration
|
||||||
|
|
||||||
ToggleFullScreen(false)
|
|
||||||
Column(
|
Column(
|
||||||
Modifier
|
Modifier
|
||||||
.nestedScroll(nestedScrollConnection)
|
.nestedScroll(nestedScrollConnection)
|
||||||
@@ -120,7 +118,6 @@ fun VideoPlayerPortal(
|
|||||||
Box {
|
Box {
|
||||||
PortalCorePlayer(
|
PortalCorePlayer(
|
||||||
Modifier
|
Modifier
|
||||||
.padding(top = 32.dp)
|
|
||||||
.heightIn(max = playerHeight)
|
.heightIn(max = playerHeight)
|
||||||
.onGloballyPositioned { layoutCoordinates ->
|
.onGloballyPositioned { layoutCoordinates ->
|
||||||
if (!posed && videoPlayerViewModel.renderedFirst) {
|
if (!posed && videoPlayerViewModel.renderedFirst) {
|
||||||
|
|||||||
@@ -2,44 +2,72 @@ package com.acitelight.aether.view.pages
|
|||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.FlowRow
|
||||||
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.heightIn
|
import androidx.compose.foundation.layout.heightIn
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.layout.widthIn
|
import androidx.compose.foundation.layout.widthIn
|
||||||
import androidx.compose.foundation.layout.wrapContentHeight
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.LazyRow
|
import androidx.compose.foundation.lazy.LazyRow
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
|
import androidx.compose.foundation.lazy.staggeredgrid.LazyHorizontalStaggeredGrid
|
||||||
|
import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid
|
||||||
|
import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells
|
||||||
|
import androidx.compose.foundation.lazy.staggeredgrid.rememberLazyStaggeredGridState
|
||||||
|
import androidx.compose.foundation.pager.HorizontalPager
|
||||||
|
import androidx.compose.foundation.pager.rememberPagerState
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.Card
|
import androidx.compose.material3.Card
|
||||||
import androidx.compose.material3.CardDefaults
|
import androidx.compose.material3.CardDefaults
|
||||||
|
import androidx.compose.material3.HorizontalDivider
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.DisposableEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.geometry.Offset
|
||||||
|
import androidx.compose.ui.graphics.Brush
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
|
||||||
|
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
|
||||||
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
|
import androidx.compose.ui.platform.LocalConfiguration
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
|
import androidx.compose.ui.platform.LocalView
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||||
|
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import coil3.compose.AsyncImage
|
import coil3.compose.AsyncImage
|
||||||
import coil3.request.ImageRequest
|
import coil3.request.ImageRequest
|
||||||
import com.acitelight.aether.ToggleFullScreen
|
|
||||||
import com.acitelight.aether.model.BookMark
|
import com.acitelight.aether.model.BookMark
|
||||||
import com.acitelight.aether.model.Comic
|
import com.acitelight.aether.model.Comic
|
||||||
|
import com.acitelight.aether.setFullScreen
|
||||||
|
import com.acitelight.aether.view.components.BiliMiniSlider
|
||||||
import com.acitelight.aether.viewModel.ComicGridViewModel
|
import com.acitelight.aether.viewModel.ComicGridViewModel
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ComicGridView(
|
fun ComicGridView(
|
||||||
comicId: String,
|
comicId: String,
|
||||||
@@ -48,104 +76,206 @@ fun ComicGridView(
|
|||||||
) {
|
) {
|
||||||
comicGridViewModel.resolve(comicId.hexToString())
|
comicGridViewModel.resolve(comicId.hexToString())
|
||||||
comicGridViewModel.updateProcess(comicId.hexToString()) {}
|
comicGridViewModel.updateProcess(comicId.hexToString()) {}
|
||||||
ToggleFullScreen(false)
|
val configuration = LocalConfiguration.current
|
||||||
val colorScheme = MaterialTheme.colorScheme
|
val screenHeight = configuration.screenHeightDp.dp
|
||||||
|
val screenWidth = configuration.screenWidthDp.dp
|
||||||
val comic by comicGridViewModel.comic
|
|
||||||
val record by comicGridViewModel.record
|
val record by comicGridViewModel.record
|
||||||
|
val comic by comicGridViewModel.comic
|
||||||
|
|
||||||
|
val view = LocalView.current
|
||||||
|
DisposableEffect(Unit) {
|
||||||
|
setFullScreen(view, true)
|
||||||
|
onDispose {
|
||||||
|
val nextRoute = navController.currentBackStackEntry?.destination?.route
|
||||||
|
if (nextRoute?.startsWith("comic_page_route") != true) {
|
||||||
|
setFullScreen(view, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val dens = LocalDensity.current
|
||||||
|
val listState = rememberLazyListState()
|
||||||
|
|
||||||
|
val nestedScrollConnection = remember {
|
||||||
|
object : NestedScrollConnection {
|
||||||
|
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
|
||||||
|
val deltaY = available.y // px
|
||||||
|
val deltaDp = with(dens) { deltaY.toDp() }
|
||||||
|
|
||||||
|
val r = if (deltaY < 0 && comicGridViewModel.coverHeight > 0.dp) {
|
||||||
|
val newHeight = (comicGridViewModel.coverHeight + deltaDp).coerceIn(0.dp, comicGridViewModel.maxHeight)
|
||||||
|
val consumedDp = newHeight - comicGridViewModel.coverHeight
|
||||||
|
comicGridViewModel.coverHeight = newHeight
|
||||||
|
val consumedPx = with(dens) { consumedDp.toPx() }
|
||||||
|
Offset(0f, consumedPx)
|
||||||
|
} else if (
|
||||||
|
deltaY > 0
|
||||||
|
&& comicGridViewModel.coverHeight < comicGridViewModel.maxHeight
|
||||||
|
&& listState.firstVisibleItemIndex == 0 && listState.firstVisibleItemScrollOffset == 0
|
||||||
|
) {
|
||||||
|
val newHeight = (comicGridViewModel.coverHeight + deltaDp).coerceIn(0.dp, comicGridViewModel.maxHeight)
|
||||||
|
val consumedDp = newHeight - comicGridViewModel.coverHeight
|
||||||
|
comicGridViewModel.coverHeight = newHeight
|
||||||
|
val consumedPx = with(dens) { consumedDp.toPx() }
|
||||||
|
Offset(0f, consumedPx)
|
||||||
|
} else {
|
||||||
|
Offset.Zero
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (comic != null) {
|
if (comic != null) {
|
||||||
Column {
|
val comic = comic!!
|
||||||
Card(
|
val pagerState = rememberPagerState(
|
||||||
Modifier
|
initialPage = 0,
|
||||||
.padding(horizontal = 16.dp)
|
pageCount = { comic.comic.bookmarks.size })
|
||||||
.padding(top = 36.dp)
|
|
||||||
.heightIn(min = 42.dp),
|
Column(Modifier
|
||||||
colors = CardDefaults.cardColors(containerColor = colorScheme.primary),
|
.nestedScroll(nestedScrollConnection).fillMaxSize()) {
|
||||||
shape = RoundedCornerShape(12.dp)
|
Box(Modifier
|
||||||
)
|
.fillMaxWidth()
|
||||||
|
.height(comicGridViewModel.coverHeight))
|
||||||
{
|
{
|
||||||
Box(
|
HorizontalPager(
|
||||||
Modifier
|
state = pagerState,
|
||||||
.heightIn(min = 42.dp)
|
modifier = Modifier.fillMaxSize()
|
||||||
.fillMaxWidth()
|
|
||||||
)
|
)
|
||||||
{
|
{ page ->
|
||||||
Text(
|
AsyncImage(
|
||||||
text = comic!!.comic.comic_name,
|
model = ImageRequest.Builder(LocalContext.current)
|
||||||
fontSize = 18.sp,
|
.data(comic.getPage(comic.comic.bookmarks[page].page, comicGridViewModel.apiClient))
|
||||||
fontWeight = FontWeight.Bold,
|
.memoryCacheKey("${comic.id}/${comic.comic.bookmarks[page].page}")
|
||||||
maxLines = 1,
|
.diskCacheKey("${comic.id}/${comic.comic.bookmarks[page].page}")
|
||||||
modifier = Modifier.padding(4.dp).align(Alignment.CenterStart)
|
.build(),
|
||||||
|
contentDescription = null,
|
||||||
|
imageLoader = comicGridViewModel.imageLoader!!,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize(),
|
||||||
|
contentScale = ContentScale.FillWidth,
|
||||||
|
onSuccess = { success ->
|
||||||
|
val drawable = success.result.image
|
||||||
|
val width = drawable.width
|
||||||
|
val height = drawable.height
|
||||||
|
val aspectRatio = width.toFloat() / height.toFloat()
|
||||||
|
comicGridViewModel.maxHeight = screenWidth / aspectRatio
|
||||||
|
|
||||||
|
if(comicGridViewModel.coverHeight > comicGridViewModel.maxHeight)
|
||||||
|
comicGridViewModel.coverHeight = comicGridViewModel.maxHeight
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Box(modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.align(Alignment.BottomCenter)
|
||||||
|
.height(50.dp)
|
||||||
|
.background(
|
||||||
|
brush = Brush.verticalGradient(
|
||||||
|
colors = listOf(
|
||||||
|
Color.Transparent,
|
||||||
|
Color.Black.copy(alpha = 0.5f),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
BiliMiniSlider(
|
||||||
|
value = (pagerState.currentPage + 1) / pagerState.pageCount.toFloat(),
|
||||||
|
modifier = Modifier
|
||||||
|
.height(6.dp)
|
||||||
|
.width(100.dp)
|
||||||
|
.align(Alignment.BottomCenter)
|
||||||
|
.fillMaxWidth(),
|
||||||
|
onValueChange = {
|
||||||
|
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Card(
|
|
||||||
Modifier
|
|
||||||
.padding(horizontal = 16.dp)
|
|
||||||
.padding(top = 4.dp)
|
|
||||||
.heightIn(min = 42.dp),
|
|
||||||
colors = CardDefaults.cardColors(containerColor = colorScheme.primary),
|
|
||||||
shape = RoundedCornerShape(12.dp)
|
|
||||||
) {
|
|
||||||
Box(
|
|
||||||
Modifier
|
|
||||||
.heightIn(min = 42.dp)
|
|
||||||
.fillMaxWidth()
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Text(
|
|
||||||
text = comic!!.comic.author,
|
|
||||||
fontSize = 16.sp,
|
|
||||||
fontWeight = FontWeight.Bold,
|
|
||||||
maxLines = 1,
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(4.dp)
|
|
||||||
.align(Alignment.CenterStart)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Card(
|
|
||||||
Modifier
|
|
||||||
.padding(horizontal = 16.dp)
|
|
||||||
.padding(top = 4.dp)
|
|
||||||
.heightIn(min = 42.dp),
|
|
||||||
colors = CardDefaults.cardColors(containerColor = colorScheme.primary),
|
|
||||||
shape = RoundedCornerShape(12.dp)
|
|
||||||
) {
|
|
||||||
Box(
|
|
||||||
Modifier
|
|
||||||
.heightIn(min = 42.dp)
|
|
||||||
.fillMaxWidth()
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Text(
|
|
||||||
text = "Tags : ${comic!!.comic.tags.joinToString(", ")}",
|
|
||||||
fontSize = 16.sp,
|
|
||||||
fontWeight = FontWeight.Bold,
|
|
||||||
maxLines = 5,
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(4.dp)
|
|
||||||
.align(Alignment.CenterStart)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
|
state = listState,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxSize()
|
||||||
.weight(1f)
|
|
||||||
.padding(top = 6.dp)
|
.padding(top = 6.dp)
|
||||||
.clip(RoundedCornerShape(6.dp))
|
.clip(RoundedCornerShape(6.dp))
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
item()
|
||||||
|
{
|
||||||
|
Text(
|
||||||
|
text = comic.comic.comic_name,
|
||||||
|
fontSize = 18.sp,
|
||||||
|
lineHeight = 22.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
maxLines = 1,
|
||||||
|
modifier = Modifier.padding(horizontal = 16.dp).padding(top = 16.dp).padding(bottom = 4.dp)
|
||||||
|
)
|
||||||
|
|
||||||
|
FlowRow(
|
||||||
|
modifier = Modifier.padding(horizontal = 16.dp).padding(bottom = 4.dp)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
comic.comic.tags.take(15).forEach()
|
||||||
|
{
|
||||||
|
ic ->
|
||||||
|
Card(
|
||||||
|
Modifier.padding(1.dp),
|
||||||
|
shape = RoundedCornerShape(8.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = ic,
|
||||||
|
fontSize = 10.sp,
|
||||||
|
lineHeight = 12.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
maxLines = 2,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(4.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Box(Modifier.fillMaxWidth())
|
||||||
|
{
|
||||||
|
Text(
|
||||||
|
text = "Author: ${comic.comic.author} \n${comic.comic.list.size} Pages",
|
||||||
|
fontSize = 11.sp,
|
||||||
|
lineHeight = 15.sp,
|
||||||
|
maxLines = 3,
|
||||||
|
modifier = Modifier.padding(horizontal = 16.dp).padding(bottom = 4.dp)
|
||||||
|
)
|
||||||
|
|
||||||
|
Button(onClick = {
|
||||||
|
comicGridViewModel.updateProcess(comicId.hexToString())
|
||||||
|
{
|
||||||
|
if (record != null) {
|
||||||
|
val route = "comic_page_route/${comic.id.toHex()}/${
|
||||||
|
record!!.position
|
||||||
|
}"
|
||||||
|
navController.navigate(route)
|
||||||
|
} else {
|
||||||
|
val route = "comic_page_route/${comic.id.toHex()}/${0}"
|
||||||
|
navController.navigate(route)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, modifier = Modifier.align(Alignment.CenterEnd))
|
||||||
|
{
|
||||||
|
Text(text = "Continue", fontSize = 16.sp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HorizontalDivider(Modifier.padding(horizontal = 12.dp).padding(bottom = 4.dp), thickness = 1.5.dp)
|
||||||
|
}
|
||||||
|
|
||||||
items(comicGridViewModel.chapterList)
|
items(comicGridViewModel.chapterList)
|
||||||
{ c ->
|
{ c ->
|
||||||
ChapterCard(comic!!, navController, c, comicGridViewModel)
|
ChapterCard(comic, navController, c, comicGridViewModel)
|
||||||
|
HorizontalDivider(Modifier.padding(horizontal = 26.dp), thickness = 1.5.dp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
Card(
|
Card(
|
||||||
Modifier
|
Modifier
|
||||||
.padding(horizontal = 16.dp)
|
.padding(horizontal = 16.dp)
|
||||||
@@ -156,12 +286,12 @@ fun ComicGridView(
|
|||||||
comicGridViewModel.updateProcess(comicId.hexToString())
|
comicGridViewModel.updateProcess(comicId.hexToString())
|
||||||
{
|
{
|
||||||
if (record != null) {
|
if (record != null) {
|
||||||
val route = "comic_page_route/${comic!!.id.toHex()}/${
|
val route = "comic_page_route/${comic.id.toHex()}/${
|
||||||
record!!.position
|
record!!.position
|
||||||
}"
|
}"
|
||||||
navController.navigate(route)
|
navController.navigate(route)
|
||||||
} else {
|
} else {
|
||||||
val route = "comic_page_route/${comic!!.id.toHex()}/${0}"
|
val route = "comic_page_route/${comic.id.toHex()}/${0}"
|
||||||
navController.navigate(route)
|
navController.navigate(route)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -178,11 +308,11 @@ fun ComicGridView(
|
|||||||
.padding(horizontal = 8.dp)
|
.padding(horizontal = 8.dp)
|
||||||
) {
|
) {
|
||||||
if (record != null) {
|
if (record != null) {
|
||||||
val k = comic!!.getPageChapterIndex(record!!.position)
|
val k = comic.getPageChapterIndex(record!!.position)
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
text = "Last Read Position: ${k.first.name} ${k.second}/${
|
text = "Last Read Position: ${k.first.name} ${k.second}/${
|
||||||
comic!!.getChapterLength(
|
comic.getChapterLength(
|
||||||
k.first.page
|
k.first.page
|
||||||
)
|
)
|
||||||
}",
|
}",
|
||||||
@@ -207,6 +337,8 @@ fun ComicGridView(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -220,8 +352,10 @@ fun ChapterCard(
|
|||||||
) {
|
) {
|
||||||
val c = chapter
|
val c = chapter
|
||||||
val iv = comic.getPageIndex(c.page)
|
val iv = comic.getPageIndex(c.page)
|
||||||
|
val r = comic.comic.list.subList(iv, iv + comic.getChapterLength(c.page))
|
||||||
|
|
||||||
Card(
|
Card(
|
||||||
|
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface.copy(0.65f)),
|
||||||
shape = RoundedCornerShape(6.dp),
|
shape = RoundedCornerShape(6.dp),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
@@ -235,57 +369,31 @@ fun ChapterCard(
|
|||||||
) {
|
) {
|
||||||
Column(Modifier.fillMaxWidth())
|
Column(Modifier.fillMaxWidth())
|
||||||
{
|
{
|
||||||
Row(Modifier.padding(6.dp))
|
Text(
|
||||||
{
|
text = chapter.name,
|
||||||
Box(
|
fontSize = 14.sp,
|
||||||
Modifier
|
fontWeight = FontWeight.Bold,
|
||||||
.heightIn(max = 170.dp)
|
maxLines = 2,
|
||||||
.clip(RoundedCornerShape(8.dp))
|
lineHeight = 16.sp,
|
||||||
.background(Color(0x44FFFFFF))
|
modifier = Modifier
|
||||||
)
|
.padding(horizontal = 8.dp).padding(vertical = 4.dp)
|
||||||
{
|
.background(Color.Transparent)
|
||||||
AsyncImage(
|
)
|
||||||
model = ImageRequest.Builder(LocalContext.current)
|
Text(
|
||||||
.data(comic.getPage(c.page, comicGridViewModel.apiClient))
|
text = "${comic.getChapterLength(chapter.page)} Pages",
|
||||||
.memoryCacheKey("${comic.id}/${c.page}")
|
fontSize = 14.sp,
|
||||||
.diskCacheKey("${comic.id}/${c.page}")
|
lineHeight = 16.sp,
|
||||||
.build(),
|
fontWeight = FontWeight.Bold,
|
||||||
contentDescription = null,
|
maxLines = 1,
|
||||||
imageLoader = comicGridViewModel.imageLoader!!,
|
modifier = Modifier
|
||||||
modifier = Modifier
|
.padding(horizontal = 8.dp)
|
||||||
.padding(8.dp)
|
.background(Color.Transparent)
|
||||||
.widthIn(max = 170.dp),
|
)
|
||||||
contentScale = ContentScale.Fit,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Column(modifier = Modifier.padding(horizontal = 12.dp)) {
|
|
||||||
Text(
|
|
||||||
text = chapter.name,
|
|
||||||
fontSize = 18.sp,
|
|
||||||
fontWeight = FontWeight.Bold,
|
|
||||||
maxLines = 5,
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(8.dp)
|
|
||||||
.background(Color.Transparent)
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
text = "${comic.getChapterLength(chapter.page)} Pages",
|
|
||||||
fontSize = 14.sp,
|
|
||||||
fontWeight = FontWeight.Bold,
|
|
||||||
maxLines = 1,
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(8.dp)
|
|
||||||
.background(Color.Transparent)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val r = comic.comic.list.subList(iv, iv + comic.getChapterLength(c.page))
|
|
||||||
LazyRow(
|
LazyRow(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(6.dp)
|
.padding(horizontal = 8.dp).padding(vertical = 4.dp)
|
||||||
) {
|
) {
|
||||||
items(r)
|
items(r)
|
||||||
{ r ->
|
{ r ->
|
||||||
@@ -294,8 +402,8 @@ fun ChapterCard(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.wrapContentHeight()
|
.wrapContentHeight()
|
||||||
.height(140.dp)
|
.height(120.dp)
|
||||||
.padding(horizontal = 6.dp),
|
.padding(horizontal = 2.dp),
|
||||||
onClick = {
|
onClick = {
|
||||||
val route =
|
val route =
|
||||||
"comic_page_route/${comic.id.toHex()}/${comic.getPageIndex(r)}"
|
"comic_page_route/${comic.id.toHex()}/${comic.getPageIndex(r)}"
|
||||||
@@ -313,7 +421,7 @@ fun ChapterCard(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.clip(RoundedCornerShape(12.dp)),
|
.clip(RoundedCornerShape(12.dp)),
|
||||||
contentScale = ContentScale.Crop,
|
contentScale = ContentScale.Fit,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import androidx.compose.material3.Icon
|
|||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.DisposableEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
@@ -38,6 +39,7 @@ import androidx.compose.ui.draw.clip
|
|||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.platform.LocalView
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
@@ -47,6 +49,7 @@ import androidx.navigation.NavHostController
|
|||||||
import coil3.compose.AsyncImage
|
import coil3.compose.AsyncImage
|
||||||
import coil3.request.ImageRequest
|
import coil3.request.ImageRequest
|
||||||
import com.acitelight.aether.model.BookMark
|
import com.acitelight.aether.model.BookMark
|
||||||
|
import com.acitelight.aether.setFullScreen
|
||||||
import com.acitelight.aether.view.components.BookmarkPop
|
import com.acitelight.aether.view.components.BookmarkPop
|
||||||
import com.acitelight.aether.viewModel.ComicPageViewModel
|
import com.acitelight.aether.viewModel.ComicPageViewModel
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -71,6 +74,15 @@ fun ComicPageView(
|
|||||||
comicPageViewModel.updateProcess(pagerState.currentPage)
|
comicPageViewModel.updateProcess(pagerState.currentPage)
|
||||||
|
|
||||||
val comic by comicPageViewModel.comic
|
val comic by comicPageViewModel.comic
|
||||||
|
|
||||||
|
val view = LocalView.current
|
||||||
|
DisposableEffect(Unit) {
|
||||||
|
setFullScreen(view, true)
|
||||||
|
onDispose {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
comic?.let {
|
comic?.let {
|
||||||
Box()
|
Box()
|
||||||
{
|
{
|
||||||
@@ -233,7 +245,7 @@ fun ComicPageView(
|
|||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(bottom = 18.dp)
|
.padding(bottom = 18.dp)
|
||||||
.padding(horizontal = 12.dp)
|
.padding(horizontal = 12.dp)
|
||||||
.height(240.dp)
|
.height(180.dp)
|
||||||
.align(Alignment.BottomCenter)
|
.align(Alignment.BottomCenter)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@@ -241,7 +253,7 @@ fun ComicPageView(
|
|||||||
{ r ->
|
{ r ->
|
||||||
Card(
|
Card(
|
||||||
colors = CardDefaults.cardColors(containerColor = colorScheme.primary.copy(0.8f)),
|
colors = CardDefaults.cardColors(containerColor = colorScheme.primary.copy(0.8f)),
|
||||||
shape = RoundedCornerShape(12.dp),
|
shape = RoundedCornerShape(8.dp),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxHeight()
|
.fillMaxHeight()
|
||||||
.wrapContentHeight()
|
.wrapContentHeight()
|
||||||
@@ -250,7 +262,7 @@ fun ComicPageView(
|
|||||||
pagerState.requestScrollToPage(page = r)
|
pagerState.requestScrollToPage(page = r)
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
Box(Modifier.padding(4.dp))
|
Box(Modifier.padding(1.dp))
|
||||||
{
|
{
|
||||||
AsyncImage(
|
AsyncImage(
|
||||||
model = ImageRequest.Builder(LocalContext.current)
|
model = ImageRequest.Builder(LocalContext.current)
|
||||||
@@ -262,7 +274,7 @@ fun ComicPageView(
|
|||||||
imageLoader = comicPageViewModel.imageLoader!!,
|
imageLoader = comicPageViewModel.imageLoader!!,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxHeight()
|
.fillMaxHeight()
|
||||||
.clip(RoundedCornerShape(12.dp))
|
.clip(RoundedCornerShape(8.dp))
|
||||||
.align(Alignment.Center),
|
.align(Alignment.Center),
|
||||||
contentScale = ContentScale.Fit,
|
contentScale = ContentScale.Fit,
|
||||||
)
|
)
|
||||||
@@ -278,18 +290,6 @@ fun ComicPageView(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
Row {
|
Row {
|
||||||
Text(
|
|
||||||
text = k.first.name,
|
|
||||||
fontSize = 14.sp,
|
|
||||||
fontWeight = FontWeight.Bold,
|
|
||||||
color = Color.White,
|
|
||||||
maxLines = 1,
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(2.dp)
|
|
||||||
.widthIn(max = 200.dp)
|
|
||||||
.align(Alignment.CenterVertically)
|
|
||||||
)
|
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
text = "${k.second}/${it.getChapterLength(k.first.page)}",
|
text = "${k.second}/${it.getChapterLength(k.first.page)}",
|
||||||
fontSize = 16.sp,
|
fontSize = 16.sp,
|
||||||
|
|||||||
@@ -6,11 +6,15 @@ import androidx.compose.foundation.layout.Arrangement
|
|||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.heightIn
|
import androidx.compose.foundation.layout.heightIn
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.layout.widthIn
|
import androidx.compose.foundation.layout.widthIn
|
||||||
import androidx.compose.foundation.layout.wrapContentHeight
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid
|
import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid
|
||||||
@@ -19,17 +23,25 @@ import androidx.compose.foundation.lazy.staggeredgrid.items
|
|||||||
import androidx.compose.foundation.lazy.staggeredgrid.rememberLazyStaggeredGridState
|
import androidx.compose.foundation.lazy.staggeredgrid.rememberLazyStaggeredGridState
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.foundation.text.BasicTextField
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.Search
|
||||||
import androidx.compose.material3.HorizontalDivider
|
import androidx.compose.material3.HorizontalDivider
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.LocalTextStyle
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.layout.Layout
|
import androidx.compose.ui.layout.Layout
|
||||||
import androidx.compose.ui.layout.Placeable
|
import androidx.compose.ui.layout.Placeable
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
@@ -118,16 +130,50 @@ fun ComicScreen(
|
|||||||
val included = comicScreenViewModel.included
|
val included = comicScreenViewModel.included
|
||||||
val state = rememberLazyStaggeredGridState()
|
val state = rememberLazyStaggeredGridState()
|
||||||
val colorScheme = MaterialTheme.colorScheme
|
val colorScheme = MaterialTheme.colorScheme
|
||||||
|
var searchFilter by comicScreenViewModel.searchFilter
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
Text(
|
Row(Modifier
|
||||||
text = "Comic& Images",
|
.padding(4.dp)
|
||||||
style = MaterialTheme.typography.headlineMedium,
|
.align(Alignment.CenterHorizontally)) {
|
||||||
modifier = Modifier
|
Text(
|
||||||
.padding(8.dp)
|
text = "Comics",
|
||||||
.align(Alignment.Start)
|
style = MaterialTheme.typography.headlineMedium,
|
||||||
)
|
modifier = Modifier.align(Alignment.CenterVertically)
|
||||||
HorizontalDivider(Modifier.padding(1.dp), thickness = 1.5.dp)
|
)
|
||||||
|
|
||||||
|
Spacer(Modifier.weight(1f))
|
||||||
|
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.CenterVertically)
|
||||||
|
.height(36.dp)
|
||||||
|
.widthIn(max = 240.dp)
|
||||||
|
.background(colorScheme.primary, RoundedCornerShape(8.dp))
|
||||||
|
.padding(horizontal = 6.dp)
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
modifier = Modifier
|
||||||
|
.size(30.dp)
|
||||||
|
.align(Alignment.CenterVertically),
|
||||||
|
imageVector = Icons.Default.Search,
|
||||||
|
contentDescription = "Catalogue"
|
||||||
|
)
|
||||||
|
Spacer(Modifier.width(4.dp))
|
||||||
|
BasicTextField(
|
||||||
|
value = searchFilter,
|
||||||
|
onValueChange = { searchFilter = it },
|
||||||
|
textStyle = LocalTextStyle.current.copy(
|
||||||
|
fontSize = 18.sp,
|
||||||
|
color = Color.White,
|
||||||
|
textAlign = TextAlign.Start
|
||||||
|
),
|
||||||
|
singleLine = true,
|
||||||
|
modifier = Modifier.align(Alignment.CenterVertically)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VariableGrid(
|
VariableGrid(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.heightIn(max = 88.dp)
|
.heightIn(max = 88.dp)
|
||||||
@@ -140,7 +186,7 @@ fun ComicScreen(
|
|||||||
Box(
|
Box(
|
||||||
Modifier
|
Modifier
|
||||||
.background(
|
.background(
|
||||||
if (included.contains(i)) Color.Green.copy(alpha = 0.65f) else colorScheme.primary,
|
if (included.contains(i)) Color.Green.copy(alpha = 0.65f) else colorScheme.surface,
|
||||||
shape = RoundedCornerShape(4.dp)
|
shape = RoundedCornerShape(4.dp)
|
||||||
)
|
)
|
||||||
.height(32.dp).widthIn(max = 72.dp)
|
.height(32.dp).widthIn(max = 72.dp)
|
||||||
@@ -167,15 +213,15 @@ fun ComicScreen(
|
|||||||
HorizontalDivider(Modifier.padding(1.dp), thickness = 1.5.dp)
|
HorizontalDivider(Modifier.padding(1.dp), thickness = 1.5.dp)
|
||||||
|
|
||||||
LazyVerticalStaggeredGrid(
|
LazyVerticalStaggeredGrid(
|
||||||
columns = StaggeredGridCells.Adaptive(136.dp),
|
columns = StaggeredGridCells.Adaptive(120.dp),
|
||||||
contentPadding = PaddingValues(8.dp),
|
contentPadding = PaddingValues(4.dp),
|
||||||
verticalItemSpacing = 8.dp,
|
verticalItemSpacing = 6.dp,
|
||||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||||
state = state,
|
state = state,
|
||||||
modifier = Modifier.fillMaxSize()
|
modifier = Modifier.fillMaxSize()
|
||||||
) {
|
) {
|
||||||
items(
|
items(
|
||||||
items = comicScreenViewModel.comics.filter { x ->
|
items = comicScreenViewModel.comics.filter { searchFilter.isEmpty() || searchFilter in it.comic.comic_name }.filter { x ->
|
||||||
included.all { y -> y in x.comic.tags } || included.isEmpty()
|
included.all { y -> y in x.comic.tags } || included.isEmpty()
|
||||||
},
|
},
|
||||||
key = { it.id }
|
key = { it.id }
|
||||||
|
|||||||
@@ -89,10 +89,13 @@ fun HomeScreen(
|
|||||||
|
|
||||||
val group =
|
val group =
|
||||||
fv.filter { it.klass == i.klass && it.video.group == i.video.group && it.video.group != "null" }
|
fv.filter { it.klass == i.klass && it.video.group == i.video.group && it.video.group != "null" }
|
||||||
for (i in group) {
|
for (ix in group) {
|
||||||
playList.add("${i.klass}/${i.id}")
|
playList.add("${ix.klass}/${ix.id}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!playList.contains("${i.klass}/${i.id}"))
|
||||||
|
playList.add("${i.klass}/${i.id}")
|
||||||
|
|
||||||
val route =
|
val route =
|
||||||
"video_player_route/${(playList.joinToString(",") + "|${i.id}").toHex()}"
|
"video_player_route/${(playList.joinToString(",") + "|${i.id}").toHex()}"
|
||||||
navController.navigate(route)
|
navController.navigate(route)
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
package com.acitelight.aether.viewModel
|
package com.acitelight.aether.viewModel
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
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.setValue
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import coil3.ImageLoader
|
import coil3.ImageLoader
|
||||||
@@ -27,6 +31,9 @@ class ComicGridViewModel @Inject constructor(
|
|||||||
val apiClient: ApiClient
|
val apiClient: ApiClient
|
||||||
) : ViewModel()
|
) : ViewModel()
|
||||||
{
|
{
|
||||||
|
var coverHeight by mutableStateOf(220.dp)
|
||||||
|
var maxHeight = 220.dp
|
||||||
|
|
||||||
var imageLoader: ImageLoader? = null
|
var imageLoader: ImageLoader? = null
|
||||||
var comic = mutableStateOf<Comic?>(null)
|
var comic = mutableStateOf<Comic?>(null)
|
||||||
val chapterList = mutableStateListOf<BookMark>()
|
val chapterList = mutableStateListOf<BookMark>()
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.acitelight.aether.viewModel
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.compose.runtime.mutableStateListOf
|
import androidx.compose.runtime.mutableStateListOf
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import coil3.ImageLoader
|
import coil3.ImageLoader
|
||||||
@@ -23,6 +24,7 @@ class ComicScreenViewModel @Inject constructor(
|
|||||||
|
|
||||||
var imageLoader: ImageLoader? = null;
|
var imageLoader: ImageLoader? = null;
|
||||||
|
|
||||||
|
val searchFilter = mutableStateOf("")
|
||||||
val comics = mutableStateListOf<Comic>()
|
val comics = mutableStateListOf<Comic>()
|
||||||
val excluded = mutableStateListOf<String>()
|
val excluded = mutableStateListOf<String>()
|
||||||
val included = mutableStateListOf<String>()
|
val included = mutableStateListOf<String>()
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
[versions]
|
[versions]
|
||||||
|
accompanistNavigationAnimation = "0.37.3"
|
||||||
agp = "8.13.0"
|
agp = "8.13.0"
|
||||||
ariaCompiler = "latest"
|
ariaCompiler = "latest"
|
||||||
bcprovJdk15on = "1.70"
|
bcprovJdk15on = "1.70"
|
||||||
@@ -10,7 +11,7 @@ datastorePreferences = "1.1.7"
|
|||||||
exoplayerplus = "0.2.0"
|
exoplayerplus = "0.2.0"
|
||||||
fetch2 = "3.4.1"
|
fetch2 = "3.4.1"
|
||||||
fetch2okhttp = "3.4.1"
|
fetch2okhttp = "3.4.1"
|
||||||
gson = "2.13.1"
|
gson = "2.13.2"
|
||||||
kotlin = "2.2.20"
|
kotlin = "2.2.20"
|
||||||
coreKtx = "1.17.0"
|
coreKtx = "1.17.0"
|
||||||
junit = "4.13.2"
|
junit = "4.13.2"
|
||||||
@@ -19,28 +20,31 @@ espressoCore = "3.7.0"
|
|||||||
kotlinxSerializationJson = "1.9.0"
|
kotlinxSerializationJson = "1.9.0"
|
||||||
lifecycleRuntimeKtx = "2.9.4"
|
lifecycleRuntimeKtx = "2.9.4"
|
||||||
activityCompose = "1.11.0"
|
activityCompose = "1.11.0"
|
||||||
composeBom = "2025.09.00"
|
composeBom = "2025.09.01"
|
||||||
media3Common = "1.8.0"
|
media3Common = "1.8.0"
|
||||||
media3Exoplayer = "1.8.0"
|
media3Exoplayer = "1.8.0"
|
||||||
media3ExoplayerFfmpeg = "1.8.0"
|
media3ExoplayerFfmpeg = "1.8.0"
|
||||||
media3Ui = "1.8.0"
|
media3Ui = "1.8.0"
|
||||||
navigationCompose = "2.9.4"
|
navigationCompose = "2.9.5"
|
||||||
okhttp = "5.1.0"
|
okhttp = "5.1.0"
|
||||||
persistentcookiejar = "1.0.1"
|
persistentcookiejar = "1.0.1"
|
||||||
repo = "Tag"
|
repo = "Tag"
|
||||||
retrofit = "3.0.0"
|
retrofit = "3.0.0"
|
||||||
retrofit2KotlinxSerializationConverter = "1.0.0"
|
retrofit2KotlinxSerializationConverter = "1.0.0"
|
||||||
media3DatasourceOkhttp = "1.8.0"
|
media3DatasourceOkhttp = "1.8.0"
|
||||||
roomCompiler = "2.8.0"
|
roomCompiler = "2.8.1"
|
||||||
roomKtx = "2.8.0"
|
roomKtx = "2.8.1"
|
||||||
roomRuntime = "2.8.0"
|
roomRuntime = "2.8.1"
|
||||||
|
|
||||||
ksp = "2.1.21-2.0.2"
|
ksp = "2.1.21-2.0.2"
|
||||||
hilt = "2.57.1"
|
hilt = "2.57.2"
|
||||||
hilt-navigation-compose = "1.3.0"
|
hilt-navigation-compose = "1.3.0"
|
||||||
composeMaterialCore = "1.5.1"
|
composeMaterialCore = "1.5.2"
|
||||||
|
constraintlayout = "2.2.1"
|
||||||
|
animation = "1.9.2"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
|
accompanist-navigation-animation = { module = "com.google.accompanist:accompanist-navigation-animation", version.ref = "accompanistNavigationAnimation" }
|
||||||
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
||||||
androidx-datastore-preferences = { module = "androidx.datastore:datastore-preferences", version.ref = "datastorePreferences" }
|
androidx-datastore-preferences = { module = "androidx.datastore:datastore-preferences", version.ref = "datastorePreferences" }
|
||||||
androidx-material-icons-extended = { module = "androidx.compose.material:material-icons-extended" }
|
androidx-material-icons-extended = { module = "androidx.compose.material:material-icons-extended" }
|
||||||
@@ -83,6 +87,8 @@ hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref
|
|||||||
hilt-android-compiler = { group = "com.google.dagger", name = "hilt-android-compiler", version.ref = "hilt" }
|
hilt-android-compiler = { group = "com.google.dagger", name = "hilt-android-compiler", version.ref = "hilt" }
|
||||||
hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "hilt-navigation-compose" }
|
hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "hilt-navigation-compose" }
|
||||||
androidx-compose-material-core = { group = "androidx.wear.compose", name = "compose-material-core", version.ref = "composeMaterialCore" }
|
androidx-compose-material-core = { group = "androidx.wear.compose", name = "compose-material-core", version.ref = "composeMaterialCore" }
|
||||||
|
androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
|
||||||
|
androidx-compose-animation = { group = "androidx.compose.animation", name = "animation", version.ref = "animation" }
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||||
|
|||||||
Reference in New Issue
Block a user