mirror of
https://github.com/Shabinder/SpotiFlyer.git
synced 2024-11-26 02:24:31 +01:00
MutableSharedFlow,Active Tracks Query ,etc fixes
This commit is contained in:
parent
1b58bbfcf0
commit
f7e71da827
@ -33,8 +33,7 @@ import com.shabinder.common.ui.colorOffWhite
|
|||||||
import com.shabinder.database.Database
|
import com.shabinder.database.Database
|
||||||
import com.tonyodev.fetch2.Status
|
import com.tonyodev.fetch2.Status
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.*
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
|
|
||||||
const val disableDozeCode = 1223
|
const val disableDozeCode = 1223
|
||||||
@ -47,8 +46,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
private lateinit var root: SpotiFlyerRoot
|
private lateinit var root: SpotiFlyerRoot
|
||||||
private val callBacks: SpotiFlyerRootCallBacks
|
private val callBacks: SpotiFlyerRootCallBacks
|
||||||
get() = root.callBacks
|
get() = root.callBacks
|
||||||
//TODO pass updates from Foreground Service
|
private val trackStatusFlow = MutableSharedFlow<HashMap<String, DownloadStatus>>(1)
|
||||||
private val downloadFlow = MutableStateFlow(hashMapOf<String, DownloadStatus>())
|
|
||||||
|
|
||||||
private lateinit var updateUIReceiver: BroadcastReceiver
|
private lateinit var updateUIReceiver: BroadcastReceiver
|
||||||
private lateinit var queryReceiver: BroadcastReceiver
|
private lateinit var queryReceiver: BroadcastReceiver
|
||||||
@ -80,7 +78,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
override val database = this@MainActivity.database
|
override val database = this@MainActivity.database
|
||||||
override val fetchPlatformQueryResult = this@MainActivity.fetcher
|
override val fetchPlatformQueryResult = this@MainActivity.fetcher
|
||||||
override val directories: Dir = this@MainActivity.dir
|
override val directories: Dir = this@MainActivity.dir
|
||||||
override val downloadProgressReport: StateFlow<HashMap<String, DownloadStatus>> = downloadFlow
|
override val downloadProgressReport: MutableSharedFlow<HashMap<String, DownloadStatus>> = trackStatusFlow
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -108,9 +106,9 @@ class MainActivity : ComponentActivity() {
|
|||||||
addAction(Status.QUEUED.name)
|
addAction(Status.QUEUED.name)
|
||||||
addAction(Status.FAILED.name)
|
addAction(Status.FAILED.name)
|
||||||
addAction(Status.DOWNLOADING.name)
|
addAction(Status.DOWNLOADING.name)
|
||||||
|
addAction(Status.COMPLETED.name)
|
||||||
addAction("Progress")
|
addAction("Progress")
|
||||||
addAction("Converting")
|
addAction("Converting")
|
||||||
addAction("track_download_completed")
|
|
||||||
}
|
}
|
||||||
updateUIReceiver = object : BroadcastReceiver() {
|
updateUIReceiver = object : BroadcastReceiver() {
|
||||||
override fun onReceive(context: Context?, intent: Intent?) {
|
override fun onReceive(context: Context?, intent: Intent?) {
|
||||||
@ -119,18 +117,20 @@ class MainActivity : ComponentActivity() {
|
|||||||
val trackDetails = intent.getParcelableExtra<TrackDetails?>("track")
|
val trackDetails = intent.getParcelableExtra<TrackDetails?>("track")
|
||||||
trackDetails?.let { track ->
|
trackDetails?.let { track ->
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
val latestMap = downloadFlow.value.apply {
|
val latestMap = trackStatusFlow.replayCache.getOrElse(0
|
||||||
|
) { hashMapOf() }.apply {
|
||||||
this[track.title] = when (intent.action) {
|
this[track.title] = when (intent.action) {
|
||||||
Status.QUEUED.name -> DownloadStatus.Queued
|
Status.QUEUED.name -> DownloadStatus.Queued
|
||||||
Status.FAILED.name -> DownloadStatus.Failed
|
Status.FAILED.name -> DownloadStatus.Failed
|
||||||
Status.DOWNLOADING.name -> DownloadStatus.Downloading()
|
Status.DOWNLOADING.name -> DownloadStatus.Downloading()
|
||||||
"Progress" -> DownloadStatus.Downloading(intent.getIntExtra("progress", 0))
|
"Progress" -> DownloadStatus.Downloading(intent.getIntExtra("progress", 0))
|
||||||
"Converting" -> DownloadStatus.Converting
|
"Converting" -> DownloadStatus.Converting
|
||||||
"track_download_completed" -> DownloadStatus.Downloaded
|
Status.COMPLETED.name -> DownloadStatus.Downloaded
|
||||||
else -> DownloadStatus.NotDownloaded
|
else -> DownloadStatus.NotDownloaded
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
downloadFlow.emit(latestMap)
|
trackStatusFlow.emit(latestMap)
|
||||||
|
Log.i("Track Update",track.title + track.downloaded.toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -146,7 +146,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
trackList?.let { list ->
|
trackList?.let { list ->
|
||||||
Log.i("Service Response", "${list.size} Tracks Active")
|
Log.i("Service Response", "${list.size} Tracks Active")
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
downloadFlow.emit(list)
|
trackStatusFlow.emit(list)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import com.shabinder.common.utils.Consumer
|
|||||||
import com.shabinder.common.models.PlatformQueryResult
|
import com.shabinder.common.models.PlatformQueryResult
|
||||||
import com.shabinder.common.models.TrackDetails
|
import com.shabinder.common.models.TrackDetails
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
|
||||||
interface SpotiFlyerList {
|
interface SpotiFlyerList {
|
||||||
@ -40,13 +41,18 @@ interface SpotiFlyerList {
|
|||||||
* */
|
* */
|
||||||
suspend fun loadImage(url:String): ImageBitmap?
|
suspend fun loadImage(url:String): ImageBitmap?
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync Tracks Statuses
|
||||||
|
* */
|
||||||
|
fun onRefreshTracksStatuses()
|
||||||
|
|
||||||
interface Dependencies {
|
interface Dependencies {
|
||||||
val storeFactory: StoreFactory
|
val storeFactory: StoreFactory
|
||||||
val fetchQuery: FetchPlatformQueryResult
|
val fetchQuery: FetchPlatformQueryResult
|
||||||
val dir: Dir
|
val dir: Dir
|
||||||
val link: String
|
val link: String
|
||||||
val listOutput: Consumer<Output>
|
val listOutput: Consumer<Output>
|
||||||
val downloadProgressFlow: StateFlow<HashMap<String,DownloadStatus>>
|
val downloadProgressFlow: MutableSharedFlow<HashMap<String, DownloadStatus>>
|
||||||
}
|
}
|
||||||
sealed class Output {
|
sealed class Output {
|
||||||
object Finished : Output()
|
object Finished : Output()
|
||||||
|
@ -42,5 +42,9 @@ internal class SpotiFlyerListImpl(
|
|||||||
listOutput.callback(SpotiFlyerList.Output.Finished)
|
listOutput.callback(SpotiFlyerList.Output.Finished)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onRefreshTracksStatuses() {
|
||||||
|
store.accept(Intent.RefreshTracksStatuses)
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun loadImage(url: String): ImageBitmap? = dir.loadImage(url)
|
override suspend fun loadImage(url: String): ImageBitmap? = dir.loadImage(url)
|
||||||
}
|
}
|
@ -10,5 +10,6 @@ internal interface SpotiFlyerListStore: Store<Intent, State, Nothing> {
|
|||||||
data class SearchLink(val link: String): Intent()
|
data class SearchLink(val link: String): Intent()
|
||||||
data class StartDownload(val track:TrackDetails): Intent()
|
data class StartDownload(val track:TrackDetails): Intent()
|
||||||
data class StartDownloadAll(val trackList: List<TrackDetails>): Intent()
|
data class StartDownloadAll(val trackList: List<TrackDetails>): Intent()
|
||||||
|
object RefreshTracksStatuses: Intent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,15 +4,18 @@ import androidx.compose.runtime.mutableStateListOf
|
|||||||
import androidx.compose.runtime.snapshots.SnapshotStateList
|
import androidx.compose.runtime.snapshots.SnapshotStateList
|
||||||
import com.arkivanov.mvikotlin.core.store.*
|
import com.arkivanov.mvikotlin.core.store.*
|
||||||
import com.arkivanov.mvikotlin.extensions.coroutines.SuspendExecutor
|
import com.arkivanov.mvikotlin.extensions.coroutines.SuspendExecutor
|
||||||
|
import com.shabinder.common.database.getLogger
|
||||||
import com.shabinder.common.di.Dir
|
import com.shabinder.common.di.Dir
|
||||||
import com.shabinder.common.di.FetchPlatformQueryResult
|
import com.shabinder.common.di.FetchPlatformQueryResult
|
||||||
import com.shabinder.common.di.downloadTracks
|
import com.shabinder.common.di.downloadTracks
|
||||||
|
import com.shabinder.common.di.queryActiveTracks
|
||||||
import com.shabinder.common.list.SpotiFlyerList.State
|
import com.shabinder.common.list.SpotiFlyerList.State
|
||||||
import com.shabinder.common.list.store.SpotiFlyerListStore.Intent
|
import com.shabinder.common.list.store.SpotiFlyerListStore.Intent
|
||||||
import com.shabinder.common.models.DownloadStatus
|
import com.shabinder.common.models.DownloadStatus
|
||||||
import com.shabinder.common.models.PlatformQueryResult
|
import com.shabinder.common.models.PlatformQueryResult
|
||||||
import com.shabinder.common.models.TrackDetails
|
import com.shabinder.common.models.TrackDetails
|
||||||
import com.shabinder.common.ui.showPopUpMessage
|
import com.shabinder.common.ui.showPopUpMessage
|
||||||
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
|
|
||||||
@ -21,8 +24,9 @@ internal class SpotiFlyerListStoreProvider(
|
|||||||
private val storeFactory: StoreFactory,
|
private val storeFactory: StoreFactory,
|
||||||
private val fetchQuery: FetchPlatformQueryResult,
|
private val fetchQuery: FetchPlatformQueryResult,
|
||||||
private val link: String,
|
private val link: String,
|
||||||
private val downloadProgressFlow: StateFlow<HashMap<String, DownloadStatus>>
|
private val downloadProgressFlow: MutableSharedFlow<HashMap<String, DownloadStatus>>
|
||||||
) {
|
) {
|
||||||
|
val logger = getLogger()
|
||||||
fun provide(): SpotiFlyerListStore =
|
fun provide(): SpotiFlyerListStore =
|
||||||
object : SpotiFlyerListStore, Store<Intent, State, Nothing> by storeFactory.create(
|
object : SpotiFlyerListStore, Store<Intent, State, Nothing> by storeFactory.create(
|
||||||
name = "SpotiFlyerListStore",
|
name = "SpotiFlyerListStore",
|
||||||
@ -42,8 +46,10 @@ internal class SpotiFlyerListStoreProvider(
|
|||||||
|
|
||||||
override suspend fun executeAction(action: Unit, getState: () -> State) {
|
override suspend fun executeAction(action: Unit, getState: () -> State) {
|
||||||
executeIntent(Intent.SearchLink(link),getState)
|
executeIntent(Intent.SearchLink(link),getState)
|
||||||
|
executeIntent(Intent.RefreshTracksStatuses,getState)
|
||||||
|
|
||||||
downloadProgressFlow.collectLatest { map ->
|
downloadProgressFlow.collectLatest { map ->
|
||||||
|
logger.d(map.size.toString(),"ListStore: flow Updated")
|
||||||
val updatedTrackList = getState().trackList.updateTracksStatuses(map)
|
val updatedTrackList = getState().trackList.updateTracksStatuses(map)
|
||||||
if(updatedTrackList.isNotEmpty()) dispatch(Result.UpdateTrackList(updatedTrackList))
|
if(updatedTrackList.isNotEmpty()) dispatch(Result.UpdateTrackList(updatedTrackList))
|
||||||
}
|
}
|
||||||
@ -53,7 +59,7 @@ internal class SpotiFlyerListStoreProvider(
|
|||||||
when (intent) {
|
when (intent) {
|
||||||
is Intent.SearchLink -> fetchQuery.query(link)?.let{ result ->
|
is Intent.SearchLink -> fetchQuery.query(link)?.let{ result ->
|
||||||
result.trackList = result.trackList.toMutableList()
|
result.trackList = result.trackList.toMutableList()
|
||||||
dispatch((Result.ResultFetched(result,result.trackList.toMutableList().updateTracksStatuses(downloadProgressFlow.value))))
|
dispatch((Result.ResultFetched(result,result.trackList.toMutableList().updateTracksStatuses(downloadProgressFlow.replayCache.getOrElse(0){ hashMapOf()}))))
|
||||||
}
|
}
|
||||||
|
|
||||||
is Intent.StartDownloadAll -> {
|
is Intent.StartDownloadAll -> {
|
||||||
@ -68,12 +74,13 @@ internal class SpotiFlyerListStoreProvider(
|
|||||||
}
|
}
|
||||||
it
|
it
|
||||||
}
|
}
|
||||||
dispatch(Result.UpdateTrackList(list.toMutableList().updateTracksStatuses(downloadProgressFlow.value)))
|
dispatch(Result.UpdateTrackList(list.toMutableList().updateTracksStatuses(downloadProgressFlow.replayCache.getOrElse(0){ hashMapOf()})))
|
||||||
}
|
}
|
||||||
is Intent.StartDownload -> {
|
is Intent.StartDownload -> {
|
||||||
downloadTracks(listOf(intent.track),fetchQuery.youtubeMusic::getYTIDBestMatch,dir::saveFileWithMetadata)
|
downloadTracks(listOf(intent.track),fetchQuery.youtubeMusic::getYTIDBestMatch,dir::saveFileWithMetadata)
|
||||||
dispatch(Result.UpdateTrackItem(intent.track.apply { downloaded = DownloadStatus.Queued }))
|
dispatch(Result.UpdateTrackItem(intent.track.apply { downloaded = DownloadStatus.Queued }))
|
||||||
}
|
}
|
||||||
|
is Intent.RefreshTracksStatuses -> queryActiveTracks()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -93,18 +100,18 @@ internal class SpotiFlyerListStoreProvider(
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
private fun MutableList<TrackDetails>.updateTracksStatuses(map:HashMap<String,DownloadStatus>):SnapshotStateList<TrackDetails>{
|
||||||
|
val titleList = this.map { it.title }
|
||||||
private fun MutableList<TrackDetails>.updateTracksStatuses(map:HashMap<String,DownloadStatus>):SnapshotStateList<TrackDetails>{
|
val newStateList = mutableStateListOf<TrackDetails>()
|
||||||
val titleList = this.map { it.title }
|
for(newTrack in map){
|
||||||
val newStateList = mutableStateListOf<TrackDetails>()
|
titleList.indexOf(newTrack.key).let { position ->
|
||||||
for(newTrack in map){
|
this.getOrNull(position)?.apply { downloaded = newTrack.value }?.also { updatedTrack ->
|
||||||
titleList.indexOf(newTrack.key).let { position ->
|
this[position] = updatedTrack
|
||||||
this.getOrNull(position)?.apply { downloaded = newTrack.value }?.also { updatedTrack ->
|
logger.d(updatedTrack.toString(),"List Store Track Update")
|
||||||
this[position] = updatedTrack
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
newStateList.addAll(this)
|
||||||
|
return newStateList
|
||||||
}
|
}
|
||||||
newStateList.addAll(this)
|
|
||||||
return newStateList
|
|
||||||
}
|
}
|
@ -53,7 +53,7 @@ fun SpotiFlyerMainContent(component: SpotiFlyerMain){
|
|||||||
when(model.selectedCategory){
|
when(model.selectedCategory){
|
||||||
HomeCategory.About -> AboutColumn()
|
HomeCategory.About -> AboutColumn()
|
||||||
HomeCategory.History -> HistoryColumn(
|
HomeCategory.History -> HistoryColumn(
|
||||||
model.records,
|
model.records.sortedByDescending { it.id },
|
||||||
component::loadImage,
|
component::loadImage,
|
||||||
component::onLinkSearch
|
component::onLinkSearch
|
||||||
)
|
)
|
||||||
|
@ -14,6 +14,7 @@ import com.shabinder.common.root.callbacks.SpotiFlyerRootCallBacks
|
|||||||
import com.shabinder.database.Database
|
import com.shabinder.database.Database
|
||||||
import com.shabinder.common.root.integration.SpotiFlyerRootImpl
|
import com.shabinder.common.root.integration.SpotiFlyerRootImpl
|
||||||
import com.shabinder.common.utils.Consumer
|
import com.shabinder.common.utils.Consumer
|
||||||
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
|
||||||
interface SpotiFlyerRoot {
|
interface SpotiFlyerRoot {
|
||||||
@ -32,7 +33,7 @@ interface SpotiFlyerRoot {
|
|||||||
val database: Database
|
val database: Database
|
||||||
val fetchPlatformQueryResult: FetchPlatformQueryResult
|
val fetchPlatformQueryResult: FetchPlatformQueryResult
|
||||||
val directories: Dir
|
val directories: Dir
|
||||||
val downloadProgressReport: StateFlow<HashMap<String,DownloadStatus>>
|
val downloadProgressReport: MutableSharedFlow<HashMap<String, DownloadStatus>>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.shabinder.common.root.integration
|
package com.shabinder.common.root.integration
|
||||||
|
|
||||||
|
import co.touchlab.kermit.Kermit
|
||||||
import com.arkivanov.decompose.ComponentContext
|
import com.arkivanov.decompose.ComponentContext
|
||||||
import com.arkivanov.decompose.RouterState
|
import com.arkivanov.decompose.RouterState
|
||||||
import com.arkivanov.decompose.pop
|
import com.arkivanov.decompose.pop
|
||||||
@ -8,6 +9,7 @@ import com.arkivanov.decompose.router
|
|||||||
import com.arkivanov.decompose.statekeeper.Parcelable
|
import com.arkivanov.decompose.statekeeper.Parcelable
|
||||||
import com.arkivanov.decompose.statekeeper.Parcelize
|
import com.arkivanov.decompose.statekeeper.Parcelize
|
||||||
import com.arkivanov.decompose.value.Value
|
import com.arkivanov.decompose.value.Value
|
||||||
|
import com.shabinder.common.database.getLogger
|
||||||
import com.shabinder.common.di.Dir
|
import com.shabinder.common.di.Dir
|
||||||
import com.shabinder.common.list.SpotiFlyerList
|
import com.shabinder.common.list.SpotiFlyerList
|
||||||
import com.shabinder.common.main.SpotiFlyerMain
|
import com.shabinder.common.main.SpotiFlyerMain
|
||||||
|
@ -41,6 +41,13 @@ actual fun giveDonation(){
|
|||||||
//TODO
|
//TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
actual fun queryActiveTracks() {
|
||||||
|
val serviceIntent = Intent(appContext, ForegroundService::class.java).apply {
|
||||||
|
action = "query"
|
||||||
|
}
|
||||||
|
ContextCompat.startForegroundService(appContext, serviceIntent)
|
||||||
|
}
|
||||||
|
|
||||||
actual suspend fun downloadTracks(
|
actual suspend fun downloadTracks(
|
||||||
list: List<TrackDetails>,
|
list: List<TrackDetails>,
|
||||||
getYTIDBestMatch:suspend (String,TrackDetails)->String?,
|
getYTIDBestMatch:suspend (String,TrackDetails)->String?,
|
||||||
|
@ -251,25 +251,30 @@ class ForegroundService : Service(),CoroutineScope{
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onCompleted(download: Download) {
|
override fun onCompleted(download: Download) {
|
||||||
launch {
|
val track = requestMap[download.request]
|
||||||
val track = requestMap[download.request]
|
try{
|
||||||
removeFromNotification("Downloading ${track?.title}")
|
track?.let {
|
||||||
try{
|
val job = launch { dir.saveFileWithMetadata(byteArrayOf(),it) }
|
||||||
track?.let {
|
allTracksStatus[it.title] = DownloadStatus.Converting
|
||||||
dir.saveFileWithMetadata(byteArrayOf(),it)
|
sendTrackBroadcast("Converting",it)
|
||||||
allTracksStatus[it.title] = DownloadStatus.Converting
|
addToNotification("Processing ${it.title}")
|
||||||
|
job.invokeOnCompletion { _ ->
|
||||||
|
converted++
|
||||||
|
sendTrackBroadcast(Status.COMPLETED.name,it)
|
||||||
|
removeFromNotification("Processing ${it.title}")
|
||||||
}
|
}
|
||||||
logger.d(tag){"${track?.title} Download Completed"}
|
|
||||||
}catch (
|
|
||||||
e: KotlinNullPointerException
|
|
||||||
){
|
|
||||||
logger.d(tag){"${track?.title} Download Failed! Error:Fetch!!!!"}
|
|
||||||
logger.d(tag){"${track?.title} Requesting Download thru Android DM"}
|
|
||||||
downloadUsingDM(download.request.url, download.request.file, track!!)
|
|
||||||
downloaded++
|
|
||||||
requestMap.remove(download.request)
|
|
||||||
}
|
}
|
||||||
|
logger.d(tag){"${track?.title} Download Completed"}
|
||||||
|
}catch (
|
||||||
|
e: KotlinNullPointerException
|
||||||
|
){
|
||||||
|
logger.d(tag){"${track?.title} Download Failed! Error:Fetch!!!!"}
|
||||||
|
logger.d(tag){"${track?.title} Requesting Download thru Android DM"}
|
||||||
|
downloadUsingDM(download.request.url, download.request.file, track!!)
|
||||||
}
|
}
|
||||||
|
downloaded++
|
||||||
|
requestMap.remove(download.request)
|
||||||
|
removeFromNotification("Downloading ${track?.title}")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDeleted(download: Download) {
|
override fun onDeleted(download: Download) {
|
||||||
@ -427,7 +432,7 @@ class ForegroundService : Service(),CoroutineScope{
|
|||||||
fetch.removeAll()
|
fetch.removeAll()
|
||||||
updateNotification()
|
updateNotification()
|
||||||
cleanFiles(File(dir.defaultDir()))
|
cleanFiles(File(dir.defaultDir()))
|
||||||
cleanFiles(File(dir.imageCacheDir()))
|
//TODO cleanFiles(File(dir.imageCacheDir()))
|
||||||
messageList = mutableListOf("","","","","")
|
messageList = mutableListOf("","","","","")
|
||||||
releaseWakeLock()
|
releaseWakeLock()
|
||||||
serviceJob.cancel()
|
serviceJob.cancel()
|
||||||
|
@ -13,3 +13,5 @@ expect suspend fun downloadTracks(
|
|||||||
getYTIDBestMatch:suspend (String,TrackDetails)->String?,
|
getYTIDBestMatch:suspend (String,TrackDetails)->String?,
|
||||||
saveFileWithMetaData:suspend (mp3ByteArray:ByteArray, trackDetails: TrackDetails) -> Unit
|
saveFileWithMetaData:suspend (mp3ByteArray:ByteArray, trackDetails: TrackDetails) -> Unit
|
||||||
)
|
)
|
||||||
|
|
||||||
|
expect fun queryActiveTracks()
|
@ -242,7 +242,7 @@ class YoutubeMusic constructor(
|
|||||||
val avgMatch = (artistMatch + durationMatch)/2
|
val avgMatch = (artistMatch + durationMatch)/2
|
||||||
linksWithMatchValue[result.videoId.toString()] = avgMatch.toInt()
|
linksWithMatchValue[result.videoId.toString()] = avgMatch.toInt()
|
||||||
}
|
}
|
||||||
logger.d("YT Api Result"){"$trackName - $linksWithMatchValue"}
|
//logger.d("YT Api Result"){"$trackName - $linksWithMatchValue"}
|
||||||
return linksWithMatchValue.toList().sortedByDescending { it.second }.toMap()
|
return linksWithMatchValue.toList().sortedByDescending { it.second }.toMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,9 @@ actual fun giveDonation(){
|
|||||||
//TODO
|
//TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
val DownloadProgressFlow: MutableStateFlow<HashMap<String,DownloadStatus>> = MutableStateFlow(hashMapOf())
|
actual fun queryActiveTracks(){}
|
||||||
|
|
||||||
|
val DownloadProgressFlow: MutableSharedFlow<HashMap<String,DownloadStatus>> = MutableSharedFlow(1)
|
||||||
|
|
||||||
actual suspend fun downloadTracks(
|
actual suspend fun downloadTracks(
|
||||||
list: List<TrackDetails>,
|
list: List<TrackDetails>,
|
||||||
@ -36,7 +38,8 @@ actual suspend fun downloadTracks(
|
|||||||
val searchQuery = "${it.title} - ${it.artists.joinToString(",")}"
|
val searchQuery = "${it.title} - ${it.artists.joinToString(",")}"
|
||||||
val videoId = getYTIDBestMatch(searchQuery,it)
|
val videoId = getYTIDBestMatch(searchQuery,it)
|
||||||
if (videoId.isNullOrBlank()) {
|
if (videoId.isNullOrBlank()) {
|
||||||
DownloadProgressFlow.emit(DownloadProgressFlow.value.apply { set(it.title,DownloadStatus.Failed) })
|
DownloadProgressFlow.emit(DownloadProgressFlow.replayCache.getOrElse(0
|
||||||
|
) { hashMapOf() }.apply { set(it.title,DownloadStatus.Failed) })
|
||||||
} else {//Found Youtube Video ID
|
} else {//Found Youtube Video ID
|
||||||
downloadTrack(videoId, it,saveFileWithMetaData)
|
downloadTrack(videoId, it,saveFileWithMetaData)
|
||||||
}
|
}
|
||||||
@ -59,14 +62,17 @@ suspend fun downloadTrack(
|
|||||||
downloadFile(url).collect {
|
downloadFile(url).collect {
|
||||||
when(it){
|
when(it){
|
||||||
is DownloadResult.Error -> {
|
is DownloadResult.Error -> {
|
||||||
DownloadProgressFlow.emit(DownloadProgressFlow.value.apply { set(trackDetails.title,DownloadStatus.Failed) })
|
DownloadProgressFlow.emit(DownloadProgressFlow.replayCache.getOrElse(0
|
||||||
|
) { hashMapOf() }.apply { set(trackDetails.title,DownloadStatus.Failed) })
|
||||||
}
|
}
|
||||||
is DownloadResult.Progress -> {
|
is DownloadResult.Progress -> {
|
||||||
DownloadProgressFlow.emit(DownloadProgressFlow.value.apply { set(trackDetails.title,DownloadStatus.Downloading(it.progress)) })
|
DownloadProgressFlow.emit(DownloadProgressFlow.replayCache.getOrElse(0
|
||||||
|
) { hashMapOf() }.apply { set(trackDetails.title,DownloadStatus.Downloading(it.progress)) })
|
||||||
}
|
}
|
||||||
is DownloadResult.Success -> {//Todo clear map
|
is DownloadResult.Success -> {//Todo clear map
|
||||||
saveFileWithMetaData(it.byteArray,trackDetails)
|
saveFileWithMetaData(it.byteArray,trackDetails)
|
||||||
DownloadProgressFlow.emit(DownloadProgressFlow.value.apply { set(trackDetails.title,DownloadStatus.Downloaded) })
|
DownloadProgressFlow.emit(DownloadProgressFlow.replayCache.getOrElse(0
|
||||||
|
) { hashMapOf() }.apply { set(trackDetails.title,DownloadStatus.Downloaded) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user