[optimize] Architecture is shifting towards Hilt comprehensively

This commit is contained in:
acite
2025-09-14 20:59:51 +08:00
parent f7701cc85b
commit 54c9d326c6
20 changed files with 100 additions and 94 deletions

View File

@@ -4,6 +4,7 @@ import com.acitelight.aether.service.ApiClient
import java.security.KeyPair import java.security.KeyPair
class Video constructor( class Video constructor(
val isLocal: Boolean,
val klass: String, val klass: String,
val id: String, val id: String,
val token: String, val token: String,

View File

@@ -47,7 +47,7 @@ object ApiClient {
private val dnsEventListener = object : EventListener() { private val dnsEventListener = object : EventListener() {
override fun dnsEnd(call: okhttp3.Call, domainName: String, inetAddressList: List<InetAddress>) { override fun dnsEnd(call: okhttp3.Call, domainName: String, inetAddressList: List<InetAddress>) {
super.dnsEnd(call, domainName, inetAddressList) super.dnsEnd(call, domainName, inetAddressList)
val ipAddresses = inetAddressList.joinToString(", ") { it.hostAddress } val ipAddresses = inetAddressList.joinToString(", ") { it.hostAddress ?: "" }
Log.d("OkHttp_DNS", "Domain '$domainName' resolved to IPs: [$ipAddresses]") Log.d("OkHttp_DNS", "Domain '$domainName' resolved to IPs: [$ipAddresses]")
} }
} }

View File

@@ -96,7 +96,7 @@ class FetchManager @Inject constructor(
fun startVideoDownload(video: Video) fun startVideoDownload(video: Video)
{ {
val path = File(context.filesDir, "videos/${video.klass}/${video.id}") val path = File(context.filesDir, "videos/${video.klass}/${video.id}/video.mp4")
val request = Request(video.getVideo(), path.path).apply { val request = Request(video.getVideo(), path.path).apply {
extras = Extras(mapOf("name" to video.video.name, "id" to video.id, "class" to video.klass)) extras = Extras(mapOf("name" to video.video.name, "id" to video.id, "class" to video.klass))
} }

View File

@@ -1,12 +1,19 @@
package com.acitelight.aether.service package com.acitelight.aether.service
import android.content.Context
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.model.ComicResponse import com.acitelight.aether.model.ComicResponse
import com.acitelight.aether.model.Video import com.acitelight.aether.model.Video
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
import javax.inject.Singleton
object MediaManager @Singleton
class MediaManager @Inject constructor(
)
{ {
var token: String = "null" var token: String = "null"
@@ -34,27 +41,11 @@ object MediaManager
} }
} }
private suspend fun listVideos(klass: String, filter: List<String>, callback: (Video) -> Unit)
{
val j = ApiClient.api!!.queryVideoClasses(klass, token)
for(it in j)
{
if(filter.contains(it))
continue
try {
callback(queryVideo(klass, it)!!)
}catch (e: Exception)
{
}
}
}
suspend fun queryVideo(klass: String, id: String): Video? suspend fun queryVideo(klass: String, id: String): Video?
{ {
try { try {
val j = ApiClient.api!!.queryVideo(klass, id, token) val j = ApiClient.api!!.queryVideo(klass, id, token)
return Video(klass = klass, id = id, token=token, j) return Video(klass = klass, id = id, token=token, isLocal = false, video = j)
}catch (e: Exception) }catch (e: Exception)
{ {
return null return null
@@ -65,7 +56,7 @@ object MediaManager
{ {
try { try {
val j = ApiClient.api!!.queryVideoBulk(klass, id, token) val j = ApiClient.api!!.queryVideoBulk(klass, id, token)
return j.zip(id).map {Video(klass = klass, id = it.second, token=token, it.first)} return j.zip(id).map {Video(klass = klass, id = it.second, token=token, isLocal = false, video = it.first)}
}catch (e: Exception) }catch (e: Exception)
{ {
return null return null

View File

@@ -14,8 +14,13 @@ import kotlinx.serialization.json.*
import java.io.File import java.io.File
import java.io.FileNotFoundException import java.io.FileNotFoundException
import java.io.IOException import java.io.IOException
import javax.inject.Inject
import javax.inject.Singleton
object RecentManager @Singleton
class RecentManager @Inject constructor(
private val mediaManager: MediaManager
)
{ {
private val mutex = Mutex() private val mutex = Mutex()
@@ -56,7 +61,7 @@ object RecentManager
for(it in gr) for(it in gr)
{ {
val v = MediaManager.queryVideoBulk(it.key, it.value.map { it.id }) val v = mediaManager.queryVideoBulk(it.key, it.value.map { it.id })
if(v != null) if(v != null)
for(j in v) for(j in v)
{ {
@@ -86,7 +91,7 @@ object RecentManager
recent.removeAt(index) recent.removeAt(index)
} }
recent.add(0, MediaManager.queryVideoBulk(video.klass, listOf(video.id))!![0]) recent.add(0, mediaManager.queryVideoBulk(video.klass, listOf(video.id))!![0])
if(recent.size >= 21) if(recent.size >= 21)

View File

@@ -29,6 +29,7 @@ import androidx.compose.ui.platform.LocalContext
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.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import coil3.compose.AsyncImage import coil3.compose.AsyncImage
@@ -109,13 +110,13 @@ fun ComicGridView(comicId: String, navController: NavHostController, comicGridVi
{ {
if(record != null) { if(record != null) {
val k = comic!!.getPageChapterIndex(record!!.position) val k = comic!!.getPageChapterIndex(record!!.position)
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)
} }
} }
@@ -150,7 +151,7 @@ fun ComicGridView(comicId: String, navController: NavHostController, comicGridVi
} }
@Composable @Composable
fun ChapterCard(comic: Comic, navController: NavHostController, chapter: BookMark, comicGridViewModel: ComicGridViewModel = viewModel()) fun ChapterCard(comic: Comic, navController: NavHostController, chapter: BookMark, comicGridViewModel: ComicGridViewModel = hiltViewModel<ComicGridViewModel>())
{ {
val c = chapter val c = chapter
val iv = comic.getPageIndex(c.page) val iv = comic.getPageIndex(c.page)
@@ -162,7 +163,7 @@ fun ChapterCard(comic: Comic, navController: NavHostController, chapter: BookMar
.wrapContentHeight() .wrapContentHeight()
.padding(horizontal = 16.dp).padding(vertical = 6.dp), .padding(horizontal = 16.dp).padding(vertical = 6.dp),
onClick = { onClick = {
val route = "comic_page_route/${"${comic.id}".toHex()}/${comic.getPageIndex(chapter.page)}" val route = "comic_page_route/${comic.id.toHex()}/${comic.getPageIndex(chapter.page)}"
navController.navigate(route) navController.navigate(route)
} }
) { ) {

View File

@@ -49,6 +49,7 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.max import androidx.compose.ui.unit.max
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import coil3.compose.AsyncImage import coil3.compose.AsyncImage
@@ -61,7 +62,7 @@ import com.acitelight.aether.viewModel.ComicPageViewModel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@Composable @Composable
fun ComicPageView(comicId: String, page: String, navController: NavHostController, comicPageViewModel: ComicPageViewModel = viewModel()) fun ComicPageView(comicId: String, page: String, navController: NavHostController, comicPageViewModel: ComicPageViewModel = hiltViewModel<ComicPageViewModel>())
{ {
comicPageViewModel.SetupClient() comicPageViewModel.SetupClient()
comicPageViewModel.Resolve(comicId.hexToString(), page.toInt()) comicPageViewModel.Resolve(comicId.hexToString(), page.toInt())
@@ -291,8 +292,8 @@ fun ComicPageView(comicId: String, page: String, navController: NavHostControll
s -> s ->
showBookMarkPop = false showBookMarkPop = false
comicPageViewModel.coroutineScope?.launch { comicPageViewModel.coroutineScope?.launch {
MediaManager.postBookmark(comicId.hexToString(), BookMark(name = s, page = comicPageViewModel.pageList[pagerState.currentPage])) comicPageViewModel.mediaManager.postBookmark(comicId.hexToString(), BookMark(name = s, page = comicPageViewModel.pageList[pagerState.currentPage]))
comicPageViewModel.comic.value = MediaManager.queryComicInfoSingle(comicId.hexToString()) comicPageViewModel.comic.value = comicPageViewModel.mediaManager.queryComicInfoSingle(comicId.hexToString())
} }
}); });
} }

View File

@@ -53,6 +53,7 @@ import androidx.compose.ui.layout.Placeable
import androidx.compose.ui.modifier.modifierLocalOf import androidx.compose.ui.modifier.modifierLocalOf
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import coil3.request.ImageRequest import coil3.request.ImageRequest
import com.acitelight.aether.Global import com.acitelight.aether.Global
@@ -135,7 +136,7 @@ fun VariableGrid(
@Composable @Composable
fun ComicScreen( fun ComicScreen(
navController: NavHostController, navController: NavHostController,
comicScreenViewModel: ComicScreenViewModel = viewModel() comicScreenViewModel: ComicScreenViewModel = hiltViewModel<ComicScreenViewModel>()
) { ) {
comicScreenViewModel.SetupClient() comicScreenViewModel.SetupClient()
val included = comicScreenViewModel.included val included = comicScreenViewModel.included

View File

@@ -32,7 +32,9 @@ import com.acitelight.aether.service.RecentManager
import com.acitelight.aether.viewModel.HomeScreenViewModel import com.acitelight.aether.viewModel.HomeScreenViewModel
@Composable @Composable
fun HomeScreen(homeScreenViewModel: HomeScreenViewModel = androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel<HomeScreenViewModel>(), navController: NavController) fun HomeScreen(
homeScreenViewModel: HomeScreenViewModel = androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel<HomeScreenViewModel>(),
navController: NavController)
{ {
if(Global.loggedIn) if(Global.loggedIn)
homeScreenViewModel.Init() homeScreenViewModel.Init()
@@ -50,14 +52,14 @@ fun HomeScreen(homeScreenViewModel: HomeScreenViewModel = androidx.hilt.lifecycl
HorizontalDivider(Modifier.padding(8.dp), 2.dp, DividerDefaults.color) HorizontalDivider(Modifier.padding(8.dp), 2.dp, DividerDefaults.color)
for(i in RecentManager.recent) for(i in homeScreenViewModel.recentManager.recent)
{ {
MiniVideoCard( MiniVideoCard(
modifier = Modifier modifier = Modifier
.padding(horizontal = 12.dp), .padding(horizontal = 12.dp),
i, i,
{ {
updateRelate(RecentManager.recent, i) updateRelate(homeScreenViewModel.recentManager.recent, i)
val route = "video_player_route/${ "${i.klass}/${i.id}".toHex() }" val route = "video_player_route/${ "${i.klass}/${i.id}".toHex() }"
navController.navigate(route) navController.navigate(route)
}, homeScreenViewModel.imageLoader!!) }, homeScreenViewModel.imageLoader!!)

View File

@@ -200,7 +200,7 @@ fun MeScreen(meScreenViewModel: MeScreenViewModel = androidx.hilt.lifecycle.view
onClick = { onClick = {
meScreenViewModel.updateServer(url, cert, context) meScreenViewModel.updateServer(url, cert, context)
}, },
modifier = Modifier.weight(0.5f) modifier = Modifier.weight(0.5f).padding(8.dp)
) { ) {
Text("Save") Text("Save")
} }
@@ -213,7 +213,7 @@ fun MeScreen(meScreenViewModel: MeScreenViewModel = androidx.hilt.lifecycle.view
Log.i("Delay Analyze", "Abyss Hello: ${h.string()}") Log.i("Delay Analyze", "Abyss Hello: ${h.string()}")
} }
}, },
modifier = Modifier.weight(0.5f) modifier = Modifier.weight(0.5f).padding(8.dp)
) { ) {
Text("Ping") Text("Ping")
} }

View File

@@ -1,5 +1,6 @@
package com.acitelight.aether.view package com.acitelight.aether.view
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
@@ -30,6 +31,7 @@ import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.snapshots.SnapshotStateList import androidx.compose.runtime.snapshots.SnapshotStateList
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.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import com.acitelight.aether.model.DownloadItemState import com.acitelight.aether.model.DownloadItemState
@@ -72,7 +74,7 @@ private fun DownloadCard(
elevation = CardDefaults.cardElevation(4.dp), elevation = CardDefaults.cardElevation(4.dp),
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(8.dp) .padding(8.dp).background(Color.Transparent)
) { ) {
Column(modifier = Modifier Column(modifier = Modifier
.fillMaxWidth() .fillMaxWidth()

View File

@@ -95,6 +95,7 @@ import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import coil3.ImageLoader import coil3.ImageLoader
import coil3.compose.AsyncImage import coil3.compose.AsyncImage
import coil3.request.ImageRequest import coil3.request.ImageRequest
@@ -208,7 +209,7 @@ fun BiliMiniSlider(
@Composable @Composable
fun VideoPlayer( fun VideoPlayer(
videoPlayerViewModel: VideoPlayerViewModel = viewModel(), videoPlayerViewModel: VideoPlayerViewModel = hiltViewModel<VideoPlayerViewModel>(),
videoId: String, videoId: String,
navController: NavHostController navController: NavHostController
) { ) {

View File

@@ -1,5 +1,6 @@
package com.acitelight.aether.view package com.acitelight.aether.view
import android.widget.Toast
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.combinedClickable
@@ -127,6 +128,7 @@ fun VideoCard(video: Video, navController: NavHostController, videoScreenViewMod
}, },
onLongClick = { onLongClick = {
videoScreenViewModel.download(video) videoScreenViewModel.download(video)
Toast.makeText(videoScreenViewModel.context, "Start downloading ${video.video.name}", Toast.LENGTH_SHORT).show()
} }
), ),
shape = RoundedCornerShape(6.dp), shape = RoundedCornerShape(6.dp),

View File

@@ -15,9 +15,15 @@ import com.acitelight.aether.model.ComicRecord
import com.acitelight.aether.model.ComicRecordDatabase import com.acitelight.aether.model.ComicRecordDatabase
import com.acitelight.aether.service.ApiClient.createOkHttp import com.acitelight.aether.service.ApiClient.createOkHttp
import com.acitelight.aether.service.MediaManager import com.acitelight.aether.service.MediaManager
import com.acitelight.aether.service.RecentManager
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject
class ComicGridViewModel : ViewModel() @HiltViewModel
class ComicGridViewModel @Inject constructor(
val mediaManager: MediaManager
) : ViewModel()
{ {
var imageLoader: ImageLoader? = null var imageLoader: ImageLoader? = null
var comic = mutableStateOf<Comic?>(null) var comic = mutableStateOf<Comic?>(null)
@@ -47,12 +53,12 @@ class ComicGridViewModel : ViewModel()
{ {
viewModelScope.launch { viewModelScope.launch {
if(comic.value == null) { if(comic.value == null) {
comic.value = MediaManager.queryComicInfoSingle(id) comic.value = mediaManager.queryComicInfoSingle(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)
} }
}else comic.value = MediaManager.queryComicInfoSingle(id) }else comic.value = mediaManager.queryComicInfoSingle(id)
} }
} }

View File

@@ -1,5 +1,6 @@
package com.acitelight.aether.viewModel package com.acitelight.aether.viewModel
import android.content.Context
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.lazy.rememberLazyListState
@@ -21,11 +22,18 @@ import com.acitelight.aether.model.ComicRecord
import com.acitelight.aether.model.ComicRecordDatabase import com.acitelight.aether.model.ComicRecordDatabase
import com.acitelight.aether.service.ApiClient.createOkHttp import com.acitelight.aether.service.ApiClient.createOkHttp
import com.acitelight.aether.service.MediaManager import com.acitelight.aether.service.MediaManager
import com.acitelight.aether.service.SettingsDataStoreManager
import com.acitelight.aether.view.hexToString import com.acitelight.aether.view.hexToString
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject
class ComicPageViewModel : ViewModel() @HiltViewModel
class ComicPageViewModel @Inject constructor(
val mediaManager: MediaManager
) : ViewModel()
{ {
var imageLoader: ImageLoader? = null var imageLoader: ImageLoader? = null
var comic = mutableStateOf<Comic?>(null) var comic = mutableStateOf<Comic?>(null)
@@ -63,7 +71,7 @@ class ComicPageViewModel : ViewModel()
if(comic.value != null) return if(comic.value != null) return
LaunchedEffect(id, page) { LaunchedEffect(id, page) {
coroutineScope?.launch { coroutineScope?.launch {
comic.value = MediaManager.queryComicInfoSingle(id) comic.value = mediaManager.queryComicInfoSingle(id)
comic.value?.let { comic.value?.let {
pageList.addAll(it.comic.list) pageList.addAll(it.comic.list)
title.value = it.comic.comic_name title.value = it.comic.comic_name

View File

@@ -11,11 +11,16 @@ import com.acitelight.aether.model.Comic
import com.acitelight.aether.model.ComicResponse import com.acitelight.aether.model.ComicResponse
import com.acitelight.aether.service.ApiClient.createOkHttp import com.acitelight.aether.service.ApiClient.createOkHttp
import com.acitelight.aether.service.MediaManager import com.acitelight.aether.service.MediaManager
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject
class ComicScreenViewModel : ViewModel() { @HiltViewModel
class ComicScreenViewModel @Inject constructor(
val mediaManager: MediaManager
) : ViewModel() {
var imageLoader: ImageLoader? = null; var imageLoader: ImageLoader? = null;
@@ -56,8 +61,8 @@ class ComicScreenViewModel : ViewModel() {
init { init {
viewModelScope.launch { viewModelScope.launch {
val l = MediaManager.listComics() val l = mediaManager.listComics()
val m = MediaManager.queryComicInfoBulk(l) val m = mediaManager.queryComicInfoBulk(l)
if(m != null) { if(m != null) {
comics.addAll(m.sortedWith(compareBy(naturalOrder()) { it.comic.comic_name })) comics.addAll(m.sortedWith(compareBy(naturalOrder()) { it.comic.comic_name }))

View File

@@ -1,46 +1,23 @@
package com.acitelight.aether.viewModel package com.acitelight.aether.viewModel
import android.app.Application
import android.content.Context
import android.widget.Toast
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import coil3.ImageLoader import coil3.ImageLoader
import coil3.network.okhttp.OkHttpNetworkFetcherFactory import coil3.network.okhttp.OkHttpNetworkFetcherFactory
import okhttp3.OkHttpClient
import com.acitelight.aether.Global
import com.acitelight.aether.dataStore
import com.acitelight.aether.model.Video
import com.acitelight.aether.model.VideoQueryIndex
import com.acitelight.aether.service.ApiClient
import com.acitelight.aether.service.ApiClient.createOkHttp import com.acitelight.aether.service.ApiClient.createOkHttp
import com.acitelight.aether.service.AuthManager
import com.acitelight.aether.service.MediaManager
import com.acitelight.aether.service.MediaManager.token
import com.acitelight.aether.service.RecentManager import com.acitelight.aether.service.RecentManager
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject import javax.inject.Inject
import com.acitelight.aether.service.* 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
) : ViewModel() ) : ViewModel()
{ {
var _init = false var _init = false
@@ -59,7 +36,7 @@ class HomeScreenViewModel @Inject constructor(
.build() .build()
remember { remember {
viewModelScope.launch { viewModelScope.launch {
RecentManager.Query(context) recentManager.Query(context)
} }
} }
} }

View File

@@ -29,7 +29,8 @@ import dagger.hilt.android.qualifiers.ApplicationContext
@HiltViewModel @HiltViewModel
class MeScreenViewModel @Inject constructor( class MeScreenViewModel @Inject constructor(
private val settingsDataStoreManager: SettingsDataStoreManager, private val settingsDataStoreManager: SettingsDataStoreManager,
@ApplicationContext private val context: Context @ApplicationContext private val context: Context,
val mediaManager: MediaManager
) : ViewModel() { ) : ViewModel() {
val username = mutableStateOf(""); val username = mutableStateOf("");
@@ -51,8 +52,8 @@ class MeScreenViewModel @Inject constructor(
try{ try{
val usedUrl = ApiClient.apply(context, url.value, if(uss.first()) cert.value else "") val usedUrl = ApiClient.apply(context, url.value, if(uss.first()) cert.value else "")
if (MediaManager.token == "null") if (mediaManager.token == "null")
MediaManager.token = AuthManager.fetchToken( mediaManager.token = AuthManager.fetchToken(
username.value, username.value,
settingsDataStoreManager.privateKeyFlow.first() settingsDataStoreManager.privateKeyFlow.first()
)!! )!!
@@ -87,7 +88,7 @@ class MeScreenViewModel @Inject constructor(
try { try {
val usedUrl = ApiClient.apply(context, u, if(uss.first()) c else "") val usedUrl = ApiClient.apply(context, u, if(uss.first()) c else "")
MediaManager.token = AuthManager.fetchToken( mediaManager.token = AuthManager.fetchToken(
us, us,
p p
)!! )!!
@@ -117,7 +118,7 @@ class MeScreenViewModel @Inject constructor(
if (u == "" || p == "" || ur == "") return@launch if (u == "" || p == "" || ur == "") return@launch
try { try {
MediaManager.token = AuthManager.fetchToken( mediaManager.token = AuthManager.fetchToken(
u, u,
p p
)!! )!!

View File

@@ -29,12 +29,18 @@ import com.acitelight.aether.service.ApiClient.createOkHttp
import com.acitelight.aether.service.MediaManager import com.acitelight.aether.service.MediaManager
import com.acitelight.aether.service.RecentManager import com.acitelight.aether.service.RecentManager
import com.acitelight.aether.view.hexToString import com.acitelight.aether.view.hexToString
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject
class VideoPlayerViewModel() : ViewModel() @HiltViewModel
class VideoPlayerViewModel @Inject constructor(
val mediaManager: MediaManager,
val recentManager: RecentManager
) : ViewModel()
{ {
var tabIndex by mutableIntStateOf(0) var tabIndex by mutableIntStateOf(0)
var isPlaying by mutableStateOf(true) var isPlaying by mutableStateOf(true)
@@ -77,8 +83,8 @@ class VideoPlayerViewModel() : ViewModel()
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.Push(context, VideoQueryIndex(v.split("/")[0], v.split("/")[1]))
_player = ExoPlayer _player = ExoPlayer
.Builder(context) .Builder(context)
.setMediaSourceFactory(DefaultMediaSourceFactory(dataSourceFactory)) .setMediaSourceFactory(DefaultMediaSourceFactory(dataSourceFactory))

View File

@@ -1,43 +1,39 @@
package com.acitelight.aether.viewModel package com.acitelight.aether.viewModel
import android.app.Application import android.app.Application
import android.content.Context
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.State import androidx.compose.runtime.State
import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateMapOf import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.snapshots.SnapshotStateList import androidx.compose.runtime.snapshots.SnapshotStateList
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import coil3.ImageLoader import coil3.ImageLoader
import coil3.network.okhttp.OkHttpNetworkFetcherFactory import coil3.network.okhttp.OkHttpNetworkFetcherFactory
import com.acitelight.aether.dataStore
import com.acitelight.aether.helper.insertInNaturalOrder
import com.acitelight.aether.model.Video import com.acitelight.aether.model.Video
import com.acitelight.aether.service.ApiClient.createOkHttp import com.acitelight.aether.service.ApiClient.createOkHttp
import com.acitelight.aether.service.FetchManager import com.acitelight.aether.service.FetchManager
import com.acitelight.aether.service.MediaManager import com.acitelight.aether.service.MediaManager
import com.acitelight.aether.service.MediaManager.queryVideoKlasses import com.acitelight.aether.service.RecentManager
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.Flow import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject import javax.inject.Inject
@HiltViewModel @HiltViewModel
class VideoScreenViewModel @Inject constructor( class VideoScreenViewModel @Inject constructor(
private val fetchManager: FetchManager private val fetchManager: FetchManager,
@ApplicationContext val context: Context,
val mediaManager: MediaManager,
val recentManager: RecentManager
) : ViewModel() ) : ViewModel()
{ {
private val _tabIndex = mutableIntStateOf(0) private val _tabIndex = mutableIntStateOf(0)
val tabIndex: State<Int> = _tabIndex val tabIndex: State<Int> = _tabIndex
// val videos = mutableStateListOf<Video>() // val videos = mutableStateListOf<Video>()
// private val _klasses = MutableStateFlow<List<String>>(emptyList())
var classes = mutableStateListOf<String>() var classes = mutableStateListOf<String>()
val classesMap = mutableStateMapOf<String, SnapshotStateList<Video>>() val classesMap = mutableStateMapOf<String, SnapshotStateList<Video>>()
@@ -56,7 +52,7 @@ class VideoScreenViewModel @Inject constructor(
} }
suspend fun init() { suspend fun init() {
classes.addAll(MediaManager.listVideoKlasses()) classes.addAll(mediaManager.listVideoKlasses())
var i = 0 var i = 0
for(it in classes) for(it in classes)
{ {
@@ -64,7 +60,7 @@ class VideoScreenViewModel @Inject constructor(
classesMap[it] = mutableStateListOf<Video>() classesMap[it] = mutableStateListOf<Video>()
} }
updatingMap[0] = true updatingMap[0] = true
val vl = MediaManager.queryVideoBulk(classes[0], queryVideoKlasses(classes[0])) val vl = mediaManager.queryVideoBulk(classes[0], mediaManager.queryVideoKlasses(classes[0]))
if(vl != null){ if(vl != null){
val r = vl.sortedWith(compareBy(naturalOrder()) { it.video.name }) val r = vl.sortedWith(compareBy(naturalOrder()) { it.video.name })
@@ -81,7 +77,7 @@ class VideoScreenViewModel @Inject constructor(
updatingMap[index] = true updatingMap[index] = true
val vl = MediaManager.queryVideoBulk(classes[index], queryVideoKlasses(classes[index])) val vl = mediaManager.queryVideoBulk(classes[index], mediaManager.queryVideoKlasses(classes[index]))
if(vl != null){ if(vl != null){
val r = vl.sortedWith(compareBy(naturalOrder()) { it.video.name }) val r = vl.sortedWith(compareBy(naturalOrder()) { it.video.name })