lint: run ktlintFormat

This commit is contained in:
Jarne Demeulemeester 2023-06-19 23:44:42 +02:00
parent 07efae6f4c
commit b426a920c3
No known key found for this signature in database
GPG key ID: 1E5C6AFBD622E9F5
116 changed files with 783 additions and 702 deletions

View file

@ -11,8 +11,8 @@ import coil.disk.DiskCache
import coil.request.CachePolicy
import com.google.android.material.color.DynamicColors
import dagger.hilt.android.HiltAndroidApp
import javax.inject.Inject
import timber.log.Timber
import javax.inject.Inject
@HiltAndroidApp
class BaseApplication : Application(), Configuration.Provider, ImageLoaderFactory {

View file

@ -59,7 +59,7 @@ abstract class BasePlayerActivity : AppCompatActivity() {
protected fun isRendererType(
mappedTrackInfo: MappingTrackSelector.MappedTrackInfo,
rendererIndex: Int,
type: Int
type: Int,
): Boolean {
val trackGroupArray = mappedTrackInfo.getTrackGroups(rendererIndex)
if (trackGroupArray.length == 0) {

View file

@ -10,17 +10,17 @@ import dev.jdtech.jellyfin.adapters.HomeEpisodeListAdapter
import dev.jdtech.jellyfin.adapters.ServerGridAdapter
import dev.jdtech.jellyfin.adapters.ViewItemListAdapter
import dev.jdtech.jellyfin.api.JellyfinApi
import dev.jdtech.jellyfin.core.R as CoreR
import dev.jdtech.jellyfin.models.FindroidEpisode
import dev.jdtech.jellyfin.models.FindroidItem
import dev.jdtech.jellyfin.models.FindroidMovie
import dev.jdtech.jellyfin.models.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
import dev.jdtech.jellyfin.core.R as CoreR
@BindingAdapter("servers")
fun bindServers(recyclerView: RecyclerView, data: List<Server>?) {
@ -109,7 +109,7 @@ fun bindUserImage(imageView: ImageView, user: User) {
private fun ImageView.loadImage(
url: String,
@DrawableRes placeholderId: Int = CoreR.color.neutral_800
@DrawableRes placeholderId: Int = CoreR.color.neutral_800,
): View {
val api = JellyfinApi.getInstance(context.applicationContext)

View file

@ -20,13 +20,13 @@ import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import com.google.android.material.navigation.NavigationBarView
import dagger.hilt.android.AndroidEntryPoint
import dev.jdtech.jellyfin.core.R as CoreR
import dev.jdtech.jellyfin.database.ServerDatabaseDao
import dev.jdtech.jellyfin.databinding.ActivityMainBinding
import dev.jdtech.jellyfin.viewmodels.MainViewModel
import dev.jdtech.jellyfin.work.SyncWorker
import javax.inject.Inject
import kotlinx.coroutines.launch
import javax.inject.Inject
import dev.jdtech.jellyfin.core.R as CoreR
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@ -53,9 +53,9 @@ class MainActivity : AppCompatActivity() {
.setConstraints(
Constraints.Builder()
.setRequiredNetworkType(
NetworkType.CONNECTED
NetworkType.CONNECTED,
)
.build()
.build(),
)
.build()
@ -105,7 +105,7 @@ class MainActivity : AppCompatActivity() {
R.id.mediaFragment,
R.id.favoriteFragment,
R.id.downloadsFragment,
)
),
)
setupActionBarWithNavController(navController, appBarConfiguration)
@ -118,8 +118,10 @@ class MainActivity : AppCompatActivity() {
R.id.twoPaneSettingsFragment, R.id.serverSelectFragment, R.id.addServerFragment, R.id.loginFragment, com.mikepenz.aboutlibraries.R.id.about_libraries_dest, R.id.usersFragment, R.id.serverAddressesFragment -> View.GONE
else -> View.VISIBLE
}
if (destination.id == com.mikepenz.aboutlibraries.R.id.about_libraries_dest) binding.mainToolbar.title =
getString(CoreR.string.app_info)
if (destination.id == com.mikepenz.aboutlibraries.R.id.about_libraries_dest) {
binding.mainToolbar.title =
getString(CoreR.string.app_info)
}
}
}

View file

@ -24,12 +24,12 @@ import dev.jdtech.jellyfin.dialogs.SpeedSelectionDialogFragment
import dev.jdtech.jellyfin.dialogs.TrackSelectionDialogFragment
import dev.jdtech.jellyfin.mpv.MPVPlayer
import dev.jdtech.jellyfin.mpv.TrackType
import dev.jdtech.jellyfin.player.video.R as PlayerVideoR
import dev.jdtech.jellyfin.utils.PlayerGestureHelper
import dev.jdtech.jellyfin.utils.PreviewScrubListener
import dev.jdtech.jellyfin.viewmodels.PlayerActivityViewModel
import javax.inject.Inject
import timber.log.Timber
import javax.inject.Inject
import dev.jdtech.jellyfin.player.video.R as PlayerVideoR
var isControlsLocked: Boolean = false
@ -63,7 +63,7 @@ class PlayerActivity : BasePlayerActivity() {
appPreferences,
this,
binding.playerView,
getSystemService(Context.AUDIO_SERVICE) as AudioManager
getSystemService(Context.AUDIO_SERVICE) as AudioManager,
)
}
@ -106,7 +106,7 @@ class PlayerActivity : BasePlayerActivity() {
is MPVPlayer -> {
TrackSelectionDialogFragment(TrackType.AUDIO, viewModel).show(
supportFragmentManager,
"trackselectiondialog"
"trackselectiondialog",
)
}
is ExoPlayer -> {
@ -126,7 +126,7 @@ class PlayerActivity : BasePlayerActivity() {
this,
resources.getString(PlayerVideoR.string.select_audio_track),
viewModel.player,
C.TRACK_TYPE_AUDIO
C.TRACK_TYPE_AUDIO,
)
val trackSelectionDialog = trackSelectionDialogBuilder.build()
trackSelectionDialog.show()
@ -156,7 +156,7 @@ class PlayerActivity : BasePlayerActivity() {
is MPVPlayer -> {
TrackSelectionDialogFragment(TrackType.SUBTITLE, viewModel).show(
supportFragmentManager,
"trackselectiondialog"
"trackselectiondialog",
)
}
is ExoPlayer -> {
@ -176,7 +176,7 @@ class PlayerActivity : BasePlayerActivity() {
this,
resources.getString(PlayerVideoR.string.select_subtile_track),
viewModel.player,
C.TRACK_TYPE_TEXT
C.TRACK_TYPE_TEXT,
)
trackSelectionDialogBuilder.setShowDisableOption(true)
@ -189,7 +189,7 @@ class PlayerActivity : BasePlayerActivity() {
speedButton.setOnClickListener {
SpeedSelectionDialogFragment(viewModel).show(
supportFragmentManager,
"speedselectiondialog"
"speedselectiondialog",
)
}
@ -210,7 +210,7 @@ class PlayerActivity : BasePlayerActivity() {
imagePreview,
timeBar,
viewModel.player,
viewModel.currentTrickPlay
viewModel.currentTrickPlay,
)
timeBar.addListener(previewScrubListener)

View file

@ -9,7 +9,7 @@ import dev.jdtech.jellyfin.databinding.CollectionItemBinding
import dev.jdtech.jellyfin.models.FindroidCollection
class CollectionListAdapter(
private val onClickListener: OnClickListener
private val onClickListener: OnClickListener,
) : ListAdapter<FindroidCollection, CollectionListAdapter.CollectionViewHolder>(DiffCallback) {
class CollectionViewHolder(private var binding: CollectionItemBinding) :
RecyclerView.ViewHolder(binding.root) {
@ -34,8 +34,8 @@ class CollectionListAdapter(
CollectionItemBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
false,
),
)
}

View file

@ -9,10 +9,10 @@ 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<DiscoveredServer, DiscoveredServerListAdapter.DiscoveredServerViewHolder>(
DiffCallback
DiffCallback,
) {
class DiscoveredServerViewHolder(private var binding: DiscoveredServerItemBinding) :
RecyclerView.ViewHolder(binding.root) {
@ -25,14 +25,14 @@ class DiscoveredServerListAdapter(
companion object DiffCallback : DiffUtil.ItemCallback<DiscoveredServer>() {
override fun areItemsTheSame(
oldItem: DiscoveredServer,
newItem: DiscoveredServer
newItem: DiscoveredServer,
): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(
oldItem: DiscoveredServer,
newItem: DiscoveredServer
newItem: DiscoveredServer,
): Boolean {
return oldItem == newItem
}
@ -40,14 +40,14 @@ class DiscoveredServerListAdapter(
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
viewType: Int,
): DiscoveredServerViewHolder {
return DiscoveredServerViewHolder(
DiscoveredServerItemBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
false,
),
)
}

View file

@ -8,12 +8,12 @@ import androidx.core.view.isVisible
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import dev.jdtech.jellyfin.core.R as CoreR
import dev.jdtech.jellyfin.databinding.EpisodeItemBinding
import dev.jdtech.jellyfin.databinding.SeasonHeaderBinding
import dev.jdtech.jellyfin.models.EpisodeItem
import dev.jdtech.jellyfin.models.FindroidEpisode
import dev.jdtech.jellyfin.models.isDownloaded
import dev.jdtech.jellyfin.core.R as CoreR
private const val ITEM_VIEW_TYPE_HEADER = 0
private const val ITEM_VIEW_TYPE_EPISODE = 1
@ -49,7 +49,7 @@ class EpisodeListAdapter(
binding.progressBar.layoutParams.width = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
(episode.playbackPositionTicks.div(episode.runtimeTicks.toFloat()).times(84)),
binding.progressBar.context.resources.displayMetrics
binding.progressBar.context.resources.displayMetrics,
).toInt()
binding.progressBar.visibility = View.VISIBLE
} else {
@ -79,8 +79,8 @@ class EpisodeListAdapter(
SeasonHeaderBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
false,
),
)
}
ITEM_VIEW_TYPE_EPISODE -> {
@ -88,8 +88,8 @@ class EpisodeListAdapter(
EpisodeItemBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
false,
),
)
}
else -> throw ClassCastException("Unknown viewType $viewType")

View file

@ -11,14 +11,14 @@ import dev.jdtech.jellyfin.models.FavoriteSection
class FavoritesListAdapter(
private val onClickListener: ViewItemListAdapter.OnClickListener,
private val onEpisodeClickListener: HomeEpisodeListAdapter.OnClickListener
private val onEpisodeClickListener: HomeEpisodeListAdapter.OnClickListener,
) : ListAdapter<FavoriteSection, FavoritesListAdapter.SectionViewHolder>(DiffCallback) {
class SectionViewHolder(private var binding: FavoriteSectionBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(
section: FavoriteSection,
onClickListener: ViewItemListAdapter.OnClickListener,
onEpisodeClickListener: HomeEpisodeListAdapter.OnClickListener
onEpisodeClickListener: HomeEpisodeListAdapter.OnClickListener,
) {
binding.section = section
if (section.id == Constants.FAVORITE_TYPE_MOVIES || section.id == Constants.FAVORITE_TYPE_SHOWS) {
@ -42,7 +42,7 @@ class FavoritesListAdapter(
override fun areContentsTheSame(
oldItem: FavoriteSection,
newItem: FavoriteSection
newItem: FavoriteSection,
): Boolean {
return oldItem == newItem
}
@ -53,8 +53,8 @@ class FavoritesListAdapter(
FavoriteSectionBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
false,
),
)
}

View file

@ -8,17 +8,17 @@ import androidx.core.view.isVisible
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import dev.jdtech.jellyfin.core.R as CoreR
import dev.jdtech.jellyfin.databinding.HomeEpisodeItemBinding
import dev.jdtech.jellyfin.models.FindroidEpisode
import dev.jdtech.jellyfin.models.FindroidItem
import dev.jdtech.jellyfin.models.FindroidMovie
import dev.jdtech.jellyfin.models.isDownloaded
import dev.jdtech.jellyfin.core.R as CoreR
class HomeEpisodeListAdapter(private val onClickListener: OnClickListener) : ListAdapter<FindroidItem, HomeEpisodeListAdapter.EpisodeViewHolder>(DiffCallback) {
class EpisodeViewHolder(
private var binding: HomeEpisodeItemBinding,
private val parent: ViewGroup
private val parent: ViewGroup,
) :
RecyclerView.ViewHolder(binding.root) {
fun bind(item: FindroidItem) {
@ -26,7 +26,8 @@ class HomeEpisodeListAdapter(private val onClickListener: OnClickListener) : Lis
if (item.playbackPositionTicks > 0) {
binding.progressBar.layoutParams.width = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
(item.playbackPositionTicks.div(item.runtimeTicks.toFloat()).times(224)), binding.progressBar.context.resources.displayMetrics
(item.playbackPositionTicks.div(item.runtimeTicks.toFloat()).times(224)),
binding.progressBar.context.resources.displayMetrics,
).toInt()
binding.progressBar.visibility = View.VISIBLE
}
@ -67,9 +68,9 @@ class HomeEpisodeListAdapter(private val onClickListener: OnClickListener) : Lis
HomeEpisodeItemBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
false,
),
parent
parent,
)
}

View file

@ -33,8 +33,8 @@ class PersonListAdapter(private val clickListener: (item: BaseItemPerson) -> Uni
PersonItemBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
false,
),
)
}

View file

@ -10,7 +10,7 @@ import dev.jdtech.jellyfin.models.ServerAddress
class ServerAddressAdapter(
private val clickListener: (address: ServerAddress) -> Unit,
private val longClickListener: (address: ServerAddress) -> Boolean
private val longClickListener: (address: ServerAddress) -> Boolean,
) : ListAdapter<ServerAddress, ServerAddressAdapter.ServerAddressViewHolder>(DiffCallback) {
class ServerAddressViewHolder(private var binding: ServerAddressListItemBinding) :
RecyclerView.ViewHolder(binding.root) {
@ -32,14 +32,14 @@ class ServerAddressAdapter(
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
viewType: Int,
): ServerAddressViewHolder {
return ServerAddressViewHolder(
ServerAddressListItemBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
false,
),
)
}

View file

@ -10,7 +10,7 @@ import dev.jdtech.jellyfin.models.Server
class ServerGridAdapter(
private val onClickListener: OnClickListener,
private val onLongClickListener: OnLongClickListener
private val onLongClickListener: OnLongClickListener,
) : ListAdapter<Server, ServerGridAdapter.ServerViewHolder>(DiffCallback) {
class ServerViewHolder(private var binding: ServerItemBinding) :
RecyclerView.ViewHolder(binding.root) {
@ -32,7 +32,7 @@ class ServerGridAdapter(
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
viewType: Int,
): ServerViewHolder {
return ServerViewHolder(ServerItemBinding.inflate(LayoutInflater.from(parent.context)))
}

View file

@ -10,7 +10,7 @@ import dev.jdtech.jellyfin.models.User
class UserListAdapter(
private val clickListener: (user: User) -> Unit,
private val longClickListener: (user: User) -> Boolean
private val longClickListener: (user: User) -> Boolean,
) : ListAdapter<User, UserListAdapter.UserViewHolder>(DiffCallback) {
class UserViewHolder(private var binding: UserListItemBinding) :
RecyclerView.ViewHolder(binding.root) {
@ -32,14 +32,14 @@ class UserListAdapter(
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
viewType: Int,
): UserViewHolder {
return UserViewHolder(
UserListItemBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
false,
),
)
}

View file

@ -9,7 +9,7 @@ import dev.jdtech.jellyfin.databinding.UserItemBinding
import dev.jdtech.jellyfin.models.User
class UserLoginListAdapter(
private val clickListener: (user: User) -> Unit
private val clickListener: (user: User) -> Unit,
) : ListAdapter<User, UserLoginListAdapter.UserLoginViewHolder>(DiffCallback) {
class UserLoginViewHolder(private var binding: UserItemBinding) :
RecyclerView.ViewHolder(binding.root) {
@ -31,14 +31,14 @@ class UserLoginListAdapter(
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
viewType: Int,
): UserLoginViewHolder {
return UserLoginViewHolder(
UserItemBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
false,
),
)
}

View file

@ -7,11 +7,11 @@ import androidx.core.view.isVisible
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import dev.jdtech.jellyfin.core.R as CoreR
import dev.jdtech.jellyfin.databinding.BaseItemBinding
import dev.jdtech.jellyfin.models.FindroidEpisode
import dev.jdtech.jellyfin.models.FindroidItem
import dev.jdtech.jellyfin.models.isDownloaded
import dev.jdtech.jellyfin.core.R as CoreR
class ViewItemListAdapter(
private val onClickListener: OnClickListener,
@ -52,9 +52,9 @@ class ViewItemListAdapter(
BaseItemBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
false,
),
parent
parent,
)
}

View file

@ -7,11 +7,11 @@ import androidx.core.view.isVisible
import androidx.paging.PagingDataAdapter
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import dev.jdtech.jellyfin.core.R as CoreR
import dev.jdtech.jellyfin.databinding.BaseItemBinding
import dev.jdtech.jellyfin.models.FindroidEpisode
import dev.jdtech.jellyfin.models.FindroidItem
import dev.jdtech.jellyfin.models.isDownloaded
import dev.jdtech.jellyfin.core.R as CoreR
class ViewItemPagingAdapter(
private val onClickListener: OnClickListener,
@ -53,9 +53,9 @@ class ViewItemPagingAdapter(
BaseItemBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
false,
),
parent
parent,
)
}

View file

@ -5,12 +5,12 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import dev.jdtech.jellyfin.core.R as CoreR
import dev.jdtech.jellyfin.databinding.CardOfflineBinding
import dev.jdtech.jellyfin.databinding.NextUpSectionBinding
import dev.jdtech.jellyfin.databinding.ViewItemBinding
import dev.jdtech.jellyfin.models.HomeItem
import dev.jdtech.jellyfin.models.View
import dev.jdtech.jellyfin.core.R as CoreR
private const val ITEM_VIEW_TYPE_NEXT_UP = 0
private const val ITEM_VIEW_TYPE_VIEW = 1
@ -20,7 +20,7 @@ class ViewListAdapter(
private val onClickListener: OnClickListener,
private val onItemClickListener: ViewItemListAdapter.OnClickListener,
private val onNextUpClickListener: HomeEpisodeListAdapter.OnClickListener,
private val onOnlineClickListener: OnClickListenerOfflineCard
private val onOnlineClickListener: OnClickListenerOfflineCard,
) : ListAdapter<HomeItem, RecyclerView.ViewHolder>(DiffCallback) {
class ViewViewHolder(private var binding: ViewItemBinding) :
@ -28,7 +28,7 @@ class ViewListAdapter(
fun bind(
dataItem: HomeItem.ViewItem,
onClickListener: OnClickListener,
onItemClickListener: ViewItemListAdapter.OnClickListener
onItemClickListener: ViewItemListAdapter.OnClickListener,
) {
val view = dataItem.view
binding.view = view
@ -75,25 +75,26 @@ class ViewListAdapter(
ITEM_VIEW_TYPE_NEXT_UP -> NextUpViewHolder(
NextUpSectionBinding.inflate(
LayoutInflater.from(
parent.context
parent.context,
),
parent, false
)
parent,
false,
),
)
ITEM_VIEW_TYPE_VIEW -> ViewViewHolder(
ViewItemBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
false,
),
)
ITEM_VIEW_TYPE_OFFLINE_CARD -> {
OfflineCardViewHolder(
CardOfflineBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
false,
),
)
}
else -> throw ClassCastException("Unknown viewType $viewType")

View file

@ -30,7 +30,7 @@ class AddServerFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
savedInstanceState: Bundle?,
): View {
binding = FragmentAddServerBinding.inflate(inflater)
@ -117,7 +117,7 @@ class AddServerFragment : Fragment() {
}
private fun bindDiscoveredServersStateServers(
serversState: AddServerViewModel.DiscoveredServersState.Servers
serversState: AddServerViewModel.DiscoveredServersState.Servers,
) {
val servers = serversState.servers
if (servers.isEmpty()) {

View file

@ -38,7 +38,7 @@ class CollectionFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
savedInstanceState: Bundle?,
): View {
binding = FragmentFavoriteBinding.inflate(inflater, container, false)
@ -48,7 +48,7 @@ class CollectionFragment : Fragment() {
},
HomeEpisodeListAdapter.OnClickListener { item ->
navigateToMediaItem(item)
}
},
)
viewLifecycleOwner.lifecycleScope.launch {
@ -112,23 +112,23 @@ class CollectionFragment : Fragment() {
findNavController().navigate(
CollectionFragmentDirections.actionCollectionFragmentToMovieFragment(
item.id,
item.name
)
item.name,
),
)
}
is FindroidShow -> {
findNavController().navigate(
CollectionFragmentDirections.actionCollectionFragmentToShowFragment(
item.id,
item.name
)
item.name,
),
)
}
is FindroidEpisode -> {
findNavController().navigate(
CollectionFragmentDirections.actionCollectionFragmentToEpisodeBottomSheetFragment(
item.id
)
item.id,
),
)
}
}

View file

@ -18,16 +18,16 @@ import dev.jdtech.jellyfin.R
import dev.jdtech.jellyfin.adapters.FavoritesListAdapter
import dev.jdtech.jellyfin.adapters.HomeEpisodeListAdapter
import dev.jdtech.jellyfin.adapters.ViewItemListAdapter
import dev.jdtech.jellyfin.core.R as CoreR
import dev.jdtech.jellyfin.databinding.FragmentDownloadsBinding
import dev.jdtech.jellyfin.models.FindroidItem
import dev.jdtech.jellyfin.models.FindroidMovie
import dev.jdtech.jellyfin.models.FindroidShow
import dev.jdtech.jellyfin.utils.restart
import dev.jdtech.jellyfin.viewmodels.DownloadsViewModel
import javax.inject.Inject
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
import dev.jdtech.jellyfin.core.R as CoreR
@AndroidEntryPoint
class DownloadsFragment : Fragment() {
@ -40,7 +40,7 @@ class DownloadsFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
savedInstanceState: Bundle?,
): View {
binding = FragmentDownloadsBinding.inflate(inflater, container, false)
@ -50,7 +50,7 @@ class DownloadsFragment : Fragment() {
},
HomeEpisodeListAdapter.OnClickListener { item ->
navigateToMediaItem(item)
}
},
)
viewLifecycleOwner.lifecycleScope.launch {
@ -108,8 +108,8 @@ class DownloadsFragment : Fragment() {
findNavController().navigate(
DownloadsFragmentDirections.actionDownloadsFragmentToMovieFragment(
item.id,
item.name
)
item.name,
),
)
}
is FindroidShow -> {
@ -117,8 +117,8 @@ class DownloadsFragment : Fragment() {
DownloadsFragmentDirections.actionDownloadsFragmentToShowFragment(
item.id,
item.name,
true
)
true,
),
)
}
}

View file

@ -1,6 +1,5 @@
package dev.jdtech.jellyfin.fragments
import android.R as AndroidR
import android.app.DownloadManager
import android.os.Bundle
import android.util.TypedValue
@ -15,7 +14,6 @@ import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import com.google.android.material.R as MaterialR
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
@ -23,7 +21,6 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import dev.jdtech.jellyfin.R
import dev.jdtech.jellyfin.bindCardItemImage
import dev.jdtech.jellyfin.core.R as CoreR
import dev.jdtech.jellyfin.databinding.EpisodeBottomSheetBinding
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
import dev.jdtech.jellyfin.dialogs.getStorageSelectionDialog
@ -36,13 +33,16 @@ import dev.jdtech.jellyfin.models.isDownloading
import dev.jdtech.jellyfin.utils.setIconTintColorAttribute
import dev.jdtech.jellyfin.viewmodels.EpisodeBottomSheetViewModel
import dev.jdtech.jellyfin.viewmodels.PlayerViewModel
import kotlinx.coroutines.launch
import org.jellyfin.sdk.model.DateTime
import timber.log.Timber
import java.text.DateFormat
import java.time.ZoneOffset
import java.util.Date
import java.util.UUID
import kotlinx.coroutines.launch
import org.jellyfin.sdk.model.DateTime
import timber.log.Timber
import android.R as AndroidR
import com.google.android.material.R as MaterialR
import dev.jdtech.jellyfin.core.R as CoreR
@AndroidEntryPoint
class EpisodeBottomSheetFragment : BottomSheetDialogFragment() {
@ -57,7 +57,7 @@ class EpisodeBottomSheetFragment : BottomSheetDialogFragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
savedInstanceState: Bundle?,
): View {
binding = EpisodeBottomSheetBinding.inflate(inflater, container, false)
@ -175,7 +175,7 @@ class EpisodeBottomSheetFragment : BottomSheetDialogFragment() {
onCancel = {
binding.itemActions.progressDownload.isVisible = false
binding.itemActions.downloadButton.setIconResource(CoreR.drawable.ic_download)
}
},
)
dialog.show()
return@getStorageSelectionDialog
@ -186,7 +186,7 @@ class EpisodeBottomSheetFragment : BottomSheetDialogFragment() {
onCancel = {
binding.itemActions.progressDownload.isVisible = false
binding.itemActions.downloadButton.setIconResource(CoreR.drawable.ic_download)
}
},
)
storageDialog.show()
return@setOnClickListener
@ -202,7 +202,7 @@ class EpisodeBottomSheetFragment : BottomSheetDialogFragment() {
onCancel = {
binding.itemActions.progressDownload.isVisible = false
binding.itemActions.downloadButton.setIconResource(CoreR.drawable.ic_download)
}
},
)
dialog.show()
return@setOnClickListener
@ -237,7 +237,7 @@ class EpisodeBottomSheetFragment : BottomSheetDialogFragment() {
binding.progressBar.layoutParams.width = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
(episode.playbackPositionTicks.div(episode.runtimeTicks).times(1.26)).toFloat(),
context?.resources?.displayMetrics
context?.resources?.displayMetrics,
).toInt()
binding.progressBar.isVisible = true
}
@ -264,7 +264,7 @@ class EpisodeBottomSheetFragment : BottomSheetDialogFragment() {
CoreR.string.episode_name_extended,
episode.parentIndexNumber,
episode.indexNumber,
episode.name
episode.name,
)
} else {
getString(
@ -272,7 +272,7 @@ class EpisodeBottomSheetFragment : BottomSheetDialogFragment() {
episode.parentIndexNumber,
episode.indexNumber,
episode.indexNumberEnd,
episode.name
episode.name,
)
}
@ -307,12 +307,12 @@ class EpisodeBottomSheetFragment : BottomSheetDialogFragment() {
private fun bindCheckButtonState(played: Boolean) {
when (played) {
true -> binding.itemActions.checkButton.setIconTintResource(
CoreR.color.red
CoreR.color.red,
)
false -> binding.itemActions.checkButton.setIconTintColorAttribute(
MaterialR.attr.colorOnSecondaryContainer,
requireActivity().theme
requireActivity().theme,
)
}
}
@ -325,12 +325,12 @@ class EpisodeBottomSheetFragment : BottomSheetDialogFragment() {
binding.itemActions.favoriteButton.setIconResource(favoriteDrawable)
when (favorite) {
true -> binding.itemActions.favoriteButton.setIconTintResource(
CoreR.color.red
CoreR.color.red,
)
false -> binding.itemActions.favoriteButton.setIconTintColorAttribute(
MaterialR.attr.colorOnSecondaryContainer,
requireActivity().theme
requireActivity().theme,
)
}
}
@ -392,7 +392,7 @@ class EpisodeBottomSheetFragment : BottomSheetDialogFragment() {
findNavController().navigate(
EpisodeBottomSheetFragmentDirections.actionEpisodeBottomSheetFragmentToPlayerActivity(
playerItems,
)
),
)
}
@ -400,8 +400,8 @@ class EpisodeBottomSheetFragment : BottomSheetDialogFragment() {
findNavController().navigate(
EpisodeBottomSheetFragmentDirections.actionEpisodeBottomSheetFragmentToShowFragment(
itemId = id,
itemName = name
)
itemName = name,
),
)
}

View file

@ -37,7 +37,7 @@ class FavoriteFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
savedInstanceState: Bundle?,
): View {
binding = FragmentFavoriteBinding.inflate(inflater, container, false)
@ -47,7 +47,7 @@ class FavoriteFragment : Fragment() {
},
HomeEpisodeListAdapter.OnClickListener { item ->
navigateToMediaItem(item)
}
},
)
viewLifecycleOwner.lifecycleScope.launch {
@ -105,23 +105,23 @@ class FavoriteFragment : Fragment() {
findNavController().navigate(
FavoriteFragmentDirections.actionFavoriteFragmentToMovieFragment(
item.id,
item.name
)
item.name,
),
)
}
is FindroidShow -> {
findNavController().navigate(
FavoriteFragmentDirections.actionFavoriteFragmentToShowFragment(
item.id,
item.name
)
item.name,
),
)
}
is FindroidEpisode -> {
findNavController().navigate(
FavoriteFragmentDirections.actionFavoriteFragmentToEpisodeBottomSheetFragment(
item.id
)
item.id,
),
)
}
}

