[feat] Image Recents
This commit is contained in:
@@ -2,11 +2,10 @@ package com.acitelight.aether.service
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.compose.runtime.mutableStateListOf
|
import androidx.compose.runtime.mutableStateListOf
|
||||||
|
import com.acitelight.aether.model.Comic
|
||||||
import com.acitelight.aether.model.Video
|
import com.acitelight.aether.model.Video
|
||||||
import com.acitelight.aether.model.VideoQueryIndex
|
import com.acitelight.aether.model.VideoQueryIndex
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import kotlinx.coroutines.sync.withLock
|
import kotlinx.coroutines.sync.withLock
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
@@ -24,7 +23,7 @@ class RecentManager @Inject constructor(
|
|||||||
{
|
{
|
||||||
private val mutex = Mutex()
|
private val mutex = Mutex()
|
||||||
|
|
||||||
suspend fun readFile(context: Context, filename: String): String {
|
private suspend fun readFile(context: Context, filename: String): String {
|
||||||
return withContext(Dispatchers.IO) {
|
return withContext(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
val file = File(context.filesDir, filename)
|
val file = File(context.filesDir, filename)
|
||||||
@@ -38,7 +37,7 @@ class RecentManager @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun writeFile(context: Context, filename: String, content: String) {
|
private suspend fun writeFile(context: Context, filename: String, content: String) {
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
val file = File(context.filesDir, filename)
|
val file = File(context.filesDir, filename)
|
||||||
@@ -50,13 +49,85 @@ class RecentManager @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun Query(context: Context): List<VideoQueryIndex>
|
suspend fun queryComic(context: Context): List<String> {
|
||||||
|
val content = readFile(context, "recent_comic.json")
|
||||||
|
try {
|
||||||
|
val ids = Json.decodeFromString<List<String>>(content)
|
||||||
|
|
||||||
|
|
||||||
|
recentComic.clear()
|
||||||
|
|
||||||
|
try {
|
||||||
|
val comics = mediaManager.queryComicInfoBulk(ids)
|
||||||
|
if (comics != null) {
|
||||||
|
for (c in comics) {
|
||||||
|
recentComic.add(recentComic.size, c)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (id in ids) {
|
||||||
|
val c = mediaManager.queryComicInfoSingle(id)
|
||||||
|
if (c != null) recentComic.add(recentComic.size, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: NoSuchMethodError) {
|
||||||
|
for (id in ids) {
|
||||||
|
val c = mediaManager.queryComicInfoSingle(id)
|
||||||
|
if (c != null) recentComic.add(recentComic.size, c)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
for (id in ids) {
|
||||||
|
val c = mediaManager.queryComicInfoSingle(id)
|
||||||
|
if (c != null) recentComic.add(recentComic.size, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return ids
|
||||||
|
} catch (e: Exception) {
|
||||||
|
print(e.message)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return listOf()
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun pushComic(context: Context, comicId: String) {
|
||||||
|
mutex.withLock {
|
||||||
|
val c = readFile(context, "recent_comic.json")
|
||||||
|
|
||||||
|
|
||||||
|
val o = recentComic.map { it.id }.toMutableList()
|
||||||
|
|
||||||
|
|
||||||
|
if (o.contains(comicId)) {
|
||||||
|
val index = o.indexOf(comicId)
|
||||||
|
recentComic.removeAt(index)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val comic = mediaManager.queryComicInfoSingle(comicId)
|
||||||
|
if (comic != null) {
|
||||||
|
recentComic.add(0, comic)
|
||||||
|
} else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recentComic.size > 21) {
|
||||||
|
recentComic.removeAt(recentComic.size - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
writeFile(context, "recent_comic.json", Json.encodeToString(recentComic.map { it.id }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun queryVideo(context: Context): List<VideoQueryIndex>
|
||||||
{
|
{
|
||||||
val content = readFile(context, "recent.json")
|
val content = readFile(context, "recent.json")
|
||||||
try{
|
try{
|
||||||
val r = Json.decodeFromString<List<VideoQueryIndex>>(content)
|
val r = Json.decodeFromString<List<VideoQueryIndex>>(content)
|
||||||
|
|
||||||
recent.clear()
|
recentVideo.clear()
|
||||||
val gr = r.groupBy { it.klass }
|
val gr = r.groupBy { it.klass }
|
||||||
|
|
||||||
for(it in gr)
|
for(it in gr)
|
||||||
@@ -65,7 +136,7 @@ class RecentManager @Inject constructor(
|
|||||||
if(v != null)
|
if(v != null)
|
||||||
for(j in v)
|
for(j in v)
|
||||||
{
|
{
|
||||||
recent.add(recent.size, j)
|
recentVideo.add(recentVideo.size, j)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,28 +149,29 @@ class RecentManager @Inject constructor(
|
|||||||
return listOf()
|
return listOf()
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun Push(context: Context, video: VideoQueryIndex)
|
suspend fun pushVideo(context: Context, video: VideoQueryIndex)
|
||||||
{
|
{
|
||||||
mutex.withLock{
|
mutex.withLock{
|
||||||
val content = readFile(context, "recent.json")
|
val content = readFile(context, "recent.json")
|
||||||
val o = recent.map{ VideoQueryIndex(it.klass, it.id) }.toMutableList()
|
val o = recentVideo.map{ VideoQueryIndex(it.klass, it.id) }.toMutableList()
|
||||||
|
|
||||||
if(o.contains(video))
|
if(o.contains(video))
|
||||||
{
|
{
|
||||||
val index = o.indexOf(video)
|
val index = o.indexOf(video)
|
||||||
val temp = recent[index]
|
val temp = recentVideo[index]
|
||||||
|
|
||||||
recent.removeAt(index)
|
recentVideo.removeAt(index)
|
||||||
}
|
}
|
||||||
recent.add(0, mediaManager.queryVideo(video.klass, video.id)!!)
|
recentVideo.add(0, mediaManager.queryVideo(video.klass, video.id)!!)
|
||||||
|
|
||||||
|
|
||||||
if(recent.size >= 21)
|
if(recentVideo.size >= 21)
|
||||||
recent.removeAt(o.size - 1)
|
recentVideo.removeAt(o.size - 1)
|
||||||
|
|
||||||
writeFile(context, "recent.json", Json.encodeToString(recent.map{ VideoQueryIndex(it.klass, it.id) }))
|
writeFile(context, "recent.json", Json.encodeToString(recentVideo.map{ VideoQueryIndex(it.klass, it.id) }))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val recent = mutableStateListOf<Video>()
|
val recentVideo = mutableStateListOf<Video>()
|
||||||
|
val recentComic = mutableStateListOf<Comic>()
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,7 @@ 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.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
|
||||||
@@ -170,7 +171,7 @@ fun ChapterCard(comic: Comic, navController: NavHostController, chapter: BookMar
|
|||||||
Row(Modifier.padding(6.dp))
|
Row(Modifier.padding(6.dp))
|
||||||
{
|
{
|
||||||
Box(Modifier
|
Box(Modifier
|
||||||
.height(170.dp)
|
.heightIn(max = 170.dp)
|
||||||
.clip(RoundedCornerShape(8.dp))
|
.clip(RoundedCornerShape(8.dp))
|
||||||
.background(Color(0x44FFFFFF)))
|
.background(Color(0x44FFFFFF)))
|
||||||
{
|
{
|
||||||
@@ -182,7 +183,7 @@ fun ChapterCard(comic: Comic, navController: NavHostController, chapter: BookMar
|
|||||||
.build(),
|
.build(),
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
imageLoader = comicGridViewModel.imageLoader!!,
|
imageLoader = comicGridViewModel.imageLoader!!,
|
||||||
modifier = Modifier.padding(8.dp),
|
modifier = Modifier.padding(8.dp).widthIn(max = 170.dp),
|
||||||
contentScale = ContentScale.Fit,
|
contentScale = ContentScale.Fit,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,49 +1,67 @@
|
|||||||
package com.acitelight.aether.view
|
package com.acitelight.aether.view
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
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.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.foundation.lazy.grid.GridCells
|
||||||
|
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||||
|
import androidx.compose.foundation.lazy.grid.items
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.foundation.pager.HorizontalPager
|
||||||
|
import androidx.compose.foundation.pager.rememberPagerState
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material3.Card
|
||||||
import androidx.compose.material3.DividerDefaults
|
import androidx.compose.material3.DividerDefaults
|
||||||
import androidx.compose.material3.HorizontalDivider
|
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.collectAsState
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
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.alpha
|
import androidx.compose.ui.draw.alpha
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.graphics.Brush
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.layout.ContentScale
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
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.navigation.compose.hiltViewModel
|
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import com.acitelight.aether.Global
|
import androidx.navigation.NavHostController
|
||||||
|
import coil3.compose.AsyncImage
|
||||||
|
import coil3.request.ImageRequest
|
||||||
import com.acitelight.aether.Global.updateRelate
|
import com.acitelight.aether.Global.updateRelate
|
||||||
import com.acitelight.aether.service.MediaManager
|
import com.acitelight.aether.model.Comic
|
||||||
import com.acitelight.aether.service.RecentManager
|
import com.acitelight.aether.viewModel.ComicScreenViewModel
|
||||||
import com.acitelight.aether.viewModel.HomeScreenViewModel
|
import com.acitelight.aether.viewModel.HomeScreenViewModel
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun HomeScreen(
|
fun HomeScreen(
|
||||||
homeScreenViewModel: HomeScreenViewModel = androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel<HomeScreenViewModel>(),
|
homeScreenViewModel: HomeScreenViewModel = androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel<HomeScreenViewModel>(),
|
||||||
navController: NavController)
|
navController: NavHostController)
|
||||||
{
|
{
|
||||||
if(Global.loggedIn)
|
val pagerState = rememberPagerState(initialPage = 0, pageCount = { 2 })
|
||||||
homeScreenViewModel.Init()
|
|
||||||
|
|
||||||
LazyColumn(modifier = Modifier.fillMaxWidth())
|
HorizontalPager(
|
||||||
{
|
state = pagerState,
|
||||||
item()
|
modifier = Modifier.fillMaxSize().background(Color.Black)
|
||||||
|
){
|
||||||
|
p ->
|
||||||
|
if(p == 0)
|
||||||
{
|
{
|
||||||
Column {
|
Column(Modifier.fillMaxHeight()) {
|
||||||
Text(
|
Text(
|
||||||
text = "Videos",
|
text = "Videos",
|
||||||
style = MaterialTheme.typography.headlineMedium,
|
style = MaterialTheme.typography.headlineMedium,
|
||||||
@@ -52,21 +70,123 @@ fun HomeScreen(
|
|||||||
|
|
||||||
HorizontalDivider(Modifier.padding(8.dp), 2.dp, DividerDefaults.color)
|
HorizontalDivider(Modifier.padding(8.dp), 2.dp, DividerDefaults.color)
|
||||||
|
|
||||||
for(i in homeScreenViewModel.recentManager.recent)
|
LazyColumn(modifier = Modifier.fillMaxWidth())
|
||||||
{
|
{
|
||||||
MiniVideoCard(
|
items(homeScreenViewModel.recentManager.recentVideo)
|
||||||
modifier = Modifier
|
{
|
||||||
.padding(horizontal = 12.dp),
|
i ->
|
||||||
i,
|
MiniVideoCard(
|
||||||
{
|
modifier = Modifier
|
||||||
updateRelate(homeScreenViewModel.recentManager.recent, i)
|
.padding(horizontal = 12.dp),
|
||||||
val route = "video_player_route/${ "${i.klass}/${i.id}".toHex() }"
|
i,
|
||||||
navController.navigate(route)
|
{
|
||||||
}, homeScreenViewModel.imageLoader!!)
|
updateRelate(homeScreenViewModel.recentManager.recentVideo, i)
|
||||||
HorizontalDivider(Modifier.padding(vertical = 8.dp).alpha(0.25f), 1.dp, DividerDefaults.color)
|
val route = "video_player_route/${ "${i.klass}/${i.id}".toHex() }"
|
||||||
|
navController.navigate(route)
|
||||||
|
}, homeScreenViewModel.imageLoader!!)
|
||||||
|
HorizontalDivider(Modifier.padding(vertical = 8.dp).alpha(0.4f), 1.dp, DividerDefaults.color)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Column(Modifier.fillMaxHeight()) {
|
||||||
|
Text(
|
||||||
|
text = "Comics",
|
||||||
|
style = MaterialTheme.typography.headlineMedium,
|
||||||
|
modifier = Modifier.padding(8.dp).align(Alignment.Start)
|
||||||
|
)
|
||||||
|
|
||||||
|
HorizontalDivider(Modifier.padding(8.dp), 2.dp, DividerDefaults.color)
|
||||||
|
|
||||||
|
LazyVerticalGrid(
|
||||||
|
columns = GridCells.Adaptive(128.dp),
|
||||||
|
contentPadding = PaddingValues(8.dp),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
|
)
|
||||||
|
{
|
||||||
|
items(homeScreenViewModel.recentManager.recentComic)
|
||||||
|
{
|
||||||
|
comic ->
|
||||||
|
ComicCardRecent(comic, navController, homeScreenViewModel)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ComicCardRecent(
|
||||||
|
comic: Comic,
|
||||||
|
navController: NavHostController,
|
||||||
|
homeScreenViewModel: HomeScreenViewModel
|
||||||
|
) {
|
||||||
|
Card(
|
||||||
|
shape = RoundedCornerShape(6.dp),
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.wrapContentHeight(),
|
||||||
|
onClick = {
|
||||||
|
val route = "comic_grid_route/${"${comic.id}".toHex()}"
|
||||||
|
navController.navigate(route)
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
Box(modifier = Modifier.fillMaxSize()) {
|
||||||
|
AsyncImage(
|
||||||
|
model = ImageRequest.Builder(LocalContext.current)
|
||||||
|
.data(comic.getPage(0))
|
||||||
|
.memoryCacheKey("${comic.id}/${0}")
|
||||||
|
.diskCacheKey("${comic.id}/${0}")
|
||||||
|
.build(),
|
||||||
|
contentDescription = null,
|
||||||
|
imageLoader = homeScreenViewModel.imageLoader!!,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize(),
|
||||||
|
contentScale = ContentScale.Crop,
|
||||||
|
)
|
||||||
|
|
||||||
|
Box(
|
||||||
|
Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(24.dp)
|
||||||
|
.background(
|
||||||
|
brush = Brush.verticalGradient(
|
||||||
|
colors = listOf(
|
||||||
|
Color.Transparent,
|
||||||
|
Color.Black.copy(alpha = 0.45f)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.align(Alignment.BottomCenter)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Text(
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.BottomEnd)
|
||||||
|
.padding(2.dp),
|
||||||
|
fontSize = 12.sp,
|
||||||
|
text = "${comic.comic.list.size} Pages",
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
color = Color.White
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text = comic.comic.comic_name,
|
||||||
|
fontSize = 14.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
maxLines = 2,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(8.dp)
|
||||||
|
.background(Color.Transparent)
|
||||||
|
.heightIn(48.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -25,7 +25,8 @@ import javax.inject.Inject
|
|||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class ComicGridViewModel @Inject constructor(
|
class ComicGridViewModel @Inject constructor(
|
||||||
@ApplicationContext val context: Context,
|
@ApplicationContext val context: Context,
|
||||||
val mediaManager: MediaManager
|
val mediaManager: MediaManager,
|
||||||
|
val recentManager: RecentManager
|
||||||
) : ViewModel()
|
) : ViewModel()
|
||||||
{
|
{
|
||||||
var imageLoader: ImageLoader? = null
|
var imageLoader: ImageLoader? = null
|
||||||
@@ -52,6 +53,7 @@ class ComicGridViewModel @Inject constructor(
|
|||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
if(comic.value == null) {
|
if(comic.value == null) {
|
||||||
comic.value = mediaManager.queryComicInfoSingle(id)
|
comic.value = mediaManager.queryComicInfoSingle(id)
|
||||||
|
recentManager.pushComic(context, id)
|
||||||
val c = comic.value!!
|
val c = comic.value!!
|
||||||
for (i in c.comic.bookmarks) {
|
for (i in c.comic.bookmarks) {
|
||||||
chapterList.add(i)
|
chapterList.add(i)
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
package com.acitelight.aether.viewModel
|
package com.acitelight.aether.viewModel
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import android.content.Context
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import coil3.ImageLoader
|
import coil3.ImageLoader
|
||||||
import coil3.network.okhttp.OkHttpNetworkFetcherFactory
|
import coil3.network.okhttp.OkHttpNetworkFetcherFactory
|
||||||
@@ -11,33 +9,27 @@ import com.acitelight.aether.service.ApiClient.createOkHttp
|
|||||||
import com.acitelight.aether.service.RecentManager
|
import com.acitelight.aether.service.RecentManager
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import com.acitelight.aether.service.*
|
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
|
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class HomeScreenViewModel @Inject constructor(
|
class HomeScreenViewModel @Inject constructor(
|
||||||
val recentManager: RecentManager
|
val recentManager: RecentManager,
|
||||||
|
@ApplicationContext val context: Context
|
||||||
) : ViewModel()
|
) : ViewModel()
|
||||||
{
|
{
|
||||||
var _init = false
|
var imageLoader: ImageLoader? = null
|
||||||
var imageLoader: ImageLoader? = null;
|
|
||||||
|
|
||||||
@Composable
|
init{
|
||||||
fun Init(){
|
|
||||||
if(_init) return
|
|
||||||
_init = true
|
|
||||||
|
|
||||||
val context = LocalContext.current
|
|
||||||
imageLoader = ImageLoader.Builder(context)
|
imageLoader = ImageLoader.Builder(context)
|
||||||
.components {
|
.components {
|
||||||
add(OkHttpNetworkFetcherFactory(createOkHttp()))
|
add(OkHttpNetworkFetcherFactory(createOkHttp()))
|
||||||
}
|
}
|
||||||
.build()
|
.build()
|
||||||
remember {
|
viewModelScope.launch {
|
||||||
viewModelScope.launch {
|
recentManager.queryVideo(context)
|
||||||
recentManager.Query(context)
|
recentManager.queryComic(context)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,8 @@
|
|||||||
package com.acitelight.aether.viewModel
|
package com.acitelight.aether.viewModel
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import androidx.annotation.OptIn
|
import androidx.annotation.OptIn
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.State
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableFloatStateOf
|
import androidx.compose.runtime.mutableFloatStateOf
|
||||||
import androidx.compose.runtime.mutableIntStateOf
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
@@ -25,7 +23,6 @@ import androidx.media3.exoplayer.ExoPlayer
|
|||||||
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory
|
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory
|
||||||
import coil3.ImageLoader
|
import coil3.ImageLoader
|
||||||
import coil3.network.okhttp.OkHttpNetworkFetcherFactory
|
import coil3.network.okhttp.OkHttpNetworkFetcherFactory
|
||||||
import com.acitelight.aether.Global
|
|
||||||
import com.acitelight.aether.model.Video
|
import com.acitelight.aether.model.Video
|
||||||
import com.acitelight.aether.model.VideoQueryIndex
|
import com.acitelight.aether.model.VideoQueryIndex
|
||||||
import com.acitelight.aether.service.ApiClient.createOkHttp
|
import com.acitelight.aether.service.ApiClient.createOkHttp
|
||||||
@@ -86,7 +83,7 @@ class VideoPlayerViewModel @Inject constructor(
|
|||||||
remember {
|
remember {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
video = mediaManager.queryVideo(v.split("/")[0], v.split("/")[1])!!
|
video = mediaManager.queryVideo(v.split("/")[0], v.split("/")[1])!!
|
||||||
recentManager.Push(context, VideoQueryIndex(v.split("/")[0], v.split("/")[1]))
|
recentManager.pushVideo(context, VideoQueryIndex(v.split("/")[0], v.split("/")[1]))
|
||||||
_player = (if(video!!.isLocal) ExoPlayer.Builder(context) else ExoPlayer.Builder(context).setMediaSourceFactory(DefaultMediaSourceFactory(dataSourceFactory)))
|
_player = (if(video!!.isLocal) ExoPlayer.Builder(context) else ExoPlayer.Builder(context).setMediaSourceFactory(DefaultMediaSourceFactory(dataSourceFactory)))
|
||||||
.build().apply {
|
.build().apply {
|
||||||
val url = video?.getVideo() ?: ""
|
val url = video?.getVideo() ?: ""
|
||||||
|
|||||||
Reference in New Issue
Block a user