diff --git a/app/build.gradle.kts b/app/build.gradle.kts index e91a002d..e1f7c7b1 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -6,6 +6,7 @@ plugins { id("androidx.navigation.safeargs.kotlin") id("dagger.hilt.android.plugin") id("com.mikepenz.aboutlibraries.plugin") + id("org.jlleitschuh.gradle.ktlint") version "11.0.0" } android { @@ -59,6 +60,12 @@ android { } } +ktlint { + android.set(true) + ignoreFailures.set(false) + disabledRules.add("max-line-length") +} + dependencies { implementation("androidx.leanback:leanback:1.2.0-alpha02") @@ -67,7 +74,6 @@ dependencies { implementation("androidx.activity:activity-ktx:1.6.1") implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0") - // Material implementation("com.google.android.material:material:1.7.0") @@ -131,4 +137,4 @@ dependencies { val pagingVersion = "3.1.1" implementation("androidx.paging:paging-runtime-ktx:$pagingVersion") -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/BaseApplication.kt b/app/src/main/java/dev/jdtech/jellyfin/BaseApplication.kt index adcca719..93cdda26 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/BaseApplication.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/BaseApplication.kt @@ -27,4 +27,4 @@ class BaseApplication : Application() { if (appPreferences.dynamicColors) DynamicColors.applyToActivitiesIfAvailable(this) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/BasePlayerActivity.kt b/app/src/main/java/dev/jdtech/jellyfin/BasePlayerActivity.kt index 806fcf3b..ed736323 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/BasePlayerActivity.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/BasePlayerActivity.kt @@ -8,7 +8,7 @@ import androidx.core.view.updatePadding import com.google.android.exoplayer2.trackselection.MappingTrackSelector import dev.jdtech.jellyfin.viewmodels.PlayerActivityViewModel -abstract class BasePlayerActivity: AppCompatActivity() { +abstract class BasePlayerActivity : AppCompatActivity() { abstract val viewModel: PlayerActivityViewModel @@ -27,9 +27,11 @@ abstract class BasePlayerActivity: AppCompatActivity() { @Suppress("DEPRECATION") protected fun hideSystemUI() { // These methods are deprecated but we still use them because the new WindowInsetsControllerCompat has a bug which makes the action bar reappear - window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or - View.SYSTEM_UI_FLAG_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or - View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) + window.decorView.systemUiVisibility = ( + View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or + View.SYSTEM_UI_FLAG_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or + View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + ) window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { @@ -66,4 +68,4 @@ abstract class BasePlayerActivity: AppCompatActivity() { } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/BindingAdapters.kt b/app/src/main/java/dev/jdtech/jellyfin/BindingAdapters.kt index 947cbc93..0a7c6e61 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/BindingAdapters.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/BindingAdapters.kt @@ -13,11 +13,11 @@ import dev.jdtech.jellyfin.adapters.ViewItemListAdapter import dev.jdtech.jellyfin.api.JellyfinApi import dev.jdtech.jellyfin.database.Server import dev.jdtech.jellyfin.models.User +import java.util.UUID import org.jellyfin.sdk.model.api.BaseItemDto import org.jellyfin.sdk.model.api.BaseItemKind import org.jellyfin.sdk.model.api.BaseItemPerson import org.jellyfin.sdk.model.api.ImageType -import java.util.UUID @BindingAdapter("servers") fun bindServers(recyclerView: RecyclerView, data: List?) { @@ -75,7 +75,7 @@ fun bindBaseItemImage(imageView: ImageView, episode: BaseItemDto?) { var imageItemId = episode.id var imageType = ImageType.PRIMARY - if (!episode.imageTags.isNullOrEmpty()) { //TODO: Downloadmetadata currently does not store imagetags, so it always uses the backdrop + if (!episode.imageTags.isNullOrEmpty()) { // TODO: Downloadmetadata currently does not store imagetags, so it always uses the backdrop when (episode.type) { BaseItemKind.MOVIE -> { if (!episode.backdropImageTags.isNullOrEmpty()) { @@ -96,13 +96,13 @@ fun bindBaseItemImage(imageView: ImageView, episode: BaseItemDto?) { } imageView - .loadImage("/items/${imageItemId}/Images/$imageType") + .loadImage("/items/$imageItemId/Images/$imageType") .posterDescription(episode.name) } @BindingAdapter("seasonPoster") fun bindSeasonPoster(imageView: ImageView, seasonId: UUID) { - imageView.loadImage("/items/${seasonId}/Images/${ImageType.PRIMARY}") + imageView.loadImage("/items/$seasonId/Images/${ImageType.PRIMARY}") } @BindingAdapter("userImage") @@ -112,7 +112,11 @@ fun bindUserImage(imageView: ImageView, user: User) { .posterDescription(user.name) } -private fun ImageView.loadImage(url: String, @DrawableRes placeholderId: Int = R.color.neutral_800, @DrawableRes errorPlaceHolderId: Int? = null): View { +private fun ImageView.loadImage( + url: String, + @DrawableRes placeholderId: Int = R.color.neutral_800, + @DrawableRes errorPlaceHolderId: Int? = null +): View { val api = JellyfinApi.getInstance(context.applicationContext) Glide @@ -134,4 +138,4 @@ private fun View.posterDescription(name: String?) { private fun View.backdropDescription(name: String?) { contentDescription = String.format(context.resources.getString(R.string.image_description_backdrop), name) -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/MainActivity.kt b/app/src/main/java/dev/jdtech/jellyfin/MainActivity.kt index ac3df1a5..a9d25b81 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/MainActivity.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/MainActivity.kt @@ -59,7 +59,6 @@ class MainActivity : AppCompatActivity() { } } - if (uiModeManager.currentModeType != Configuration.UI_MODE_TYPE_TELEVISION) { val navView: NavigationBarView = binding.navView as NavigationBarView @@ -109,4 +108,4 @@ class MainActivity : AppCompatActivity() { } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/PlayerActivity.kt b/app/src/main/java/dev/jdtech/jellyfin/PlayerActivity.kt index 5a624cc9..d04b646f 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/PlayerActivity.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/PlayerActivity.kt @@ -21,8 +21,8 @@ import dev.jdtech.jellyfin.mpv.TrackType import dev.jdtech.jellyfin.utils.AppPreferences import dev.jdtech.jellyfin.utils.PlayerGestureHelper import dev.jdtech.jellyfin.viewmodels.PlayerActivityViewModel -import timber.log.Timber import javax.inject.Inject +import timber.log.Timber @AndroidEntryPoint class PlayerActivity : BasePlayerActivity() { @@ -177,4 +177,3 @@ class PlayerActivity : BasePlayerActivity() { hideSystemUI() } } - diff --git a/app/src/main/java/dev/jdtech/jellyfin/adapters/CollectionListAdapter.kt b/app/src/main/java/dev/jdtech/jellyfin/adapters/CollectionListAdapter.kt index 13fd7e84..61c4cd52 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/adapters/CollectionListAdapter.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/adapters/CollectionListAdapter.kt @@ -50,4 +50,4 @@ class CollectionListAdapter( class OnClickListener(val clickListener: (collection: BaseItemDto) -> Unit) { fun onClick(collection: BaseItemDto) = clickListener(collection) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/adapters/DiscoveredServerListAdapter.kt b/app/src/main/java/dev/jdtech/jellyfin/adapters/DiscoveredServerListAdapter.kt index f057edcb..bce7eaf3 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/adapters/DiscoveredServerListAdapter.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/adapters/DiscoveredServerListAdapter.kt @@ -9,7 +9,8 @@ import dev.jdtech.jellyfin.databinding.DiscoveredServerItemBinding import dev.jdtech.jellyfin.models.DiscoveredServer class DiscoveredServerListAdapter( - private val clickListener: (server: DiscoveredServer) -> Unit) : + private val clickListener: (server: DiscoveredServer) -> Unit +) : ListAdapter( DiffCallback ) { @@ -55,4 +56,4 @@ class DiscoveredServerListAdapter( holder.itemView.setOnClickListener { clickListener(server) } holder.bind(server) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/adapters/DownloadEpisodeListAdapter.kt b/app/src/main/java/dev/jdtech/jellyfin/adapters/DownloadEpisodeListAdapter.kt index 70555829..633ef916 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/adapters/DownloadEpisodeListAdapter.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/adapters/DownloadEpisodeListAdapter.kt @@ -12,8 +12,8 @@ import dev.jdtech.jellyfin.databinding.SeasonHeaderBinding import dev.jdtech.jellyfin.models.DownloadSeriesMetadata import dev.jdtech.jellyfin.models.PlayerItem import dev.jdtech.jellyfin.utils.downloadMetadataToBaseItemDto -import org.jellyfin.sdk.model.api.BaseItemDto import java.util.UUID +import org.jellyfin.sdk.model.api.BaseItemDto private const val ITEM_VIEW_TYPE_HEADER = 0 private const val ITEM_VIEW_TYPE_EPISODE = 1 @@ -125,4 +125,4 @@ sealed class DownloadEpisodeItem { data class Episode(val episode: PlayerItem) : DownloadEpisodeItem() { override val id = episode.itemId } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/adapters/DownloadSeriesListAdapter.kt b/app/src/main/java/dev/jdtech/jellyfin/adapters/DownloadSeriesListAdapter.kt index 4494b51f..67993d99 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/adapters/DownloadSeriesListAdapter.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/adapters/DownloadSeriesListAdapter.kt @@ -13,8 +13,7 @@ import dev.jdtech.jellyfin.utils.downloadSeriesMetadataToBaseItemDto class DownloadSeriesListAdapter( private val onClickListener: OnClickListener, private val fixedWidth: Boolean = false, - ) : - ListAdapter(DiffCallback) { +) : ListAdapter(DiffCallback) { class ItemViewHolder(private var binding: BaseItemBinding, private val parent: ViewGroup) : RecyclerView.ViewHolder(binding.root) { @@ -32,11 +31,17 @@ class DownloadSeriesListAdapter( } companion object DiffCallback : DiffUtil.ItemCallback() { - override fun areItemsTheSame(oldItem: DownloadSeriesMetadata, newItem: DownloadSeriesMetadata): Boolean { + override fun areItemsTheSame( + oldItem: DownloadSeriesMetadata, + newItem: DownloadSeriesMetadata + ): Boolean { return oldItem.itemId == newItem.itemId } - override fun areContentsTheSame(oldItem: DownloadSeriesMetadata, newItem: DownloadSeriesMetadata): Boolean { + override fun areContentsTheSame( + oldItem: DownloadSeriesMetadata, + newItem: DownloadSeriesMetadata + ): Boolean { return oldItem == newItem } } @@ -47,7 +52,8 @@ class DownloadSeriesListAdapter( LayoutInflater.from(parent.context), parent, false - ), parent + ), + parent ) } @@ -62,4 +68,4 @@ class DownloadSeriesListAdapter( class OnClickListener(val clickListener: (item: DownloadSeriesMetadata) -> Unit) { fun onClick(item: DownloadSeriesMetadata) = clickListener(item) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/adapters/DownloadViewItemListAdapter.kt b/app/src/main/java/dev/jdtech/jellyfin/adapters/DownloadViewItemListAdapter.kt index 050b9065..ab629c35 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/adapters/DownloadViewItemListAdapter.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/adapters/DownloadViewItemListAdapter.kt @@ -14,8 +14,7 @@ import dev.jdtech.jellyfin.utils.downloadMetadataToBaseItemDto class DownloadViewItemListAdapter( private val onClickListener: OnClickListener, private val fixedWidth: Boolean = false, - ) : - ListAdapter(DiffCallback) { +) : ListAdapter(DiffCallback) { class ItemViewHolder(private var binding: BaseItemBinding, private val parent: ViewGroup) : RecyclerView.ViewHolder(binding.root) { @@ -48,7 +47,8 @@ class DownloadViewItemListAdapter( LayoutInflater.from(parent.context), parent, false - ), parent + ), + parent ) } @@ -63,4 +63,4 @@ class DownloadViewItemListAdapter( class OnClickListener(val clickListener: (item: PlayerItem) -> Unit) { fun onClick(item: PlayerItem) = clickListener(item) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/adapters/DownloadsListAdapter.kt b/app/src/main/java/dev/jdtech/jellyfin/adapters/DownloadsListAdapter.kt index cbeb2521..9f9f819b 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/adapters/DownloadsListAdapter.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/adapters/DownloadsListAdapter.kt @@ -61,4 +61,4 @@ class DownloadsListAdapter( val collection = getItem(position) holder.bind(collection, onClickListener, onSeriesClickListener) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/adapters/EpisodeListAdapter.kt b/app/src/main/java/dev/jdtech/jellyfin/adapters/EpisodeListAdapter.kt index f25e50a8..e3a97328 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/adapters/EpisodeListAdapter.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/adapters/EpisodeListAdapter.kt @@ -9,8 +9,8 @@ import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import dev.jdtech.jellyfin.databinding.EpisodeItemBinding import dev.jdtech.jellyfin.databinding.SeasonHeaderBinding +import java.util.UUID import org.jellyfin.sdk.model.api.BaseItemDto -import java.util.* private const val ITEM_VIEW_TYPE_HEADER = 0 private const val ITEM_VIEW_TYPE_EPISODE = 1 @@ -129,4 +129,4 @@ sealed class EpisodeItem { data class Episode(val episode: BaseItemDto) : EpisodeItem() { override val id = episode.id } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/adapters/FavoritesListAdapter.kt b/app/src/main/java/dev/jdtech/jellyfin/adapters/FavoritesListAdapter.kt index 76c372d3..5985a109 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/adapters/FavoritesListAdapter.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/adapters/FavoritesListAdapter.kt @@ -61,4 +61,4 @@ class FavoritesListAdapter( val collection = getItem(position) holder.bind(collection, onClickListener, onEpisodeClickListener) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/adapters/HomeEpisodeListAdapter.kt b/app/src/main/java/dev/jdtech/jellyfin/adapters/HomeEpisodeListAdapter.kt index 41ecf2ea..42a83f01 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/adapters/HomeEpisodeListAdapter.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/adapters/HomeEpisodeListAdapter.kt @@ -17,8 +17,10 @@ class HomeEpisodeListAdapter(private val onClickListener: OnClickListener) : Lis fun bind(episode: BaseItemDto) { binding.episode = episode if (episode.userData?.playedPercentage != null) { - binding.progressBar.layoutParams.width = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, - (episode.userData?.playedPercentage?.times(2.24))!!.toFloat(), binding.progressBar.context.resources.displayMetrics).toInt() + binding.progressBar.layoutParams.width = TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + (episode.userData?.playedPercentage?.times(2.24))!!.toFloat(), binding.progressBar.context.resources.displayMetrics + ).toInt() binding.progressBar.visibility = View.VISIBLE } @@ -64,4 +66,4 @@ class HomeEpisodeListAdapter(private val onClickListener: OnClickListener) : Lis class OnClickListener(val clickListener: (item: BaseItemDto) -> Unit) { fun onClick(item: BaseItemDto) = clickListener(item) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/adapters/PersonListAdapter.kt b/app/src/main/java/dev/jdtech/jellyfin/adapters/PersonListAdapter.kt index 1c85cfb1..31ca9a53 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/adapters/PersonListAdapter.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/adapters/PersonListAdapter.kt @@ -8,7 +8,7 @@ import androidx.recyclerview.widget.RecyclerView import dev.jdtech.jellyfin.databinding.PersonItemBinding import org.jellyfin.sdk.model.api.BaseItemPerson -class PersonListAdapter(private val clickListener: (item: BaseItemPerson) -> Unit) :ListAdapter(DiffCallback) { +class PersonListAdapter(private val clickListener: (item: BaseItemPerson) -> Unit) : ListAdapter(DiffCallback) { class PersonViewHolder(private var binding: PersonItemBinding) : RecyclerView.ViewHolder(binding.root) { @@ -43,4 +43,4 @@ class PersonListAdapter(private val clickListener: (item: BaseItemPerson) -> Uni holder.bind(item) holder.itemView.setOnClickListener { clickListener(item) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/adapters/ServerGridAdapter.kt b/app/src/main/java/dev/jdtech/jellyfin/adapters/ServerGridAdapter.kt index 7b7e849e..760be617 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/adapters/ServerGridAdapter.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/adapters/ServerGridAdapter.kt @@ -11,7 +11,7 @@ import dev.jdtech.jellyfin.databinding.ServerItemBinding class ServerGridAdapter( private val onClickListener: OnClickListener, private val onLongClickListener: OnLongClickListener - ) : ListAdapter(DiffCallback) { +) : ListAdapter(DiffCallback) { class ServerViewHolder(private var binding: ServerItemBinding) : RecyclerView.ViewHolder(binding.root) { fun bind(server: Server) { @@ -55,4 +55,4 @@ class ServerGridAdapter( class OnLongClickListener(val clickListener: (server: Server) -> Boolean) { fun onLongClick(server: Server) = clickListener(server) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/adapters/UserListAdapter.kt b/app/src/main/java/dev/jdtech/jellyfin/adapters/UserListAdapter.kt index ec9023e4..9d3a8207 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/adapters/UserListAdapter.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/adapters/UserListAdapter.kt @@ -47,4 +47,4 @@ class UserListAdapter( holder.itemView.setOnClickListener { clickListener(user) } holder.bind(user) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/adapters/ViewItemListAdapter.kt b/app/src/main/java/dev/jdtech/jellyfin/adapters/ViewItemListAdapter.kt index d4779c09..67c048bc 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/adapters/ViewItemListAdapter.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/adapters/ViewItemListAdapter.kt @@ -14,8 +14,7 @@ import org.jellyfin.sdk.model.api.BaseItemKind class ViewItemListAdapter( private val onClickListener: OnClickListener, private val fixedWidth: Boolean = false, - ) : - ListAdapter(DiffCallback) { +) : ListAdapter(DiffCallback) { class ItemViewHolder(private var binding: BaseItemBinding, private val parent: ViewGroup) : RecyclerView.ViewHolder(binding.root) { @@ -49,7 +48,8 @@ class ViewItemListAdapter( LayoutInflater.from(parent.context), parent, false - ), parent + ), + parent ) } @@ -64,4 +64,4 @@ class ViewItemListAdapter( class OnClickListener(val clickListener: (item: BaseItemDto) -> Unit) { fun onClick(item: BaseItemDto) = clickListener(item) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/adapters/ViewItemPagingAdapter.kt b/app/src/main/java/dev/jdtech/jellyfin/adapters/ViewItemPagingAdapter.kt index 1cc5a7b8..ca8825cb 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/adapters/ViewItemPagingAdapter.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/adapters/ViewItemPagingAdapter.kt @@ -49,7 +49,8 @@ class ViewItemPagingAdapter( LayoutInflater.from(parent.context), parent, false - ), parent + ), + parent ) } @@ -66,4 +67,4 @@ class ViewItemPagingAdapter( class OnClickListener(val clickListener: (item: BaseItemDto) -> Unit) { fun onClick(item: BaseItemDto) = clickListener(item) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/adapters/ViewListAdapter.kt b/app/src/main/java/dev/jdtech/jellyfin/adapters/ViewListAdapter.kt index 6cef5147..0e6ef7d0 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/adapters/ViewListAdapter.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/adapters/ViewListAdapter.kt @@ -65,7 +65,8 @@ class ViewListAdapter( NextUpSectionBinding.inflate( LayoutInflater.from( parent.context - ), parent, false + ), + parent, false ) ) ITEM_VIEW_TYPE_VIEW -> ViewViewHolder( @@ -119,4 +120,4 @@ sealed class HomeItem { } abstract val id: UUID -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/api/JellyfinApi.kt b/app/src/main/java/dev/jdtech/jellyfin/api/JellyfinApi.kt index 2d56aaaa..eb02c98b 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/api/JellyfinApi.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/api/JellyfinApi.kt @@ -2,6 +2,7 @@ package dev.jdtech.jellyfin.api import android.content.Context import dev.jdtech.jellyfin.BuildConfig +import java.util.UUID import org.jellyfin.sdk.api.client.extensions.devicesApi import org.jellyfin.sdk.api.client.extensions.itemsApi import org.jellyfin.sdk.api.client.extensions.mediaInfoApi @@ -15,7 +16,6 @@ import org.jellyfin.sdk.api.client.extensions.userViewsApi import org.jellyfin.sdk.api.client.extensions.videosApi import org.jellyfin.sdk.createJellyfin import org.jellyfin.sdk.model.ClientInfo -import java.util.UUID /** * Jellyfin API class using org.jellyfin.sdk:jellyfin-platform-android @@ -59,4 +59,4 @@ class JellyfinApi(androidContext: Context) { } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/database/Converters.kt b/app/src/main/java/dev/jdtech/jellyfin/database/Converters.kt index a63d80a3..ca106f13 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/database/Converters.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/database/Converters.kt @@ -1,7 +1,7 @@ package dev.jdtech.jellyfin.database import androidx.room.TypeConverter -import java.util.* +import java.util.UUID class Converters { @TypeConverter @@ -13,4 +13,4 @@ class Converters { fun fromUUIDToString(value: UUID?): String? { return value?.toString() } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/database/DownloadDatabase.kt b/app/src/main/java/dev/jdtech/jellyfin/database/DownloadDatabase.kt index 27483d6f..552f2ab8 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/database/DownloadDatabase.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/database/DownloadDatabase.kt @@ -13,4 +13,4 @@ import dev.jdtech.jellyfin.models.DownloadItem @TypeConverters(Converters::class) abstract class DownloadDatabase : RoomDatabase() { abstract val downloadDatabaseDao: DownloadDatabaseDao -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/database/DownloadDatabaseDao.kt b/app/src/main/java/dev/jdtech/jellyfin/database/DownloadDatabaseDao.kt index 65597044..8d4c84d8 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/database/DownloadDatabaseDao.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/database/DownloadDatabaseDao.kt @@ -4,7 +4,7 @@ import androidx.room.Dao import androidx.room.Insert import androidx.room.Query import dev.jdtech.jellyfin.models.DownloadItem -import java.util.* +import java.util.UUID @Dao interface DownloadDatabaseDao { @@ -28,5 +28,4 @@ interface DownloadDatabaseDao { @Query("SELECT EXISTS (SELECT 1 FROM downloads WHERE id = :id)") fun exists(id: UUID): Boolean - -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/database/Server.kt b/app/src/main/java/dev/jdtech/jellyfin/database/Server.kt index 268c44cc..d5d33751 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/database/Server.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/database/Server.kt @@ -12,4 +12,4 @@ data class Server( val userId: String, val userName: String, val accessToken: String, -) \ No newline at end of file +) 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 4a1b8f02..e10178a4 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/database/ServerDatabase.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/database/ServerDatabase.kt @@ -6,4 +6,4 @@ import androidx.room.RoomDatabase @Database(entities = [Server::class], version = 1, exportSchema = false) abstract class ServerDatabase : RoomDatabase() { abstract val serverDatabaseDao: ServerDatabaseDao -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/database/ServerDatabaseDao.kt b/app/src/main/java/dev/jdtech/jellyfin/database/ServerDatabaseDao.kt index 017b3d81..b060ae3d 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/database/ServerDatabaseDao.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/database/ServerDatabaseDao.kt @@ -1,7 +1,11 @@ package dev.jdtech.jellyfin.database import androidx.lifecycle.LiveData -import androidx.room.* +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query +import androidx.room.Update @Dao interface ServerDatabaseDao { @@ -28,4 +32,4 @@ interface ServerDatabaseDao { @Query("delete from servers where id = :id") fun delete(id: String) -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/di/ApiModule.kt b/app/src/main/java/dev/jdtech/jellyfin/di/ApiModule.kt index 8be4797c..bda9b2ca 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/di/ApiModule.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/di/ApiModule.kt @@ -36,4 +36,4 @@ object ApiModule { return jellyfinApi } -} \ 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 323c078e..ddc05851 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/di/AppModule.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/di/AppModule.kt @@ -17,4 +17,4 @@ object AppModule { fun provideApplication(@ApplicationContext app: Context): BaseApplication { return app as BaseApplication } -} \ No newline at end of file +} 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 4318ba80..fe4d88e1 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/di/DatabaseModule.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/di/DatabaseModule.kt @@ -43,4 +43,4 @@ object DatabaseModule { .build() .downloadDatabaseDao } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/di/GlideModule.kt b/app/src/main/java/dev/jdtech/jellyfin/di/GlideModule.kt index fc7a61ba..30234fae 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/di/GlideModule.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/di/GlideModule.kt @@ -46,4 +46,4 @@ class GlideModule : AppGlideModule() { ) ) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/di/RepositoryModule.kt b/app/src/main/java/dev/jdtech/jellyfin/di/RepositoryModule.kt index e3865bb7..729ac1f0 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/di/RepositoryModule.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/di/RepositoryModule.kt @@ -19,4 +19,4 @@ object RepositoryModule { ): JellyfinRepository { return JellyfinRepositoryImpl(jellyfinApi) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/di/SharedPreferencesModule.kt b/app/src/main/java/dev/jdtech/jellyfin/di/SharedPreferencesModule.kt index d3f6de19..9fc159ed 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/di/SharedPreferencesModule.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/di/SharedPreferencesModule.kt @@ -10,7 +10,6 @@ import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent import javax.inject.Singleton - @Module @InstallIn(SingletonComponent::class) object SharedPreferencesModule { diff --git a/app/src/main/java/dev/jdtech/jellyfin/dialogs/DeleteServerDialogFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/dialogs/DeleteServerDialogFragment.kt index 73dfb56e..683bbfdb 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/dialogs/DeleteServerDialogFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/dialogs/DeleteServerDialogFragment.kt @@ -19,9 +19,8 @@ class DeleteServerDialogFragment(private val viewModel: ServerSelectViewModel, v viewModel.deleteServer(server) } .setNegativeButton(getString(R.string.cancel)) { _, _ -> - } builder.create() } ?: throw IllegalStateException("Activity cannot be null") } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/dialogs/ErrorDialogFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/dialogs/ErrorDialogFragment.kt index 2dac7b17..0f352ef8 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/dialogs/ErrorDialogFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/dialogs/ErrorDialogFragment.kt @@ -10,7 +10,7 @@ import java.lang.IllegalStateException class ErrorDialogFragment( private val error: Exception - ) : DialogFragment() { +) : DialogFragment() { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { return activity?.let { val builder = MaterialAlertDialogBuilder(it, R.style.ErrorDialogStyle) @@ -28,9 +28,8 @@ class ErrorDialogFragment( val shareIntent = Intent.createChooser(sendIntent, null) startActivity(shareIntent) - } builder.create() } ?: throw IllegalStateException("Activity cannot be null") } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/dialogs/SortDialogFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/dialogs/SortDialogFragment.kt index 50232b99..18b888ca 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/dialogs/SortDialogFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/dialogs/SortDialogFragment.kt @@ -8,9 +8,9 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder import dev.jdtech.jellyfin.R import dev.jdtech.jellyfin.utils.SortBy import dev.jdtech.jellyfin.viewmodels.LibraryViewModel -import org.jellyfin.sdk.model.api.SortOrder import java.lang.IllegalStateException -import java.util.* +import java.util.UUID +import org.jellyfin.sdk.model.api.SortOrder class SortDialogFragment( private val parentId: UUID, @@ -84,4 +84,4 @@ class SortDialogFragment( builder.create() } ?: throw IllegalStateException("Activity cannot be null") } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/dialogs/SpeedSelectionDialogFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/dialogs/SpeedSelectionDialogFragment.kt index c651d1b9..bbd4a110 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/dialogs/SpeedSelectionDialogFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/dialogs/SpeedSelectionDialogFragment.kt @@ -29,7 +29,5 @@ class SpeedSelectionDialogFragment( } builder.create() } ?: throw IllegalStateException("Activity cannot be null") - - } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/dialogs/TrackSelectionDialogFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/dialogs/TrackSelectionDialogFragment.kt index d789e37e..61e3a21e 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/dialogs/TrackSelectionDialogFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/dialogs/TrackSelectionDialogFragment.kt @@ -22,7 +22,8 @@ class TrackSelectionDialogFragment( builder.setTitle(getString(R.string.select_audio_track)) .setSingleChoiceItems( getTrackNames(viewModel.currentAudioTracks), - viewModel.currentAudioTracks.indexOfFirst { it.selected }) { dialog, which -> + viewModel.currentAudioTracks.indexOfFirst { it.selected } + ) { dialog, which -> viewModel.switchToTrack( TrackType.AUDIO, viewModel.currentAudioTracks[which] @@ -38,7 +39,8 @@ class TrackSelectionDialogFragment( builder.setTitle(getString(R.string.select_subtile_track)) .setSingleChoiceItems( getTrackNames(viewModel.currentSubtitleTracks), - viewModel.currentSubtitleTracks.indexOfFirst { if (viewModel.disableSubtitle) it.ffIndex == -1 else it.selected }) { dialog, which -> + viewModel.currentSubtitleTracks.indexOfFirst { if (viewModel.disableSubtitle) it.ffIndex == -1 else it.selected } + ) { dialog, which -> viewModel.switchToTrack( TrackType.SUBTITLE, viewModel.currentSubtitleTracks[which] @@ -63,4 +65,4 @@ class TrackSelectionDialogFragment( nameParts.joinToString(separator = " - ") }.toTypedArray() } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/dialogs/VideoVersionDialogFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/dialogs/VideoVersionDialogFragment.kt index 11377734..9189865d 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/dialogs/VideoVersionDialogFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/dialogs/VideoVersionDialogFragment.kt @@ -4,9 +4,9 @@ import android.app.Dialog import android.os.Bundle import androidx.fragment.app.DialogFragment import com.google.android.material.dialog.MaterialAlertDialogBuilder -import java.lang.IllegalStateException import dev.jdtech.jellyfin.R import dev.jdtech.jellyfin.viewmodels.PlayerViewModel +import java.lang.IllegalStateException import org.jellyfin.sdk.model.api.BaseItemDto class VideoVersionDialogFragment( @@ -24,4 +24,4 @@ class VideoVersionDialogFragment( }.create() } ?: throw IllegalStateException("Activity cannot be null") } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/AddServerFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/AddServerFragment.kt index a9bb9cd5..806d4ddf 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/AddServerFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/AddServerFragment.kt @@ -31,7 +31,8 @@ class AddServerFragment : Fragment() { private val viewModel: AddServerViewModel by viewModels() override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, + inflater: LayoutInflater, + container: ViewGroup?, savedInstanceState: Bundle? ): View { binding = FragmentAddServerBinding.inflate(inflater) @@ -136,7 +137,9 @@ class AddServerFragment : Fragment() { } } - private fun bindDiscoveredServersStateServers(serversState: AddServerViewModel.DiscoveredServersState.Servers) { + private fun bindDiscoveredServersStateServers( + serversState: AddServerViewModel.DiscoveredServersState.Servers + ) { val servers = serversState.servers if (servers.isEmpty()) { binding.serversRecyclerView.isVisible = false @@ -154,4 +157,4 @@ class AddServerFragment : Fragment() { private fun navigateToLoginFragment() { findNavController().navigate(AddServerFragmentDirections.actionAddServerFragmentToLoginFragment()) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/DownloadFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/DownloadFragment.kt index 9da04e86..111345cf 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/DownloadFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/DownloadFragment.kt @@ -12,16 +12,18 @@ import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import androidx.navigation.fragment.findNavController import dagger.hilt.android.AndroidEntryPoint -import dev.jdtech.jellyfin.adapters.* +import dev.jdtech.jellyfin.adapters.DownloadSeriesListAdapter +import dev.jdtech.jellyfin.adapters.DownloadViewItemListAdapter +import dev.jdtech.jellyfin.adapters.DownloadsListAdapter import dev.jdtech.jellyfin.databinding.FragmentDownloadBinding import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment import dev.jdtech.jellyfin.models.DownloadSeriesMetadata import dev.jdtech.jellyfin.models.PlayerItem import dev.jdtech.jellyfin.utils.checkIfLoginRequired import dev.jdtech.jellyfin.viewmodels.DownloadViewModel +import java.util.UUID import kotlinx.coroutines.launch import timber.log.Timber -import java.util.* @AndroidEntryPoint class DownloadFragment : Fragment() { @@ -32,18 +34,21 @@ class DownloadFragment : Fragment() { private lateinit var errorDialog: ErrorDialogFragment override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, + inflater: LayoutInflater, + container: ViewGroup?, savedInstanceState: Bundle? ): View { binding = FragmentDownloadBinding.inflate(inflater, container, false) - binding.downloadsRecyclerView.adapter = DownloadsListAdapter( - DownloadViewItemListAdapter.OnClickListener { item -> - navigateToMediaInfoFragment(item) - }, DownloadSeriesListAdapter.OnClickListener { item -> - navigateToDownloadSeriesFragment(item) - } - ) + binding.downloadsRecyclerView.adapter = + DownloadsListAdapter( + DownloadViewItemListAdapter.OnClickListener { item -> + navigateToMediaInfoFragment(item) + }, + DownloadSeriesListAdapter.OnClickListener { item -> + navigateToDownloadSeriesFragment(item) + } + ) viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { @@ -97,11 +102,7 @@ class DownloadFragment : Fragment() { private fun navigateToMediaInfoFragment(item: PlayerItem) { findNavController().navigate( DownloadFragmentDirections.actionDownloadFragmentToMediaInfoFragment( - UUID.randomUUID(), - item.name, - item.item!!.type, - item, - isOffline = true + UUID.randomUUID(), item.name, item.item!!.type, item, isOffline = true ) ) } @@ -109,9 +110,8 @@ class DownloadFragment : Fragment() { private fun navigateToDownloadSeriesFragment(series: DownloadSeriesMetadata) { findNavController().navigate( DownloadFragmentDirections.actionDownloadFragmentToDownloadSeriesFragment( - seriesMetadata = series, - seriesName = series.name + seriesMetadata = series, seriesName = series.name ) ) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/DownloadSeriesFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/DownloadSeriesFragment.kt index 9b9b8225..82d8987c 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/DownloadSeriesFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/DownloadSeriesFragment.kt @@ -1,11 +1,11 @@ package dev.jdtech.jellyfin.fragments import android.os.Bundle -import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.core.view.isVisible +import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope @@ -18,8 +18,8 @@ import dev.jdtech.jellyfin.databinding.FragmentDownloadSeriesBinding import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment import dev.jdtech.jellyfin.models.PlayerItem import dev.jdtech.jellyfin.viewmodels.DownloadSeriesViewModel +import java.util.UUID import kotlinx.coroutines.launch -import java.util.* @AndroidEntryPoint class DownloadSeriesFragment : Fragment() { @@ -32,7 +32,8 @@ class DownloadSeriesFragment : Fragment() { private val args: DownloadSeriesFragmentArgs by navArgs() override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, + inflater: LayoutInflater, + container: ViewGroup?, savedInstanceState: Bundle? ): View { binding = FragmentDownloadSeriesBinding.inflate(inflater, container, false) @@ -45,9 +46,12 @@ class DownloadSeriesFragment : Fragment() { binding.viewModel = viewModel binding.episodesRecyclerView.adapter = - DownloadEpisodeListAdapter(DownloadEpisodeListAdapter.OnClickListener { episode -> - navigateToEpisodeBottomSheetFragment(episode) - }, args.seriesMetadata) + DownloadEpisodeListAdapter( + DownloadEpisodeListAdapter.OnClickListener { episode -> + navigateToEpisodeBottomSheetFragment(episode) + }, + args.seriesMetadata + ) viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { @@ -94,4 +98,4 @@ class DownloadSeriesFragment : Fragment() { ) ) } -} \ 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 a7777c7d..2ab0881c 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/EpisodeBottomSheetFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/EpisodeBottomSheetFragment.kt @@ -26,11 +26,11 @@ import dev.jdtech.jellyfin.utils.setTintColor import dev.jdtech.jellyfin.utils.setTintColorAttribute import dev.jdtech.jellyfin.viewmodels.EpisodeBottomSheetViewModel import dev.jdtech.jellyfin.viewmodels.PlayerViewModel +import java.util.UUID import kotlinx.coroutines.launch import org.jellyfin.sdk.model.api.BaseItemKind import org.jellyfin.sdk.model.api.LocationType import timber.log.Timber -import java.util.* @AndroidEntryPoint class EpisodeBottomSheetFragment : BottomSheetDialogFragment() { @@ -50,7 +50,7 @@ class EpisodeBottomSheetFragment : BottomSheetDialogFragment() { binding.playButton.setOnClickListener { binding.playButton.setImageResource(android.R.color.transparent) binding.progressCircular.isVisible = true - if (viewModel.canRetry){ + if (viewModel.canRetry) { binding.playButton.isEnabled = false viewModel.download() return@setOnClickListener @@ -195,7 +195,6 @@ class EpisodeBottomSheetFragment : BottomSheetDialogFragment() { } } - binding.episodeName.text = String.format( getString(R.string.episode_name_extended), episode.parentIndexNumber, @@ -275,4 +274,4 @@ class EpisodeBottomSheetFragment : BottomSheetDialogFragment() { ) ) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/FavoriteFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/FavoriteFragment.kt index 963ff445..5c8501b3 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/FavoriteFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/FavoriteFragment.kt @@ -1,11 +1,11 @@ package dev.jdtech.jellyfin.fragments import android.os.Bundle -import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.core.view.isVisible +import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope @@ -32,7 +32,8 @@ class FavoriteFragment : Fragment() { private lateinit var errorDialog: ErrorDialogFragment override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, + inflater: LayoutInflater, + container: ViewGroup?, savedInstanceState: Bundle? ): View { binding = FragmentFavoriteBinding.inflate(inflater, container, false) @@ -40,9 +41,11 @@ class FavoriteFragment : Fragment() { binding.favoritesRecyclerView.adapter = FavoritesListAdapter( ViewItemListAdapter.OnClickListener { item -> navigateToMediaInfoFragment(item) - }, HomeEpisodeListAdapter.OnClickListener { item -> + }, + HomeEpisodeListAdapter.OnClickListener { item -> navigateToEpisodeBottomSheetFragment(item) - }) + } + ) viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { @@ -110,4 +113,4 @@ class FavoriteFragment : Fragment() { ) ) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/HomeFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/HomeFragment.kt index ad653229..1bb71e79 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/HomeFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/HomeFragment.kt @@ -57,21 +57,24 @@ class HomeFragment : Fragment() { super.onViewCreated(view, savedInstanceState) val menuHost: MenuHost = requireActivity() - menuHost.addMenuProvider(object : MenuProvider { - override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { - menuInflater.inflate(R.menu.home_menu, menu) - } - - override fun onMenuItemSelected(menuItem: MenuItem): Boolean { - return when (menuItem.itemId) { - R.id.action_settings -> { - navigateToSettingsFragment() - true - } - else -> false + menuHost.addMenuProvider( + object : MenuProvider { + override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { + menuInflater.inflate(R.menu.home_menu, menu) } - } - }, viewLifecycleOwner, Lifecycle.State.RESUMED) + + override fun onMenuItemSelected(menuItem: MenuItem): Boolean { + return when (menuItem.itemId) { + R.id.action_settings -> { + navigateToSettingsFragment() + true + } + else -> false + } + } + }, + viewLifecycleOwner, Lifecycle.State.RESUMED + ) } override fun onResume() { @@ -97,7 +100,8 @@ class HomeFragment : Fragment() { else -> Toast.makeText(requireContext(), R.string.unknown_error, LENGTH_LONG) .show() } - }) + } + ) binding.errorLayout.errorRetryButton.setOnClickListener { viewModel.loadData() @@ -190,4 +194,4 @@ class HomeFragment : Fragment() { HomeFragmentDirections.actionHomeFragmentToSettingsFragment() ) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/LibraryFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/LibraryFragment.kt index cb635204..093e6c6d 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/LibraryFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/LibraryFragment.kt @@ -4,7 +4,12 @@ import android.app.UiModeManager import android.content.SharedPreferences import android.content.res.Configuration import android.os.Bundle -import android.view.* +import android.view.LayoutInflater +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem +import android.view.View +import android.view.ViewGroup import androidx.appcompat.app.AppCompatActivity import androidx.core.view.MenuHost import androidx.core.view.MenuProvider @@ -20,18 +25,18 @@ import androidx.paging.LoadState import androidx.recyclerview.widget.LinearSnapHelper import dagger.hilt.android.AndroidEntryPoint import dev.jdtech.jellyfin.R -import dev.jdtech.jellyfin.viewmodels.LibraryViewModel import dev.jdtech.jellyfin.adapters.ViewItemPagingAdapter import dev.jdtech.jellyfin.databinding.FragmentLibraryBinding import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment import dev.jdtech.jellyfin.dialogs.SortDialogFragment import dev.jdtech.jellyfin.utils.SortBy import dev.jdtech.jellyfin.utils.checkIfLoginRequired +import dev.jdtech.jellyfin.viewmodels.LibraryViewModel +import java.lang.IllegalArgumentException +import javax.inject.Inject import kotlinx.coroutines.launch import org.jellyfin.sdk.model.api.BaseItemDto import org.jellyfin.sdk.model.api.SortOrder -import java.lang.IllegalArgumentException -import javax.inject.Inject @AndroidEntryPoint class LibraryFragment : Fragment() { @@ -47,7 +52,8 @@ class LibraryFragment : Fragment() { lateinit var sp: SharedPreferences override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, + inflater: LayoutInflater, + container: ViewGroup?, savedInstanceState: Bundle? ): View { binding = FragmentLibraryBinding.inflate(inflater, container, false) @@ -95,7 +101,8 @@ class LibraryFragment : Fragment() { else -> false } } - }, viewLifecycleOwner, Lifecycle.State.RESUMED + }, + viewLifecycleOwner, Lifecycle.State.RESUMED ) binding.title?.text = args.libraryName @@ -117,9 +124,11 @@ class LibraryFragment : Fragment() { } binding.itemsRecyclerView.adapter = - ViewItemPagingAdapter(ViewItemPagingAdapter.OnClickListener { item -> - navigateToMediaInfoFragment(item) - }) + ViewItemPagingAdapter( + ViewItemPagingAdapter.OnClickListener { item -> + navigateToMediaInfoFragment(item) + } + ) (binding.itemsRecyclerView.adapter as ViewItemPagingAdapter).addLoadStateListener { when (it.refresh) { @@ -214,4 +223,4 @@ class LibraryFragment : Fragment() { ) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/LoginFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/LoginFragment.kt index b8393412..709dfe98 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/LoginFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/LoginFragment.kt @@ -31,7 +31,8 @@ class LoginFragment : Fragment() { private val viewModel: LoginViewModel by viewModels() override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, + inflater: LayoutInflater, + container: ViewGroup?, savedInstanceState: Bundle? ): View { binding = FragmentLoginBinding.inflate(inflater) @@ -165,4 +166,4 @@ class LoginFragment : Fragment() { findNavController().navigate(LoginFragmentDirections.actionLoginFragmentToHomeFragment()) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaFragment.kt index 76daa03f..3734c86b 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaFragment.kt @@ -1,7 +1,13 @@ package dev.jdtech.jellyfin.fragments import android.os.Bundle -import android.view.* +import android.view.LayoutInflater +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem +import android.view.View +import android.view.ViewGroup +import android.view.WindowManager import androidx.appcompat.widget.SearchView import androidx.core.view.MenuHost import androidx.core.view.MenuProvider @@ -41,9 +47,11 @@ class MediaFragment : Fragment() { binding = FragmentMediaBinding.inflate(inflater, container, false) binding.viewsRecyclerView.adapter = - CollectionListAdapter(CollectionListAdapter.OnClickListener { library -> - navigateToLibraryFragment(library) - }) + CollectionListAdapter( + CollectionListAdapter.OnClickListener { library -> + navigateToLibraryFragment(library) + } + ) viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { @@ -73,32 +81,35 @@ class MediaFragment : Fragment() { super.onViewCreated(view, savedInstanceState) val menuHost: MenuHost = requireActivity() - menuHost.addMenuProvider(object : MenuProvider { - override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { - menuInflater.inflate(R.menu.media_menu, menu) + menuHost.addMenuProvider( + object : MenuProvider { + override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { + menuInflater.inflate(R.menu.media_menu, menu) - val search = menu.findItem(R.id.action_search) - val searchView = search.actionView as SearchView - searchView.queryHint = getString(R.string.search_hint) + val search = menu.findItem(R.id.action_search) + val searchView = search.actionView as SearchView + searchView.queryHint = getString(R.string.search_hint) - searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { - override fun onQueryTextSubmit(p0: String?): Boolean { - if (p0 != null) { - navigateToSearchResultFragment(p0) + searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { + override fun onQueryTextSubmit(p0: String?): Boolean { + if (p0 != null) { + navigateToSearchResultFragment(p0) + } + return true } - return true - } - override fun onQueryTextChange(p0: String?): Boolean { - return false - } - }) - } + override fun onQueryTextChange(p0: String?): Boolean { + return false + } + }) + } - override fun onMenuItemSelected(menuItem: MenuItem): Boolean { - return true - } - }, viewLifecycleOwner, Lifecycle.State.RESUMED) + override fun onMenuItemSelected(menuItem: MenuItem): Boolean { + return true + } + }, + viewLifecycleOwner, Lifecycle.State.RESUMED + ) } override fun onStart() { @@ -133,7 +144,6 @@ class MediaFragment : Fragment() { binding.viewsRecyclerView.isVisible = false binding.errorLayout.errorPanel.isVisible = true checkIfLoginRequired(uiState.error.message) - } private fun navigateToLibraryFragment(library: BaseItemDto) { @@ -151,4 +161,4 @@ class MediaFragment : Fragment() { MediaFragmentDirections.actionNavigationMediaToSearchResultFragment(query) ) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaInfoFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaInfoFragment.kt index c7fdca57..7655ab0b 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaInfoFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaInfoFragment.kt @@ -31,11 +31,11 @@ import dev.jdtech.jellyfin.utils.setTintColor import dev.jdtech.jellyfin.utils.setTintColorAttribute import dev.jdtech.jellyfin.viewmodels.MediaInfoViewModel import dev.jdtech.jellyfin.viewmodels.PlayerViewModel +import java.util.UUID import kotlinx.coroutines.launch import org.jellyfin.sdk.model.api.BaseItemDto import org.jellyfin.sdk.model.api.BaseItemKind import timber.log.Timber -import java.util.UUID @AndroidEntryPoint class MediaInfoFragment : Fragment() { @@ -48,7 +48,8 @@ class MediaInfoFragment : Fragment() { lateinit var errorDialog: ErrorDialogFragment override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, + inflater: LayoutInflater, + container: ViewGroup?, savedInstanceState: Bundle? ): View { binding = FragmentMediaInfoBinding.inflate(inflater, container, false) @@ -111,9 +112,12 @@ class MediaInfoFragment : Fragment() { } binding.seasonsRecyclerView.adapter = - ViewItemListAdapter(ViewItemListAdapter.OnClickListener { season -> - navigateToSeasonFragment(season) - }, fixedWidth = true) + ViewItemListAdapter( + ViewItemListAdapter.OnClickListener { season -> + navigateToSeasonFragment(season) + }, + fixedWidth = true + ) binding.peopleRecyclerView.adapter = PersonListAdapter { person -> navigateToPersonDetail(person.id) } @@ -121,7 +125,7 @@ class MediaInfoFragment : Fragment() { binding.playButton.setOnClickListener { binding.playButton.setImageResource(android.R.color.transparent) binding.progressCircular.isVisible = true - if (viewModel.canRetry){ + if (viewModel.canRetry) { binding.playButton.isEnabled = false viewModel.download() return@setOnClickListener @@ -187,7 +191,6 @@ class MediaInfoFragment : Fragment() { ) ) } - } else { binding.favoriteButton.isVisible = false binding.checkButton.isVisible = false @@ -225,7 +228,6 @@ class MediaInfoFragment : Fragment() { false -> binding.checkButton.setTintColorAttribute(R.attr.colorOnSecondaryContainer, requireActivity().theme) } - // Favorite icon val favoriteDrawable = when (favorite) { true -> R.drawable.ic_heart_filled @@ -248,7 +250,6 @@ class MediaInfoFragment : Fragment() { } } - binding.name.text = item.name binding.originalTitle.text = item.originalTitle if (dateString.isEmpty()) { @@ -363,4 +364,4 @@ class MediaInfoFragment : Fragment() { MediaInfoFragmentDirections.actionMediaInfoFragmentToPersonDetailFragment(personId) ) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/PersonDetailFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/PersonDetailFragment.kt index cea77ed4..c91c8011 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/PersonDetailFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/PersonDetailFragment.kt @@ -146,4 +146,4 @@ internal class PersonDetailFragment : Fragment() { ) ) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/SearchResultFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/SearchResultFragment.kt index ece3a79e..623d4684 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/SearchResultFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/SearchResultFragment.kt @@ -1,11 +1,11 @@ package dev.jdtech.jellyfin.fragments import android.os.Bundle -import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.core.view.isVisible +import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope @@ -34,7 +34,8 @@ class SearchResultFragment : Fragment() { private lateinit var errorDialog: ErrorDialogFragment override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, + inflater: LayoutInflater, + container: ViewGroup?, savedInstanceState: Bundle? ): View { binding = FragmentSearchResultBinding.inflate(inflater, container, false) @@ -42,9 +43,11 @@ class SearchResultFragment : Fragment() { binding.searchResultsRecyclerView.adapter = FavoritesListAdapter( ViewItemListAdapter.OnClickListener { item -> navigateToMediaInfoFragment(item) - }, HomeEpisodeListAdapter.OnClickListener { item -> + }, + HomeEpisodeListAdapter.OnClickListener { item -> navigateToEpisodeBottomSheetFragment(item) - }) + } + ) viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { @@ -73,7 +76,6 @@ class SearchResultFragment : Fragment() { errorDialog.show(parentFragmentManager, "errordialog") } - return binding.root } @@ -119,4 +121,4 @@ class SearchResultFragment : Fragment() { ) ) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/SeasonFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/SeasonFragment.kt index bf24b2a1..8106e1a3 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/SeasonFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/SeasonFragment.kt @@ -1,11 +1,11 @@ package dev.jdtech.jellyfin.fragments import android.os.Bundle -import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.core.view.isVisible +import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope @@ -32,7 +32,8 @@ class SeasonFragment : Fragment() { private lateinit var errorDialog: ErrorDialogFragment override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, + inflater: LayoutInflater, + container: ViewGroup?, savedInstanceState: Bundle? ): View { binding = FragmentSeasonBinding.inflate(inflater, container, false) @@ -70,10 +71,12 @@ class SeasonFragment : Fragment() { } binding.episodesRecyclerView.adapter = - EpisodeListAdapter(EpisodeListAdapter.OnClickListener { episode -> - navigateToEpisodeBottomSheetFragment(episode) - }, args.seriesId, args.seriesName, args.seasonId, args.seasonName) - + EpisodeListAdapter( + EpisodeListAdapter.OnClickListener { episode -> + navigateToEpisodeBottomSheetFragment(episode) + }, + args.seriesId, args.seriesName, args.seasonId, args.seasonName + ) } private fun bindUiStateNormal(uiState: SeasonViewModel.UiState.Normal) { @@ -106,4 +109,4 @@ class SeasonFragment : Fragment() { ) ) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/ServerSelectFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/ServerSelectFragment.kt index 77c7bc39..63de875a 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/ServerSelectFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/ServerSelectFragment.kt @@ -1,19 +1,19 @@ package dev.jdtech.jellyfin.fragments import android.os.Bundle -import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import androidx.navigation.fragment.findNavController import dagger.hilt.android.AndroidEntryPoint +import dev.jdtech.jellyfin.adapters.ServerGridAdapter import dev.jdtech.jellyfin.databinding.FragmentServerSelectBinding import dev.jdtech.jellyfin.dialogs.DeleteServerDialogFragment -import dev.jdtech.jellyfin.adapters.ServerGridAdapter import dev.jdtech.jellyfin.viewmodels.ServerSelectViewModel import kotlinx.coroutines.launch @@ -24,7 +24,8 @@ class ServerSelectFragment : Fragment() { private val viewModel: ServerSelectViewModel by viewModels() override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, + inflater: LayoutInflater, + container: ViewGroup?, savedInstanceState: Bundle? ): View { binding = FragmentServerSelectBinding.inflate(inflater) @@ -34,15 +35,18 @@ class ServerSelectFragment : Fragment() { binding.viewModel = viewModel binding.serversRecyclerView.adapter = - ServerGridAdapter(ServerGridAdapter.OnClickListener { server -> - viewModel.connectToServer(server) - }, ServerGridAdapter.OnLongClickListener { server -> - DeleteServerDialogFragment(viewModel, server).show( - parentFragmentManager, - "deleteServer" - ) - true - }) + ServerGridAdapter( + ServerGridAdapter.OnClickListener { server -> + viewModel.connectToServer(server) + }, + ServerGridAdapter.OnLongClickListener { server -> + DeleteServerDialogFragment(viewModel, server).show( + parentFragmentManager, + "deleteServer" + ) + true + } + ) binding.buttonAddServer.setOnClickListener { navigateToAddServerFragment() @@ -70,4 +74,4 @@ class ServerSelectFragment : Fragment() { private fun navigateToMainActivity() { findNavController().navigate(ServerSelectFragmentDirections.actionServerSelectFragmentToHomeFragment()) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsAppearanceFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsAppearanceFragment.kt index f45c4237..fecec562 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsAppearanceFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsAppearanceFragment.kt @@ -20,4 +20,4 @@ class SettingsAppearanceFragment : PreferenceFragmentCompat() { true } } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsCacheFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsCacheFragment.kt index df97e1b7..09ee661f 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsCacheFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsCacheFragment.kt @@ -15,4 +15,4 @@ class SettingsCacheFragment : PreferenceFragmentCompat() { editText.inputType = InputType.TYPE_CLASS_NUMBER } } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsDeviceFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsDeviceFragment.kt index aeea1b5c..b4af947a 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsDeviceFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsDeviceFragment.kt @@ -22,4 +22,4 @@ class SettingsDeviceFragment : PreferenceFragmentCompat() { true } } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsDownloadsFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsDownloadsFragment.kt index cb5e4994..93d58cc1 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsDownloadsFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsDownloadsFragment.kt @@ -9,4 +9,4 @@ class SettingsDownloadsFragment : PreferenceFragmentCompat() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.fragment_settings_downloads, rootKey) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsFragment.kt index dcbf4ba5..3c088ab5 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsFragment.kt @@ -8,7 +8,7 @@ import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import dev.jdtech.jellyfin.R -class SettingsFragment: PreferenceFragmentCompat() { +class SettingsFragment : PreferenceFragmentCompat() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.fragment_settings, rootKey) @@ -31,4 +31,4 @@ class SettingsFragment: PreferenceFragmentCompat() { true } } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsLanguageFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsLanguageFragment.kt index 213f9f5f..0792803d 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsLanguageFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsLanguageFragment.kt @@ -9,4 +9,4 @@ class SettingsLanguageFragment : PreferenceFragmentCompat() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.fragment_settings_language, rootKey) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsPlayerFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsPlayerFragment.kt index f08c949a..0db0e5eb 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsPlayerFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/SettingsPlayerFragment.kt @@ -24,4 +24,4 @@ class SettingsPlayerFragment : PreferenceFragmentCompat() { true } } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/TwoPaneSettingsFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/TwoPaneSettingsFragment.kt index c79de4f5..ec5fef40 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/TwoPaneSettingsFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/TwoPaneSettingsFragment.kt @@ -7,4 +7,4 @@ class TwoPaneSettingsFragment : PreferenceHeaderFragmentCompat() { override fun onCreatePreferenceHeader(): PreferenceFragmentCompat { return SettingsFragment() } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/models/CollectionType.kt b/app/src/main/java/dev/jdtech/jellyfin/models/CollectionType.kt index 114968d3..0a523d8e 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/models/CollectionType.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/models/CollectionType.kt @@ -13,4 +13,4 @@ enum class CollectionType(val type: String) { HomeVideos, Music, Playlists, Books, LiveTv, BoxSets ) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/models/DiscoveredServer.kt b/app/src/main/java/dev/jdtech/jellyfin/models/DiscoveredServer.kt index acc548c3..bb34caa8 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/models/DiscoveredServer.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/models/DiscoveredServer.kt @@ -4,4 +4,4 @@ data class DiscoveredServer( val id: String, val name: String, val address: String -) \ No newline at end of file +) diff --git a/app/src/main/java/dev/jdtech/jellyfin/models/DownloadItem.kt b/app/src/main/java/dev/jdtech/jellyfin/models/DownloadItem.kt index 4664e8f3..e6d7ffb1 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/models/DownloadItem.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/models/DownloadItem.kt @@ -3,9 +3,9 @@ package dev.jdtech.jellyfin.models import android.os.Parcelable import androidx.room.Entity import androidx.room.PrimaryKey +import java.util.UUID import kotlinx.parcelize.Parcelize import org.jellyfin.sdk.model.api.BaseItemKind -import java.util.* @Parcelize @Entity(tableName = "downloads") @@ -23,4 +23,4 @@ data class DownloadItem( val playbackPosition: Long? = null, val playedPercentage: Double? = null, val downloadId: Long? = null, -) : Parcelable \ No newline at end of file +) : Parcelable diff --git a/app/src/main/java/dev/jdtech/jellyfin/models/DownloadSection.kt b/app/src/main/java/dev/jdtech/jellyfin/models/DownloadSection.kt index 74862086..e03b5b0f 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/models/DownloadSection.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/models/DownloadSection.kt @@ -1,10 +1,10 @@ package dev.jdtech.jellyfin.models -import java.util.* +import java.util.UUID data class DownloadSection( val id: UUID, val name: String, val items: List? = null, val series: List? = null -) \ No newline at end of file +) diff --git a/app/src/main/java/dev/jdtech/jellyfin/models/DownloadSeriesMetadata.kt b/app/src/main/java/dev/jdtech/jellyfin/models/DownloadSeriesMetadata.kt index 1343848d..8ad88bb9 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/models/DownloadSeriesMetadata.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/models/DownloadSeriesMetadata.kt @@ -1,12 +1,12 @@ package dev.jdtech.jellyfin.models import android.os.Parcelable +import java.util.UUID import kotlinx.parcelize.Parcelize -import java.util.* @Parcelize data class DownloadSeriesMetadata( val itemId: UUID, val name: String? = null, val episodes: List -) : Parcelable \ No newline at end of file +) : Parcelable diff --git a/app/src/main/java/dev/jdtech/jellyfin/models/ExternalSubtitle.kt b/app/src/main/java/dev/jdtech/jellyfin/models/ExternalSubtitle.kt index 99d35c60..cfe5e4a0 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/models/ExternalSubtitle.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/models/ExternalSubtitle.kt @@ -10,4 +10,4 @@ class ExternalSubtitle( val language: String, val uri: Uri, val mimeType: String, -) : Parcelable \ No newline at end of file +) : Parcelable diff --git a/app/src/main/java/dev/jdtech/jellyfin/models/FavoriteSection.kt b/app/src/main/java/dev/jdtech/jellyfin/models/FavoriteSection.kt index d1926471..b2d4aca1 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/models/FavoriteSection.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/models/FavoriteSection.kt @@ -6,4 +6,4 @@ data class FavoriteSection( val id: Int, val name: String, var items: List -) \ No newline at end of file +) diff --git a/app/src/main/java/dev/jdtech/jellyfin/models/HomeSection.kt b/app/src/main/java/dev/jdtech/jellyfin/models/HomeSection.kt index 025531ac..b2a27c4b 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/models/HomeSection.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/models/HomeSection.kt @@ -1,10 +1,10 @@ package dev.jdtech.jellyfin.models +import java.util.UUID import org.jellyfin.sdk.model.api.BaseItemDto -import java.util.* data class HomeSection( val id: UUID, val name: String, var items: List -) \ No newline at end of file +) diff --git a/app/src/main/java/dev/jdtech/jellyfin/models/PlayerItem.kt b/app/src/main/java/dev/jdtech/jellyfin/models/PlayerItem.kt index dfa08e35..79ba5906 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/models/PlayerItem.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/models/PlayerItem.kt @@ -1,8 +1,8 @@ package dev.jdtech.jellyfin.models import android.os.Parcelable -import kotlinx.parcelize.Parcelize import java.util.UUID +import kotlinx.parcelize.Parcelize @Parcelize data class PlayerItem( @@ -15,4 +15,4 @@ data class PlayerItem( val indexNumber: Int? = null, val item: DownloadItem? = null, val externalSubtitles: List = emptyList() -) : Parcelable \ No newline at end of file +) : Parcelable diff --git a/app/src/main/java/dev/jdtech/jellyfin/models/User.kt b/app/src/main/java/dev/jdtech/jellyfin/models/User.kt index 13b9ac08..e9c8d480 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/models/User.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/models/User.kt @@ -5,4 +5,4 @@ import java.util.UUID data class User( val id: UUID, val name: String -) \ No newline at end of file +) diff --git a/app/src/main/java/dev/jdtech/jellyfin/models/View.kt b/app/src/main/java/dev/jdtech/jellyfin/models/View.kt index 52ce76dd..01ca888d 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/models/View.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/models/View.kt @@ -1,11 +1,11 @@ package dev.jdtech.jellyfin.models -import org.jellyfin.sdk.model.api.BaseItemDto import java.util.UUID +import org.jellyfin.sdk.model.api.BaseItemDto data class View( val id: UUID, val name: String?, var items: List? = null, val type: String? -) \ No newline at end of file +) diff --git a/app/src/main/java/dev/jdtech/jellyfin/mpv/MPVPlayer.kt b/app/src/main/java/dev/jdtech/jellyfin/mpv/MPVPlayer.kt index e7ec39ff..89b04e01 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/mpv/MPVPlayer.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/mpv/MPVPlayer.kt @@ -1,6 +1,5 @@ package dev.jdtech.jellyfin.mpv -import `is`.xyz.mpv.MPVLib import android.app.Application import android.content.Context import android.content.res.AssetManager @@ -13,24 +12,39 @@ import android.view.SurfaceHolder import android.view.SurfaceView import android.view.TextureView import androidx.core.content.getSystemService -import com.google.android.exoplayer2.* +import com.google.android.exoplayer2.BasePlayer +import com.google.android.exoplayer2.C +import com.google.android.exoplayer2.DeviceInfo +import com.google.android.exoplayer2.ExoPlaybackException +import com.google.android.exoplayer2.Format +import com.google.android.exoplayer2.MediaItem +import com.google.android.exoplayer2.MediaMetadata +import com.google.android.exoplayer2.PlaybackParameters +import com.google.android.exoplayer2.Player import com.google.android.exoplayer2.Player.Commands +import com.google.android.exoplayer2.Timeline +import com.google.android.exoplayer2.Tracks import com.google.android.exoplayer2.audio.AudioAttributes import com.google.android.exoplayer2.source.TrackGroup import com.google.android.exoplayer2.text.Cue import com.google.android.exoplayer2.text.CueGroup import com.google.android.exoplayer2.trackselection.TrackSelectionParameters -import com.google.android.exoplayer2.util.* +import com.google.android.exoplayer2.util.Clock +import com.google.android.exoplayer2.util.FlagSet +import com.google.android.exoplayer2.util.ListenerSet +import com.google.android.exoplayer2.util.MimeTypes +import com.google.android.exoplayer2.util.Util import com.google.android.exoplayer2.video.VideoSize import dev.jdtech.jellyfin.utils.AppPreferences +import `is`.xyz.mpv.MPVLib +import java.io.File +import java.io.FileOutputStream +import java.util.concurrent.CopyOnWriteArraySet import kotlinx.parcelize.Parcelize import org.json.JSONArray import org.json.JSONException import org.json.JSONObject import timber.log.Timber -import java.io.File -import java.io.FileOutputStream -import java.util.concurrent.CopyOnWriteArraySet @Suppress("SpellCheckingInspection") class MPVPlayer( @@ -627,16 +641,16 @@ class MPVPlayer( .addIf(COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM, hasPreviousMediaItem() && !isPlayingAd) .addIf( COMMAND_SEEK_TO_PREVIOUS, - !currentTimeline.isEmpty - && (hasPreviousMediaItem() || !isCurrentMediaItemLive || isCurrentMediaItemSeekable) - && !isPlayingAd + !currentTimeline.isEmpty && + (hasPreviousMediaItem() || !isCurrentMediaItemLive || isCurrentMediaItemSeekable) && + !isPlayingAd ) .addIf(COMMAND_SEEK_TO_NEXT_MEDIA_ITEM, hasNextMediaItem() && !isPlayingAd) .addIf( COMMAND_SEEK_TO_NEXT, - !currentTimeline.isEmpty - && (hasNextMediaItem() || (isCurrentMediaItemLive && isCurrentMediaItemDynamic)) - && !isPlayingAd + !currentTimeline.isEmpty && + (hasNextMediaItem() || (isCurrentMediaItemLive && isCurrentMediaItemDynamic)) && + !isPlayingAd ) .addIf(COMMAND_SEEK_TO_MEDIA_ITEM, !isPlayingAd) .addIf(COMMAND_SEEK_BACK, isCurrentMediaItemSeekable && !isPlayingAd) @@ -655,7 +669,7 @@ class MPVPlayer( tracks = Tracks.EMPTY playbackParameters = PlaybackParameters.DEFAULT initialCommands.clear() - //initialSeekTo = 0L + // initialSeekTo = 0L } /** Prepares the player. */ @@ -1212,8 +1226,7 @@ class MPVPlayer( MPVLib.setOptionString("panscan", "1") MPVLib.setOptionString("sub-use-margins", "yes") MPVLib.setOptionString("sub-ass-force-margins", "yes") - } - else { + } else { MPVLib.setOptionString("panscan", "0") MPVLib.setOptionString("sub-use-margins", "no") MPVLib.setOptionString("sub-ass-force-margins", "no") @@ -1409,7 +1422,8 @@ class MPVPlayer( IntArray(this.length) { C.FORMAT_HANDLED }, BooleanArray(this.length) { it == indexCurrentVideo } ) - }) + } + ) } if (trackListAudio.isNotEmpty()) { trackGroups.add( @@ -1420,7 +1434,8 @@ class MPVPlayer( IntArray(this.length) { C.FORMAT_HANDLED }, BooleanArray(this.length) { it == indexCurrentAudio } ) - }) + } + ) } if (trackListText.isNotEmpty()) { trackGroups.add( @@ -1431,7 +1446,8 @@ class MPVPlayer( IntArray(this.length) { C.FORMAT_HANDLED }, BooleanArray(this.length) { it == indexCurrentText } ) - }) + } + ) } if (trackGroups.isNotEmpty()) { tracks = Tracks(trackGroups) diff --git a/app/src/main/java/dev/jdtech/jellyfin/repository/ItemsPagingSource.kt b/app/src/main/java/dev/jdtech/jellyfin/repository/ItemsPagingSource.kt index 0939b88d..a0ec0cfa 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/repository/ItemsPagingSource.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/repository/ItemsPagingSource.kt @@ -4,11 +4,11 @@ import androidx.paging.PagingSource import androidx.paging.PagingState import dev.jdtech.jellyfin.api.JellyfinApi import dev.jdtech.jellyfin.utils.SortBy +import java.util.UUID import org.jellyfin.sdk.model.api.BaseItemDto import org.jellyfin.sdk.model.api.BaseItemKind import org.jellyfin.sdk.model.api.SortOrder import timber.log.Timber -import java.util.* class ItemsPagingSource( private val jellyfinApi: JellyfinApi, @@ -25,14 +25,14 @@ class ItemsPagingSource( return try { val response = jellyfinApi.itemsApi.getItems( - jellyfinApi.userId!!, - parentId = parentId, - includeItemTypes = includeTypes, - recursive = recursive, - sortBy = listOf(sortBy.SortString), - sortOrder = listOf(sortOrder), - startIndex = position, - limit = params.loadSize + jellyfinApi.userId!!, + parentId = parentId, + includeItemTypes = includeTypes, + recursive = recursive, + sortBy = listOf(sortBy.SortString), + sortOrder = listOf(sortOrder), + startIndex = position, + limit = params.loadSize ).content.items.orEmpty() LoadResult.Page( data = response, @@ -47,4 +47,4 @@ class ItemsPagingSource( override fun getRefreshKey(state: PagingState): Int { return 0 } -} \ 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 index 27493b01..38e6f2f3 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/repository/JellyfinRepository.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/repository/JellyfinRepository.kt @@ -1,11 +1,14 @@ package dev.jdtech.jellyfin.repository - import androidx.paging.PagingData import dev.jdtech.jellyfin.utils.SortBy +import java.util.UUID import kotlinx.coroutines.flow.Flow -import org.jellyfin.sdk.model.api.* -import java.util.* +import org.jellyfin.sdk.model.api.BaseItemDto +import org.jellyfin.sdk.model.api.BaseItemKind +import org.jellyfin.sdk.model.api.ItemFields +import org.jellyfin.sdk.model.api.MediaSourceInfo +import org.jellyfin.sdk.model.api.SortOrder interface JellyfinRepository { suspend fun getUserViews(): List @@ -78,4 +81,4 @@ interface JellyfinRepository { fun getBaseUrl(): String suspend fun updateDeviceName(name: String) -} \ 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 index a3f16ac8..cc6cc137 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/repository/JellyfinRepositoryImpl.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/repository/JellyfinRepositoryImpl.kt @@ -5,12 +5,25 @@ import androidx.paging.PagingConfig import androidx.paging.PagingData import dev.jdtech.jellyfin.api.JellyfinApi import dev.jdtech.jellyfin.utils.SortBy +import java.util.UUID import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.withContext -import org.jellyfin.sdk.model.api.* +import org.jellyfin.sdk.model.api.BaseItemDto +import org.jellyfin.sdk.model.api.BaseItemKind +import org.jellyfin.sdk.model.api.DeviceOptionsDto +import org.jellyfin.sdk.model.api.DeviceProfile +import org.jellyfin.sdk.model.api.DirectPlayProfile +import org.jellyfin.sdk.model.api.DlnaProfileType +import org.jellyfin.sdk.model.api.GeneralCommandType +import org.jellyfin.sdk.model.api.ItemFields +import org.jellyfin.sdk.model.api.ItemFilter +import org.jellyfin.sdk.model.api.MediaSourceInfo +import org.jellyfin.sdk.model.api.PlaybackInfoDto +import org.jellyfin.sdk.model.api.SortOrder +import org.jellyfin.sdk.model.api.SubtitleDeliveryMethod +import org.jellyfin.sdk.model.api.SubtitleProfile import timber.log.Timber -import java.util.* class JellyfinRepositoryImpl(private val jellyfinApi: JellyfinApi) : JellyfinRepository { override suspend fun getUserViews(): List = withContext(Dispatchers.IO) { @@ -150,7 +163,8 @@ class JellyfinRepositoryImpl(private val jellyfinApi: JellyfinApi) : JellyfinRep override suspend fun getMediaSources(itemId: UUID): List = withContext(Dispatchers.IO) { jellyfinApi.mediaInfoApi.getPostedPlaybackInfo( - itemId, PlaybackInfoDto( + itemId, + PlaybackInfoDto( userId = jellyfinApi.userId!!, deviceProfile = DeviceProfile( name = "Direct play all", @@ -220,7 +234,8 @@ class JellyfinRepositoryImpl(private val jellyfinApi: JellyfinApi) : JellyfinRep GeneralCommandType.PLAY_STATE, GeneralCommandType.PLAY_NEXT, GeneralCommandType.PLAY_MEDIA_SOURCE - ), supportsMediaControl = true + ), + supportsMediaControl = true ) } } diff --git a/app/src/main/java/dev/jdtech/jellyfin/tv/TvPlayerActivity.kt b/app/src/main/java/dev/jdtech/jellyfin/tv/TvPlayerActivity.kt index 26514704..a33b6c2f 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/tv/TvPlayerActivity.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/tv/TvPlayerActivity.kt @@ -70,13 +70,15 @@ internal class TvPlayerActivity : BasePlayerActivity() { when { viewModel.player.isPlaying -> { viewModel.player.pause() - setImageDrawable(ResourcesCompat.getDrawable(resources, R.drawable.ic_play, theme) + setImageDrawable( + ResourcesCompat.getDrawable(resources, R.drawable.ic_play, theme) ) } viewModel.player.isLoading -> Unit else -> { viewModel.player.play() - setImageDrawable(ResourcesCompat.getDrawable(resources, R.drawable.ic_play, theme) + setImageDrawable( + ResourcesCompat.getDrawable(resources, R.drawable.ic_play, theme) ) } } @@ -155,4 +157,4 @@ internal class TvPlayerActivity : BasePlayerActivity() { return popup } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/tv/ui/HomeFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/tv/ui/HomeFragment.kt index 73a70b2f..d8eddf41 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/tv/ui/HomeFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/tv/ui/HomeFragment.kt @@ -10,7 +10,11 @@ import android.widget.ImageButton import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.viewModels import androidx.leanback.app.BrowseSupportFragment -import androidx.leanback.widget.* +import androidx.leanback.widget.ArrayObjectAdapter +import androidx.leanback.widget.DiffCallback +import androidx.leanback.widget.HeaderItem +import androidx.leanback.widget.ListRow +import androidx.leanback.widget.ListRowPresenter import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle @@ -146,15 +150,21 @@ internal class HomeFragment : BrowseSupportFragment() { adapterMap[name]?.setItems(items, diffCallback) } else { adapterMap[name] = when (this) { - is HomeItem.Libraries -> ArrayObjectAdapter(LibaryItemPresenter { item -> - navigateToLibraryFragment(item) - }).apply { setItems(items, diffCallback) } - is HomeItem.Section -> ArrayObjectAdapter(DynamicMediaItemPresenter { item -> - navigateToMediaDetailFragment(item) - }).apply { setItems(items, diffCallback) } - is HomeItem.ViewItem -> ArrayObjectAdapter(MediaItemPresenter { item -> - navigateToMediaDetailFragment(item) - }).apply { setItems(items, diffCallback) } + is HomeItem.Libraries -> ArrayObjectAdapter( + LibaryItemPresenter { item -> + navigateToLibraryFragment(item) + } + ).apply { setItems(items, diffCallback) } + is HomeItem.Section -> ArrayObjectAdapter( + DynamicMediaItemPresenter { item -> + navigateToMediaDetailFragment(item) + } + ).apply { setItems(items, diffCallback) } + is HomeItem.ViewItem -> ArrayObjectAdapter( + MediaItemPresenter { item -> + navigateToMediaDetailFragment(item) + } + ).apply { setItems(items, diffCallback) } } } diff --git a/app/src/main/java/dev/jdtech/jellyfin/tv/ui/MediaDetailFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/tv/ui/MediaDetailFragment.kt index 0311e392..0d38a918 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/tv/ui/MediaDetailFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/tv/ui/MediaDetailFragment.kt @@ -76,7 +76,8 @@ internal class MediaDetailFragment : Fragment() { val seasonsAdapter = ViewItemListAdapter( fixedWidth = true, - onClickListener = ViewItemListAdapter.OnClickListener {}) + onClickListener = ViewItemListAdapter.OnClickListener {} + ) binding.seasonsRow.gridView.adapter = seasonsAdapter binding.seasonsRow.gridView.verticalSpacing = 25 @@ -254,4 +255,4 @@ internal class MediaDetailFragment : Fragment() { ) ) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/tv/ui/MediaSectionPresenter.kt b/app/src/main/java/dev/jdtech/jellyfin/tv/ui/MediaSectionPresenter.kt index 9f72ffdf..1a84f3ee 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/tv/ui/MediaSectionPresenter.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/tv/ui/MediaSectionPresenter.kt @@ -105,4 +105,4 @@ class DynamicMediaItemPresenter(private val onClick: (BaseItemDto) -> Unit) : Pr } override fun onUnbindViewHolder(viewHolder: ViewHolder) = Unit -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/tv/ui/TrackSelectorAdapter.kt b/app/src/main/java/dev/jdtech/jellyfin/tv/ui/TrackSelectorAdapter.kt index 600c93ec..ffe127a1 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/tv/ui/TrackSelectorAdapter.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/tv/ui/TrackSelectorAdapter.kt @@ -68,4 +68,4 @@ class TrackSelectorAdapter( val selected: Boolean, val playerTrack: MPVPlayer.Companion.Track ) -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/utils/Constants.kt b/app/src/main/java/dev/jdtech/jellyfin/utils/Constants.kt index 3ab5d43c..347a3e0e 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/utils/Constants.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/utils/Constants.kt @@ -27,4 +27,4 @@ object Constants { const val FAVORITE_TYPE_MOVIES = 0 const val FAVORITE_TYPE_SHOWS = 1 const val FAVORITE_TYPE_EPISODES = 2 -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/utils/DownloadUtilities.kt b/app/src/main/java/dev/jdtech/jellyfin/utils/DownloadUtilities.kt index 636e7be6..b6bde7de 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/utils/DownloadUtilities.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/utils/DownloadUtilities.kt @@ -11,12 +11,12 @@ import dev.jdtech.jellyfin.models.DownloadItem import dev.jdtech.jellyfin.models.DownloadSeriesMetadata import dev.jdtech.jellyfin.models.PlayerItem import dev.jdtech.jellyfin.repository.JellyfinRepository +import java.io.File +import java.util.UUID import org.jellyfin.sdk.model.api.BaseItemDto import org.jellyfin.sdk.model.api.BaseItemKind import org.jellyfin.sdk.model.api.UserItemDataDto import timber.log.Timber -import java.io.File -import java.util.UUID var defaultStorage: File? = null @@ -76,7 +76,7 @@ fun loadDownloadLocation(context: Context) { fun checkDownloadStatus(downloadDatabase: DownloadDatabaseDao, context: Context) { val items = downloadDatabase.loadItems() for (item in items) { - try{ + try { val query = DownloadManager.Query() .setFilterById(item.downloadId!!) val result = context.getSystemService()!!.query(query) @@ -156,7 +156,6 @@ fun deleteDownloadedEpisode(downloadDatabase: DownloadDatabaseDao, itemId: UUID) } catch (e: Exception) { Timber.e(e) } - } fun postDownloadPlaybackProgress( @@ -277,6 +276,5 @@ suspend fun syncPlaybackProgress( } catch (e: Exception) { Timber.e(e) } - } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/utils/PlayerGestureHelper.kt b/app/src/main/java/dev/jdtech/jellyfin/utils/PlayerGestureHelper.kt index 40a1ac74..f141e4ca 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/utils/PlayerGestureHelper.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/utils/PlayerGestureHelper.kt @@ -14,15 +14,15 @@ import com.google.android.exoplayer2.ui.AspectRatioFrameLayout import com.google.android.exoplayer2.ui.StyledPlayerView import dev.jdtech.jellyfin.PlayerActivity import dev.jdtech.jellyfin.mpv.MPVPlayer -import timber.log.Timber import kotlin.math.abs +import timber.log.Timber class PlayerGestureHelper( private val appPreferences: AppPreferences, private val activity: PlayerActivity, private val playerView: StyledPlayerView, private val audioManager: AudioManager -) { +) { /** * Tracks whether video content should fill the screen, cutting off unwanted content on the sides. * Useful on wide-screen phones to remove black bars from some movies. @@ -45,133 +45,143 @@ class PlayerGestureHelper( private var lastScaleEvent: Long = 0 - private val tapGestureDetector = GestureDetector(playerView.context, object : GestureDetector.SimpleOnGestureListener() { - override fun onSingleTapConfirmed(e: MotionEvent): Boolean { - playerView.apply { - if (!isControllerFullyVisible) showController() else hideController() - } - - return true - } - - override fun onDoubleTap(e: MotionEvent): Boolean { - val viewCenterX = playerView.measuredWidth / 2 - val currentPos = playerView.player?.currentPosition ?: 0 - - if (e.x.toInt() > viewCenterX) { - playerView.player?.seekTo(currentPos + appPreferences.playerSeekForwardIncrement) - } - else { - playerView.player?.seekTo((currentPos - appPreferences.playerSeekBackIncrement).coerceAtLeast(0)) - } - return true - } - }) - - private val gestureDetector = GestureDetector(playerView.context, object : GestureDetector.SimpleOnGestureListener() { - override fun onSingleTapConfirmed(e: MotionEvent): Boolean { - playerView.apply { - if (!isControllerFullyVisible) showController() else hideController() - } - - return true - } - - override fun onDoubleTap(e: MotionEvent): Boolean { - val viewCenterX = playerView.measuredWidth / 2 - val currentPos = playerView.player?.currentPosition ?: 0 - - if (e.x.toInt() > viewCenterX) { - playerView.player?.seekTo(currentPos + appPreferences.playerSeekForwardIncrement) - } - else { - playerView.player?.seekTo((currentPos - appPreferences.playerSeekBackIncrement).coerceAtLeast(0)) - } - return true - } - - @SuppressLint("SetTextI18n") - override fun onScroll(firstEvent: MotionEvent, currentEvent: MotionEvent, distanceX: Float, distanceY: Float): Boolean { - if (firstEvent.y < playerView.resources.dip(Constants.GESTURE_EXCLUSION_AREA_TOP)) - return false - - // Check whether swipe was oriented vertically - if (abs(distanceY / distanceX) < 2) { - return if ((abs(currentEvent.x - firstEvent.x) > 50 || swipeGestureProgressOpen) && - !swipeGestureBrightnessOpen && - !swipeGestureVolumeOpen && - (SystemClock.elapsedRealtime() - lastScaleEvent) > 200) { - val currentPos = playerView.player?.currentPosition ?: 0 - val vidDuration = (playerView.player?.duration ?: 0).coerceAtLeast(0) - - val difference = ((currentEvent.x - firstEvent.x) * 90).toLong() - val newPos = (currentPos + difference).coerceIn(0, vidDuration) - - activity.binding.progressScrubberLayout.visibility = View.VISIBLE - activity.binding.progressScrubberText.text = "${longToTimestamp(difference)} [${longToTimestamp(newPos, true)}]" - swipeGestureValueTrackerProgress = newPos - swipeGestureProgressOpen = true - true - } else false - } - - if (swipeGestureValueTrackerProgress > -1 || swipeGestureProgressOpen) - return false - - val viewCenterX = playerView.measuredWidth / 2 - - // Distance to swipe to go from min to max - val distanceFull = playerView.measuredHeight * Constants.FULL_SWIPE_RANGE_SCREEN_RATIO - val ratioChange = distanceY / distanceFull - - if (firstEvent.x.toInt() > viewCenterX) { - // Swiping on the right, change volume - - val currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC) - if (swipeGestureValueTrackerVolume == -1f) swipeGestureValueTrackerVolume = currentVolume.toFloat() - - val maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC) - val change = ratioChange * maxVolume - swipeGestureValueTrackerVolume += change - - val toSet = swipeGestureValueTrackerVolume.toInt().coerceIn(0, maxVolume) - audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, toSet, 0) - - activity.binding.gestureVolumeLayout.visibility = View.VISIBLE - activity.binding.gestureVolumeProgressBar.max = maxVolume - activity.binding.gestureVolumeProgressBar.progress = toSet - activity.binding.gestureVolumeText.text = "${(toSet.toFloat()/maxVolume.toFloat()).times(100).toInt()}%" - - swipeGestureVolumeOpen = true - } else { - // Swiping on the left, change brightness - val window = activity.window - val brightnessRange = BRIGHTNESS_OVERRIDE_OFF..BRIGHTNESS_OVERRIDE_FULL - - // Initialize on first swipe - if (swipeGestureValueTrackerBrightness == -1f) { - val brightness = window.attributes.screenBrightness - Timber.d("Brightness ${Settings.System.getFloat(activity.contentResolver, Settings.System.SCREEN_BRIGHTNESS)}") - swipeGestureValueTrackerBrightness = when (brightness) { - in brightnessRange -> brightness - else -> Settings.System.getFloat(activity.contentResolver, Settings.System.SCREEN_BRIGHTNESS)/255 - } + private val tapGestureDetector = GestureDetector( + playerView.context, + object : GestureDetector.SimpleOnGestureListener() { + override fun onSingleTapConfirmed(e: MotionEvent): Boolean { + playerView.apply { + if (!isControllerFullyVisible) showController() else hideController() } - swipeGestureValueTrackerBrightness = (swipeGestureValueTrackerBrightness + ratioChange).coerceIn(brightnessRange) - val lp = window.attributes - lp.screenBrightness = swipeGestureValueTrackerBrightness - window.attributes = lp - activity.binding.gestureBrightnessLayout.visibility = View.VISIBLE - activity.binding.gestureBrightnessProgressBar.max = BRIGHTNESS_OVERRIDE_FULL.times(100).toInt() - activity.binding.gestureBrightnessProgressBar.progress = lp.screenBrightness.times(100).toInt() - activity.binding.gestureBrightnessText.text = "${(lp.screenBrightness/BRIGHTNESS_OVERRIDE_FULL).times(100).toInt()}%" - - swipeGestureBrightnessOpen = true + return true + } + + override fun onDoubleTap(e: MotionEvent): Boolean { + val viewCenterX = playerView.measuredWidth / 2 + val currentPos = playerView.player?.currentPosition ?: 0 + + if (e.x.toInt() > viewCenterX) { + playerView.player?.seekTo(currentPos + appPreferences.playerSeekForwardIncrement) + } else { + playerView.player?.seekTo((currentPos - appPreferences.playerSeekBackIncrement).coerceAtLeast(0)) + } + return true } - return true } - }) + ) + + private val gestureDetector = GestureDetector( + playerView.context, + object : GestureDetector.SimpleOnGestureListener() { + override fun onSingleTapConfirmed(e: MotionEvent): Boolean { + playerView.apply { + if (!isControllerFullyVisible) showController() else hideController() + } + + return true + } + + override fun onDoubleTap(e: MotionEvent): Boolean { + val viewCenterX = playerView.measuredWidth / 2 + val currentPos = playerView.player?.currentPosition ?: 0 + + if (e.x.toInt() > viewCenterX) { + playerView.player?.seekTo(currentPos + appPreferences.playerSeekForwardIncrement) + } else { + playerView.player?.seekTo((currentPos - appPreferences.playerSeekBackIncrement).coerceAtLeast(0)) + } + return true + } + + @SuppressLint("SetTextI18n") + override fun onScroll( + firstEvent: MotionEvent, + currentEvent: MotionEvent, + distanceX: Float, + distanceY: Float + ): Boolean { + if (firstEvent.y < playerView.resources.dip(Constants.GESTURE_EXCLUSION_AREA_TOP)) + return false + + // Check whether swipe was oriented vertically + if (abs(distanceY / distanceX) < 2) { + return if ((abs(currentEvent.x - firstEvent.x) > 50 || swipeGestureProgressOpen) && + !swipeGestureBrightnessOpen && + !swipeGestureVolumeOpen && + (SystemClock.elapsedRealtime() - lastScaleEvent) > 200 + ) { + val currentPos = playerView.player?.currentPosition ?: 0 + val vidDuration = (playerView.player?.duration ?: 0).coerceAtLeast(0) + + val difference = ((currentEvent.x - firstEvent.x) * 90).toLong() + val newPos = (currentPos + difference).coerceIn(0, vidDuration) + + activity.binding.progressScrubberLayout.visibility = View.VISIBLE + activity.binding.progressScrubberText.text = "${longToTimestamp(difference)} [${longToTimestamp(newPos, true)}]" + swipeGestureValueTrackerProgress = newPos + swipeGestureProgressOpen = true + true + } else false + } + + if (swipeGestureValueTrackerProgress > -1 || swipeGestureProgressOpen) + return false + + val viewCenterX = playerView.measuredWidth / 2 + + // Distance to swipe to go from min to max + val distanceFull = playerView.measuredHeight * Constants.FULL_SWIPE_RANGE_SCREEN_RATIO + val ratioChange = distanceY / distanceFull + + if (firstEvent.x.toInt() > viewCenterX) { + // Swiping on the right, change volume + + val currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC) + if (swipeGestureValueTrackerVolume == -1f) swipeGestureValueTrackerVolume = currentVolume.toFloat() + + val maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC) + val change = ratioChange * maxVolume + swipeGestureValueTrackerVolume += change + + val toSet = swipeGestureValueTrackerVolume.toInt().coerceIn(0, maxVolume) + audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, toSet, 0) + + activity.binding.gestureVolumeLayout.visibility = View.VISIBLE + activity.binding.gestureVolumeProgressBar.max = maxVolume + activity.binding.gestureVolumeProgressBar.progress = toSet + activity.binding.gestureVolumeText.text = "${(toSet.toFloat() / maxVolume.toFloat()).times(100).toInt()}%" + + swipeGestureVolumeOpen = true + } else { + // Swiping on the left, change brightness + val window = activity.window + val brightnessRange = BRIGHTNESS_OVERRIDE_OFF..BRIGHTNESS_OVERRIDE_FULL + + // Initialize on first swipe + if (swipeGestureValueTrackerBrightness == -1f) { + val brightness = window.attributes.screenBrightness + Timber.d("Brightness ${Settings.System.getFloat(activity.contentResolver, Settings.System.SCREEN_BRIGHTNESS)}") + swipeGestureValueTrackerBrightness = when (brightness) { + in brightnessRange -> brightness + else -> Settings.System.getFloat(activity.contentResolver, Settings.System.SCREEN_BRIGHTNESS) / 255 + } + } + swipeGestureValueTrackerBrightness = (swipeGestureValueTrackerBrightness + ratioChange).coerceIn(brightnessRange) + val lp = window.attributes + lp.screenBrightness = swipeGestureValueTrackerBrightness + window.attributes = lp + + activity.binding.gestureBrightnessLayout.visibility = View.VISIBLE + activity.binding.gestureBrightnessProgressBar.max = BRIGHTNESS_OVERRIDE_FULL.times(100).toInt() + activity.binding.gestureBrightnessProgressBar.progress = lp.screenBrightness.times(100).toInt() + activity.binding.gestureBrightnessText.text = "${(lp.screenBrightness / BRIGHTNESS_OVERRIDE_FULL).times(100).toInt()}%" + + swipeGestureBrightnessOpen = true + } + return true + } + } + ) private val hideGestureVolumeIndicatorOverlayAction = Runnable { activity.binding.gestureVolumeLayout.visibility = View.GONE @@ -191,27 +201,29 @@ class PlayerGestureHelper( /** * Handles scale/zoom gesture */ - private val zoomGestureDetector = ScaleGestureDetector(playerView.context, object : ScaleGestureDetector.OnScaleGestureListener { - override fun onScaleBegin(detector: ScaleGestureDetector): Boolean = true + private val zoomGestureDetector = ScaleGestureDetector( + playerView.context, + object : ScaleGestureDetector.OnScaleGestureListener { + override fun onScaleBegin(detector: ScaleGestureDetector): Boolean = true - override fun onScale(detector: ScaleGestureDetector): Boolean { - lastScaleEvent = SystemClock.elapsedRealtime() - val scaleFactor = detector.scaleFactor - if (abs(scaleFactor - Constants.ZOOM_SCALE_BASE) > Constants.ZOOM_SCALE_THRESHOLD) { - isZoomEnabled = scaleFactor > 1 - updateZoomMode(isZoomEnabled) + override fun onScale(detector: ScaleGestureDetector): Boolean { + lastScaleEvent = SystemClock.elapsedRealtime() + val scaleFactor = detector.scaleFactor + if (abs(scaleFactor - Constants.ZOOM_SCALE_BASE) > Constants.ZOOM_SCALE_THRESHOLD) { + isZoomEnabled = scaleFactor > 1 + updateZoomMode(isZoomEnabled) + } + return true } - return true - } - override fun onScaleEnd(detector: ScaleGestureDetector) = Unit - }).apply { isQuickScaleEnabled = false } + override fun onScaleEnd(detector: ScaleGestureDetector) = Unit + } + ).apply { isQuickScaleEnabled = false } private fun updateZoomMode(enabled: Boolean) { if (playerView.player is MPVPlayer) { (playerView.player as MPVPlayer).updateZoomMode(enabled) - } - else { + } else { playerView.resizeMode = if (enabled) AspectRatioFrameLayout.RESIZE_MODE_ZOOM else AspectRatioFrameLayout.RESIZE_MODE_FIT } } diff --git a/app/src/main/java/dev/jdtech/jellyfin/utils/SortBy.kt b/app/src/main/java/dev/jdtech/jellyfin/utils/SortBy.kt index 09164b7d..48c4e4b4 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/utils/SortBy.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/utils/SortBy.kt @@ -19,4 +19,4 @@ enum class SortBy(val SortString: String) { } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/utils/extensions.kt b/app/src/main/java/dev/jdtech/jellyfin/utils/extensions.kt index 6b2e15cd..8db9f8de 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/utils/extensions.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/utils/extensions.kt @@ -23,7 +23,7 @@ fun BaseItemDto.toView(): View { fun Fragment.checkIfLoginRequired(error: String?) { if (error != null) { - if (error.contains("401")) { + if (error.contains("401")) { Timber.d("Login required!") findNavController().navigate(AppNavigationDirections.actionGlobalLoginFragment()) } @@ -50,4 +50,4 @@ fun ImageButton.setTintColorAttribute(@AttrRes attributeId: Int, theme: Resource theme ) ) -} \ 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 ee199f2b..f4c61043 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/AddServerViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/AddServerViewModel.kt @@ -11,13 +11,21 @@ import dev.jdtech.jellyfin.api.JellyfinApi import dev.jdtech.jellyfin.database.Server import dev.jdtech.jellyfin.database.ServerDatabaseDao import dev.jdtech.jellyfin.models.DiscoveredServer -import kotlinx.coroutines.* -import kotlinx.coroutines.flow.* +import javax.inject.Inject +import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.cancel +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asSharedFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.onCompletion +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import org.jellyfin.sdk.discovery.RecommendedServerInfo import org.jellyfin.sdk.discovery.RecommendedServerInfoScore import org.jellyfin.sdk.discovery.RecommendedServerIssue import timber.log.Timber -import javax.inject.Inject @HiltViewModel class AddServerViewModel @@ -54,11 +62,13 @@ constructor( viewModelScope.launch(Dispatchers.IO) { val servers = jellyfinApi.jellyfin.discovery.discoverLocalServers() servers.collect { serverDiscoveryInfo -> - discoveredServers.add(DiscoveredServer( - serverDiscoveryInfo.id, - serverDiscoveryInfo.name, - serverDiscoveryInfo.address - )) + discoveredServers.add( + DiscoveredServer( + serverDiscoveryInfo.id, + serverDiscoveryInfo.name, + serverDiscoveryInfo.address + ) + ) _discoveredServersState.emit( DiscoveredServersState.Servers(ArrayList(discoveredServers)) ) @@ -131,7 +141,6 @@ constructor( } } } catch (_: CancellationException) { - } catch (e: Exception) { _uiState.emit( UiState.Error( @@ -215,4 +224,4 @@ constructor( if (server != null) return true return false } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/DownloadSeriesViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/DownloadSeriesViewModel.kt index e4467cfa..ccca57e5 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/DownloadSeriesViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/DownloadSeriesViewModel.kt @@ -5,10 +5,10 @@ import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import dev.jdtech.jellyfin.adapters.DownloadEpisodeItem import dev.jdtech.jellyfin.models.DownloadSeriesMetadata +import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch -import javax.inject.Inject @HiltViewModel class DownloadSeriesViewModel @@ -36,8 +36,11 @@ constructor() : ViewModel() { private fun getEpisodes(seriesMetadata: DownloadSeriesMetadata): List { val episodes = seriesMetadata.episodes - return listOf(DownloadEpisodeItem.Header) + episodes.sortedWith(compareBy( - { it.item!!.parentIndexNumber }, - { it.item!!.indexNumber })).map { DownloadEpisodeItem.Episode(it) } + return listOf(DownloadEpisodeItem.Header) + episodes.sortedWith( + compareBy( + { it.item!!.parentIndexNumber }, + { it.item!!.indexNumber } + ) + ).map { DownloadEpisodeItem.Episode(it) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/DownloadViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/DownloadViewModel.kt index 3c2b4af3..cf31acce 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/DownloadViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/DownloadViewModel.kt @@ -1,7 +1,8 @@ package dev.jdtech.jellyfin.viewmodels import android.app.Application -import androidx.lifecycle.* +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import dev.jdtech.jellyfin.database.DownloadDatabaseDao import dev.jdtech.jellyfin.models.DownloadSection @@ -9,13 +10,14 @@ import dev.jdtech.jellyfin.models.DownloadSeriesMetadata import dev.jdtech.jellyfin.models.PlayerItem import dev.jdtech.jellyfin.utils.checkDownloadStatus import dev.jdtech.jellyfin.utils.loadDownloadedEpisodes -import kotlinx.coroutines.* +import java.util.UUID +import javax.inject.Inject +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import org.jellyfin.sdk.model.api.BaseItemKind -import java.util.* -import javax.inject.Inject @HiltViewModel class DownloadViewModel @@ -78,4 +80,4 @@ constructor( } } } -} \ No newline at end of file +} 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 86dfb0f9..a84b114d 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/EpisodeBottomSheetViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/EpisodeBottomSheetViewModel.kt @@ -1,12 +1,23 @@ package dev.jdtech.jellyfin.viewmodels import android.app.Application -import androidx.lifecycle.* +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import dev.jdtech.jellyfin.database.DownloadDatabaseDao import dev.jdtech.jellyfin.models.PlayerItem import dev.jdtech.jellyfin.repository.JellyfinRepository -import dev.jdtech.jellyfin.utils.* +import dev.jdtech.jellyfin.utils.canRetryDownload +import dev.jdtech.jellyfin.utils.deleteDownloadedEpisode +import dev.jdtech.jellyfin.utils.downloadMetadataToBaseItemDto +import dev.jdtech.jellyfin.utils.isItemAvailable +import dev.jdtech.jellyfin.utils.isItemDownloaded +import dev.jdtech.jellyfin.utils.requestDownload +import java.text.DateFormat +import java.time.ZoneOffset +import java.util.Date +import java.util.UUID +import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch @@ -14,11 +25,6 @@ import org.jellyfin.sdk.api.client.exception.ApiClientException import org.jellyfin.sdk.model.DateTime import org.jellyfin.sdk.model.api.BaseItemDto import timber.log.Timber -import java.text.DateFormat -import java.time.ZoneOffset -import java.util.Date -import java.util.UUID -import javax.inject.Inject @HiltViewModel class EpisodeBottomSheetViewModel @@ -178,4 +184,4 @@ constructor( val date = Date.from(instant) return DateFormat.getDateInstance(DateFormat.SHORT).format(date) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/FavoriteViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/FavoriteViewModel.kt index 9a0f3e1e..ec1c539d 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/FavoriteViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/FavoriteViewModel.kt @@ -9,13 +9,13 @@ import dev.jdtech.jellyfin.R import dev.jdtech.jellyfin.models.FavoriteSection import dev.jdtech.jellyfin.repository.JellyfinRepository import dev.jdtech.jellyfin.utils.Constants +import javax.inject.Inject import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.jellyfin.sdk.model.api.BaseItemKind -import javax.inject.Inject @HiltViewModel class FavoriteViewModel @@ -56,7 +56,8 @@ constructor( FavoriteSection( Constants.FAVORITE_TYPE_MOVIES, resources.getString(R.string.movies_label), - items.filter { it.type == BaseItemKind.MOVIE }).let { + items.filter { it.type == BaseItemKind.MOVIE } + ).let { if (it.items.isNotEmpty()) favoriteSections.add( it ) @@ -64,7 +65,8 @@ constructor( FavoriteSection( Constants.FAVORITE_TYPE_SHOWS, resources.getString(R.string.shows_label), - items.filter { it.type == BaseItemKind.SERIES }).let { + items.filter { it.type == BaseItemKind.SERIES } + ).let { if (it.items.isNotEmpty()) favoriteSections.add( it ) @@ -72,7 +74,8 @@ constructor( FavoriteSection( Constants.FAVORITE_TYPE_EPISODES, resources.getString(R.string.episodes_label), - items.filter { it.type == BaseItemKind.EPISODE }).let { + items.filter { it.type == BaseItemKind.EPISODE } + ).let { if (it.items.isNotEmpty()) favoriteSections.add( it ) @@ -85,4 +88,4 @@ constructor( } } } -} \ 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 1d2fd410..0f22c7b2 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/HomeViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/HomeViewModel.kt @@ -14,13 +14,13 @@ import dev.jdtech.jellyfin.models.HomeSection import dev.jdtech.jellyfin.repository.JellyfinRepository import dev.jdtech.jellyfin.utils.syncPlaybackProgress import dev.jdtech.jellyfin.utils.toView +import java.util.UUID +import javax.inject.Inject import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import java.util.* -import javax.inject.Inject @HiltViewModel class HomeViewModel @Inject internal constructor( @@ -117,5 +117,3 @@ class HomeViewModel @Inject internal constructor( .map { (view, latest) -> view.toView().apply { items = latest } } .map { ViewItem(it) } } - - diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/LibraryViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/LibraryViewModel.kt index 946f4306..f42beac7 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/LibraryViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/LibraryViewModel.kt @@ -1,10 +1,13 @@ package dev.jdtech.jellyfin.viewmodels -import androidx.lifecycle.* +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope import androidx.paging.PagingData import dagger.hilt.android.lifecycle.HiltViewModel import dev.jdtech.jellyfin.repository.JellyfinRepository import dev.jdtech.jellyfin.utils.SortBy +import java.util.UUID +import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow @@ -13,8 +16,6 @@ import org.jellyfin.sdk.model.api.BaseItemDto import org.jellyfin.sdk.model.api.BaseItemKind import org.jellyfin.sdk.model.api.SortOrder import timber.log.Timber -import java.util.* -import javax.inject.Inject @HiltViewModel class LibraryViewModel @@ -60,4 +61,4 @@ constructor( } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/LoginViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/LoginViewModel.kt index b6ae5377..024a7634 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/LoginViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/LoginViewModel.kt @@ -2,7 +2,8 @@ package dev.jdtech.jellyfin.viewmodels import android.content.SharedPreferences import android.content.res.Resources -import androidx.lifecycle.* +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import dev.jdtech.jellyfin.BaseApplication import dev.jdtech.jellyfin.R @@ -10,6 +11,8 @@ import dev.jdtech.jellyfin.api.JellyfinApi import dev.jdtech.jellyfin.database.Server import dev.jdtech.jellyfin.database.ServerDatabaseDao import dev.jdtech.jellyfin.models.User +import javax.inject.Inject +import kotlin.Exception import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow @@ -18,8 +21,6 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.jellyfin.sdk.model.api.AuthenticateUserByName -import javax.inject.Inject -import kotlin.Exception @HiltViewModel class LoginViewModel @@ -129,4 +130,4 @@ constructor( database.insert(server) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MainViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MainViewModel.kt index c95a1c33..b848641f 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MainViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MainViewModel.kt @@ -5,4 +5,4 @@ import androidx.lifecycle.ViewModel class MainViewModel : ViewModel() { var startDestinationChanged = false var startDestinationTvChanged = false -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaInfoViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaInfoViewModel.kt index 7a012d7d..6a0b77dd 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaInfoViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaInfoViewModel.kt @@ -7,7 +7,14 @@ import dagger.hilt.android.lifecycle.HiltViewModel import dev.jdtech.jellyfin.database.DownloadDatabaseDao import dev.jdtech.jellyfin.models.PlayerItem import dev.jdtech.jellyfin.repository.JellyfinRepository -import dev.jdtech.jellyfin.utils.* +import dev.jdtech.jellyfin.utils.canRetryDownload +import dev.jdtech.jellyfin.utils.deleteDownloadedEpisode +import dev.jdtech.jellyfin.utils.downloadMetadataToBaseItemDto +import dev.jdtech.jellyfin.utils.isItemAvailable +import dev.jdtech.jellyfin.utils.isItemDownloaded +import dev.jdtech.jellyfin.utils.requestDownload +import java.util.UUID +import javax.inject.Inject import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow @@ -18,8 +25,6 @@ import org.jellyfin.sdk.model.api.BaseItemDto import org.jellyfin.sdk.model.api.BaseItemKind import org.jellyfin.sdk.model.api.BaseItemPerson import timber.log.Timber -import java.util.UUID -import javax.inject.Inject @HiltViewModel class MediaInfoViewModel @@ -267,4 +272,4 @@ constructor( fun deleteItem() { deleteDownloadedEpisode(downloadDatabase, playerItem.itemId) } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaViewModel.kt index cff7b51f..e9b2fcb0 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaViewModel.kt @@ -1,14 +1,15 @@ package dev.jdtech.jellyfin.viewmodels -import androidx.lifecycle.* +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import dev.jdtech.jellyfin.models.CollectionType import dev.jdtech.jellyfin.repository.JellyfinRepository +import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import org.jellyfin.sdk.model.api.BaseItemDto -import javax.inject.Inject @HiltViewModel class MediaViewModel @@ -45,4 +46,4 @@ constructor( } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/PersonDetailViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/PersonDetailViewModel.kt index 57dedf99..9b70979e 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/PersonDetailViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/PersonDetailViewModel.kt @@ -4,13 +4,13 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import dev.jdtech.jellyfin.repository.JellyfinRepository +import java.util.UUID +import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import org.jellyfin.sdk.model.api.BaseItemDto import org.jellyfin.sdk.model.api.BaseItemKind -import java.util.UUID -import javax.inject.Inject @HiltViewModel internal class PersonDetailViewModel @Inject internal constructor( @@ -66,4 +66,4 @@ internal class PersonDetailViewModel @Inject internal constructor( val movies: List, val shows: List ) -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/PlayerActivityViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/PlayerActivityViewModel.kt index e8e13841..d42d1472 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/PlayerActivityViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/PlayerActivityViewModel.kt @@ -8,7 +8,11 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import androidx.preference.PreferenceManager -import com.google.android.exoplayer2.* +import com.google.android.exoplayer2.C +import com.google.android.exoplayer2.DefaultRenderersFactory +import com.google.android.exoplayer2.ExoPlayer +import com.google.android.exoplayer2.MediaItem +import com.google.android.exoplayer2.Player import com.google.android.exoplayer2.trackselection.DefaultTrackSelector import dagger.hilt.android.lifecycle.HiltViewModel import dev.jdtech.jellyfin.database.DownloadDatabaseDao @@ -18,11 +22,11 @@ import dev.jdtech.jellyfin.mpv.TrackType import dev.jdtech.jellyfin.repository.JellyfinRepository import dev.jdtech.jellyfin.utils.AppPreferences import dev.jdtech.jellyfin.utils.postDownloadPlaybackProgress +import java.util.UUID +import javax.inject.Inject import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import timber.log.Timber -import java.util.UUID -import javax.inject.Inject @HiltViewModel class PlayerActivityViewModel @@ -133,8 +137,8 @@ constructor( player.setMediaItems(mediaItems, currentMediaItemIndex, items.getOrNull(currentMediaItemIndex)?.playbackPosition ?: C.TIME_UNSET) val useMpv = sp.getBoolean("mpv_player", false) - if(!useMpv || !playFromDownloads) - player.prepare() //TODO: This line causes a crash when playing from downloads with MPV + if (!useMpv || !playFromDownloads) + player.prepare() // TODO: This line causes a crash when playing from downloads with MPV player.play() pollPosition(player) } @@ -167,8 +171,8 @@ constructor( override fun run() { viewModelScope.launch { if (player.currentMediaItem != null && player.currentMediaItem!!.mediaId.isNotEmpty()) { - if(playFromDownloads){ - postDownloadPlaybackProgress(downloadDatabase, items[0].itemId, player.currentPosition, (player.currentPosition.toDouble()/player.duration.toDouble()).times(100)) //TODO Automatically use the correct item + if (playFromDownloads) { + postDownloadPlaybackProgress(downloadDatabase, items[0].itemId, player.currentPosition, (player.currentPosition.toDouble() / player.duration.toDouble()).times(100)) // TODO Automatically use the correct item } try { jellyfinRepository.postPlaybackProgress( @@ -265,4 +269,4 @@ constructor( player.setPlaybackSpeed(speed) playbackSpeed = speed } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/PlayerViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/PlayerViewModel.kt index 64aafc36..3dd25c14 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/PlayerViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/PlayerViewModel.kt @@ -14,6 +14,7 @@ import dev.jdtech.jellyfin.models.PlayerItem import dev.jdtech.jellyfin.repository.JellyfinRepository import dev.jdtech.jellyfin.utils.getDownloadPlayerItem import dev.jdtech.jellyfin.utils.isItemAvailable +import javax.inject.Inject import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.launch @@ -24,7 +25,6 @@ import org.jellyfin.sdk.model.api.LocationType.VIRTUAL import org.jellyfin.sdk.model.api.MediaProtocol import org.jellyfin.sdk.model.api.MediaStreamType import timber.log.Timber -import javax.inject.Inject @HiltViewModel class PlayerViewModel @Inject internal constructor( @@ -234,4 +234,4 @@ class PlayerViewModel @Inject internal constructor( data class PlayerItemError(val error: Exception) : PlayerItemState() data class PlayerItems(val items: List) : PlayerItemState() -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SearchResultViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SearchResultViewModel.kt index 739870b6..6e236ecc 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SearchResultViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SearchResultViewModel.kt @@ -9,13 +9,13 @@ import dev.jdtech.jellyfin.R import dev.jdtech.jellyfin.models.FavoriteSection import dev.jdtech.jellyfin.repository.JellyfinRepository import dev.jdtech.jellyfin.utils.Constants +import javax.inject.Inject import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.jellyfin.sdk.model.api.BaseItemKind -import javax.inject.Inject @HiltViewModel class SearchResultViewModel @@ -52,7 +52,8 @@ constructor( FavoriteSection( Constants.FAVORITE_TYPE_MOVIES, resources.getString(R.string.movies_label), - items.filter { it.type == BaseItemKind.MOVIE }).let { + items.filter { it.type == BaseItemKind.MOVIE } + ).let { if (it.items.isNotEmpty()) sections.add( it ) @@ -60,7 +61,8 @@ constructor( FavoriteSection( Constants.FAVORITE_TYPE_SHOWS, resources.getString(R.string.shows_label), - items.filter { it.type == BaseItemKind.SERIES }).let { + items.filter { it.type == BaseItemKind.SERIES } + ).let { if (it.items.isNotEmpty()) sections.add( it ) @@ -68,7 +70,8 @@ constructor( FavoriteSection( Constants.FAVORITE_TYPE_EPISODES, resources.getString(R.string.episodes_label), - items.filter { it.type == BaseItemKind.EPISODE }).let { + items.filter { it.type == BaseItemKind.EPISODE } + ).let { if (it.items.isNotEmpty()) sections.add( it ) @@ -81,4 +84,4 @@ constructor( } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SeasonViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SeasonViewModel.kt index cf4207ad..c222ddfd 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SeasonViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SeasonViewModel.kt @@ -1,15 +1,16 @@ package dev.jdtech.jellyfin.viewmodels -import androidx.lifecycle.* +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import dev.jdtech.jellyfin.adapters.EpisodeItem import dev.jdtech.jellyfin.repository.JellyfinRepository +import java.util.UUID +import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import org.jellyfin.sdk.model.api.ItemFields -import java.util.* -import javax.inject.Inject @HiltViewModel class SeasonViewModel @@ -43,4 +44,4 @@ constructor( jellyfinRepository.getEpisodes(seriesId, seasonId, fields = listOf(ItemFields.OVERVIEW)) return listOf(EpisodeItem.Header) + episodes.map { EpisodeItem.Episode(it) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/ServerSelectViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/ServerSelectViewModel.kt index ab578c50..b29e9933 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/ServerSelectViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/ServerSelectViewModel.kt @@ -7,12 +7,12 @@ import dagger.hilt.android.lifecycle.HiltViewModel import dev.jdtech.jellyfin.api.JellyfinApi import dev.jdtech.jellyfin.database.Server import dev.jdtech.jellyfin.database.ServerDatabaseDao +import java.util.UUID +import javax.inject.Inject import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.launch -import java.util.* -import javax.inject.Inject @HiltViewModel class ServerSelectViewModel @@ -53,4 +53,4 @@ constructor( _navigateToMain.emit(true) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SettingsDeviceViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SettingsDeviceViewModel.kt index b7104036..06c94657 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SettingsDeviceViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SettingsDeviceViewModel.kt @@ -4,9 +4,9 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import dev.jdtech.jellyfin.repository.JellyfinRepository +import javax.inject.Inject import kotlinx.coroutines.launch import timber.log.Timber -import javax.inject.Inject @HiltViewModel internal class SettingsDeviceViewModel @@ -23,4 +23,4 @@ internal class SettingsDeviceViewModel } } } -} \ No newline at end of file +}