View file

@ -23,7 +23,6 @@ import dev.jdtech.jellyfin.AppPreferences
import dev.jdtech.jellyfin.adapters.HomeEpisodeListAdapter
import dev.jdtech.jellyfin.adapters.ViewItemListAdapter
import dev.jdtech.jellyfin.adapters.ViewListAdapter
import dev.jdtech.jellyfin.core.R as CoreR
import dev.jdtech.jellyfin.databinding.FragmentHomeBinding
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
import dev.jdtech.jellyfin.models.FindroidEpisode
@ -33,9 +32,10 @@ import dev.jdtech.jellyfin.models.FindroidShow
import dev.jdtech.jellyfin.utils.checkIfLoginRequired
import dev.jdtech.jellyfin.utils.restart
import dev.jdtech.jellyfin.viewmodels.HomeViewModel
import javax.inject.Inject
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
import dev.jdtech.jellyfin.core.R as CoreR
@AndroidEntryPoint
class HomeFragment : Fragment() {
@ -53,7 +53,7 @@ class HomeFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
savedInstanceState: Bundle?,
): View {
binding = FragmentHomeBinding.inflate(inflater, container, false)
@ -87,7 +87,7 @@ class HomeFragment : Fragment() {
settings.isVisible = true
return true
}
}
},
)
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
@ -114,7 +114,8 @@ class HomeFragment : Fragment() {
}
}
},
viewLifecycleOwner, Lifecycle.State.RESUMED
viewLifecycleOwner,
Lifecycle.State.RESUMED,
)
}
@ -155,7 +156,7 @@ class HomeFragment : Fragment() {
onOnlineClickListener = ViewListAdapter.OnClickListenerOfflineCard {
appPreferences.offlineMode = false
activity?.restart()
}
},
)
binding.errorLayout.errorRetryButton.setOnClickListener {
@ -211,8 +212,8 @@ class HomeFragment : Fragment() {
HomeFragmentDirections.actionNavigationHomeToLibraryFragment(
libraryId = view.id,
libraryName = view.name,
libraryType = view.type
)
libraryType = view.type,
),
)
}
@ -222,23 +223,23 @@ class HomeFragment : Fragment() {
findNavController().navigate(
HomeFragmentDirections.actionNavigationHomeToMovieFragment(
item.id,
item.name
)
item.name,
),
)
}
is FindroidShow -> {
findNavController().navigate(
HomeFragmentDirections.actionNavigationHomeToShowFragment(
item.id,
item.name
)
item.name,
),
)
}
is FindroidEpisode -> {
findNavController().navigate(
HomeFragmentDirections.actionNavigationHomeToEpisodeBottomSheetFragment(
item.id
)
item.id,
),
)
}
}
@ -246,13 +247,13 @@ class HomeFragment : Fragment() {
private fun navigateToSettingsFragment() {
findNavController().navigate(
HomeFragmentDirections.actionHomeFragmentToSettingsFragment()
HomeFragmentDirections.actionHomeFragmentToSettingsFragment(),
)
}
private fun navigateToSearchResultFragment(query: String) {
findNavController().navigate(
HomeFragmentDirections.actionHomeFragmentToSearchResultFragment(query)
HomeFragmentDirections.actionHomeFragmentToSearchResultFragment(query),
)
}
}

