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
|
||||
*/
|
||||
class LoadingFragment : Fragment() {
|
||||
private val loadingModel: LoadingViewModel by viewModels {
|
||||
LoadingViewModel.Factory(requireActivity().application)
|
||||
}
|
||||
private val loadingModel: LoadingViewModel by viewModels()
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
|
@ -71,7 +69,7 @@ class LoadingFragment : Fragment() {
|
|||
}
|
||||
|
||||
if (loadingModel.response.value == null) {
|
||||
loadingModel.load()
|
||||
loadingModel.load(requireContext())
|
||||
}
|
||||
|
||||
return binding.root
|
||||
|
@ -110,7 +108,7 @@ class LoadingFragment : Fragment() {
|
|||
if (granted) {
|
||||
// If granted, its now safe to load, which will clear the NO_PERMS response
|
||||
// we applied earlier.
|
||||
loadingModel.load()
|
||||
loadingModel.load(requireContext())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
package org.oxycblt.auxio.loading
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import kotlinx.coroutines.launch
|
||||
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.
|
||||
* @author OxygenCobalt
|
||||
*/
|
||||
class LoadingViewModel(private val app: Application) : ViewModel() {
|
||||
class LoadingViewModel : ViewModel() {
|
||||
private val mResponse = MutableLiveData<MusicStore.Response?>(null)
|
||||
private val mDoGrant = MutableLiveData(false)
|
||||
|
||||
|
@ -27,9 +26,9 @@ class LoadingViewModel(private val app: Application) : ViewModel() {
|
|||
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
|
||||
if (isBusy) return
|
||||
|
||||
|
@ -37,7 +36,7 @@ class LoadingViewModel(private val app: Application) : ViewModel() {
|
|||
mResponse.value = null
|
||||
|
||||
viewModelScope.launch {
|
||||
mResponse.value = musicStore.load(app)
|
||||
mResponse.value = musicStore.load(context)
|
||||
isBusy = false
|
||||
}
|
||||
}
|
||||
|
@ -62,15 +61,4 @@ class LoadingViewModel(private val app: Application) : ViewModel() {
|
|||
fun notifyNoPermissions() {
|
||||
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
|
||||
|
||||
import android.app.Application
|
||||
import android.content.ContentResolver
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.provider.OpenableColumns
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
@ -42,42 +42,45 @@ class MusicStore private constructor() {
|
|||
|
||||
/**
|
||||
* 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) {
|
||||
// TODO: Move this to an internal function
|
||||
this@MusicStore.logD("Starting initial music load...")
|
||||
loadMusicInternal(context)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do the internal music loading process.
|
||||
*/
|
||||
private fun loadMusicInternal(context: Context): Response {
|
||||
logD("Starting initial music load...")
|
||||
|
||||
try {
|
||||
val start = System.currentTimeMillis()
|
||||
|
||||
try {
|
||||
val loader = MusicLoader(app)
|
||||
loader.load()
|
||||
val loader = MusicLoader(context)
|
||||
loader.load()
|
||||
|
||||
if (loader.songs.isEmpty()) {
|
||||
return@withContext Response.NO_MUSIC
|
||||
}
|
||||
|
||||
mSongs = loader.songs
|
||||
mAlbums = loader.albums
|
||||
mArtists = loader.artists
|
||||
mGenres = loader.genres
|
||||
|
||||
this@MusicStore.logD(
|
||||
"Music load completed successfully in ${System.currentTimeMillis() - start}ms."
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
logE("Something went horribly wrong.")
|
||||
logE(e.stackTraceToString())
|
||||
|
||||
return@withContext Response.FAILED
|
||||
if (loader.songs.isEmpty()) {
|
||||
return Response.NO_MUSIC
|
||||
}
|
||||
|
||||
loaded = true
|
||||
mSongs = loader.songs
|
||||
mAlbums = loader.albums
|
||||
mArtists = loader.artists
|
||||
mGenres = loader.genres
|
||||
|
||||
return@withContext Response.SUCCESS
|
||||
logD("Music load completed successfully in ${System.currentTimeMillis() - start}ms.")
|
||||
} catch (e: Exception) {
|
||||
logE("Something went horribly wrong.")
|
||||
logE(e.stackTraceToString())
|
||||
|
||||
return Response.FAILED
|
||||
}
|
||||
|
||||
loaded = true
|
||||
|
||||
return Response.SUCCESS
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -12,8 +12,8 @@ import org.oxycblt.auxio.R
|
|||
import org.oxycblt.auxio.ui.getPlural
|
||||
|
||||
/**
|
||||
* List of ID3 genres + Winamp extensions, each index corresponds to their int value.
|
||||
* There are a lot more int-genre extensions as far as Im aware, but this works for most cases.
|
||||
* A complete array of all the hardcoded genre values for ID3 <v3, contains standard genres and
|
||||
* winamp extensions.
|
||||
*/
|
||||
private val ID3_GENRES = arrayOf(
|
||||
// ID3 Standard
|
||||
|
|
|
@ -172,6 +172,8 @@ class PlaybackViewModel : ViewModel(), PlaybackStateManager.Callback {
|
|||
if (playbackManager.isRestored && musicStore.loaded) {
|
||||
playWithUriInternal(uri, context)
|
||||
} else {
|
||||
logD("Cant play this URI right now, waiting...")
|
||||
|
||||
mIntentUri = uri
|
||||
}
|
||||
}
|
||||
|
|
|
@ -247,8 +247,6 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateManager.Ca
|
|||
|
||||
notification.setPlaying(this, isPlaying)
|
||||
startForegroundOrNotify()
|
||||
|
||||
logD("Playing Status: $isPlaying")
|
||||
}
|
||||
|
||||
override fun onLoopUpdate(loopMode: LoopMode) {
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/inter_semibold"
|
||||
android:onClick="@{() -> loadingModel.load()}"
|
||||
android:onClick="@{() -> loadingModel.load(context)}"
|
||||
android:text="@string/label_retry"
|
||||
android:textColor="?attr/colorPrimary"
|
||||
android:visibility="gone"
|
||||
|
|
Loading…
Reference in a new issue