diff --git a/app/src/main/java/dev/jdtech/jellyfin/database/ServerDatabase.kt b/app/src/main/java/dev/jdtech/jellyfin/database/ServerDatabase.kt index 4f111994..4a1b8f02 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/database/ServerDatabase.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/database/ServerDatabase.kt @@ -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 - } - } - } } \ No newline at end of file diff --git a/app/src/main/java/dev/jdtech/jellyfin/di/AppModule.kt b/app/src/main/java/dev/jdtech/jellyfin/di/AppModule.kt index 187940f9..323c078e 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/di/AppModule.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/di/AppModule.kt @@ -11,7 +11,7 @@ import javax.inject.Singleton @Module @InstallIn(SingletonComponent::class) -class AppModule { +object AppModule { @Singleton @Provides fun provideApplication(@ApplicationContext app: Context): BaseApplication { diff --git a/app/src/main/java/dev/jdtech/jellyfin/di/DatabaseModule.kt b/app/src/main/java/dev/jdtech/jellyfin/di/DatabaseModule.kt index ad887540..8932892f 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/di/DatabaseModule.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/di/DatabaseModule.kt @@ -13,7 +13,7 @@ import javax.inject.Singleton @Module @InstallIn(SingletonComponent::class) -class DatabaseModule { +object DatabaseModule { @Singleton @Provides fun provideServerDatabaseDao(@ApplicationContext app: Context): ServerDatabaseDao { diff --git a/app/src/main/java/dev/jdtech/jellyfin/di/RepositoryModule.kt b/app/src/main/java/dev/jdtech/jellyfin/di/RepositoryModule.kt new file mode 100644 index 00000000..bc7c2585 --- /dev/null +++ b/app/src/main/java/dev/jdtech/jellyfin/di/RepositoryModule.kt @@ -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) + } +} \ No newline at end of file diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/EpisodeBottomSheetFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/EpisodeBottomSheetFragment.kt index 6c65e205..121c13c1 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/EpisodeBottomSheetFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/EpisodeBottomSheetFragment.kt @@ -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 } } \ No newline at end of file diff --git a/app/src/main/java/dev/jdtech/jellyfin/repository/JellyfinRepository.kt b/app/src/main/java/dev/jdtech/jellyfin/repository/JellyfinRepository.kt new file mode 100644 index 00000000..7122b61a --- /dev/null +++ b/app/src/main/java/dev/jdtech/jellyfin/repository/JellyfinRepository.kt @@ -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 +} \ No newline at end of file diff --git a/app/src/main/java/dev/jdtech/jellyfin/repository/JellyfinRepositoryImpl.kt b/app/src/main/java/dev/jdtech/jellyfin/repository/JellyfinRepositoryImpl.kt new file mode 100644 index 00000000..6b0e3cdb --- /dev/null +++ b/app/src/main/java/dev/jdtech/jellyfin/repository/JellyfinRepositoryImpl.kt @@ -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 + } +} \ No newline at end of file diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/AddServerViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/AddServerViewModel.kt index e3d3370c..7e0bddb5 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/AddServerViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/AddServerViewModel.kt @@ -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() val navigateToLogin: LiveData = _navigateToLogin @@ -25,8 +29,6 @@ constructor(application: Application) : ViewModel() { private val _error = MutableLiveData() val error: LiveData = _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}") diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/EpisodeBottomSheetViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/EpisodeBottomSheetViewModel.kt index 629c738a..6bf96236 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/EpisodeBottomSheetViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/EpisodeBottomSheetViewModel.kt @@ -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() val item: LiveData = _item @@ -27,22 +30,14 @@ class EpisodeBottomSheetViewModel(application: Application, episodeId: UUID) : A private val _dateString = MutableLiveData() val dateString: LiveData = _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) diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/EpisodeBottomSheetViewModelFactory.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/EpisodeBottomSheetViewModelFactory.kt deleted file mode 100644 index 7951ca59..00000000 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/EpisodeBottomSheetViewModelFactory.kt +++ /dev/null @@ -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 create(modelClass: Class): T { - if (modelClass.isAssignableFrom(EpisodeBottomSheetViewModel::class.java)) { - @Suppress("UNCHECKED_CAST") - return EpisodeBottomSheetViewModel(application, episodeId) as T - } - throw IllegalArgumentException("Unknown ViewModel class") - } -} \ No newline at end of file diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/HomeViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/HomeViewModel.kt index bd37f072..7e7e191c 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/HomeViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/HomeViewModel.kt @@ -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