View file

@ -21,7 +21,6 @@ import androidx.paging.LoadState
import dagger.hilt.android.AndroidEntryPoint
import dev.jdtech.jellyfin.AppPreferences
import dev.jdtech.jellyfin.adapters.ViewItemPagingAdapter
import dev.jdtech.jellyfin.core.R as CoreR
import dev.jdtech.jellyfin.databinding.FragmentLibraryBinding
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
import dev.jdtech.jellyfin.dialogs.SortDialogFragment
@ -32,10 +31,11 @@ import dev.jdtech.jellyfin.models.FindroidShow
import dev.jdtech.jellyfin.models.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.SortOrder
import java.lang.IllegalArgumentException
import javax.inject.Inject
import dev.jdtech.jellyfin.core.R as CoreR
@AndroidEntryPoint
class LibraryFragment : Fragment() {
@ -52,7 +52,7 @@ class LibraryFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
savedInstanceState: Bundle?,
): View {
binding = FragmentLibraryBinding.inflate(inflater, container, false)
return binding.root
@ -75,10 +75,10 @@ class LibraryFragment : Fragment() {
args.libraryId,
args.libraryType,
viewModel,
"sortBy"
"sortBy",
).show(
parentFragmentManager,
"sortdialog"
"sortdialog",
)
true
}
@ -87,10 +87,10 @@ class LibraryFragment : Fragment() {
args.libraryId,
args.libraryType,
viewModel,
"sortOrder"
"sortOrder",
).show(
parentFragmentManager,
"sortdialog"
"sortdialog",
)
true
}
@ -98,7 +98,8 @@ class LibraryFragment : Fragment() {
}
}
},
viewLifecycleOwner, Lifecycle.State.RESUMED
viewLifecycleOwner,
Lifecycle.State.RESUMED,
)
binding.errorLayout.errorRetryButton.setOnClickListener {
@ -108,7 +109,7 @@ class LibraryFragment : Fragment() {
binding.errorLayout.errorDetailsButton.setOnClickListener {
errorDialog.show(
parentFragmentManager,
ErrorDialogFragment.TAG
ErrorDialogFragment.TAG,
)
}
@ -116,7 +117,7 @@ class LibraryFragment : Fragment() {
ViewItemPagingAdapter(
ViewItemPagingAdapter.OnClickListener { item ->
navigateToItem(item)
}
},
)
(binding.itemsRecyclerView.adapter as ViewItemPagingAdapter).addLoadStateListener {
@ -162,7 +163,7 @@ class LibraryFragment : Fragment() {
args.libraryId,
args.libraryType,
sortBy = sortBy,
sortOrder = sortOrder
sortOrder = sortOrder,
)
}
}
@ -201,24 +202,24 @@ class LibraryFragment : Fragment() {
findNavController().navigate(
LibraryFragmentDirections.actionLibraryFragmentToMovieFragment(
item.id,
item.name
)
item.name,
),
)
}
is FindroidShow -> {
findNavController().navigate(
LibraryFragmentDirections.actionLibraryFragmentToShowFragment(
item.id,
item.name
)
item.name,
),
)
}
is FindroidBoxSet -> {
findNavController().navigate(
LibraryFragmentDirections.actionLibraryFragmentToCollectionFragment(
item.id,
item.name
)
item.name,
),
)
}
}

View file

@ -17,13 +17,13 @@ import androidx.navigation.fragment.navArgs
import dagger.hilt.android.AndroidEntryPoint
import dev.jdtech.jellyfin.AppPreferences
import dev.jdtech.jellyfin.adapters.UserLoginListAdapter
import dev.jdtech.jellyfin.core.R as CoreR
import dev.jdtech.jellyfin.database.ServerDatabaseDao
import dev.jdtech.jellyfin.databinding.FragmentLoginBinding
import dev.jdtech.jellyfin.viewmodels.LoginViewModel
import javax.inject.Inject
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
import dev.jdtech.jellyfin.core.R as CoreR
@AndroidEntryPoint
class LoginFragment : Fragment() {
@ -41,7 +41,7 @@ class LoginFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
savedInstanceState: Bundle?,
): View {
binding = FragmentLoginBinding.inflate(inflater)

View file

@ -20,7 +20,6 @@ import androidx.lifecycle.repeatOnLifecycle
import androidx.navigation.fragment.findNavController
import dagger.hilt.android.AndroidEntryPoint
import dev.jdtech.jellyfin.adapters.CollectionListAdapter
import dev.jdtech.jellyfin.core.R as CoreR
import dev.jdtech.jellyfin.databinding.FragmentMediaBinding
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
import dev.jdtech.jellyfin.models.FindroidCollection
@ -28,6 +27,7 @@ import dev.jdtech.jellyfin.utils.checkIfLoginRequired
import dev.jdtech.jellyfin.viewmodels.MediaViewModel
import kotlinx.coroutines.launch
import timber.log.Timber
import dev.jdtech.jellyfin.core.R as CoreR
@AndroidEntryPoint
class MediaFragment : Fragment() {
@ -42,7 +42,7 @@ class MediaFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
savedInstanceState: Bundle?,
): View {
binding = FragmentMediaBinding.inflate(inflater, container, false)
@ -50,7 +50,7 @@ class MediaFragment : Fragment() {
CollectionListAdapter(
CollectionListAdapter.OnClickListener { library ->
navigateToLibraryFragment(library)
}
},
)
viewLifecycleOwner.lifecycleScope.launch {
@ -108,7 +108,8 @@ class MediaFragment : Fragment() {
return true
}
},
viewLifecycleOwner, Lifecycle.State.RESUMED
viewLifecycleOwner,
Lifecycle.State.RESUMED,
)
}
@ -152,13 +153,13 @@ class MediaFragment : Fragment() {
libraryId = library.id,
libraryName = library.name,
libraryType = library.type,
)
),
)
}
private fun navigateToSearchResultFragment(query: String) {
findNavController().navigate(
MediaFragmentDirections.actionNavigationMediaToSearchResultFragment(query)
MediaFragmentDirections.actionNavigationMediaToSearchResultFragment(query),
)
}
}

View file

