Merge branch 'jarnedemeulemeester:main' into Skip-credit

This commit is contained in:
Cd16d 2024-06-02 13:34:01 +02:00 committed by GitHub
commit 0999823d6d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
61 changed files with 110 additions and 159 deletions

View file

@ -12,7 +12,7 @@ jobs:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Validate Gradle Wrapper - name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v2 uses: gradle/actions/wrapper-validation@v3
- name: Set up JDK 17 - name: Set up JDK 17
uses: actions/setup-java@v4 uses: actions/setup-java@v4
with: with:
@ -29,7 +29,7 @@ jobs:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Validate Gradle Wrapper - name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v2 uses: gradle/actions/wrapper-validation@v3
- name: Set up JDK 17 - name: Set up JDK 17
uses: actions/setup-java@v4 uses: actions/setup-java@v4
with: with:

View file

@ -20,7 +20,7 @@ jobs:
bundler-cache: true bundler-cache: true
- name: Validate Gradle Wrapper - name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v2 uses: gradle/actions/wrapper-validation@v3
- name: Set up JDK 17 - name: Set up JDK 17
uses: actions/setup-java@v4 uses: actions/setup-java@v4

View file

@ -103,9 +103,7 @@ dependencies {
implementation(libs.androidx.constraintlayout) implementation(libs.androidx.constraintlayout)
implementation(libs.androidx.core) implementation(libs.androidx.core)
implementation(libs.androidx.hilt.work) implementation(libs.androidx.hilt.work)
implementation(libs.androidx.lifecycle.runtime)
implementation(libs.androidx.lifecycle.viewmodel) implementation(libs.androidx.lifecycle.viewmodel)
implementation(libs.androidx.media3.exoplayer)
implementation(libs.androidx.media3.ui) implementation(libs.androidx.media3.ui)
implementation(libs.androidx.media3.session) implementation(libs.androidx.media3.session)
implementation(libs.androidx.navigation.fragment) implementation(libs.androidx.navigation.fragment)

View file

@ -8,7 +8,6 @@ import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat import androidx.core.view.WindowInsetsControllerCompat
import androidx.core.view.updatePadding import androidx.core.view.updatePadding
import androidx.media3.exoplayer.trackselection.MappingTrackSelector
import androidx.media3.session.MediaSession import androidx.media3.session.MediaSession
import dev.jdtech.jellyfin.viewmodels.PlayerActivityViewModel import dev.jdtech.jellyfin.viewmodels.PlayerActivityViewModel
@ -72,19 +71,6 @@ abstract class BasePlayerActivity : AppCompatActivity() {
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
} }
protected fun isRendererType(
mappedTrackInfo: MappingTrackSelector.MappedTrackInfo,
rendererIndex: Int,
type: Int,
): Boolean {
val trackGroupArray = mappedTrackInfo.getTrackGroups(rendererIndex)
if (trackGroupArray.length == 0) {
return false
}
val trackType = mappedTrackInfo.getRendererType(rendererIndex)
return type == trackType
}
protected fun configureInsets(playerControls: View) { protected fun configureInsets(playerControls: View) {
playerControls.setOnApplyWindowInsetsListener { _, windowInsets -> playerControls.setOnApplyWindowInsetsListener { _, windowInsets ->
val cutout = windowInsets.displayCutout val cutout = windowInsets.displayCutout

View file

@ -293,7 +293,7 @@ class PlayerActivity : BasePlayerActivity() {
hideSystemUI() hideSystemUI()
} }
override fun onNewIntent(intent: Intent?) { override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent) super.onNewIntent(intent)
setIntent(intent) setIntent(intent)
@ -302,6 +302,7 @@ class PlayerActivity : BasePlayerActivity() {
} }
override fun onUserLeaveHint() { override fun onUserLeaveHint() {
super.onUserLeaveHint()
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S && if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S &&
appPreferences.playerPipGesture && appPreferences.playerPipGesture &&
viewModel.player.isPlaying && viewModel.player.isPlaying &&

View file

@ -1,6 +1,7 @@
package dev.jdtech.jellyfin.fragments package dev.jdtech.jellyfin.fragments
import android.os.Bundle import android.os.Bundle
import android.text.Html.fromHtml
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@ -82,7 +83,7 @@ class LoginFragment : Fragment() {
viewModel.uiState.collect { uiState -> viewModel.uiState.collect { uiState ->
Timber.d("$uiState") Timber.d("$uiState")
when (uiState) { when (uiState) {
is LoginViewModel.UiState.Normal -> bindUiStateNormal() is LoginViewModel.UiState.Normal -> bindUiStateNormal(uiState)
is LoginViewModel.UiState.Error -> bindUiStateError(uiState) is LoginViewModel.UiState.Error -> bindUiStateError(uiState)
is LoginViewModel.UiState.Loading -> bindUiStateLoading() is LoginViewModel.UiState.Loading -> bindUiStateLoading()
} }
@ -135,11 +136,15 @@ class LoginFragment : Fragment() {
return binding.root return binding.root
} }
private fun bindUiStateNormal() { private fun bindUiStateNormal(uiState: LoginViewModel.UiState.Normal) {
binding.buttonLogin.isEnabled = true binding.buttonLogin.isEnabled = true
binding.progressCircular.isVisible = false binding.progressCircular.isVisible = false
binding.editTextUsernameLayout.isEnabled = true binding.editTextUsernameLayout.isEnabled = true
binding.editTextPasswordLayout.isEnabled = true binding.editTextPasswordLayout.isEnabled = true
uiState.disclaimer?.let { disclaimer ->
binding.loginDisclaimer.text = fromHtml(disclaimer, 0)
}
} }
private fun bindUiStateError(uiState: LoginViewModel.UiState.Error) { private fun bindUiStateError(uiState: LoginViewModel.UiState.Error) {

View file

@ -141,6 +141,15 @@
android:visibility="invisible" /> android:visibility="invisible" />
</RelativeLayout> </RelativeLayout>
<TextView
android:id="@+id/login_disclaimer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_margin="24dp"
android:textSize="16sp"
tools:text="Sample login disclaimer" />
</LinearLayout> </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,6 +1,7 @@
plugins { plugins {
alias(libs.plugins.android.application) alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android) alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.compose.compiler)
alias(libs.plugins.kotlin.parcelize) alias(libs.plugins.kotlin.parcelize)
alias(libs.plugins.hilt) alias(libs.plugins.hilt)
alias(libs.plugins.ksp) alias(libs.plugins.ksp)
@ -56,6 +57,8 @@ android {
} }
compileOptions { compileOptions {
isCoreLibraryDesugaringEnabled = true
sourceCompatibility = Versions.java sourceCompatibility = Versions.java
targetCompatibility = Versions.java targetCompatibility = Versions.java
} }
@ -64,10 +67,6 @@ android {
compose = true compose = true
} }
composeOptions {
kotlinCompilerExtensionVersion = Versions.composeCompiler
}
packaging { packaging {
resources { resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}" excludes += "/META-INF/{AL2.0,LGPL2.1}"
@ -95,12 +94,13 @@ dependencies {
implementation(libs.androidx.compose.material3) implementation(libs.androidx.compose.material3)
implementation(libs.androidx.core) implementation(libs.androidx.core)
implementation(libs.androidx.hilt.navigation.compose) implementation(libs.androidx.hilt.navigation.compose)
implementation(libs.androidx.lifecycle.runtime)
implementation(libs.androidx.lifecycle.viewmodel.compose) implementation(libs.androidx.lifecycle.viewmodel.compose)
implementation(libs.androidx.media3.exoplayer) implementation(libs.androidx.media3.exoplayer)
implementation(libs.androidx.media3.ui) implementation(libs.androidx.media3.ui)
implementation(libs.androidx.media3.session) implementation(libs.androidx.media3.session)
implementation(libs.androidx.paging.compose) implementation(libs.androidx.paging.compose)
implementation(libs.androidx.tv.foundation)
implementation(libs.androidx.tv.material)
implementation(libs.coil.compose) implementation(libs.coil.compose)
implementation(libs.coil.svg) implementation(libs.coil.svg)
implementation(libs.compose.destinations.core) implementation(libs.compose.destinations.core)
@ -108,8 +108,9 @@ dependencies {
implementation(libs.hilt.android) implementation(libs.hilt.android)
ksp(libs.hilt.compiler) ksp(libs.hilt.compiler)
implementation(libs.jellyfin.core) implementation(libs.jellyfin.core)
implementation(libs.androidx.tv.foundation) implementation(libs.media3.ffmpeg.decoder)
implementation(libs.androidx.tv.material)
coreLibraryDesugaring(libs.android.desugar.jdk)
debugImplementation(libs.androidx.compose.ui.tooling) debugImplementation(libs.androidx.compose.ui.tooling)
} }

View file

@ -27,4 +27,6 @@
-dontwarn org.conscrypt.* -dontwarn org.conscrypt.*
-dontwarn org.openjsse.javax.net.ssl.SSLParameters -dontwarn org.openjsse.javax.net.ssl.SSLParameters
-dontwarn org.openjsse.javax.net.ssl.SSLSocket -dontwarn org.openjsse.javax.net.ssl.SSLSocket
-dontwarn org.openjsse.net.ssl.OpenJSSE -dontwarn org.openjsse.net.ssl.OpenJSSE
-keep class dev.jdtech.**

View file

@ -23,7 +23,6 @@ data class PlayerActivityNavArgs(
@ActivityDestination( @ActivityDestination(
navArgsDelegate = PlayerActivityNavArgs::class, navArgsDelegate = PlayerActivityNavArgs::class,
) )
@androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class)
class PlayerActivity : ComponentActivity() { class PlayerActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)

View file

@ -32,7 +32,6 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import androidx.tv.material3.Button import androidx.tv.material3.Button
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.Icon import androidx.tv.material3.Icon
import androidx.tv.material3.LocalContentColor import androidx.tv.material3.LocalContentColor
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
@ -71,7 +70,6 @@ fun AddServerScreen(
) )
} }
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
private fun AddServerScreenLayout( private fun AddServerScreenLayout(
uiState: AddServerViewModel.UiState, uiState: AddServerViewModel.UiState,

View file

@ -22,7 +22,6 @@ import androidx.hilt.navigation.compose.hiltViewModel
import androidx.tv.foundation.lazy.list.TvLazyColumn import androidx.tv.foundation.lazy.list.TvLazyColumn
import androidx.tv.foundation.lazy.list.TvLazyRow import androidx.tv.foundation.lazy.list.TvLazyRow
import androidx.tv.foundation.lazy.list.items import androidx.tv.foundation.lazy.list.items
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Text import androidx.tv.material3.Text
import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.Destination
@ -88,7 +87,6 @@ fun HomeScreen(
) )
} }
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
private fun HomeScreenLayout( private fun HomeScreenLayout(
uiState: HomeViewModel.UiState, uiState: HomeViewModel.UiState,

View file

@ -17,7 +17,6 @@ import androidx.hilt.navigation.compose.hiltViewModel
import androidx.tv.foundation.lazy.grid.TvGridCells import androidx.tv.foundation.lazy.grid.TvGridCells
import androidx.tv.foundation.lazy.grid.TvLazyVerticalGrid import androidx.tv.foundation.lazy.grid.TvLazyVerticalGrid
import androidx.tv.foundation.lazy.grid.items import androidx.tv.foundation.lazy.grid.items
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.navigation.DestinationsNavigator import com.ramcosta.composedestinations.navigation.DestinationsNavigator
@ -50,7 +49,6 @@ fun LibrariesScreen(
) )
} }
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
private fun LibrariesScreenLayout( private fun LibrariesScreenLayout(
uiState: MediaViewModel.UiState, uiState: MediaViewModel.UiState,

View file

@ -18,7 +18,6 @@ import androidx.paging.compose.collectAsLazyPagingItems
import androidx.tv.foundation.lazy.grid.TvGridCells import androidx.tv.foundation.lazy.grid.TvGridCells
import androidx.tv.foundation.lazy.grid.TvGridItemSpan import androidx.tv.foundation.lazy.grid.TvGridItemSpan
import androidx.tv.foundation.lazy.grid.TvLazyVerticalGrid import androidx.tv.foundation.lazy.grid.TvLazyVerticalGrid
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Text import androidx.tv.material3.Text
import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.Destination
@ -75,7 +74,6 @@ fun LibraryScreen(
) )
} }
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
private fun LibraryScreenLayout( private fun LibraryScreenLayout(
libraryName: String, libraryName: String,

View file

@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
@ -32,7 +33,6 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import androidx.tv.material3.Button import androidx.tv.material3.Button
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.Icon import androidx.tv.material3.Icon
import androidx.tv.material3.LocalContentColor import androidx.tv.material3.LocalContentColor
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
@ -86,7 +86,6 @@ fun LoginScreen(
) )
} }
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
private fun LoginScreenLayout( private fun LoginScreenLayout(
uiState: LoginViewModel.UiState, uiState: LoginViewModel.UiState,
@ -110,6 +109,14 @@ private fun LoginScreenLayout(
else -> Unit else -> Unit
} }
var disclaimer: String? by remember {
mutableStateOf(null)
}
if (uiState is LoginViewModel.UiState.Normal) {
disclaimer = uiState.disclaimer
}
val isError = uiState is LoginViewModel.UiState.Error val isError = uiState is LoginViewModel.UiState.Error
val isLoading = uiState is LoginViewModel.UiState.Loading val isLoading = uiState is LoginViewModel.UiState.Loading
@ -241,6 +248,10 @@ private fun LoginScreenLayout(
} }
} }
} }
Text(
text = disclaimer ?: "",
modifier = Modifier.padding(MaterialTheme.spacings.default),
)
} }
} }
@ -254,7 +265,7 @@ private fun LoginScreenLayout(
private fun LoginScreenLayoutPreview() { private fun LoginScreenLayoutPreview() {
FindroidTheme { FindroidTheme {
LoginScreenLayout( LoginScreenLayout(
uiState = LoginViewModel.UiState.Normal, uiState = LoginViewModel.UiState.Normal(),
quickConnectUiState = LoginViewModel.QuickConnectUiState.Normal, quickConnectUiState = LoginViewModel.QuickConnectUiState.Normal,
onLoginClick = { _, _ -> }, onLoginClick = { _, _ -> },
onQuickConnectClick = {}, onQuickConnectClick = {},

View file

@ -29,7 +29,6 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.Icon import androidx.tv.material3.Icon
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Tab import androidx.tv.material3.Tab
@ -78,7 +77,6 @@ enum class TabDestination(
// LiveTV(CoreR.drawable.ic_tv, CoreR.string.live_tv) // LiveTV(CoreR.drawable.ic_tv, CoreR.string.live_tv)
} }
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
private fun MainScreenLayout( private fun MainScreenLayout(
uiState: MainViewModel.UiState, uiState: MainViewModel.UiState,

View file

@ -39,7 +39,6 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.toSize import androidx.compose.ui.unit.toSize
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import androidx.tv.material3.Button import androidx.tv.material3.Button
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.Icon import androidx.tv.material3.Icon
import androidx.tv.material3.LocalContentColor import androidx.tv.material3.LocalContentColor
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
@ -115,7 +114,6 @@ fun MovieScreen(
) )
} }
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
private fun MovieScreenLayout( private fun MovieScreenLayout(
uiState: MovieViewModel.UiState, uiState: MovieViewModel.UiState,

View file

@ -30,7 +30,6 @@ import androidx.media3.common.TrackSelectionOverride
import androidx.media3.common.util.UnstableApi import androidx.media3.common.util.UnstableApi
import androidx.media3.session.MediaSession import androidx.media3.session.MediaSession
import androidx.media3.ui.PlayerView import androidx.media3.ui.PlayerView
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.navigation.DestinationsNavigator import com.ramcosta.composedestinations.navigation.DestinationsNavigator
@ -204,7 +203,6 @@ fun PlayerScreen(
} }
@androidx.annotation.OptIn(UnstableApi::class) @androidx.annotation.OptIn(UnstableApi::class)
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
fun VideoPlayerControls( fun VideoPlayerControls(
title: String, title: String,

View file

@ -18,7 +18,6 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import androidx.tv.foundation.lazy.list.TvLazyColumn import androidx.tv.foundation.lazy.list.TvLazyColumn
import androidx.tv.foundation.lazy.list.items import androidx.tv.foundation.lazy.list.items
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Text import androidx.tv.material3.Text
import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.Destination
@ -76,7 +75,6 @@ fun SeasonScreen(
) )
} }
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
private fun SeasonScreenLayout( private fun SeasonScreenLayout(
seriesName: String, seriesName: String,

View file

@ -35,7 +35,6 @@ import androidx.tv.foundation.lazy.list.TvLazyRow
import androidx.tv.foundation.lazy.list.items import androidx.tv.foundation.lazy.list.items
import androidx.tv.material3.Border import androidx.tv.material3.Border
import androidx.tv.material3.ClickableSurfaceDefaults import androidx.tv.material3.ClickableSurfaceDefaults
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.Icon import androidx.tv.material3.Icon
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.OutlinedButton import androidx.tv.material3.OutlinedButton
@ -103,7 +102,6 @@ fun ServerSelectScreen(
) )
} }
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
private fun ServerSelectScreenLayout( private fun ServerSelectScreenLayout(
uiState: ServerSelectViewModel.UiState, uiState: ServerSelectViewModel.UiState,
@ -246,7 +244,6 @@ private fun ServerSelectScreenLayoutPreviewNoServers() {
} }
} }
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
private fun ServerComponent( private fun ServerComponent(
server: DiscoveredServer, server: DiscoveredServer,

View file

@ -19,7 +19,6 @@ import androidx.tv.foundation.lazy.grid.TvGridCells
import androidx.tv.foundation.lazy.grid.TvGridItemSpan import androidx.tv.foundation.lazy.grid.TvGridItemSpan
import androidx.tv.foundation.lazy.grid.TvLazyVerticalGrid import androidx.tv.foundation.lazy.grid.TvLazyVerticalGrid
import androidx.tv.foundation.lazy.grid.items import androidx.tv.foundation.lazy.grid.items
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Text import androidx.tv.material3.Text
import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.Destination
@ -80,7 +79,6 @@ fun SettingsScreen(
} }
} }
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
private fun SettingsScreenLayout( private fun SettingsScreenLayout(
uiState: SettingsViewModel.UiState, uiState: SettingsViewModel.UiState,

View file

@ -25,7 +25,6 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import androidx.tv.foundation.lazy.list.TvLazyColumn import androidx.tv.foundation.lazy.list.TvLazyColumn
import androidx.tv.foundation.lazy.list.items import androidx.tv.foundation.lazy.list.items
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Text import androidx.tv.material3.Text
import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.Destination
@ -90,7 +89,6 @@ fun SettingsSubScreen(
} }
} }
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
private fun SettingsSubScreenLayout( private fun SettingsSubScreenLayout(
uiState: SettingsViewModel.UiState, uiState: SettingsViewModel.UiState,

View file

@ -49,7 +49,6 @@ import androidx.tv.foundation.lazy.list.TvLazyRow
import androidx.tv.foundation.lazy.list.items import androidx.tv.foundation.lazy.list.items
import androidx.tv.foundation.lazy.list.rememberTvLazyListState import androidx.tv.foundation.lazy.list.rememberTvLazyListState
import androidx.tv.material3.Button import androidx.tv.material3.Button
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.Icon import androidx.tv.material3.Icon
import androidx.tv.material3.LocalContentColor import androidx.tv.material3.LocalContentColor
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
@ -126,7 +125,6 @@ fun ShowScreen(
) )
} }
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
private fun ShowScreenLayout( private fun ShowScreenLayout(
uiState: ShowViewModel.UiState, uiState: ShowViewModel.UiState,

View file

@ -33,7 +33,6 @@ import androidx.tv.foundation.lazy.list.TvLazyRow
import androidx.tv.foundation.lazy.list.items import androidx.tv.foundation.lazy.list.items
import androidx.tv.material3.Border import androidx.tv.material3.Border
import androidx.tv.material3.ClickableSurfaceDefaults import androidx.tv.material3.ClickableSurfaceDefaults
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.Icon import androidx.tv.material3.Icon
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.OutlinedButton import androidx.tv.material3.OutlinedButton
@ -99,7 +98,6 @@ fun UserSelectScreen(
) )
} }
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
private fun UserSelectScreenLayout( private fun UserSelectScreenLayout(
uiState: UserSelectViewModel.UiState, uiState: UserSelectViewModel.UiState,
@ -204,7 +202,6 @@ private fun UserSelectScreenLayoutPreviewNoUsers() {
} }
} }
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
private fun UserComponent( private fun UserComponent(
user: User, user: User,

View file

@ -23,7 +23,6 @@ import androidx.compose.ui.unit.dp
import androidx.tv.material3.Border import androidx.tv.material3.Border
import androidx.tv.material3.ClickableSurfaceDefaults import androidx.tv.material3.ClickableSurfaceDefaults
import androidx.tv.material3.ClickableSurfaceScale import androidx.tv.material3.ClickableSurfaceScale
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Surface import androidx.tv.material3.Surface
import androidx.tv.material3.Text import androidx.tv.material3.Text
@ -32,7 +31,6 @@ import dev.jdtech.jellyfin.ui.dummy.dummyEpisode
import dev.jdtech.jellyfin.ui.theme.FindroidTheme import dev.jdtech.jellyfin.ui.theme.FindroidTheme
import dev.jdtech.jellyfin.ui.theme.spacings import dev.jdtech.jellyfin.ui.theme.spacings
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
fun EpisodeCard( fun EpisodeCard(
episode: FindroidEpisode, episode: FindroidEpisode,

View file

@ -21,7 +21,6 @@ import androidx.compose.ui.unit.dp
import androidx.tv.material3.Border import androidx.tv.material3.Border
import androidx.tv.material3.ClickableSurfaceDefaults import androidx.tv.material3.ClickableSurfaceDefaults
import androidx.tv.material3.ClickableSurfaceScale import androidx.tv.material3.ClickableSurfaceScale
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Surface import androidx.tv.material3.Surface
import androidx.tv.material3.Text import androidx.tv.material3.Text
@ -33,7 +32,6 @@ import dev.jdtech.jellyfin.ui.dummy.dummyMovie
import dev.jdtech.jellyfin.ui.theme.FindroidTheme import dev.jdtech.jellyfin.ui.theme.FindroidTheme
import dev.jdtech.jellyfin.ui.theme.spacings import dev.jdtech.jellyfin.ui.theme.spacings
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
fun ItemCard( fun ItemCard(
item: FindroidItem, item: FindroidItem,

View file

@ -6,7 +6,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
import coil.compose.AsyncImage import coil.compose.AsyncImage
import dev.jdtech.jellyfin.models.FindroidEpisode import dev.jdtech.jellyfin.models.FindroidEpisode
@ -17,7 +16,6 @@ enum class Direction {
HORIZONTAL, VERTICAL HORIZONTAL, VERTICAL
} }
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
fun ItemPoster( fun ItemPoster(
item: FindroidItem, item: FindroidItem,

View file

@ -20,7 +20,6 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.height import androidx.compose.ui.unit.height
import androidx.compose.ui.unit.width import androidx.compose.ui.unit.width
import androidx.compose.ui.zIndex import androidx.compose.ui.zIndex
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.TabRow import androidx.tv.material3.TabRow
@ -35,7 +34,6 @@ import androidx.tv.material3.TabRow
* *
* This component is adapted from androidx.tv.material3.TabRowDefaults.PillIndicator * This component is adapted from androidx.tv.material3.TabRowDefaults.PillIndicator
*/ */
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
fun PillBorderIndicator( fun PillBorderIndicator(
currentTabPosition: DpRect, currentTabPosition: DpRect,

View file

@ -17,7 +17,6 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.tv.material3.Border import androidx.tv.material3.Border
import androidx.tv.material3.ClickableSurfaceDefaults import androidx.tv.material3.ClickableSurfaceDefaults
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.Icon import androidx.tv.material3.Icon
import androidx.tv.material3.Surface import androidx.tv.material3.Surface
import coil.compose.AsyncImage import coil.compose.AsyncImage
@ -29,7 +28,6 @@ import dev.jdtech.jellyfin.ui.dummy.dummyUser
import dev.jdtech.jellyfin.ui.theme.FindroidTheme import dev.jdtech.jellyfin.ui.theme.FindroidTheme
import org.jellyfin.sdk.model.api.ImageType import org.jellyfin.sdk.model.api.ImageType
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
fun ProfileButton( fun ProfileButton(
user: User?, user: User?,

View file

@ -14,7 +14,6 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.Icon import androidx.tv.material3.Icon
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Text import androidx.tv.material3.Text
@ -25,7 +24,6 @@ import dev.jdtech.jellyfin.ui.theme.FindroidTheme
import dev.jdtech.jellyfin.ui.theme.spacings import dev.jdtech.jellyfin.ui.theme.spacings
import dev.jdtech.jellyfin.core.R as CoreR import dev.jdtech.jellyfin.core.R as CoreR
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
fun ProgressBadge( fun ProgressBadge(
item: FindroidItem, item: FindroidItem,

View file

@ -21,7 +21,6 @@ import androidx.compose.ui.unit.dp
import androidx.tv.material3.Border import androidx.tv.material3.Border
import androidx.tv.material3.ClickableSurfaceDefaults import androidx.tv.material3.ClickableSurfaceDefaults
import androidx.tv.material3.ClickableSurfaceScale import androidx.tv.material3.ClickableSurfaceScale
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.Icon import androidx.tv.material3.Icon
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Surface import androidx.tv.material3.Surface
@ -31,7 +30,6 @@ import dev.jdtech.jellyfin.ui.theme.FindroidTheme
import dev.jdtech.jellyfin.ui.theme.spacings import dev.jdtech.jellyfin.ui.theme.spacings
import dev.jdtech.jellyfin.core.R as CoreR import dev.jdtech.jellyfin.core.R as CoreR
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
fun SettingsCategoryCard( fun SettingsCategoryCard(
preference: PreferenceCategory, preference: PreferenceCategory,

View file

@ -22,7 +22,6 @@ import androidx.tv.foundation.lazy.list.TvLazyColumn
import androidx.tv.material3.Border import androidx.tv.material3.Border
import androidx.tv.material3.ClickableSurfaceDefaults import androidx.tv.material3.ClickableSurfaceDefaults
import androidx.tv.material3.ClickableSurfaceScale import androidx.tv.material3.ClickableSurfaceScale
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.RadioButton import androidx.tv.material3.RadioButton
import androidx.tv.material3.Surface import androidx.tv.material3.Surface
@ -33,7 +32,6 @@ import dev.jdtech.jellyfin.ui.theme.FindroidTheme
import dev.jdtech.jellyfin.ui.theme.spacings import dev.jdtech.jellyfin.ui.theme.spacings
import dev.jdtech.jellyfin.core.R as CoreR import dev.jdtech.jellyfin.core.R as CoreR
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
fun SettingsDetailsCard( fun SettingsDetailsCard(
preference: PreferenceSelect, preference: PreferenceSelect,

View file

@ -21,7 +21,6 @@ import androidx.compose.ui.unit.dp
import androidx.tv.material3.Border import androidx.tv.material3.Border
import androidx.tv.material3.ClickableSurfaceDefaults import androidx.tv.material3.ClickableSurfaceDefaults
import androidx.tv.material3.ClickableSurfaceScale import androidx.tv.material3.ClickableSurfaceScale
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.Icon import androidx.tv.material3.Icon
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Surface import androidx.tv.material3.Surface
@ -32,7 +31,6 @@ import dev.jdtech.jellyfin.ui.theme.FindroidTheme
import dev.jdtech.jellyfin.ui.theme.spacings import dev.jdtech.jellyfin.ui.theme.spacings
import dev.jdtech.jellyfin.core.R as CoreR import dev.jdtech.jellyfin.core.R as CoreR
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
fun SettingsSelectCard( fun SettingsSelectCard(
preference: PreferenceSelect, preference: PreferenceSelect,

View file

@ -21,7 +21,6 @@ import androidx.compose.ui.unit.dp
import androidx.tv.material3.Border import androidx.tv.material3.Border
import androidx.tv.material3.ClickableSurfaceDefaults import androidx.tv.material3.ClickableSurfaceDefaults
import androidx.tv.material3.ClickableSurfaceScale import androidx.tv.material3.ClickableSurfaceScale
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.Icon import androidx.tv.material3.Icon
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Surface import androidx.tv.material3.Surface
@ -32,7 +31,6 @@ import dev.jdtech.jellyfin.models.PreferenceSwitch
import dev.jdtech.jellyfin.ui.theme.FindroidTheme import dev.jdtech.jellyfin.ui.theme.FindroidTheme
import dev.jdtech.jellyfin.ui.theme.spacings import dev.jdtech.jellyfin.ui.theme.spacings
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
fun SettingsSwitchCard( fun SettingsSwitchCard(
preference: PreferenceSwitch, preference: PreferenceSwitch,

View file

@ -15,12 +15,10 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
import dev.jdtech.jellyfin.ui.theme.FindroidTheme import dev.jdtech.jellyfin.ui.theme.FindroidTheme
import dev.jdtech.jellyfin.ui.theme.spacings import dev.jdtech.jellyfin.ui.theme.spacings
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
fun VideoPlayerControlsLayout( fun VideoPlayerControlsLayout(
mediaTitle: @Composable () -> Unit, mediaTitle: @Composable () -> Unit,

View file

@ -7,11 +7,9 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.graphics.painter.Painter
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.Icon import androidx.tv.material3.Icon
import androidx.tv.material3.IconButton import androidx.tv.material3.IconButton
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
fun VideoPlayerMediaButton( fun VideoPlayerMediaButton(
icon: Painter, icon: Painter,

View file

@ -4,12 +4,10 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Text import androidx.tv.material3.Text
import dev.jdtech.jellyfin.ui.theme.FindroidTheme import dev.jdtech.jellyfin.ui.theme.FindroidTheme
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
fun VideoPlayerMediaTitle( fun VideoPlayerMediaTitle(
title: String, title: String,

View file

@ -21,12 +21,10 @@ import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
import dev.jdtech.jellyfin.ui.theme.FindroidTheme import dev.jdtech.jellyfin.ui.theme.FindroidTheme
import dev.jdtech.jellyfin.ui.theme.spacings import dev.jdtech.jellyfin.ui.theme.spacings
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
fun VideoPlayerOverlay( fun VideoPlayerOverlay(
isPlaying: Boolean, isPlaying: Boolean,

View file

@ -25,12 +25,11 @@ import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
import dev.jdtech.jellyfin.ui.theme.FindroidTheme import dev.jdtech.jellyfin.ui.theme.FindroidTheme
import dev.jdtech.jellyfin.utils.handleDPadKeyEvents import dev.jdtech.jellyfin.utils.handleDPadKeyEvents
@OptIn(ExperimentalTvMaterial3Api::class, ExperimentalComposeUiApi::class) @OptIn(ExperimentalComposeUiApi::class)
@Composable @Composable
fun VideoPlayerSeekBar( fun VideoPlayerSeekBar(
progress: Float, progress: Float,

View file

@ -15,7 +15,6 @@ import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.Icon import androidx.tv.material3.Icon
import androidx.tv.material3.IconButton import androidx.tv.material3.IconButton
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
@ -25,7 +24,6 @@ import dev.jdtech.jellyfin.ui.theme.spacings
import kotlin.time.Duration import kotlin.time.Duration
import dev.jdtech.jellyfin.core.R as CoreR import dev.jdtech.jellyfin.core.R as CoreR
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
fun VideoPlayerSeeker( fun VideoPlayerSeeker(
focusRequester: FocusRequester, focusRequester: FocusRequester,

View file

@ -24,7 +24,6 @@ import androidx.tv.foundation.lazy.list.items
import androidx.tv.material3.Border import androidx.tv.material3.Border
import androidx.tv.material3.ClickableSurfaceDefaults import androidx.tv.material3.ClickableSurfaceDefaults
import androidx.tv.material3.ClickableSurfaceScale import androidx.tv.material3.ClickableSurfaceScale
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.RadioButton import androidx.tv.material3.RadioButton
import androidx.tv.material3.Surface import androidx.tv.material3.Surface
@ -45,7 +44,6 @@ data class VideoPlayerTrackSelectorDialogResult(
val index: Int, val index: Int,
) : Parcelable ) : Parcelable
@OptIn(ExperimentalTvMaterial3Api::class)
@Destination(style = BaseDialogStyle::class) @Destination(style = BaseDialogStyle::class)
@Composable @Composable
fun VideoPlayerTrackSelectorDialog( fun VideoPlayerTrackSelectorDialog(

View file

@ -2,7 +2,6 @@ package dev.jdtech.jellyfin.ui.theme
import androidx.compose.material3.darkColorScheme import androidx.compose.material3.darkColorScheme
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.darkColorScheme as darkColorSchemeTv import androidx.tv.material3.darkColorScheme as darkColorSchemeTv
val PrimaryDark = Color(0xffa1c9ff) val PrimaryDark = Color(0xffa1c9ff)
@ -23,7 +22,6 @@ val ColorScheme = darkColorScheme(
background = Neutral1000, background = Neutral1000,
) )
@OptIn(ExperimentalTvMaterial3Api::class)
val ColorSchemeTv = darkColorSchemeTv( val ColorSchemeTv = darkColorSchemeTv(
primary = ColorScheme.primary, primary = ColorScheme.primary,
onPrimary = ColorScheme.onPrimary, onPrimary = ColorScheme.onPrimary,

View file

@ -3,7 +3,6 @@ package dev.jdtech.jellyfin.ui.theme
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Shapes import androidx.compose.material3.Shapes
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.Shapes as ShapesTv import androidx.tv.material3.Shapes as ShapesTv
val shapes = Shapes( val shapes = Shapes(
@ -11,7 +10,6 @@ val shapes = Shapes(
small = RoundedCornerShape(10.dp), small = RoundedCornerShape(10.dp),
) )
@OptIn(ExperimentalTvMaterial3Api::class)
val shapesTv = ShapesTv( val shapesTv = ShapesTv(
extraSmall = shapes.extraSmall, extraSmall = shapes.extraSmall,
small = shapes.small, small = shapes.small,

View file

@ -4,7 +4,6 @@ import androidx.compose.runtime.Immutable
import androidx.compose.runtime.compositionLocalOf import androidx.compose.runtime.compositionLocalOf
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
@Immutable @Immutable
@ -17,9 +16,7 @@ data class Spacings(
val extraLarge: Dp = 64.dp, val extraLarge: Dp = 64.dp,
) )
@OptIn(ExperimentalTvMaterial3Api::class)
val MaterialTheme.spacings val MaterialTheme.spacings
get() = Spacings() get() = Spacings()
@OptIn(ExperimentalTvMaterial3Api::class)
val LocalSpacings = compositionLocalOf { MaterialTheme.spacings } val LocalSpacings = compositionLocalOf { MaterialTheme.spacings }

View file

@ -10,12 +10,10 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape import androidx.compose.ui.graphics.RectangleShape
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.NonInteractiveSurfaceDefaults
import androidx.tv.material3.Surface import androidx.tv.material3.Surface
import androidx.tv.material3.SurfaceDefaults
import androidx.tv.material3.MaterialTheme as MaterialThemeTv import androidx.tv.material3.MaterialTheme as MaterialThemeTv
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable @Composable
fun FindroidTheme( fun FindroidTheme(
content: @Composable BoxScope.() -> Unit, content: @Composable BoxScope.() -> Unit,
@ -34,7 +32,7 @@ fun FindroidTheme(
shapes = shapesTv, shapes = shapesTv,
content = { content = {
Surface( Surface(
colors = NonInteractiveSurfaceDefaults.colors( colors = SurfaceDefaults.colors(
containerColor = androidx.tv.material3.MaterialTheme.colorScheme.background, containerColor = androidx.tv.material3.MaterialTheme.colorScheme.background,
), ),
shape = RectangleShape, shape = RectangleShape,

View file

@ -4,7 +4,6 @@ import androidx.compose.material3.Typography
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.Typography as TypographyTv import androidx.tv.material3.Typography as TypographyTv
val Typography = Typography( val Typography = Typography(
@ -34,7 +33,6 @@ val Typography = Typography(
), ),
) )
@OptIn(ExperimentalTvMaterial3Api::class)
val TypographyTv = TypographyTv( val TypographyTv = TypographyTv(
displayMedium = Typography.displayMedium, displayMedium = Typography.displayMedium,
headlineMedium = Typography.headlineMedium, headlineMedium = Typography.headlineMedium,

View file

@ -11,6 +11,5 @@ object Versions {
val java = JavaVersion.VERSION_17 val java = JavaVersion.VERSION_17
const val composeCompiler = "1.5.11"
const val ktlint = "0.50.0" const val ktlint = "0.50.0"
} }

View file

@ -1,6 +1,7 @@
plugins { plugins {
alias(libs.plugins.android.library) alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android) alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.compose.compiler)
alias(libs.plugins.kotlin.parcelize) alias(libs.plugins.kotlin.parcelize)
alias(libs.plugins.ksp) alias(libs.plugins.ksp)
alias(libs.plugins.androidx.navigation.safeargs) alias(libs.plugins.androidx.navigation.safeargs)
@ -39,10 +40,6 @@ android {
buildFeatures { buildFeatures {
compose = true compose = true
} }
composeOptions {
kotlinCompilerExtensionVersion = Versions.composeCompiler
}
} }
ktlint { ktlint {
@ -57,16 +54,13 @@ dependencies {
implementation(projects.data) implementation(projects.data)
implementation(projects.preferences) implementation(projects.preferences)
implementation(projects.player.core) implementation(projects.player.core)
implementation(libs.androidx.activity)
implementation(libs.androidx.appcompat) implementation(libs.androidx.appcompat)
implementation(composeBom) implementation(composeBom)
implementation(libs.androidx.compose.ui) implementation(libs.androidx.compose.ui)
implementation(libs.androidx.core) implementation(libs.androidx.core)
implementation(libs.androidx.hilt.work) implementation(libs.androidx.hilt.work)
ksp(libs.androidx.hilt.compiler) ksp(libs.androidx.hilt.compiler)
implementation(libs.androidx.lifecycle.runtime)
implementation(libs.androidx.lifecycle.viewmodel) implementation(libs.androidx.lifecycle.viewmodel)
implementation(libs.androidx.navigation.fragment)
implementation(libs.androidx.paging) implementation(libs.androidx.paging)
implementation(libs.androidx.preference) implementation(libs.androidx.preference)
implementation(libs.androidx.room.runtime) implementation(libs.androidx.room.runtime)

View file

@ -61,7 +61,7 @@ constructor(
parentId = parentId, parentId = parentId,
includeTypes = itemType, includeTypes = itemType,
recursive = recursive, recursive = recursive,
sortBy = sortBy, sortBy = if (libraryType == CollectionType.TvShows && sortBy == SortBy.DATE_PLAYED) SortBy.SERIES_DATE_PLAYED else sortBy, // Jellyfin uses a different enum for sorting series by data played
sortOrder = sortOrder, sortOrder = sortOrder,
).cachedIn(viewModelScope) ).cachedIn(viewModelScope)
_uiState.emit(UiState.Normal(items)) _uiState.emit(UiState.Normal(items))

View file

@ -19,6 +19,7 @@ import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.jellyfin.sdk.api.client.extensions.authenticateWithQuickConnect import org.jellyfin.sdk.api.client.extensions.authenticateWithQuickConnect
import org.jellyfin.sdk.api.client.extensions.brandingApi
import org.jellyfin.sdk.model.api.AuthenticateUserByName import org.jellyfin.sdk.model.api.AuthenticateUserByName
import org.jellyfin.sdk.model.api.AuthenticationResult import org.jellyfin.sdk.model.api.AuthenticationResult
import javax.inject.Inject import javax.inject.Inject
@ -32,7 +33,7 @@ constructor(
private val jellyfinApi: JellyfinApi, private val jellyfinApi: JellyfinApi,
private val database: ServerDatabaseDao, private val database: ServerDatabaseDao,
) : ViewModel() { ) : ViewModel() {
private val _uiState = MutableStateFlow<UiState>(UiState.Normal) private val _uiState = MutableStateFlow<UiState>(UiState.Normal())
val uiState = _uiState.asStateFlow() val uiState = _uiState.asStateFlow()
private val _usersState = MutableStateFlow<UsersState>(UsersState.Loading) private val _usersState = MutableStateFlow<UsersState>(UsersState.Loading)
val usersState = _usersState.asStateFlow() val usersState = _usersState.asStateFlow()
@ -44,8 +45,10 @@ constructor(
private var quickConnectJob: Job? = null private var quickConnectJob: Job? = null
private var loginDisclaimer: String? = null
sealed class UiState { sealed class UiState {
data object Normal : UiState() data class Normal(val disclaimer: String? = null) : UiState()
data object Loading : UiState() data object Loading : UiState()
data class Error(val message: UiText) : UiState() data class Error(val message: UiText) : UiState()
} }
@ -62,10 +65,18 @@ constructor(
} }
init { init {
loadDisclaimer()
loadPublicUsers() loadPublicUsers()
loadQuickConnectAvailable() loadQuickConnectAvailable()
} }
private fun loadDisclaimer() {
viewModelScope.launch {
loginDisclaimer = jellyfinApi.api.brandingApi.getBrandingOptions().content.loginDisclaimer
_uiState.emit(UiState.Normal(loginDisclaimer))
}
}
private fun loadPublicUsers() { private fun loadPublicUsers() {
viewModelScope.launch { viewModelScope.launch {
_usersState.emit(UsersState.Loading) _usersState.emit(UsersState.Loading)
@ -121,7 +132,7 @@ constructor(
saveAuthenticationResult(authenticationResult) saveAuthenticationResult(authenticationResult)
_uiState.emit(UiState.Normal) _uiState.emit(UiState.Normal(loginDisclaimer))
eventsChannel.send(LoginEvent.NavigateToHome) eventsChannel.send(LoginEvent.NavigateToHome)
} catch (e: Exception) { } catch (e: Exception) {
val message = val message =

View file

@ -175,4 +175,21 @@
<string name="picture_in_picture_gesture">Gest domowy obrazu w obrazie</string> <string name="picture_in_picture_gesture">Gest domowy obrazu w obrazie</string>
<string name="picture_in_picture">Obraz w obrazie</string> <string name="picture_in_picture">Obraz w obrazie</string>
<string name="picture_in_picture_gesture_summary">Użyj przycisku strony głównej lub gestu, aby przejść do trybu obrazu w obrazie podczas odtwarzania wideo</string> <string name="picture_in_picture_gesture_summary">Użyj przycisku strony głównej lub gestu, aby przejść do trybu obrazu w obrazie podczas odtwarzania wideo</string>
<string name="collection_no_media">Ta kolekcja nie zawiera żadnych elementów</string>
<string name="no_servers_found">Nie znaleziono żadnego serwera</string>
<string name="no_users_found">Nie znaleziono użytkowników</string>
<string name="select_user">Wybierz użytkownika</string>
<string name="live_tv">Telewizja na żywo</string>
<string name="play">Odtwórz</string>
<string name="watch_trailer">Odtwórz trailer</string>
<string name="player_start_maximized">Uruchom w trybie pełnoekranowym</string>
<string name="player_start_maximized_summary">Domyślnie odtwórz wideo w trybie pełnoekranowym</string>
<string name="player_gestures_chapter_skip_summary">Długo przytrzymaj z prawej lub lewej strony aby pominąć rozdziały (omija 2x przyspieszenie wideo)</string>
<string name="player_gestures_chapter_skip">Gest rozdziału</string>
<string name="pref_player_chapter_markers">Znaczniki rozdziałów</string>
<string name="pref_player_chapter_markers_summary">Wyświetl znaczniki rozdziałów na pasku odtwarzania</string>
<string name="mark_as_played">Zaznacz jako obejrzane</string>
<string name="unmark_as_played">Zaznacz jako nieobejrzane</string>
<string name="add_to_favorites">Dodaj do ulubionych</string>
<string name="remove_from_favorites">Usuń z ulubionych</string>
</resources> </resources>

View file

@ -185,4 +185,11 @@
<string name="unmark_as_played">Zrušiť označenie pozretého</string> <string name="unmark_as_played">Zrušiť označenie pozretého</string>
<string name="add_to_favorites">Pridať k obľúbeným</string> <string name="add_to_favorites">Pridať k obľúbeným</string>
<string name="remove_from_favorites">Odstrániť z obľúbených</string> <string name="remove_from_favorites">Odstrániť z obľúbených</string>
<string name="collection_no_media">Táto kolekcia neobsahuje žiadne média</string>
<string name="player_start_maximized">Začni maximalizovaný</string>
<string name="player_start_maximized_summary">Štandardne otvor video v maximalizovanom režime</string>
<string name="player_gestures_chapter_skip">Gesto na kapitoly</string>
<string name="player_gestures_chapter_skip_summary">Dlhé stlačenie na ľavej / pravej strane pre preskočenie kapitoly (prepíše gesto na 2x rýchlosť)</string>
<string name="pref_player_chapter_markers">Značky kapitol</string>
<string name="pref_player_chapter_markers_summary">Zobraz značky kapitol na časovej osi</string>
</resources> </resources>

View file

@ -7,6 +7,7 @@ enum class SortBy(val sortString: String) {
DATE_ADDED("DateCreated"), DATE_ADDED("DateCreated"),
DATE_PLAYED("DatePlayed"), DATE_PLAYED("DatePlayed"),
RELEASE_DATE("PremiereDate"), RELEASE_DATE("PremiereDate"),
SERIES_DATE_PLAYED("SeriesDatePlayed"),
; ;
companion object { companion object {

View file

@ -306,7 +306,6 @@ class JellyfinRepositoryImpl(
responseProfiles = emptyList(), responseProfiles = emptyList(),
subtitleProfiles = listOf( subtitleProfiles = listOf(
SubtitleProfile("srt", SubtitleDeliveryMethod.EXTERNAL), SubtitleProfile("srt", SubtitleDeliveryMethod.EXTERNAL),
SubtitleProfile("vtt", SubtitleDeliveryMethod.EXTERNAL),
SubtitleProfile("ass", SubtitleDeliveryMethod.EXTERNAL), SubtitleProfile("ass", SubtitleDeliveryMethod.EXTERNAL),
), ),
xmlRootAttributes = emptyList(), xmlRootAttributes = emptyList(),

View file

@ -1,18 +1,18 @@
[versions] [versions]
aboutlibraries = "11.1.3" aboutlibraries = "11.2.0"
android-desugar-jdk-libs = "2.0.4" android-desugar-jdk-libs = "2.0.4"
android-plugin = "8.3.2" android-plugin = "8.4.1"
androidx-activity = "1.8.2" androidx-activity = "1.9.0"
androidx-appcompat = "1.6.1" androidx-appcompat = "1.6.1"
androidx-compose-bom = "2024.04.00" androidx-compose-bom = "2024.05.00"
androidx-compose-material3 = "1.2.1" androidx-compose-material3 = "1.2.1"
androidx-constraintlayout = "2.1.4" androidx-constraintlayout = "2.1.4"
androidx-core = "1.12.0" androidx-core = "1.13.1"
androidx-hilt = "1.2.0" androidx-hilt = "1.2.0"
androidx-lifecycle = "2.7.0" androidx-lifecycle = "2.8.0"
androidx-media3 = "1.3.1" androidx-media3 = "1.3.1"
androidx-navigation = "2.7.7" androidx-navigation = "2.7.7"
androidx-paging = "3.2.1" androidx-paging = "3.3.0"
androidx-preference = "1.2.1" androidx-preference = "1.2.1"
androidx-recyclerview = "1.3.2" androidx-recyclerview = "1.3.2"
androidx-room = "2.6.1" androidx-room = "2.6.1"
@ -23,19 +23,20 @@ androidx-test-junit = "1.1.5"
androidx-test-rules = "1.5.0" androidx-test-rules = "1.5.0"
androidx-test-runner = "1.5.2" androidx-test-runner = "1.5.2"
androidx-tv = "1.0.0-alpha10" androidx-tv = "1.0.0-alpha10"
androidx-tv-material3 = "1.0.0-beta01"
androidx-work = "2.9.0" androidx-work = "2.9.0"
coil = "2.6.0" coil = "2.6.0"
hilt = "2.51.1" hilt = "2.51.1"
compose-destinations = "1.10.2" compose-destinations = "1.10.2"
jellyfin = "1.4.7" jellyfin = "1.4.7"
junit = "4.13.2" junit = "4.13.2"
kotlin = "1.9.23" kotlin = "2.0.0"
kotlinx-serialization = "1.6.3" kotlinx-serialization = "1.6.3"
ksp = "1.9.23-1.0.20" ksp = "2.0.0-1.0.21"
ktlint = "12.1.0" ktlint = "12.1.1"
libmpv = "0.2.0" libmpv = "0.2.0"
material = "1.11.0" material = "1.12.0"
media3-ffmpeg-decoder = "1.2.1+1" media3-ffmpeg-decoder = "1.3.1+2"
timber = "5.0.1" timber = "5.0.1"
[libraries] [libraries]
@ -55,7 +56,7 @@ androidx-core = { group = "androidx.core", name = "core", version.ref = "android
androidx-hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "androidx-hilt" } androidx-hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "androidx-hilt" }
androidx-hilt-work = { group = "androidx.hilt", name = "hilt-work", version.ref = "androidx-hilt" } androidx-hilt-work = { group = "androidx.hilt", name = "hilt-work", version.ref = "androidx-hilt" }
androidx-hilt-compiler = { group = "androidx.hilt", name = "hilt-compiler", version.ref = "androidx-hilt" } androidx-hilt-compiler = { group = "androidx.hilt", name = "hilt-compiler", version.ref = "androidx-hilt" }
androidx-lifecycle-runtime = { group = "androidx.lifecycle", name = "lifecycle-runtime", version.ref = "androidx-lifecycle" } androidx-lifecycle-runtime = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "androidx-lifecycle" }
androidx-lifecycle-viewmodel = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "androidx-lifecycle" } androidx-lifecycle-viewmodel = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "androidx-lifecycle" }
androidx-lifecycle-viewmodel-compose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "androidx-lifecycle" } androidx-lifecycle-viewmodel-compose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "androidx-lifecycle" }
androidx-media3-common = { group = "androidx.media3", name = "media3-common", version.ref = "androidx-media3" } androidx-media3-common = { group = "androidx.media3", name = "media3-common", version.ref = "androidx-media3" }
@ -79,7 +80,7 @@ androidx-test-junit = { group = "androidx.test.ext", name = "junit", version.ref
androidx-test-rules = { group = "androidx.test" , name = "rules", version.ref = "androidx-test-rules" } androidx-test-rules = { group = "androidx.test" , name = "rules", version.ref = "androidx-test-rules" }
androidx-test-runner = { group = "androidx.test", name = "runner", version.ref = "androidx-test-runner" } androidx-test-runner = { group = "androidx.test", name = "runner", version.ref = "androidx-test-runner" }
androidx-tv-foundation = { group = "androidx.tv", name = "tv-foundation", version.ref = "androidx-tv" } androidx-tv-foundation = { group = "androidx.tv", name = "tv-foundation", version.ref = "androidx-tv" }
androidx-tv-material = { group = "androidx.tv", name = "tv-material", version.ref = "androidx-tv" } androidx-tv-material = { group = "androidx.tv", name = "tv-material", version.ref = "androidx-tv-material3" }
androidx-work = { group = "androidx.work", name = "work-runtime", version.ref = "androidx-work" } androidx-work = { group = "androidx.work", name = "work-runtime", version.ref = "androidx-work" }
androidx-work-testing = { group = "androidx.work", name = "work-testing", version.ref = "androidx-work" } androidx-work-testing = { group = "androidx.work", name = "work-testing", version.ref = "androidx-work" }
coil = { group = "io.coil-kt", name = "coil", version.ref = "coil" } coil = { group = "io.coil-kt", name = "coil", version.ref = "coil" }
@ -106,6 +107,7 @@ android-library = { id = "com.android.library", version.ref = "android-plugin" }
androidx-navigation-safeargs = { id = "androidx.navigation.safeargs.kotlin", version.ref = "androidx-navigation" } androidx-navigation-safeargs = { id = "androidx.navigation.safeargs.kotlin", version.ref = "androidx-navigation" }
hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" } hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" } kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" }
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }

View file

@ -36,10 +36,5 @@ ktlint {
} }
dependencies { dependencies {
implementation(projects.data)
implementation(projects.preferences)
implementation(libs.androidx.core)
implementation(libs.androidx.preference)
implementation(libs.jellyfin.core)
implementation(libs.timber) implementation(libs.timber)
} }

View file

@ -41,7 +41,6 @@ dependencies {
implementation(projects.player.core) implementation(projects.player.core)
implementation(projects.data) implementation(projects.data)
implementation(projects.preferences) implementation(projects.preferences)
implementation(libs.androidx.core)
implementation(libs.androidx.lifecycle.runtime) implementation(libs.androidx.lifecycle.runtime)
implementation(libs.androidx.lifecycle.viewmodel) implementation(libs.androidx.lifecycle.viewmodel)
implementation(libs.androidx.media3.exoplayer) implementation(libs.androidx.media3.exoplayer)

View file

@ -9,7 +9,7 @@ fun List<Tracks.Group>.getTrackNames(): Array<String> {
val format = group.mediaTrackGroup.getFormat(0) val format = group.mediaTrackGroup.getFormat(0)
nameParts.run { nameParts.run {
add(format.label) add(format.label)
add(format.language?.let { Locale(it).displayLanguage }) add(format.language?.let { Locale(it.split("-").last()).displayLanguage })
add(format.codecs) add(format.codecs)
filterNotNull().joinToString(separator = " - ") filterNotNull().joinToString(separator = " - ")
} }

View file

@ -28,7 +28,6 @@ import dev.jdtech.jellyfin.repository.JellyfinRepository
import dev.jdtech.jellyfin.utils.bif.BifData import dev.jdtech.jellyfin.utils.bif.BifData
import dev.jdtech.jellyfin.utils.bif.BifUtil import dev.jdtech.jellyfin.utils.bif.BifUtil
import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
@ -37,7 +36,6 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import timber.log.Timber import timber.log.Timber
import java.util.UUID import java.util.UUID
import javax.inject.Inject import javax.inject.Inject
@ -193,11 +191,6 @@ constructor(
currentMediaItemIndex, currentMediaItemIndex,
startPosition, startPosition,
) )
if (appPreferences.playerMpv) { // For some reason, adding a 1ms delay between these two lines fixes a crash when playing with mpv from downloads
withContext(Dispatchers.IO) {
Thread.sleep(1)
}
}
player.prepare() player.prepare()
player.play() player.play()
pollPosition(player) pollPosition(player)

View file

@ -139,20 +139,13 @@ class PlayerViewModel @Inject internal constructor(
mediaStream.isExternal && mediaStream.type == MediaStreamType.SUBTITLE && !mediaStream.path.isNullOrBlank() mediaStream.isExternal && mediaStream.type == MediaStreamType.SUBTITLE && !mediaStream.path.isNullOrBlank()
} }
.map { mediaStream -> .map { mediaStream ->
// Temp fix for vtt
// Jellyfin returns a srt stream when it should return vtt stream.
var deliveryUrl = mediaStream.path!!
if (mediaStream.codec == "webvtt") {
deliveryUrl = deliveryUrl.replace("Stream.srt", "Stream.vtt")
}
ExternalSubtitle( ExternalSubtitle(
mediaStream.title, mediaStream.title,
mediaStream.language, mediaStream.language,
Uri.parse(deliveryUrl), Uri.parse(mediaStream.path!!),
when (mediaStream.codec) { when (mediaStream.codec) {
"subrip" -> MimeTypes.APPLICATION_SUBRIP "subrip" -> MimeTypes.APPLICATION_SUBRIP
"webvtt" -> MimeTypes.TEXT_VTT "webvtt" -> MimeTypes.APPLICATION_SUBRIP
"ass" -> MimeTypes.TEXT_SSA "ass" -> MimeTypes.TEXT_SSA
else -> MimeTypes.TEXT_UNKNOWN else -> MimeTypes.TEXT_UNKNOWN
}, },

View file

@ -15,4 +15,5 @@
<string name="player_controls_progress">Pasek postępu</string> <string name="player_controls_progress">Pasek postępu</string>
<string name="player_controls_play_pause">Odtwórz/wstrzymaj</string> <string name="player_controls_play_pause">Odtwórz/wstrzymaj</string>
<string name="player_controls_picture_in_picture">Wejdź w tryb obrazu w obrazie</string> <string name="player_controls_picture_in_picture">Wejdź w tryb obrazu w obrazie</string>
<string name="none">Brak</string>
</resources> </resources>