Update music loading init process
Change the loading process so that LoadingViewModel no longer requires an application instance to start. Also move the main music loading code to an internal function.
This commit is contained in:
parent
2c93e3f362
commit
466629e43d
7 changed files with 43 additions and 54 deletions
|
@ -20,9 +20,7 @@ import org.oxycblt.auxio.music.MusicStore
|
||||||
* @author OxygenCobalt
|
* @author OxygenCobalt
|
||||||
*/
|
*/
|
||||||
class LoadingFragment : Fragment() {
|
class LoadingFragment : Fragment() {
|
||||||
private val loadingModel: LoadingViewModel by viewModels {
|
private val loadingModel: LoadingViewModel by viewModels()
|
||||||
LoadingViewModel.Factory(requireActivity().application)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
|
@ -71,7 +69,7 @@ class LoadingFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loadingModel.response.value == null) {
|
if (loadingModel.response.value == null) {
|
||||||
loadingModel.load()
|
loadingModel.load(requireContext())
|
||||||
}
|
}
|
||||||
|
|
||||||
return binding.root
|
return binding.root
|
||||||
|
@ -110,7 +108,7 @@ class LoadingFragment : Fragment() {
|
||||||
if (granted) {
|
if (granted) {
|
||||||
// If granted, its now safe to load, which will clear the NO_PERMS response
|
// If granted, its now safe to load, which will clear the NO_PERMS response
|
||||||
// we applied earlier.
|
// we applied earlier.
|
||||||
loadingModel.load()
|
loadingModel.load(requireContext())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
package org.oxycblt.auxio.loading
|
package org.oxycblt.auxio.loading
|
||||||
|
|
||||||
import android.app.Application
|
import android.content.Context
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.ViewModelProvider
|
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.oxycblt.auxio.music.MusicStore
|
import org.oxycblt.auxio.music.MusicStore
|
||||||
|
@ -13,7 +12,7 @@ import org.oxycblt.auxio.music.MusicStore
|
||||||
* ViewModel responsible for the loading UI and beginning the loading process overall.
|
* ViewModel responsible for the loading UI and beginning the loading process overall.
|
||||||
* @author OxygenCobalt
|
* @author OxygenCobalt
|
||||||
*/
|
*/
|
||||||
class LoadingViewModel(private val app: Application) : ViewModel() {
|
class LoadingViewModel : ViewModel() {
|
||||||
private val mResponse = MutableLiveData<MusicStore.Response?>(null)
|
private val mResponse = MutableLiveData<MusicStore.Response?>(null)
|
||||||
private val mDoGrant = MutableLiveData(false)
|
private val mDoGrant = MutableLiveData(false)
|
||||||
|
|
||||||
|
@ -27,9 +26,9 @@ class LoadingViewModel(private val app: Application) : ViewModel() {
|
||||||
private val musicStore = MusicStore.getInstance()
|
private val musicStore = MusicStore.getInstance()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Begin the music loading process. The response is pushed to [response]
|
* Begin the music loading process. The response from MusicStore is pushed to [response]
|
||||||
*/
|
*/
|
||||||
fun load() {
|
fun load(context: Context) {
|
||||||
// Dont start a new load if the last one hasnt finished
|
// Dont start a new load if the last one hasnt finished
|
||||||
if (isBusy) return
|
if (isBusy) return
|
||||||
|
|
||||||
|
@ -37,7 +36,7 @@ class LoadingViewModel(private val app: Application) : ViewModel() {
|
||||||
mResponse.value = null
|
mResponse.value = null
|
||||||
|
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
mResponse.value = musicStore.load(app)
|
mResponse.value = musicStore.load(context)
|
||||||
isBusy = false
|
isBusy = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,15 +61,4 @@ class LoadingViewModel(private val app: Application) : ViewModel() {
|
||||||
fun notifyNoPermissions() {
|
fun notifyNoPermissions() {
|
||||||
mResponse.value = MusicStore.Response.NO_PERMS
|
mResponse.value = MusicStore.Response.NO_PERMS
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
class Factory(private val application: Application) : ViewModelProvider.Factory {
|
|
||||||
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
|
|
||||||
if (modelClass.isAssignableFrom(LoadingViewModel::class.java)) {
|
|
||||||
return LoadingViewModel(application) as T
|
|
||||||
}
|
|
||||||
|
|
||||||
throw IllegalArgumentException("Unknown ViewModel class.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.oxycblt.auxio.music
|
package org.oxycblt.auxio.music
|
||||||
|
|
||||||
import android.app.Application
|
|
||||||
import android.content.ContentResolver
|
import android.content.ContentResolver
|
||||||
|
import android.content.Context
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.provider.OpenableColumns
|
import android.provider.OpenableColumns
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
@ -42,21 +42,27 @@ class MusicStore private constructor() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load/Sort the entire music library. Should always be ran on a coroutine.
|
* Load/Sort the entire music library. Should always be ran on a coroutine.
|
||||||
* @param app [Application] required to load the music.
|
|
||||||
*/
|
*/
|
||||||
suspend fun load(app: Application): Response {
|
suspend fun load(context: Context): Response {
|
||||||
return withContext(Dispatchers.IO) {
|
return withContext(Dispatchers.IO) {
|
||||||
// TODO: Move this to an internal function
|
loadMusicInternal(context)
|
||||||
this@MusicStore.logD("Starting initial music load...")
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val start = System.currentTimeMillis()
|
/**
|
||||||
|
* Do the internal music loading process.
|
||||||
|
*/
|
||||||
|
private fun loadMusicInternal(context: Context): Response {
|
||||||
|
logD("Starting initial music load...")
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val loader = MusicLoader(app)
|
val start = System.currentTimeMillis()
|
||||||
|
|
||||||
|
val loader = MusicLoader(context)
|
||||||
loader.load()
|
loader.load()
|
||||||
|
|
||||||
if (loader.songs.isEmpty()) {
|
if (loader.songs.isEmpty()) {
|
||||||
return@withContext Response.NO_MUSIC
|
return Response.NO_MUSIC
|
||||||
}
|
}
|
||||||
|
|
||||||
mSongs = loader.songs
|
mSongs = loader.songs
|
||||||
|
@ -64,20 +70,17 @@ class MusicStore private constructor() {
|
||||||
mArtists = loader.artists
|
mArtists = loader.artists
|
||||||
mGenres = loader.genres
|
mGenres = loader.genres
|
||||||
|
|
||||||
this@MusicStore.logD(
|
logD("Music load completed successfully in ${System.currentTimeMillis() - start}ms.")
|
||||||
"Music load completed successfully in ${System.currentTimeMillis() - start}ms."
|
|
||||||
)
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
logE("Something went horribly wrong.")
|
logE("Something went horribly wrong.")
|
||||||
logE(e.stackTraceToString())
|
logE(e.stackTraceToString())
|
||||||
|
|
||||||
return@withContext Response.FAILED
|
return Response.FAILED
|
||||||
}
|
}
|
||||||
|
|
||||||
loaded = true
|
loaded = true
|
||||||
|
|
||||||
return@withContext Response.SUCCESS
|
return Response.SUCCESS
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -12,8 +12,8 @@ import org.oxycblt.auxio.R
|
||||||
import org.oxycblt.auxio.ui.getPlural
|
import org.oxycblt.auxio.ui.getPlural
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of ID3 genres + Winamp extensions, each index corresponds to their int value.
|
* A complete array of all the hardcoded genre values for ID3 <v3, contains standard genres and
|
||||||
* There are a lot more int-genre extensions as far as Im aware, but this works for most cases.
|
* winamp extensions.
|
||||||
*/
|
*/
|
||||||
private val ID3_GENRES = arrayOf(
|
private val ID3_GENRES = arrayOf(
|
||||||
// ID3 Standard
|
// ID3 Standard
|
||||||
|
|
|
@ -172,6 +172,8 @@ class PlaybackViewModel : ViewModel(), PlaybackStateManager.Callback {
|
||||||
if (playbackManager.isRestored && musicStore.loaded) {
|
if (playbackManager.isRestored && musicStore.loaded) {
|
||||||
playWithUriInternal(uri, context)
|
playWithUriInternal(uri, context)
|
||||||
} else {
|
} else {
|
||||||
|
logD("Cant play this URI right now, waiting...")
|
||||||
|
|
||||||
mIntentUri = uri
|
mIntentUri = uri
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -247,8 +247,6 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateManager.Ca
|
||||||
|
|
||||||
notification.setPlaying(this, isPlaying)
|
notification.setPlaying(this, isPlaying)
|
||||||
startForegroundOrNotify()
|
startForegroundOrNotify()
|
||||||
|
|
||||||
logD("Playing Status: $isPlaying")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onLoopUpdate(loopMode: LoopMode) {
|
override fun onLoopUpdate(loopMode: LoopMode) {
|
||||||
|
|
|
@ -53,7 +53,7 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:fontFamily="@font/inter_semibold"
|
android:fontFamily="@font/inter_semibold"
|
||||||
android:onClick="@{() -> loadingModel.load()}"
|
android:onClick="@{() -> loadingModel.load(context)}"
|
||||||
android:text="@string/label_retry"
|
android:text="@string/label_retry"
|
||||||
android:textColor="?attr/colorPrimary"
|
android:textColor="?attr/colorPrimary"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
|
|
Loading…
Reference in a new issue