@ -24,7 +24,6 @@ import dev.jdtech.jellyfin.AppPreferences
import dev.jdtech.jellyfin.R
import dev.jdtech.jellyfin.adapters.PersonListAdapter
import dev.jdtech.jellyfin.bindItemBackdropImage
import dev.jdtech.jellyfin.core.R as CoreR
import dev.jdtech.jellyfin.databinding.FragmentMovieBinding
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
import dev.jdtech.jellyfin.dialogs.getStorageSelectionDialog
@ -40,10 +39,11 @@ import dev.jdtech.jellyfin.utils.checkIfLoginRequired
import dev.jdtech.jellyfin.utils.setIconTintColorAttribute
import dev.jdtech.jellyfin.viewmodels.MovieViewModel
import dev.jdtech.jellyfin.viewmodels.PlayerViewModel
import java.util.UUID
import javax.inject.Inject
import kotlinx.coroutines.launch
import timber.log.Timber
import java.util.UUID
import javax.inject.Inject
import dev.jdtech.jellyfin.core.R as CoreR
@AndroidEntryPoint
class MovieFragment : Fragment() {
@ -61,7 +61,7 @@ class MovieFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
savedInstanceState: Bundle?,
): View {
binding = FragmentMovieBinding.inflate(inflater, container, false)
@ -152,13 +152,14 @@ class MovieFragment : Fragment() {
binding.itemActions.progressPlay.isVisible = true
if (viewModel.item.sources.filter { it.type == FindroidSourceType.REMOTE }.size > 1) {
val dialog = getVideoVersionDialog(
requireContext(), viewModel.item,
requireContext(),
viewModel.item,
onItemSelected = {
playerViewModel.loadPlayerItems(viewModel.item, it)
},
onCancel = {
playButtonNormal()
}
},
)
dialog.show()
return@setOnClickListener
@ -170,7 +171,7 @@ class MovieFragment : Fragment() {
viewModel.item.trailer.let { trailerUri ->
val intent = Intent(
Intent.ACTION_VIEW,
Uri.parse(trailerUri)
Uri.parse(trailerUri),
)
try {
startActivity(intent)
@ -215,7 +216,7 @@ class MovieFragment : Fragment() {
onCancel = {
binding.itemActions.progressDownload.isVisible = false
binding.itemActions.downloadButton.setIconResource(CoreR.drawable.ic_download)
}
},
)
dialog.show()
return@getStorageSelectionDialog
@ -226,7 +227,7 @@ class MovieFragment : Fragment() {
onCancel = {
binding.itemActions.progressDownload.isVisible = false
binding.itemActions.downloadButton.setIconResource(CoreR.drawable.ic_download)
}
},
)
storageDialog.show()
return@setOnClickListener
@ -242,7 +243,7 @@ class MovieFragment : Fragment() {
onCancel = {
binding.itemActions.progressDownload.isVisible = false
binding.itemActions.downloadButton.setIconResource(CoreR.drawable.ic_download)
}
},
)
dialog.show()
return@setOnClickListener
@ -324,7 +325,8 @@ class MovieFragment : Fragment() {
videoProfileChip.isVisible = when (this) {
DisplayProfile.HDR,
DisplayProfile.HDR10,
DisplayProfile.HLG -> {
DisplayProfile.HLG,
-> {
videoProfileChip.chipStartPadding = .0f
true
}
@ -411,7 +413,7 @@ class MovieFragment : Fragment() {
true -> binding.itemActions.checkButton.setIconTintResource(CoreR.color.red)
false -> binding.itemActions.checkButton.setIconTintColorAttribute(
com.google.android.material.R.attr.colorOnSecondaryContainer,
requireActivity().theme
requireActivity().theme,
)
}
}
@ -426,7 +428,7 @@ class MovieFragment : Fragment() {
true -> binding.itemActions.favoriteButton.setIconTintResource(CoreR.color.red)
false -> binding.itemActions.favoriteButton.setIconTintColorAttribute(
com.google.android.material.R.attr.colorOnSecondaryContainer,
requireActivity().theme
requireActivity().theme,
)
}
}
@ -494,14 +496,14 @@ class MovieFragment : Fragment() {
) {
findNavController().navigate(
MovieFragmentDirections.actionMovieFragmentToPlayerActivity(
playerItems
)
playerItems,
),
)
}
private fun navigateToPersonDetail(personId: UUID) {
findNavController().navigate(
MovieFragmentDirections.actionMovieFragmentToPersonDetailFragment(personId)
MovieFragmentDirections.actionMovieFragmentToPersonDetailFragment(personId),
)
}
}

View file

@ -17,7 +17,6 @@ import androidx.navigation.fragment.navArgs
import dagger.hilt.android.AndroidEntryPoint
import dev.jdtech.jellyfin.adapters.ViewItemListAdapter
import dev.jdtech.jellyfin.bindItemImage
import dev.jdtech.jellyfin.core.R as CoreR
import dev.jdtech.jellyfin.databinding.FragmentPersonDetailBinding
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
import dev.jdtech.jellyfin.models.FindroidItem
@ -27,6 +26,7 @@ import dev.jdtech.jellyfin.utils.checkIfLoginRequired
import dev.jdtech.jellyfin.viewmodels.PersonDetailViewModel
import kotlinx.coroutines.launch
import timber.log.Timber
import dev.jdtech.jellyfin.core.R as CoreR
@AndroidEntryPoint
internal class PersonDetailFragment : Fragment() {
@ -41,7 +41,7 @@ internal class PersonDetailFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
savedInstanceState: Bundle?,
): View {
binding = FragmentPersonDetailBinding.inflate(inflater, container, false)
return binding.root
@ -120,7 +120,7 @@ internal class PersonDetailFragment : Fragment() {
private fun adapter() = ViewItemListAdapter(
fixedWidth = true,
onClickListener = ViewItemListAdapter.OnClickListener { navigateToMediaItem(it) }
onClickListener = ViewItemListAdapter.OnClickListener { navigateToMediaItem(it) },
)
private fun setupOverviewExpansion() = binding.overview.post {
@ -145,16 +145,16 @@ internal class PersonDetailFragment : Fragment() {
findNavController().navigate(
PersonDetailFragmentDirections.actionPersonDetailFragmentToMovieFragment(
itemId = item.id,
itemName = item.name
)
itemName = item.name,
),
)
}
is FindroidShow -> {
findNavController().navigate(
PersonDetailFragmentDirections.actionPersonDetailFragmentToShowFragment(
itemId = item.id,
itemName = item.name
)
itemName = item.name,
),
)
}
}

View file

@ -39,7 +39,7 @@ class SearchResultFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
savedInstanceState: Bundle?,
): View {
binding = FragmentSearchResultBinding.inflate(inflater, container, false)
@ -49,7 +49,7 @@ class SearchResultFragment : Fragment() {
},
HomeEpisodeListAdapter.OnClickListener { item ->
navigateToMediaItem(item)
}
},
)
viewLifecycleOwner.lifecycleScope.launch {
@ -113,23 +113,23 @@ class SearchResultFragment : Fragment() {
findNavController().navigate(
SearchResultFragmentDirections.actionSearchResultFragmentToMovieFragment(
item.id,
item.name
)
item.name,
),
)
}
is FindroidShow -> {
findNavController().navigate(
SearchResultFragmentDirections.actionSearchResultFragmentToShowFragment(
item.id,
item.name
)
item.name,
),
)
}
is FindroidEpisode -> {
findNavController().navigate(
SearchResultFragmentDirections.actionSearchResultFragmentToEpisodeBottomSheetFragment(
item.id
)
item.id,
),
)
}
}

View file

@ -37,7 +37,7 @@ class SeasonFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
savedInstanceState: Bundle?,
): View {
binding = FragmentSeasonBinding.inflate(inflater, container, false)
return binding.root
@ -124,8 +124,8 @@ class SeasonFragment : Fragment() {
private fun navigateToEpisodeBottomSheetFragment(episode: FindroidEpisode) {
findNavController().navigate(
SeasonFragmentDirections.actionSeasonFragmentToEpisodeBottomSheetFragment(
episode.id
)
episode.id,
),
)
}
@ -134,8 +134,8 @@ class SeasonFragment : Fragment() {
) {
findNavController().navigate(
SeasonFragmentDirections.actionSeasonFragmentToPlayerActivity(
playerItems
)
playerItems,
),
)
}
}

View file

@ -30,7 +30,7 @@ class ServerAddressesFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
savedInstanceState: Bundle?,
): View {
binding = FragmentServerAddressesBinding.inflate(inflater)
@ -42,16 +42,16 @@ class ServerAddressesFragment : Fragment() {
{ address ->
DeleteServerAddressDialog(viewModel, address).show(
parentFragmentManager,
"deleteServerAddress"
"deleteServerAddress",
)
true
}
},
)
binding.buttonAddAddress.setOnClickListener {
AddServerAddressDialog(viewModel).show(
parentFragmentManager,
"addServerAddress"
"addServerAddress",
)
}

View file

