First JellyfinRepository implementation

This commit is contained in:
Jarne Demeulemeester 2021-07-06 14:24:53 +02:00
parent 16bc87969d
commit e79731f21b
No known key found for this signature in database
GPG key ID: 60884A0C1EBA43E5
11 changed files with 79 additions and 78 deletions

View file

@ -1,32 +1,9 @@
package dev.jdtech.jellyfin.database
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
@Database(entities = [Server::class], version = 1, exportSchema = false)
abstract class ServerDatabase : RoomDatabase() {
abstract val serverDatabaseDao: ServerDatabaseDao
companion object {
@Volatile
private var INSTANCE: ServerDatabase? = null
fun getInstance(context: Context): ServerDatabase {
synchronized(this) {
var instance = INSTANCE
if (instance == null) {
instance = Room.databaseBuilder(
context.applicationContext,
ServerDatabase::class.java,
"servers"
)
.fallbackToDestructiveMigration().build()
INSTANCE = instance
}
return instance
}
}
}
}

View file

@ -11,7 +11,7 @@ import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
class AppModule {
object AppModule {
@Singleton
@Provides
fun provideApplication(@ApplicationContext app: Context): BaseApplication {

View file

@ -13,7 +13,7 @@ import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
class DatabaseModule {
object DatabaseModule {
@Singleton
@Provides
fun provideServerDatabaseDao(@ApplicationContext app: Context): ServerDatabaseDao {

View file

@ -0,0 +1,23 @@
package dev.jdtech.jellyfin.di
import android.content.Context
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import dev.jdtech.jellyfin.api.JellyfinApi
import dev.jdtech.jellyfin.repository.JellyfinRepository
import dev.jdtech.jellyfin.repository.JellyfinRepositoryImpl
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
object RepositoryModule {
@Singleton
@Provides
fun provideJellyfinRepository(@ApplicationContext application: Context): JellyfinRepository {
val jellyfinApi = JellyfinApi.getInstance(application, "")
return JellyfinRepositoryImpl(jellyfinApi)
}
}

View file

@ -11,13 +11,13 @@ import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import dagger.hilt.android.AndroidEntryPoint
import dev.jdtech.jellyfin.databinding.EpisodeBottomSheetBinding
import dev.jdtech.jellyfin.viewmodels.EpisodeBottomSheetViewModel
import dev.jdtech.jellyfin.viewmodels.EpisodeBottomSheetViewModelFactory
@AndroidEntryPoint
class EpisodeBottomSheetFragment : BottomSheetDialogFragment() {
private val args: EpisodeBottomSheetFragmentArgs by navArgs()
private lateinit var binding: EpisodeBottomSheetBinding
private val viewModel: EpisodeBottomSheetViewModel by viewModels()
override fun onCreateView(
inflater: LayoutInflater,
@ -25,11 +25,6 @@ class EpisodeBottomSheetFragment : BottomSheetDialogFragment() {
savedInstanceState: Bundle?
): View {
binding = EpisodeBottomSheetBinding.inflate(inflater, container, false)
val viewModelFactory = EpisodeBottomSheetViewModelFactory(
requireNotNull(this.activity).application,
args.episodeId
)
val viewModel: EpisodeBottomSheetViewModel by viewModels { viewModelFactory }
binding.lifecycleOwner = this
binding.viewModel = viewModel
@ -44,6 +39,8 @@ class EpisodeBottomSheetFragment : BottomSheetDialogFragment() {
}
})
viewModel.loadEpisode(args.episodeId)
return binding.root
}
}

View file

@ -0,0 +1,8 @@
package dev.jdtech.jellyfin.repository
import org.jellyfin.sdk.model.api.BaseItemDto
import java.util.*
interface JellyfinRepository {
suspend fun getItem(itemId: UUID): BaseItemDto
}

View file

@ -0,0 +1,17 @@
package dev.jdtech.jellyfin.repository
import dev.jdtech.jellyfin.api.JellyfinApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.jellyfin.sdk.model.api.BaseItemDto
import java.util.*
class JellyfinRepositoryImpl(private val jellyfinApi: JellyfinApi) : JellyfinRepository {
override suspend fun getItem(itemId: UUID): BaseItemDto {
val item: BaseItemDto
withContext(Dispatchers.IO) {
item = jellyfinApi.userLibraryApi.getItem(jellyfinApi.userId!!, itemId).content
}
return item
}
}

View file

@ -2,22 +2,26 @@ package dev.jdtech.jellyfin.viewmodels
import android.app.Application
import android.util.Log
import androidx.lifecycle.*
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import dev.jdtech.jellyfin.api.JellyfinApi
import dev.jdtech.jellyfin.database.Server
import dev.jdtech.jellyfin.database.ServerDatabase
import dev.jdtech.jellyfin.database.ServerDatabaseDao
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.lang.Exception
import javax.inject.Inject
@HiltViewModel
class AddServerViewModel
@Inject
constructor(application: Application) : ViewModel() {
private val database = ServerDatabase.getInstance(application).serverDatabaseDao
constructor(
private val application: Application,
private val database: ServerDatabaseDao
) : ViewModel() {
private val _navigateToLogin = MutableLiveData<Boolean>()
val navigateToLogin: LiveData<Boolean> = _navigateToLogin
@ -25,8 +29,6 @@ constructor(application: Application) : ViewModel() {
private val _error = MutableLiveData<String>()
val error: LiveData<String> = _error
private val app = application
/**
* Run multiple check on the server before continuing:
*
@ -37,7 +39,7 @@ constructor(application: Application) : ViewModel() {
_error.value = null
viewModelScope.launch {
val jellyfinApi = JellyfinApi.newInstance(app, baseUrl)
val jellyfinApi = JellyfinApi.newInstance(application, baseUrl)
try {
val publicSystemInfo by jellyfinApi.systemApi.getPublicSystemInfo()
Log.i("AddServerViewModel", "Remote server: ${publicSystemInfo.id}")

View file

@ -1,22 +1,25 @@
package dev.jdtech.jellyfin.viewmodels
import android.app.Application
import android.os.Build
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dev.jdtech.jellyfin.api.JellyfinApi
import kotlinx.coroutines.Dispatchers
import dagger.hilt.android.lifecycle.HiltViewModel
import dev.jdtech.jellyfin.repository.JellyfinRepository
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.jellyfin.sdk.model.api.BaseItemDto
import java.text.DateFormat
import java.time.ZoneOffset
import java.util.*
import javax.inject.Inject
class EpisodeBottomSheetViewModel(application: Application, episodeId: UUID) : AndroidViewModel(application) {
private val jellyfinApi = JellyfinApi.getInstance(application, "")
@HiltViewModel
class EpisodeBottomSheetViewModel
@Inject
constructor(
private val jellyfinRepository: JellyfinRepository
) : ViewModel() {
private val _item = MutableLiveData<BaseItemDto>()
val item: LiveData<BaseItemDto> = _item
@ -27,22 +30,14 @@ class EpisodeBottomSheetViewModel(application: Application, episodeId: UUID) : A
private val _dateString = MutableLiveData<String>()
val dateString: LiveData<String> = _dateString
init {
fun loadEpisode(episodeId: UUID) {
viewModelScope.launch {
_item.value = getItem(episodeId)
_item.value = jellyfinRepository.getItem(episodeId)
_runTime.value = "${_item.value?.runTimeTicks?.div(600000000)} min"
_dateString.value = getDateString(_item.value!!)
}
}
private suspend fun getItem(id: UUID) : BaseItemDto {
val item: BaseItemDto
withContext(Dispatchers.IO) {
item = jellyfinApi.userLibraryApi.getItem(jellyfinApi.userId!!, id).content
}
return item
}
private fun getDateString(item: BaseItemDto): String {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val instant = item.premiereDate?.toInstant(ZoneOffset.UTC)

View file

@ -1,20 +0,0 @@
package dev.jdtech.jellyfin.viewmodels
import android.app.Application
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import java.lang.IllegalArgumentException
import java.util.*
class EpisodeBottomSheetViewModelFactory(
private val application: Application,
private val episodeId: UUID
) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(EpisodeBottomSheetViewModel::class.java)) {
@Suppress("UNCHECKED_CAST")
return EpisodeBottomSheetViewModel(application, episodeId) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}

View file

@ -1,9 +1,11 @@
package dev.jdtech.jellyfin.viewmodels
import android.app.Application
import androidx.lifecycle.*
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import dev.jdtech.jellyfin.BaseApplication
import dev.jdtech.jellyfin.R
import dev.jdtech.jellyfin.adapters.HomeItem
import dev.jdtech.jellyfin.api.JellyfinApi