ultrasonic-app-subsonic-and.../ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/GenericListModel.kt

114 lines
3.5 KiB
Kotlin
Raw Normal View History

package org.moire.ultrasonic.fragment
import android.app.Application
import android.content.Context
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import java.net.ConnectException
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koin.core.component.KoinApiExtension
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import org.moire.ultrasonic.data.ActiveServerProvider
import org.moire.ultrasonic.data.ServerSetting
import org.moire.ultrasonic.domain.MusicFolder
import org.moire.ultrasonic.service.CommunicationErrorHandler
import org.moire.ultrasonic.service.MusicService
import org.moire.ultrasonic.service.MusicServiceFactory
import org.moire.ultrasonic.util.Util
/**
* An abstract Model, which can be extended to retrieve a list of items from the API
*/
@KoinApiExtension
abstract class GenericListModel(application: Application) :
AndroidViewModel(application), KoinComponent {
val activeServerProvider: ActiveServerProvider by inject()
val activeServer: ServerSetting
get() = activeServerProvider.getActiveServer()
val context: Context
get() = getApplication<Application>().applicationContext
var currentListIsSortable = true
var showHeader = true
var showSelectFolderHeader = false
internal val musicFolders: MutableLiveData<List<MusicFolder>> = MutableLiveData()
/**
* Helper function to check online status
*/
fun isOffline(): Boolean {
return ActiveServerProvider.isOffline()
}
/**
* Refreshes the cached items from the server
*/
fun refresh(swipe: SwipeRefreshLayout, bundle: Bundle?) {
backgroundLoadFromServer(true, swipe, bundle ?: Bundle())
}
/**
* Trigger a load() and notify the UI that we are loading
*/
fun backgroundLoadFromServer(
refresh: Boolean,
swipe: SwipeRefreshLayout,
bundle: Bundle = Bundle()
) {
viewModelScope.launch {
swipe.isRefreshing = true
loadFromServer(refresh, swipe, bundle)
swipe.isRefreshing = false
}
}
/**
* Calls the load() function with error handling
*/
suspend fun loadFromServer(refresh: Boolean, swipe: SwipeRefreshLayout, bundle: Bundle) =
withContext(Dispatchers.IO) {
val musicService = MusicServiceFactory.getMusicService()
val isOffline = ActiveServerProvider.isOffline()
val useId3Tags = Util.getShouldUseId3Tags()
try {
load(isOffline, useId3Tags, musicService, refresh, bundle)
} catch (exception: ConnectException) {
Handler(Looper.getMainLooper()).post {
CommunicationErrorHandler.handleError(exception, swipe.context)
}
}
}
/**
* This is the central function you need to implement if you want to extend this class
*/
abstract fun load(
isOffline: Boolean,
useId3Tags: Boolean,
musicService: MusicService,
refresh: Boolean,
args: Bundle
)
/**
* Retrieves the available Music Folders in a LiveData
*/
fun getMusicFolders(): LiveData<List<MusicFolder>> {
return musicFolders
}
}