@ -26,7 +26,7 @@ class ServerSelectFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
savedInstanceState: Bundle?,
): View {
binding = FragmentServerSelectBinding.inflate(inflater)
@ -42,10 +42,10 @@ class ServerSelectFragment : Fragment() {
ServerGridAdapter.OnLongClickListener { server ->
DeleteServerDialogFragment(viewModel, server).show(
parentFragmentManager,
"deleteServer"
"deleteServer",
)
true
}
},
)
binding.buttonAddServer.setOnClickListener {
@ -67,7 +67,7 @@ class ServerSelectFragment : Fragment() {
private fun navigateToAddServerFragment() {
findNavController().navigate(
ServerSelectFragmentDirections.actionServerSelectFragmentToAddServerFragment()
ServerSelectFragmentDirections.actionServerSelectFragmentToAddServerFragment(),
)
}

View file

@ -5,8 +5,8 @@ import androidx.fragment.app.viewModels
import androidx.preference.EditTextPreference
import androidx.preference.PreferenceFragmentCompat
import dagger.hilt.android.AndroidEntryPoint
import dev.jdtech.jellyfin.core.R as CoreR
import dev.jdtech.jellyfin.viewmodels.SettingsDeviceViewModel
import dev.jdtech.jellyfin.core.R as CoreR
@AndroidEntryPoint
@Suppress("unused")

View file

@ -8,9 +8,9 @@ import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import dagger.hilt.android.AndroidEntryPoint
import dev.jdtech.jellyfin.AppPreferences
import dev.jdtech.jellyfin.core.R as CoreR
import dev.jdtech.jellyfin.utils.restart
import javax.inject.Inject
import dev.jdtech.jellyfin.core.R as CoreR
@AndroidEntryPoint
class SettingsFragment : PreferenceFragmentCompat() {
@ -45,7 +45,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
findPreference<Preference>("privacyPolicy")?.setOnPreferenceClickListener {
val intent = Intent(
Intent.ACTION_VIEW,
Uri.parse("https://github.com/jarnedemeulemeester/findroid/blob/main/PRIVACY")
Uri.parse("https://github.com/jarnedemeulemeester/findroid/blob/main/PRIVACY"),
)
startActivity(intent)
true

View file

@ -20,8 +20,8 @@ class SettingsLanguageFragment : PreferenceFragmentCompat() {
startActivity(
Intent(
Settings.ACTION_APP_LOCALE_SETTINGS,
Uri.parse("package:${requireContext().packageName}")
)
Uri.parse("package:${requireContext().packageName}"),
),
)
true
}

View file

@ -22,7 +22,6 @@ import dev.jdtech.jellyfin.adapters.PersonListAdapter
import dev.jdtech.jellyfin.adapters.ViewItemListAdapter
import dev.jdtech.jellyfin.bindCardItemImage
import dev.jdtech.jellyfin.bindItemBackdropImage
import dev.jdtech.jellyfin.core.R as CoreR
import dev.jdtech.jellyfin.databinding.FragmentShowBinding
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
import dev.jdtech.jellyfin.models.FindroidItem
@ -34,10 +33,11 @@ import dev.jdtech.jellyfin.utils.checkIfLoginRequired
import dev.jdtech.jellyfin.utils.setIconTintColorAttribute
import dev.jdtech.jellyfin.viewmodels.PlayerViewModel
import dev.jdtech.jellyfin.viewmodels.ShowViewModel
import java.util.UUID
import javax.inject.Inject
import kotlinx.coroutines.launch
import timber.log.Timber
import java.util.UUID
import javax.inject.Inject
import dev.jdtech.jellyfin.core.R as CoreR
@AndroidEntryPoint
class ShowFragment : Fragment() {
@ -55,7 +55,7 @@ class ShowFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
savedInstanceState: Bundle?,
): View {
binding = FragmentShowBinding.inflate(inflater, container, false)
@ -104,7 +104,7 @@ class ShowFragment : Fragment() {
viewModel.item.trailer.let { trailerUri ->
val intent = Intent(
Intent.ACTION_VIEW,
Uri.parse(trailerUri)
Uri.parse(trailerUri),
)
try {
startActivity(intent)
@ -123,7 +123,7 @@ class ShowFragment : Fragment() {
ViewItemListAdapter.OnClickListener { season ->
if (season is FindroidSeason) navigateToSeasonFragment(season)
},
fixedWidth = true
fixedWidth = true,
)
binding.peopleRecyclerView.adapter = PersonListAdapter { person ->
navigateToPersonDetail(person.id)
@ -183,9 +183,11 @@ class ShowFragment : Fragment() {
binding.itemActions.downloadButton.isVisible = true
binding.itemActions.downloadButton.isEnabled = !downloaded
if (downloaded) binding.itemActions.downloadButton.setIconTintResource(
CoreR.color.red
)
if (downloaded) {
binding.itemActions.downloadButton.setIconTintResource(
CoreR.color.red,
)
}
}
false -> {
@ -222,7 +224,7 @@ class ShowFragment : Fragment() {
CoreR.string.episode_name_extended,
nextUp?.parentIndexNumber,
nextUp?.indexNumber,
nextUp?.name
nextUp?.name,
)
} else {
binding.nextUpName.text = getString(
@ -230,7 +232,7 @@ class ShowFragment : Fragment() {
nextUp?.parentIndexNumber,
nextUp?.indexNumber,
nextUp?.indexNumberEnd,
nextUp?.name
nextUp?.name,
)
}
@ -265,7 +267,7 @@ class ShowFragment : Fragment() {
true -> binding.itemActions.checkButton.setIconTintResource(CoreR.color.red)
false -> binding.itemActions.checkButton.setIconTintColorAttribute(
R.attr.colorOnSecondaryContainer,
requireActivity().theme
requireActivity().theme,
)
}
}
@ -280,7 +282,7 @@ class ShowFragment : Fragment() {
true -> binding.itemActions.favoriteButton.setIconTintResource(CoreR.color.red)
false -> binding.itemActions.favoriteButton.setIconTintColorAttribute(
R.attr.colorOnSecondaryContainer,
requireActivity().theme
requireActivity().theme,
)
}
}
@ -310,8 +312,8 @@ class ShowFragment : Fragment() {
private fun navigateToEpisodeBottomSheetFragment(episode: FindroidItem) {
findNavController().navigate(
ShowFragmentDirections.actionShowFragmentToEpisodeBottomSheetFragment(
episode.id
)
episode.id,
),
)
}
@ -322,8 +324,8 @@ class ShowFragment : Fragment() {
season.id,
season.seriesName,
season.name,
args.offline
)
args.offline,
),
)
}
@ -332,14 +334,14 @@ class ShowFragment : Fragment() {
) {
findNavController().navigate(
ShowFragmentDirections.actionShowFragmentToPlayerActivity(
playerItems
)
playerItems,
),
)
}
private fun navigateToPersonDetail(personId: UUID) {
findNavController().navigate(
ShowFragmentDirections.actionShowFragmentToPersonDetailFragment(personId)
ShowFragmentDirections.actionShowFragmentToPersonDetailFragment(personId),
)
}
}

View file

@ -30,7 +30,7 @@ class UsersFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
savedInstanceState: Bundle?,
): View {
binding = FragmentUsersBinding.inflate(inflater)
@ -42,10 +42,10 @@ class UsersFragment : Fragment() {
{ user ->
DeleteUserDialogFragment(viewModel, user).show(
parentFragmentManager,
"deleteUser"
"deleteUser",
)
true
}
},
)
binding.buttonAddUser.setOnClickListener {
@ -90,7 +90,7 @@ class UsersFragment : Fragment() {
private fun navigateToLoginFragment() {
findNavController().navigate(
AppNavigationDirections.actionGlobalLoginFragment()
AppNavigationDirections.actionGlobalLoginFragment(),
)
}

View file

@ -20,14 +20,14 @@ import dev.jdtech.jellyfin.Constants
import dev.jdtech.jellyfin.PlayerActivity
import dev.jdtech.jellyfin.isControlsLocked
import dev.jdtech.jellyfin.mpv.MPVPlayer
import kotlin.math.abs
import timber.log.Timber
import kotlin.math.abs
class PlayerGestureHelper(
private val appPreferences: AppPreferences,
private val activity: PlayerActivity,
private val playerView: PlayerView,
private val audioManager: AudioManager
private val audioManager: AudioManager,
) {
/**
* Tracks whether video content should fill the screen, cutting off unwanted content on the sides.
@ -78,7 +78,7 @@ class PlayerGestureHelper(
}
return true
}
}
},
)
private val seekGestureDetector = GestureDetector(
@ -89,7 +89,7 @@ class PlayerGestureHelper(
firstEvent: MotionEvent,
currentEvent: MotionEvent,
distanceX: Float,
distanceY: Float
distanceY: Float,
): Boolean {
// Excludes area where app gestures conflicting with system gestures
if (inExclusionArea(firstEvent)) return false
@ -114,11 +114,13 @@ class PlayerGestureHelper(
swipeGestureValueTrackerProgress = newPos
swipeGestureProgressOpen = true
true
} else false
} else {
false
}
}
return true
}
}
},
)
private val vbGestureDetector = GestureDetector(
@ -129,7 +131,7 @@ class PlayerGestureHelper(
firstEvent: MotionEvent,
currentEvent: MotionEvent,
distanceX: Float,
distanceY: Float
distanceY: Float,
): Boolean {
// Excludes area where app gestures conflicting with system gestures
if (inExclusionArea(firstEvent)) return false
@ -138,8 +140,9 @@ class PlayerGestureHelper(
if (abs(distanceY / distanceX) < 2) return false
if (swipeGestureValueTrackerProgress > -1 || swipeGestureProgressOpen)
if (swipeGestureValueTrackerProgress > -1 || swipeGestureProgressOpen) {
return false
}
val viewCenterX = playerView.measuredWidth / 2
@ -197,7 +200,7 @@ class PlayerGestureHelper(
}
return true
}
}
},
)
private val hideGestureVolumeIndicatorOverlayAction = Runnable {
@ -236,7 +239,7 @@ class PlayerGestureHelper(
}
override fun onScaleEnd(detector: ScaleGestureDetector) = Unit
}
},
).apply { isQuickScaleEnabled = false }
private fun updateZoomMode(enabled: Boolean) {
@ -294,14 +297,16 @@ class PlayerGestureHelper(
if ((firstEvent.x < insets.left) || (firstEvent.x > (screenWidth - insets.right)) ||
(firstEvent.y < insets.top) || (firstEvent.y > (screenHeight - insets.bottom))
)
) {
return true
}
} else if (firstEvent.y < playerView.resources.dip(Constants.GESTURE_EXCLUSION_AREA_VERTICAL) ||
firstEvent.y > screenHeight - playerView.resources.dip(Constants.GESTURE_EXCLUSION_AREA_VERTICAL) ||
firstEvent.x < playerView.resources.dip(Constants.GESTURE_EXCLUSION_AREA_HORIZONTAL) ||
firstEvent.x > screenWidth - playerView.resources.dip(Constants.GESTURE_EXCLUSION_AREA_HORIZONTAL)
)
) {
return true
}
return false
}

View file

@ -17,7 +17,7 @@ class PreviewScrubListener(
private val scrubbingPreview: ImageView,
private val timeBarView: View,
private val player: Player,
private val currentTrickPlay: StateFlow<BifData?>
private val currentTrickPlay: StateFlow<BifData?>,
) : TimeBar.OnScrubListener {
private val roundedCorners = RoundedCornersTransformation(10f)
@ -26,8 +26,9 @@ class PreviewScrubListener(
override fun onScrubStart(timeBar: TimeBar, position: Long) {
Timber.d("Scrubbing started at $position")
if (currentTrickPlay.value == null)
if (currentTrickPlay.value == null) {
return
}
scrubbingPreview.visibility = View.VISIBLE
onScrubMove(timeBar, position)

View file

@ -19,13 +19,13 @@ object ApiModule {
fun provideJellyfinApi(
@ApplicationContext application: Context,
appPreferences: AppPreferences,
serverDatabase: ServerDatabaseDao
serverDatabase: ServerDatabaseDao,
): JellyfinApi {
val jellyfinApi = JellyfinApi.getInstance(
context = application,
requestTimeout = appPreferences.requestTimeout,
connectTimeout = appPreferences.connectTimeout,
socketTimeout = appPreferences.socketTimeout
socketTimeout = appPreferences.socketTimeout,
)
val serverId = appPreferences.currentServer ?: return jellyfinApi

View file

@ -20,7 +20,7 @@ object DatabaseModule {
return Room.databaseBuilder(
app.applicationContext,
ServerDatabase::class.java,
"servers"
"servers",
)
.fallbackToDestructiveMigration()
.allowMainThreadQueries()

View file

@ -10,7 +10,7 @@ import dev.jdtech.jellyfin.viewmodels.ServerAddressesViewModel
import java.lang.IllegalStateException
class AddServerAddressDialog(
private val viewModel: ServerAddressesViewModel
private val viewModel: ServerAddressesViewModel,
) : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val editText = EditText(this.context)

View file

@ -11,7 +11,7 @@ import java.lang.IllegalStateException
class DeleteServerAddressDialog(
private val viewModel: ServerAddressesViewModel,
val address: ServerAddress
val address: ServerAddress,
) : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return activity?.let {

View file

@ -10,17 +10,17 @@ import dev.jdtech.jellyfin.core.R
import dev.jdtech.jellyfin.models.CollectionType
import dev.jdtech.jellyfin.models.SortBy
import dev.jdtech.jellyfin.viewmodels.LibraryViewModel
import org.jellyfin.sdk.model.api.SortOrder
import java.lang.IllegalStateException
import java.util.UUID
import javax.inject.Inject
import org.jellyfin.sdk.model.api.SortOrder
@AndroidEntryPoint
class SortDialogFragment(
private val parentId: UUID,
private val libraryType: CollectionType,
private val viewModel: LibraryViewModel,
private val sortType: String
private val sortType: String,
) : DialogFragment() {
@Inject
lateinit var appPreferences: AppPreferences
@ -48,7 +48,8 @@ class SortDialogFragment(
builder
.setTitle(getString(R.string.sort_by))
.setSingleChoiceItems(
sortByOptions, currentSortBy.ordinal
sortByOptions,
currentSortBy.ordinal,
) { dialog, which ->
val sortBy = sortByValues[which]
appPreferences.sortBy = sortBy.name
@ -56,7 +57,7 @@ class SortDialogFragment(
parentId,
libraryType,
sortBy = sortBy,
sortOrder = currentSortOrder
sortOrder = currentSortOrder,
)
dialog.dismiss()
}
@ -68,7 +69,8 @@ class SortDialogFragment(
builder
.setTitle(getString(R.string.sort_order))
.setSingleChoiceItems(
sortByOptions, currentSortOrder.ordinal
sortByOptions,
currentSortOrder.ordinal,
) { dialog, which ->
val sortOrder = try {
sortOrderValues[which]
@ -82,7 +84,7 @@ class SortDialogFragment(
parentId,
libraryType,
sortBy = currentSortBy,
sortOrder = sortOrder
sortOrder = sortOrder,
)
dialog.dismiss()
}

View file

@ -3,5 +3,5 @@ package dev.jdtech.jellyfin.models
data class DiscoveredServer(
val id: String,
val name: String,
val address: String
val address: String,
)

View file

@ -6,5 +6,5 @@ data class DownloadSection(
val id: UUID,
val name: String,
val items: List<PlayerItem>? = null,
val series: List<DownloadSeriesMetadata>? = null
val series: List<DownloadSeriesMetadata>? = null,
)

View file

@ -1,9 +1,9 @@
package dev.jdtech.jellyfin.models
data class ExceptionUiText(
val uiText: UiText
val uiText: UiText,
) : Exception()
data class ExceptionUiTexts(
val uiTexts: Collection<UiText>
val uiTexts: Collection<UiText>,
) : Exception()

View file

@ -3,5 +3,5 @@ package dev.jdtech.jellyfin.models
data class FavoriteSection(
val id: Int,
val name: UiText,
var items: List<FindroidItem>
var items: List<FindroidItem>,
)

View file

@ -5,5 +5,5 @@ import java.util.UUID
data class HomeSection(
val id: UUID,
val name: UiText,
var items: List<FindroidItem>
var items: List<FindroidItem>,
)

View file

@ -7,7 +7,7 @@ sealed class UiText {
data class DynamicString(val value: String) : UiText()
class StringResource(
@StringRes val resId: Int,
vararg val args: Any?
vararg val args: Any?,
) : UiText()
fun asString(resources: Resources): String {

View file

@ -6,5 +6,5 @@ data class View(
val id: UUID,
val name: String,
var items: List<FindroidItem>? = null,
val type: CollectionType
val type: CollectionType,
)

View file

@ -11,14 +11,14 @@ import androidx.annotation.AttrRes
import com.google.android.material.button.MaterialButton
import dev.jdtech.jellyfin.models.CollectionType
import dev.jdtech.jellyfin.models.View
import java.io.Serializable
import org.jellyfin.sdk.model.api.BaseItemDto
import java.io.Serializable
fun BaseItemDto.toView(): View {
return View(
id = id,
name = name ?: "",
type = valueOf(collectionType, CollectionType.Movies)
type = valueOf(collectionType, CollectionType.Movies),
)
}
@ -30,14 +30,17 @@ fun MaterialButton.setIconTintColorAttribute(@AttrRes attributeId: Int, theme: R
this.iconTint = ColorStateList.valueOf(
resources.getColor(
typedValue.resourceId,
theme
)
theme,
),
)
}
inline fun <reified T : Serializable> Bundle.serializable(key: String): T? = when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> getSerializable(key, T::class.java)
else -> @Suppress("DEPRECATION") getSerializable(key) as? T
else ->
@Suppress("DEPRECATION")
getSerializable(key)
as? T
}
fun Activity.restart() {

View file

@ -13,11 +13,11 @@ import dev.jdtech.jellyfin.models.toFindroidSeason
import dev.jdtech.jellyfin.models.toFindroidShow
import dev.jdtech.jellyfin.models.toFindroidSource
import dev.jdtech.jellyfin.repository.JellyfinRepository
import java.io.File
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File
import javax.inject.Inject
@AndroidEntryPoint
class DownloadReceiver : BroadcastReceiver() {
@ -44,16 +44,16 @@ class DownloadReceiver : BroadcastReceiver() {
} else {
val items = mutableListOf<FindroidItem>()
items.addAll(
database.getMovies().map { it.toFindroidMovie(database, repository.getUserId()) }
database.getMovies().map { it.toFindroidMovie(database, repository.getUserId()) },
)
items.addAll(
database.getShows().map { it.toFindroidShow(database, repository.getUserId()) }
database.getShows().map { it.toFindroidShow(database, repository.getUserId()) },
)
items.addAll(
database.getSeasons().map { it.toFindroidSeason(database, repository.getUserId()) }
database.getSeasons().map { it.toFindroidSeason(database, repository.getUserId()) },
)
items.addAll(
database.getEpisodes().map { it.toFindroidEpisode(database, repository.getUserId()) }
database.getEpisodes().map { it.toFindroidEpisode(database, repository.getUserId()) },
)
items.firstOrNull { it.id == source.itemId }?.let {

View file

@ -8,7 +8,6 @@ import android.os.StatFs
import android.text.format.Formatter
import androidx.core.net.toUri
import dev.jdtech.jellyfin.AppPreferences
import dev.jdtech.jellyfin.core.R as CoreR
import dev.jdtech.jellyfin.database.ServerDatabaseDao
import dev.jdtech.jellyfin.models.FindroidEpisode
import dev.jdtech.jellyfin.models.FindroidItem
@ -29,6 +28,7 @@ import dev.jdtech.jellyfin.repository.JellyfinRepository
import java.io.File
import java.util.UUID
import kotlin.Exception
import dev.jdtech.jellyfin.core.R as CoreR
class DownloaderImpl(
private val context: Context,
@ -50,7 +50,7 @@ class DownloaderImpl(
val trickPlayData = if (trickPlayManifest != null) {
jellyfinRepository.getTrickPlayData(
item.id,
trickPlayManifest.widthResolutions.max()
trickPlayManifest.widthResolutions.max(),
)
} else {
null
@ -68,8 +68,8 @@ class DownloaderImpl(
UiText.StringResource(
CoreR.string.not_enough_storage,
Formatter.formatFileSize(context, source.size),
Formatter.formatFileSize(context, stats.availableBytes)
)
Formatter.formatFileSize(context, stats.availableBytes),
),
)
}
when (item) {
@ -98,10 +98,10 @@ class DownloaderImpl(
is FindroidEpisode -> {
database.insertShow(
jellyfinRepository.getShow(item.seriesId)
.toFindroidShowDto(appPreferences.currentServer!!)
.toFindroidShowDto(appPreferences.currentServer!!),
)
database.insertSeason(
jellyfinRepository.getSeason(item.seasonId).toFindroidSeasonDto()
jellyfinRepository.getSeason(item.seasonId).toFindroidSeasonDto(),
)
database.insertEpisode(item.toFindroidEpisodeDto(appPreferences.currentServer!!))
database.insertSource(source.toFindroidSourceDto(item.id, path.path.orEmpty()))
@ -189,8 +189,8 @@ class DownloaderImpl(
if (cursor.moveToFirst()) {
downloadStatus = cursor.getInt(
cursor.getColumnIndexOrThrow(
DownloadManager.COLUMN_STATUS
)
DownloadManager.COLUMN_STATUS,
),
)
when (downloadStatus) {
DownloadManager.STATUS_RUNNING -> {
@ -233,7 +233,7 @@ class DownloaderImpl(
private fun downloadTrickPlay(
item: FindroidItem,
trickPlayManifest: TrickPlayManifest,
byteArray: ByteArray
byteArray: ByteArray,
) {
database.insertTrickPlayManifest(trickPlayManifest.toTrickPlayManifestDto(item.id))
File(context.filesDir, "trickplay").mkdirs()

View file

@ -13,8 +13,6 @@ import dev.jdtech.jellyfin.models.ExceptionUiTexts
import dev.jdtech.jellyfin.models.Server
import dev.jdtech.jellyfin.models.ServerAddress
import dev.jdtech.jellyfin.models.UiText
import java.util.UUID
import javax.inject.Inject
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableSharedFlow
@ -27,6 +25,8 @@ import org.jellyfin.sdk.discovery.RecommendedServerInfo
import org.jellyfin.sdk.discovery.RecommendedServerInfoScore
import org.jellyfin.sdk.discovery.RecommendedServerIssue
import timber.log.Timber
import java.util.UUID
import javax.inject.Inject
@HiltViewModel
class AddServerViewModel
@ -34,7 +34,7 @@ class AddServerViewModel
constructor(
private val appPreferences: AppPreferences,
private val jellyfinApi: JellyfinApi,
private val database: ServerDatabaseDao
private val database: ServerDatabaseDao,
) : ViewModel() {
private val _uiState = MutableStateFlow<UiState>(UiState.Normal)
val uiState = _uiState.asStateFlow()
@ -65,11 +65,11 @@ constructor(
DiscoveredServer(
serverDiscoveryInfo.id,
serverDiscoveryInfo.name,
serverDiscoveryInfo.address
)
serverDiscoveryInfo.address,
),
)
_discoveredServersState.emit(
DiscoveredServersState.Servers(ArrayList(discoveredServers))
DiscoveredServersState.Servers(ArrayList(discoveredServers)),
)
}
}
@ -96,7 +96,7 @@ constructor(
val candidates = jellyfinApi.jellyfin.discovery.getAddressCandidates(inputValue)
val recommended = jellyfinApi.jellyfin.discovery.getRecommendedServers(
candidates,
RecommendedServerInfoScore.OK
RecommendedServerInfoScore.OK,
)
val goodServers = mutableListOf<RecommendedServerInfo>()
@ -139,17 +139,17 @@ constructor(
} catch (_: CancellationException) {
} catch (e: ExceptionUiText) {
_uiState.emit(
UiState.Error(listOf(e.uiText))
UiState.Error(listOf(e.uiText)),
)
} catch (e: ExceptionUiTexts) {
_uiState.emit(
UiState.Error(e.uiTexts)
UiState.Error(e.uiTexts),
)
} catch (e: Exception) {
_uiState.emit(
UiState.Error(
listOf(if (e.message != null) UiText.DynamicString(e.message!!) else UiText.StringResource(R.string.unknown_error))
)
listOf(if (e.message != null) UiText.DynamicString(e.message!!) else UiText.StringResource(R.string.unknown_error)),
),
)
}
}
@ -173,7 +173,7 @@ constructor(
val serverAddress = ServerAddress(
id = UUID.randomUUID(),
serverId = serverInDatabase.id,
address = recommendedServerInfo.address
address = recommendedServerInfo.address,
)
insertServerAddress(serverAddress)
@ -183,7 +183,7 @@ constructor(
val serverAddress = ServerAddress(
id = UUID.randomUUID(),
serverId = serverInfo.id!!,
address = recommendedServerInfo.address
address = recommendedServerInfo.address,
)
val server = Server(

View file

@ -11,19 +11,19 @@ import dev.jdtech.jellyfin.models.FindroidMovie
import dev.jdtech.jellyfin.models.FindroidShow
import dev.jdtech.jellyfin.models.UiText
import dev.jdtech.jellyfin.repository.JellyfinRepository
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.UUID
import javax.inject.Inject
@HiltViewModel
class CollectionViewModel
@Inject
constructor(
private val jellyfinRepository: JellyfinRepository
private val jellyfinRepository: JellyfinRepository,
) : ViewModel() {
private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
val uiState = _uiState.asStateFlow()
@ -52,29 +52,35 @@ constructor(
FavoriteSection(
Constants.FAVORITE_TYPE_MOVIES,
UiText.StringResource(R.string.movies_label),
items.filterIsInstance<FindroidMovie>()
items.filterIsInstance<FindroidMovie>(),
).let {
if (it.items.isNotEmpty()) favoriteSections.add(
it
)
if (it.items.isNotEmpty()) {
favoriteSections.add(
it,
)
}
}
FavoriteSection(
Constants.FAVORITE_TYPE_SHOWS,
UiText.StringResource(R.string.shows_label),
items.filterIsInstance<FindroidShow>()
items.filterIsInstance<FindroidShow>(),
).let {
if (it.items.isNotEmpty()) favoriteSections.add(
it
)
if (it.items.isNotEmpty()) {
favoriteSections.add(
it,
)
}
}
FavoriteSection(
Constants.FAVORITE_TYPE_EPISODES,
UiText.StringResource(R.string.episodes_label),
items.filterIsInstance<FindroidEpisode>()
items.filterIsInstance<FindroidEpisode>(),
).let {
if (it.items.isNotEmpty()) favoriteSections.add(
it
)
if (it.items.isNotEmpty()) {
favoriteSections.add(
it,
)
}
}
}

View file

@ -11,20 +11,20 @@ import dev.jdtech.jellyfin.models.FindroidMovie
import dev.jdtech.jellyfin.models.FindroidShow
import dev.jdtech.jellyfin.models.UiText
import dev.jdtech.jellyfin.repository.JellyfinRepository
import javax.inject.Inject
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
class DownloadsViewModel
@Inject
constructor(
private val appPreferences: AppPreferences,
private val repository: JellyfinRepository
private val repository: JellyfinRepository,
) : ViewModel() {
private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
val uiState = _uiState.asStateFlow()
@ -65,20 +65,24 @@ constructor(
FavoriteSection(
Constants.FAVORITE_TYPE_MOVIES,
UiText.StringResource(R.string.movies_label),
items.filterIsInstance<FindroidMovie>()
items.filterIsInstance<FindroidMovie>(),
).let {
if (it.items.isNotEmpty()) sections.add(
it
)
if (it.items.isNotEmpty()) {
sections.add(
it,
)
}
}
FavoriteSection(
Constants.FAVORITE_TYPE_SHOWS,
UiText.StringResource(R.string.shows_label),
items.filterIsInstance<FindroidShow>()
items.filterIsInstance<FindroidShow>(),
).let {
if (it.items.isNotEmpty()) sections.add(
it
)
if (it.items.isNotEmpty()) {
sections.add(
it,
)
}
}
_uiState.emit(UiState.Normal(sections))
}

View file

@ -13,15 +13,15 @@ import dev.jdtech.jellyfin.models.UiText
import dev.jdtech.jellyfin.models.isDownloading
import dev.jdtech.jellyfin.repository.JellyfinRepository
import dev.jdtech.jellyfin.utils.Downloader
import java.io.File
import java.util.UUID
import javax.inject.Inject
import kotlin.random.Random
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import java.io.File
import java.util.UUID
import javax.inject.Inject
import kotlin.random.Random
@HiltViewModel
class EpisodeBottomSheetViewModel
@ -71,7 +71,7 @@ constructor(
_uiState.emit(
UiState.Normal(
item,
)
),
)
} catch (_: NullPointerException) {
// Navigate back because item does not exist (probably because it's been deleted)

View file

@ -11,18 +11,18 @@ import dev.jdtech.jellyfin.models.FindroidMovie
import dev.jdtech.jellyfin.models.FindroidShow
import dev.jdtech.jellyfin.models.UiText
import dev.jdtech.jellyfin.repository.JellyfinRepository
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 javax.inject.Inject
@HiltViewModel
class FavoriteViewModel
@Inject
constructor(
private val jellyfinRepository: JellyfinRepository
private val jellyfinRepository: JellyfinRepository,
) : ViewModel() {
private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
val uiState = _uiState.asStateFlow()
@ -49,29 +49,35 @@ constructor(
FavoriteSection(
Constants.FAVORITE_TYPE_MOVIES,
UiText.StringResource(R.string.movies_label),
items.filterIsInstance<FindroidMovie>()
items.filterIsInstance<FindroidMovie>(),
).let {
if (it.items.isNotEmpty()) favoriteSections.add(
it
)
if (it.items.isNotEmpty()) {
favoriteSections.add(
it,
)
}
}
FavoriteSection(
Constants.FAVORITE_TYPE_SHOWS,
UiText.StringResource(R.string.shows_label),
items.filterIsInstance<FindroidShow>()
items.filterIsInstance<FindroidShow>(),
).let {
if (it.items.isNotEmpty()) favoriteSections.add(
it
)
if (it.items.isNotEmpty()) {
favoriteSections.add(
it,
)
}
}
FavoriteSection(
Constants.FAVORITE_TYPE_EPISODES,
UiText.StringResource(R.string.episodes_label),
items.filterIsInstance<FindroidEpisode>()
items.filterIsInstance<FindroidEpisode>(),
).let {
if (it.items.isNotEmpty()) favoriteSections.add(
it
)
if (it.items.isNotEmpty()) {
favoriteSections.add(
it,
)
}
}
}

View file

@ -11,11 +11,11 @@ import dev.jdtech.jellyfin.models.HomeSection
import dev.jdtech.jellyfin.models.UiText
import dev.jdtech.jellyfin.repository.JellyfinRepository
import dev.jdtech.jellyfin.utils.toView
import java.util.UUID
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import java.util.UUID
import javax.inject.Inject
@HiltViewModel
class HomeViewModel @Inject internal constructor(
@ -77,8 +77,8 @@ class HomeViewModel @Inject internal constructor(
HomeSection(
uuidLibraries,
uiTextLibraries,
collections
)
collections,
),
)
}
@ -92,8 +92,8 @@ class HomeViewModel @Inject internal constructor(
HomeSection(
uuidContinueWatching,
uiTextContinueWatching,
resumeItems
)
resumeItems,
),
)
}
@ -102,8 +102,8 @@ class HomeViewModel @Inject internal constructor(
HomeSection(
uuidNextUp,
uiTextNextUp,
nextUpItems
)
nextUpItems,
),
)
}

View file

@ -9,8 +9,6 @@ import dev.jdtech.jellyfin.models.CollectionType
import dev.jdtech.jellyfin.models.FindroidItem
import dev.jdtech.jellyfin.models.SortBy
import dev.jdtech.jellyfin.repository.JellyfinRepository
import java.util.UUID
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
@ -18,12 +16,14 @@ import kotlinx.coroutines.launch
import org.jellyfin.sdk.model.api.BaseItemKind
import org.jellyfin.sdk.model.api.SortOrder
import timber.log.Timber
import java.util.UUID
import javax.inject.Inject
@HiltViewModel
class LibraryViewModel
@Inject
constructor(
private val jellyfinRepository: JellyfinRepository
private val jellyfinRepository: JellyfinRepository,
) : ViewModel() {
private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
val uiState = _uiState.asStateFlow()
@ -40,7 +40,7 @@ constructor(
parentId: UUID,
libraryType: CollectionType,
sortBy: SortBy = SortBy.defaultValue,
sortOrder: SortOrder = SortOrder.ASCENDING
sortOrder: SortOrder = SortOrder.ASCENDING,
) {
itemsloaded = true
Timber.d("$libraryType")
@ -58,7 +58,7 @@ constructor(
includeTypes = itemType,
recursive = true,
sortBy = sortBy,
sortOrder = sortOrder
sortOrder = sortOrder,
).cachedIn(viewModelScope)
_uiState.emit(UiState.Normal(items))
} catch (e: Exception) {

View file

@ -9,8 +9,6 @@ import dev.jdtech.jellyfin.core.R
import dev.jdtech.jellyfin.database.ServerDatabaseDao
import dev.jdtech.jellyfin.models.UiText
import dev.jdtech.jellyfin.models.User
import javax.inject.Inject
import kotlin.Exception
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
@ -23,6 +21,8 @@ import kotlinx.coroutines.withContext
import org.jellyfin.sdk.api.client.extensions.authenticateWithQuickConnect
import org.jellyfin.sdk.model.api.AuthenticateUserByName
import org.jellyfin.sdk.model.api.AuthenticationResult
import javax.inject.Inject
import kotlin.Exception
@HiltViewModel
class LoginViewModel
@ -30,7 +30,7 @@ class LoginViewModel
constructor(
private val appPreferences: AppPreferences,
private val jellyfinApi: JellyfinApi,
private val database: ServerDatabaseDao
private val database: ServerDatabaseDao,
) : ViewModel() {
private val _uiState = MutableStateFlow<UiState>(UiState.Normal)
val uiState = _uiState.asStateFlow()
@ -114,8 +114,8 @@ constructor(
val authenticationResult by jellyfinApi.userApi.authenticateUserByName(
data = AuthenticateUserByName(
username = username,
pw = password
)
pw = password,
),
)
saveAuthenticationResult(authenticationResult)
@ -124,8 +124,10 @@ constructor(
_navigateToMain.emit(true)
} catch (e: Exception) {
val message =
if (e.message?.contains("401") == true) UiText.StringResource(R.string.login_error_wrong_username_password) else UiText.StringResource(
R.string.unknown_error
if (e.message?.contains("401") == true) {
UiText.StringResource(R.string.login_error_wrong_username_password)
} else UiText.StringResource(
R.string.unknown_error,
)
_uiState.emit(UiState.Error(message))
}
@ -147,7 +149,7 @@ constructor(
delay(5000L)
}
val authenticationResult by jellyfinApi.userApi.authenticateWithQuickConnect(
secret = quickConnectState.secret
secret = quickConnectState.secret,
)
saveAuthenticationResult(authenticationResult)
@ -167,7 +169,7 @@ constructor(
id = authenticationResult.user!!.id,
name = authenticationResult.user!!.name!!,
serverId = serverInfo.id!!,
accessToken = authenticationResult.accessToken!!
accessToken = authenticationResult.accessToken!!,
)
insertUser(appPreferences.currentServer!!, user)

View file

@ -6,16 +6,16 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import dev.jdtech.jellyfin.models.CollectionType
import dev.jdtech.jellyfin.models.FindroidCollection
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 javax.inject.Inject
@HiltViewModel
class MediaViewModel
@Inject
constructor(
private val jellyfinRepository: JellyfinRepository
private val jellyfinRepository: JellyfinRepository,
) : ViewModel() {
private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
@ -41,7 +41,7 @@ constructor(
_uiState.emit(UiState.Normal(collections))
} catch (e: Exception) {
_uiState.emit(
UiState.Error(e)
UiState.Error(e),
)
}
}

View file

@ -19,10 +19,6 @@ import dev.jdtech.jellyfin.models.VideoMetadata
import dev.jdtech.jellyfin.models.isDownloading
import dev.jdtech.jellyfin.repository.JellyfinRepository
import dev.jdtech.jellyfin.utils.Downloader
import java.io.File
import java.util.UUID
import javax.inject.Inject
import kotlin.random.Random
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Runnable
import kotlinx.coroutines.flow.MutableSharedFlow
@ -34,6 +30,10 @@ import kotlinx.coroutines.withContext
import org.jellyfin.sdk.model.api.BaseItemPerson
import org.jellyfin.sdk.model.api.MediaStream
import org.jellyfin.sdk.model.api.MediaStreamType
import java.io.File
import java.util.UUID
import javax.inject.Inject
import kotlin.random.Random
@HiltViewModel
class MovieViewModel
@ -41,7 +41,7 @@ class MovieViewModel
constructor(
private val repository: JellyfinRepository,
private val database: ServerDatabaseDao,
private val downloader: Downloader
private val downloader: Downloader,
) : ViewModel() {
private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
val uiState = _uiState.asStateFlow()
@ -111,7 +111,7 @@ constructor(
getMediaString(item, MediaStreamType.SUBTITLE),
runTime,
getDateString(item),
)
),
)
} catch (_: NullPointerException) {
// Navigate back because item does not exist (probably because it's been deleted)
@ -175,7 +175,7 @@ constructor(
AudioChannel.CH_5_1.raw -> AudioChannel.CH_5_1
AudioChannel.CH_7_1.raw -> AudioChannel.CH_7_1
else -> AudioChannel.CH_2_0
}
},
)
/**
@ -199,7 +199,7 @@ constructor(
AudioCodec.TRUEHD.toString() -> AudioCodec.TRUEHD
AudioCodec.DTS.toString() -> AudioCodec.DTS
else -> AudioCodec.MP3
}
},
)
true
}
@ -217,12 +217,14 @@ constructor(
*/
if (stream.videoDoViTitle != null) {
DisplayProfile.DOLBY_VISION
} else when (videoRangeType) {
DisplayProfile.HDR.raw -> DisplayProfile.HDR
DisplayProfile.HDR10.raw -> DisplayProfile.HDR10
DisplayProfile.HLG.raw -> DisplayProfile.HLG
else -> DisplayProfile.SDR
}
} else {
when (videoRangeType) {
DisplayProfile.HDR.raw -> DisplayProfile.HDR
DisplayProfile.HDR10.raw -> DisplayProfile.HDR10
DisplayProfile.HLG.raw -> DisplayProfile.HLG
else -> DisplayProfile.SDR
}
},
)
/**
@ -240,7 +242,7 @@ constructor(
}
else -> Resolution.SD
}
},
)
}
true
@ -256,7 +258,7 @@ constructor(
displayProfile.toSet().toList(),
audioChannels.toSet().toList(),
audioCodecs.toSet().toList(),
isAtmosAudio
isAtmosAudio,
)
}

View file

@ -6,17 +6,17 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import dev.jdtech.jellyfin.models.FindroidMovie
import dev.jdtech.jellyfin.models.FindroidShow
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
class PersonDetailViewModel @Inject internal constructor(
private val jellyfinRepository: JellyfinRepository
private val jellyfinRepository: JellyfinRepository,
) : ViewModel() {
private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
@ -37,13 +37,13 @@ class PersonDetailViewModel @Inject internal constructor(
val data = PersonOverview(
name = personDetail.name.orEmpty(),
overview = personDetail.overview.orEmpty(),
dto = personDetail
dto = personDetail,
)
val items = jellyfinRepository.getPersonItems(
personIds = listOf(personId),
includeTypes = listOf(BaseItemKind.MOVIE, BaseItemKind.SERIES),
recursive = true
recursive = true,
)
val movies = items.filterIsInstance<FindroidMovie>()
@ -61,11 +61,11 @@ class PersonDetailViewModel @Inject internal constructor(
data class PersonOverview(
val name: String,
val overview: String,
val dto: BaseItemDto
val dto: BaseItemDto,
)
data class StarredIn(
val movies: List<FindroidMovie>,
val shows: List<FindroidShow>
val shows: List<FindroidShow>,
)
}

View file

@ -11,18 +11,18 @@ import dev.jdtech.jellyfin.models.FindroidMovie
import dev.jdtech.jellyfin.models.FindroidShow
import dev.jdtech.jellyfin.models.UiText
import dev.jdtech.jellyfin.repository.JellyfinRepository
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 javax.inject.Inject
@HiltViewModel
class SearchResultViewModel
@Inject
constructor(
private val jellyfinRepository: JellyfinRepository
private val jellyfinRepository: JellyfinRepository,
) : ViewModel() {
private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
val uiState = _uiState.asStateFlow()
@ -50,29 +50,35 @@ constructor(
FavoriteSection(
Constants.FAVORITE_TYPE_MOVIES,
UiText.StringResource(R.string.movies_label),
items.filterIsInstance<FindroidMovie>()
items.filterIsInstance<FindroidMovie>(),
).let {
if (it.items.isNotEmpty()) sections.add(
it
)
if (it.items.isNotEmpty()) {
sections.add(
it,
)
}
}
FavoriteSection(
Constants.FAVORITE_TYPE_SHOWS,
UiText.StringResource(R.string.shows_label),
items.filterIsInstance<FindroidShow>()
items.filterIsInstance<FindroidShow>(),
).let {
if (it.items.isNotEmpty()) sections.add(
it
)
if (it.items.isNotEmpty()) {
sections.add(
it,
)
}
}
FavoriteSection(
Constants.FAVORITE_TYPE_EPISODES,
UiText.StringResource(R.string.episodes_label),
items.filterIsInstance<FindroidEpisode>()
items.filterIsInstance<FindroidEpisode>(),
).let {
if (it.items.isNotEmpty()) sections.add(
it
)
if (it.items.isNotEmpty()) {
sections.add(
it,
)
}
}
}

View file

@ -6,20 +6,20 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import dev.jdtech.jellyfin.models.EpisodeItem
import dev.jdtech.jellyfin.models.FindroidSeason
import dev.jdtech.jellyfin.repository.JellyfinRepository
import java.util.UUID
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import org.jellyfin.sdk.model.api.ItemFields
import java.util.UUID
import javax.inject.Inject
@HiltViewModel
class SeasonViewModel
@Inject
constructor(
private val jellyfinRepository: JellyfinRepository
private val jellyfinRepository: JellyfinRepository,
) : ViewModel() {
private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
val uiState = _uiState.asStateFlow()

View file

@ -6,8 +6,6 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import dev.jdtech.jellyfin.api.JellyfinApi
import dev.jdtech.jellyfin.database.ServerDatabaseDao
import dev.jdtech.jellyfin.models.ServerAddress
import java.util.UUID
import javax.inject.Inject
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
@ -15,6 +13,8 @@ import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import timber.log.Timber
import java.util.UUID
import javax.inject.Inject
@HiltViewModel
class ServerAddressesViewModel

View file

@ -7,11 +7,11 @@ import dev.jdtech.jellyfin.AppPreferences
import dev.jdtech.jellyfin.api.JellyfinApi
import dev.jdtech.jellyfin.database.ServerDatabaseDao
import dev.jdtech.jellyfin.models.Server
import javax.inject.Inject
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
class ServerSelectViewModel
@ -19,7 +19,7 @@ class ServerSelectViewModel
constructor(
private val jellyfinApi: JellyfinApi,
private val database: ServerDatabaseDao,
private val appPreferences: AppPreferences
private val appPreferences: AppPreferences,
) : ViewModel() {
val servers = database.getAllServers()

View file

@ -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
class SettingsDeviceViewModel

View file

@ -7,8 +7,6 @@ import dev.jdtech.jellyfin.models.FindroidEpisode
import dev.jdtech.jellyfin.models.FindroidSeason
import dev.jdtech.jellyfin.models.FindroidShow
import dev.jdtech.jellyfin.repository.JellyfinRepository
import java.util.UUID
import javax.inject.Inject
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
@ -17,6 +15,8 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.jellyfin.sdk.model.api.BaseItemPerson
import java.util.UUID
import javax.inject.Inject
@HiltViewModel
class ShowViewModel
@ -89,7 +89,7 @@ constructor(
dateString,
nextUp,
seasons,
)
),
)
} catch (_: NullPointerException) {
// Navigate back because item does not exist (probably because it's been deleted)

View file

@ -6,7 +6,6 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import dev.jdtech.jellyfin.api.JellyfinApi
import dev.jdtech.jellyfin.database.ServerDatabaseDao
import dev.jdtech.jellyfin.models.User
import javax.inject.Inject
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
@ -14,6 +13,7 @@ import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
@HiltViewModel
class UsersViewModel

View file

@ -29,7 +29,7 @@ class SyncWorker @AssistedInject constructor(
androidContext = context.applicationContext,
requestTimeout = appPreferences.requestTimeout,
connectTimeout = appPreferences.connectTimeout,
socketTimeout = appPreferences.socketTimeout
socketTimeout = appPreferences.socketTimeout,
)
return withContext(Dispatchers.IO) {
@ -59,7 +59,7 @@ class SyncWorker @AssistedInject constructor(
private suspend fun syncUserData(
jellyfinApi: JellyfinApi,
user: User,
items: List<FindroidItem>
items: List<FindroidItem>,
) {
for (item in items) {
val userData = database.getUserDataToBeSynced(user.id, item.id) ?: continue

View file

@ -3,7 +3,6 @@ package dev.jdtech.jellyfin.api
import android.content.Context
import dev.jdtech.jellyfin.Constants
import dev.jdtech.jellyfin.data.BuildConfig
import java.util.UUID
import org.jellyfin.sdk.api.client.HttpClientOptions
import org.jellyfin.sdk.api.client.extensions.devicesApi
import org.jellyfin.sdk.api.client.extensions.itemsApi
@ -19,6 +18,7 @@ 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
@ -31,7 +31,7 @@ class JellyfinApi(
androidContext: Context,
requestTimeout: Long = Constants.NETWORK_DEFAULT_REQUEST_TIMEOUT,
connectTimeout: Long = Constants.NETWORK_DEFAULT_CONNECT_TIMEOUT,
socketTimeout: Long = Constants.NETWORK_DEFAULT_SOCKET_TIMEOUT
socketTimeout: Long = Constants.NETWORK_DEFAULT_SOCKET_TIMEOUT,
) {
val jellyfin = createJellyfin {
clientInfo =
@ -42,8 +42,8 @@ class JellyfinApi(
httpClientOptions = HttpClientOptions(
requestTimeout = requestTimeout,
connectTimeout = connectTimeout,
socketTimeout = socketTimeout
)
socketTimeout = socketTimeout,
),
)
var userId: UUID? = null
@ -68,7 +68,7 @@ class JellyfinApi(
context: Context,
requestTimeout: Long = Constants.NETWORK_DEFAULT_REQUEST_TIMEOUT,
connectTimeout: Long = Constants.NETWORK_DEFAULT_CONNECT_TIMEOUT,
socketTimeout: Long = Constants.NETWORK_DEFAULT_SOCKET_TIMEOUT
socketTimeout: Long = Constants.NETWORK_DEFAULT_SOCKET_TIMEOUT,
): JellyfinApi {
synchronized(this) {
var instance = INSTANCE
@ -77,7 +77,7 @@ class JellyfinApi(
androidContext = context.applicationContext,
requestTimeout = requestTimeout,
connectTimeout = connectTimeout,
socketTimeout = socketTimeout
socketTimeout = socketTimeout,
)
INSTANCE = instance
}

View file

@ -1,9 +1,9 @@
package dev.jdtech.jellyfin.database
import androidx.room.TypeConverter
import org.jellyfin.sdk.model.DateTime
import java.time.ZoneOffset
import java.util.UUID
import org.jellyfin.sdk.model.DateTime
class Converters {
@TypeConverter

View file

@ -21,8 +21,8 @@ import dev.jdtech.jellyfin.models.User
entities = [Server::class, ServerAddress::class, User::class, FindroidMovieDto::class, FindroidShowDto::class, FindroidSeasonDto::class, FindroidEpisodeDto::class, FindroidSourceDto::class, FindroidMediaStreamDto::class, TrickPlayManifestDto::class, IntroDto::class, FindroidUserDataDto::class],
version = 3,
autoMigrations = [
AutoMigration(from = 2, to = 3)
]
AutoMigration(from = 2, to = 3),
],
)
@TypeConverters(Converters::class)
abstract class ServerDatabase : RoomDatabase() {

View file

@ -241,7 +241,7 @@ abstract class ServerDatabaseDao {
itemId = itemId,
played = false,
favorite = false,
playbackPositionTicks = 0L
playbackPositionTicks = 0L,
)
insertUserData(userData)
}

View file

@ -8,11 +8,16 @@ enum class CollectionType(val type: String) {
Playlists("playlists"),
Books("books"),
LiveTv("livetv"),
BoxSets("boxsets");
BoxSets("boxsets"),
;
companion object {
val unsupportedCollections = listOf(
HomeVideos, Music, Playlists, Books, LiveTv
HomeVideos,
Music,
Playlists,
Books,
LiveTv,
)
}
}

View file

@ -1,7 +1,7 @@
package dev.jdtech.jellyfin.models
import java.util.UUID
import org.jellyfin.sdk.model.api.BaseItemDto
import java.util.UUID
data class FindroidBoxSet(
override val id: UUID,

View file

@ -1,7 +1,7 @@
package dev.jdtech.jellyfin.models
import java.util.UUID
import org.jellyfin.sdk.model.api.BaseItemDto
import java.util.UUID
data class FindroidCollection(
override val id: UUID,
@ -16,7 +16,7 @@ data class FindroidCollection(
override val runtimeTicks: Long = 0L,
override val playbackPositionTicks: Long = 0L,
override val unplayedItemCount: Int? = null,
val type: CollectionType
val type: CollectionType,
) : FindroidItem
fun BaseItemDto.toFindroidCollection(): FindroidCollection? {

View file

@ -2,11 +2,11 @@ package dev.jdtech.jellyfin.models
import dev.jdtech.jellyfin.database.ServerDatabaseDao
import dev.jdtech.jellyfin.repository.JellyfinRepository
import java.util.UUID
import org.jellyfin.sdk.model.DateTime
import org.jellyfin.sdk.model.api.BaseItemDto
import org.jellyfin.sdk.model.api.LocationType
import org.jellyfin.sdk.model.api.PlayAccess
import java.util.UUID
data class FindroidEpisode(
override val id: UUID,
@ -34,7 +34,7 @@ data class FindroidEpisode(
suspend fun BaseItemDto.toFindroidEpisode(
jellyfinRepository: JellyfinRepository,
database: ServerDatabaseDao? = null
database: ServerDatabaseDao? = null,
): FindroidEpisode? {
val sources = mutableListOf<FindroidSource>()
sources.addAll(mediaSources?.map { it.toFindroidSource(jellyfinRepository, id) } ?: emptyList())

View file

@ -14,19 +14,19 @@ import java.util.UUID
entity = FindroidSeasonDto::class,
parentColumns = arrayOf("id"),
childColumns = arrayOf("seasonId"),
onDelete = ForeignKey.CASCADE
onDelete = ForeignKey.CASCADE,
),
ForeignKey(
entity = FindroidShowDto::class,
parentColumns = arrayOf("id"),
childColumns = arrayOf("seriesId"),
onDelete = ForeignKey.CASCADE
)
onDelete = ForeignKey.CASCADE,
),
],
indices = [
Index("seasonId"),
Index("seriesId"),
]
],
)
data class FindroidEpisodeDto(
@PrimaryKey

View file

@ -2,9 +2,9 @@ package dev.jdtech.jellyfin.models
import dev.jdtech.jellyfin.database.ServerDatabaseDao
import dev.jdtech.jellyfin.repository.JellyfinRepository
import java.util.UUID
import org.jellyfin.sdk.model.api.BaseItemDto
import org.jellyfin.sdk.model.api.BaseItemKind
import java.util.UUID
interface FindroidItem {
val id: UUID
@ -23,7 +23,7 @@ interface FindroidItem {
suspend fun BaseItemDto.toFindroidItem(
jellyfinRepository: JellyfinRepository,
serverDatabase: ServerDatabaseDao? = null
serverDatabase: ServerDatabaseDao? = null,
): FindroidItem? {
return when (type) {
BaseItemKind.MOVIE -> toFindroidMovie(jellyfinRepository, serverDatabase)

View file

@ -2,11 +2,11 @@ package dev.jdtech.jellyfin.models
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.util.UUID
import org.jellyfin.sdk.model.api.MediaStreamType
import java.util.UUID
@Entity(
tableName = "mediastreams"
tableName = "mediastreams",
)
data class FindroidMediaStreamDto(
@PrimaryKey

View file

@ -2,11 +2,11 @@ package dev.jdtech.jellyfin.models
import dev.jdtech.jellyfin.database.ServerDatabaseDao
import dev.jdtech.jellyfin.repository.JellyfinRepository
import java.util.UUID
import org.jellyfin.sdk.model.DateTime
import org.jellyfin.sdk.model.api.BaseItemDto
import org.jellyfin.sdk.model.api.BaseItemPerson
import org.jellyfin.sdk.model.api.PlayAccess
import java.util.UUID
data class FindroidMovie(
override val id: UUID,
@ -34,7 +34,7 @@ data class FindroidMovie(
suspend fun BaseItemDto.toFindroidMovie(
jellyfinRepository: JellyfinRepository,
serverDatabase: ServerDatabaseDao? = null
serverDatabase: ServerDatabaseDao? = null,
): FindroidMovie {
val sources = mutableListOf<FindroidSource>()
sources.addAll(mediaSources?.map { it.toFindroidSource(jellyfinRepository, id) } ?: emptyList())

View file

@ -1,9 +1,9 @@
package dev.jdtech.jellyfin.models
import dev.jdtech.jellyfin.database.ServerDatabaseDao
import java.util.UUID
import org.jellyfin.sdk.model.api.BaseItemDto
import org.jellyfin.sdk.model.api.PlayAccess
import java.util.UUID
data class FindroidSeason(
override val id: UUID,

View file

@ -13,12 +13,12 @@ import java.util.UUID
entity = FindroidShowDto::class,
parentColumns = arrayOf("id"),
childColumns = arrayOf("seriesId"),
onDelete = ForeignKey.CASCADE
)
onDelete = ForeignKey.CASCADE,
),
],
indices = [
Index("seriesId"),
]
],
)
data class FindroidSeasonDto(
@PrimaryKey

View file

@ -1,11 +1,11 @@
package dev.jdtech.jellyfin.models
import dev.jdtech.jellyfin.database.ServerDatabaseDao
import java.util.UUID
import org.jellyfin.sdk.model.DateTime
import org.jellyfin.sdk.model.api.BaseItemDto
import org.jellyfin.sdk.model.api.BaseItemPerson
import org.jellyfin.sdk.model.api.PlayAccess
import java.util.UUID
data class FindroidShow(
override val id: UUID,

View file

@ -2,10 +2,10 @@ package dev.jdtech.jellyfin.models
import dev.jdtech.jellyfin.database.ServerDatabaseDao
import dev.jdtech.jellyfin.repository.JellyfinRepository
import java.io.File
import java.util.UUID
import org.jellyfin.sdk.model.api.MediaProtocol
import org.jellyfin.sdk.model.api.MediaSourceInfo
import java.io.File
import java.util.UUID
data class FindroidSource(
val id: String,
@ -14,7 +14,7 @@ data class FindroidSource(
val path: String,
val size: Long,
val mediaStreams: List<FindroidMediaStream>,
val downloadId: Long? = null
val downloadId: Long? = null,
)
suspend fun MediaSourceInfo.toFindroidSource(
@ -39,7 +39,7 @@ suspend fun MediaSourceInfo.toFindroidSource(
type = FindroidSourceType.REMOTE,
path = path,
size = size ?: 0,
mediaStreams = mediaStreams?.map { it.toFindroidMediaStream(jellyfinRepository) } ?: emptyList()
mediaStreams = mediaStreams?.map { it.toFindroidMediaStream(jellyfinRepository) } ?: emptyList(),
)
}

View file

@ -5,7 +5,7 @@ import androidx.room.PrimaryKey
import java.util.UUID
@Entity(
tableName = "sources"
tableName = "sources",
)
data class FindroidSourceDto(
@PrimaryKey

View file

@ -5,7 +5,7 @@ import java.util.UUID
@Entity(
tableName = "userdata",
primaryKeys = ["userId", "itemId"]
primaryKeys = ["userId", "itemId"],
)
data class FindroidUserDataDto(
val userId: UUID,

View file

@ -12,7 +12,7 @@ data class Intro(
@SerialName("ShowSkipPromptAt")
val showSkipPromptAt: Double,
@SerialName("HideSkipPromptAt")
val hideSkipPromptAt: Double
val hideSkipPromptAt: Double,
)
fun IntroDto.toIntro(): Intro {

View file

@ -13,14 +13,14 @@ import java.util.UUID
entity = Server::class,
parentColumns = arrayOf("id"),
childColumns = arrayOf("serverId"),
onDelete = ForeignKey.CASCADE
)
]
onDelete = ForeignKey.CASCADE,
),
],
)
data class ServerAddress(
@PrimaryKey
val id: UUID,
@ColumnInfo(index = true)
val serverId: String,
val address: String
val address: String,
)

View file

@ -8,12 +8,12 @@ data class ServerWithAddresses(
val server: Server,
@Relation(
parentColumn = "id",
entityColumn = "serverId"
entityColumn = "serverId",
)
val addresses: List<ServerAddress>,
@Relation(
parentColumn = "currentUserId",
entityColumn = "id"
entityColumn = "id",
)
val user: User?
val user: User?,
)

View file

@ -8,12 +8,12 @@ data class ServerWithAddressesAndUsers(
val server: Server,
@Relation(
parentColumn = "id",
entityColumn = "serverId"
entityColumn = "serverId",
)
val addresses: List<ServerAddress>,
@Relation(
parentColumn = "id",
entityColumn = "serverId"
entityColumn = "serverId",
)
val users: List<User>
val users: List<User>,
)

View file

@ -8,7 +8,7 @@ data class ServerWithUsers(
val server: Server,
@Relation(
parentColumn = "id",
entityColumn = "serverId"
entityColumn = "serverId",
)
val users: List<User>
val users: List<User>,
)

View file

@ -6,7 +6,8 @@ enum class SortBy(val SortString: String) {
PARENTAL_RATING("CriticRating"),
DATE_ADDED("DateCreated"),
DATE_PLAYED("DatePlayed"),
RELEASE_DATE("PremiereDate");
RELEASE_DATE("PremiereDate"),
;
companion object {
val defaultValue = NAME

View file

@ -8,7 +8,7 @@ data class TrickPlayManifest(
@SerialName("Version")
val version: String,
@SerialName("WidthResolutions")
val widthResolutions: List<Int>
val widthResolutions: List<Int>,
)
fun TrickPlayManifestDto.toTrickPlayManifest(): TrickPlayManifest {

View file

@ -13,9 +13,9 @@ import java.util.UUID
entity = Server::class,
parentColumns = arrayOf("id"),
childColumns = arrayOf("serverId"),
onDelete = ForeignKey.CASCADE
)
]
onDelete = ForeignKey.CASCADE,
),
],
)
data class User(
@PrimaryKey
@ -23,5 +23,5 @@ data class User(
val name: String,
@ColumnInfo(index = true)
val serverId: String,
val accessToken: String? = null
val accessToken: String? = null,
)

Some files were not shown because too many files have changed in this diff Show more