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 package dev.jdtech.jellyfin.database
import android.content.Context
import androidx.room.Database import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase import androidx.room.RoomDatabase
@Database(entities = [Server::class], version = 1, exportSchema = false) @Database(entities = [Server::class], version = 1, exportSchema = false)
abstract class ServerDatabase : RoomDatabase() { abstract class ServerDatabase : RoomDatabase() {
abstract val serverDatabaseDao: ServerDatabaseDao 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 @Module
@InstallIn(SingletonComponent::class) @InstallIn(SingletonComponent::class)
class AppModule { object AppModule {
@Singleton @Singleton
@Provides @Provides
fun provideApplication(@ApplicationContext app: Context): BaseApplication { fun provideApplication(@ApplicationContext app: Context): BaseApplication {

View file

@ -13,7 +13,7 @@ import javax.inject.Singleton
@Module @Module
@InstallIn(SingletonComponent::class) @InstallIn(SingletonComponent::class)
class DatabaseModule { object DatabaseModule {
@Singleton @Singleton
@Provides @Provides
fun provideServerDatabaseDao(@ApplicationContext app: Context): ServerDatabaseDao { 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 dagger.hilt.android.AndroidEntryPoint
import dev.jdtech.jellyfin.databinding.EpisodeBottomSheetBinding import dev.jdtech.jellyfin.databinding.EpisodeBottomSheetBinding
import dev.jdtech.jellyfin.viewmodels.EpisodeBottomSheetViewModel import dev.jdtech.jellyfin.viewmodels.EpisodeBottomSheetViewModel
import dev.jdtech.jellyfin.viewmodels.EpisodeBottomSheetViewModelFactory
@AndroidEntryPoint @AndroidEntryPoint
class EpisodeBottomSheetFragment : BottomSheetDialogFragment() { class EpisodeBottomSheetFragment : BottomSheetDialogFragment() {
private val args: EpisodeBottomSheetFragmentArgs by navArgs() private val args: EpisodeBottomSheetFragmentArgs by navArgs()
private lateinit var binding: EpisodeBottomSheetBinding private lateinit var binding: EpisodeBottomSheetBinding
private val viewModel: EpisodeBottomSheetViewModel by viewModels()
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
@ -25,11 +25,6 @@ class EpisodeBottomSheetFragment : BottomSheetDialogFragment() {
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View { ): View {
binding = EpisodeBottomSheetBinding.inflate(inflater, container, false) 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.lifecycleOwner = this
binding.viewModel = viewModel binding.viewModel = viewModel
@ -44,6 +39,8 @@ class EpisodeBottomSheetFragment : BottomSheetDialogFragment() {
} }
}) })
viewModel.loadEpisode(args.episodeId)
return binding.root 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.app.Application
import android.util.Log 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 dagger.hilt.android.lifecycle.HiltViewModel
import dev.jdtech.jellyfin.api.JellyfinApi import dev.jdtech.jellyfin.api.JellyfinApi
import dev.jdtech.jellyfin.database.Server 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.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.lang.Exception
import javax.inject.Inject import javax.inject.Inject
@HiltViewModel @HiltViewModel
class AddServerViewModel class AddServerViewModel
@Inject @Inject
constructor(application: Application) : ViewModel() { constructor(
private val database = ServerDatabase.getInstance(application).serverDatabaseDao private val application: Application,
private val database: ServerDatabaseDao
) : ViewModel() {
private val _navigateToLogin = MutableLiveData<Boolean>() private val _navigateToLogin = MutableLiveData<Boolean>()
val navigateToLogin: LiveData<Boolean> = _navigateToLogin val navigateToLogin: LiveData<Boolean> = _navigateToLogin
@ -25,8 +29,6 @@ constructor(application: Application) : ViewModel() {
private val _error = MutableLiveData<String>() private val _error = MutableLiveData<String>()
val error: LiveData<String> = _error val error: LiveData<String> = _error
private val app = application
/** /**
* Run multiple check on the server before continuing: * Run multiple check on the server before continuing:
* *
@ -37,7 +39,7 @@ constructor(application: Application) : ViewModel() {
_error.value = null _error.value = null
viewModelScope.launch { viewModelScope.launch {
val jellyfinApi = JellyfinApi.newInstance(app, baseUrl) val jellyfinApi = JellyfinApi.newInstance(application, baseUrl)
try { try {
val publicSystemInfo by jellyfinApi.systemApi.getPublicSystemInfo() val publicSystemInfo by jellyfinApi.systemApi.getPublicSystemInfo()
Log.i("AddServerViewModel", "Remote server: ${publicSystemInfo.id}") Log.i("AddServerViewModel", "Remote server: ${publicSystemInfo.id}")

View file

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