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

View file

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

View file

@ -103,9 +103,7 @@ dependencies {
implementation(libs.androidx.constraintlayout)
implementation(libs.androidx.core)
implementation(libs.androidx.hilt.work)
implementation(libs.androidx.lifecycle.runtime)
implementation(libs.androidx.lifecycle.viewmodel)
implementation(libs.androidx.media3.exoplayer)
implementation(libs.androidx.media3.ui)
implementation(libs.androidx.media3.session)
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.WindowInsetsControllerCompat
import androidx.core.view.updatePadding
import androidx.media3.exoplayer.trackselection.MappingTrackSelector
import androidx.media3.session.MediaSession
import dev.jdtech.jellyfin.viewmodels.PlayerActivityViewModel
@ -72,19 +71,6 @@ abstract class BasePlayerActivity : AppCompatActivity() {
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) {
playerControls.setOnApplyWindowInsetsListener { _, windowInsets ->
val cutout = windowInsets.displayCutout

View file

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

View file

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

View file

@ -141,6 +141,15 @@
android:visibility="invisible" />
</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>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

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

View file

@ -28,3 +28,5 @@
-dontwarn org.openjsse.javax.net.ssl.SSLParameters
-dontwarn org.openjsse.javax.net.ssl.SSLSocket
-dontwarn org.openjsse.net.ssl.OpenJSSE
-keep class dev.jdtech.**

View file

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

View file

@ -32,7 +32,6 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.tv.material3.Button
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.Icon
import androidx.tv.material3.LocalContentColor
import androidx.tv.material3.MaterialTheme
@ -71,7 +70,6 @@ fun AddServerScreen(
)
}
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable
private fun AddServerScreenLayout(
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.TvLazyRow
import androidx.tv.foundation.lazy.list.items
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Text
import com.ramcosta.composedestinations.annotation.Destination
@ -88,7 +87,6 @@ fun HomeScreen(
)
}
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable
private fun HomeScreenLayout(
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.TvLazyVerticalGrid
import androidx.tv.foundation.lazy.grid.items
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
@ -50,7 +49,6 @@ fun LibrariesScreen(
)
}
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable
private fun LibrariesScreenLayout(
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.TvGridItemSpan
import androidx.tv.foundation.lazy.grid.TvLazyVerticalGrid
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Text
import com.ramcosta.composedestinations.annotation.Destination
@ -75,7 +74,6 @@ fun LibraryScreen(
)
}
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable
private fun LibraryScreenLayout(
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.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
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.hilt.navigation.compose.hiltViewModel
import androidx.tv.material3.Button
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.Icon
import androidx.tv.material3.LocalContentColor
import androidx.tv.material3.MaterialTheme
@ -86,7 +86,6 @@ fun LoginScreen(
)
}
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable
private fun LoginScreenLayout(
uiState: LoginViewModel.UiState,
@ -110,6 +109,14 @@ private fun LoginScreenLayout(
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 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() {
FindroidTheme {
LoginScreenLayout(
uiState = LoginViewModel.UiState.Normal,
uiState = LoginViewModel.UiState.Normal(),
quickConnectUiState = LoginViewModel.QuickConnectUiState.Normal,
onLoginClick = { _, _ -> },
onQuickConnectClick = {},

View file

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

View file

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

View file

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

View file

@ -18,7 +18,6 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.tv.foundation.lazy.list.TvLazyColumn
import androidx.tv.foundation.lazy.list.items
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Text
import com.ramcosta.composedestinations.annotation.Destination
@ -76,7 +75,6 @@ fun SeasonScreen(
)
}
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable
private fun SeasonScreenLayout(
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.material3.Border
import androidx.tv.material3.ClickableSurfaceDefaults
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.Icon
import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.OutlinedButton
@ -103,7 +102,6 @@ fun ServerSelectScreen(
)
}
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable
private fun ServerSelectScreenLayout(
uiState: ServerSelectViewModel.UiState,
@ -246,7 +244,6 @@ private fun ServerSelectScreenLayoutPreviewNoServers() {
}
}
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable
private fun ServerComponent(
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.TvLazyVerticalGrid
import androidx.tv.foundation.lazy.grid.items
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Text
import com.ramcosta.composedestinations.annotation.Destination
@ -80,7 +79,6 @@ fun SettingsScreen(
}
}
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable
private fun SettingsScreenLayout(
uiState: SettingsViewModel.UiState,

View file

@ -25,7 +25,6 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.tv.foundation.lazy.list.TvLazyColumn
import androidx.tv.foundation.lazy.list.items
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Text
import com.ramcosta.composedestinations.annotation.Destination
@ -90,7 +89,6 @@ fun SettingsSubScreen(
}
}
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable
private fun SettingsSubScreenLayout(
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.rememberTvLazyListState
import androidx.tv.material3.Button
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.Icon
import androidx.tv.material3.LocalContentColor
import androidx.tv.material3.MaterialTheme
@ -126,7 +125,6 @@ fun ShowScreen(
)
}
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable
private fun ShowScreenLayout(
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.material3.Border
import androidx.tv.material3.ClickableSurfaceDefaults
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.Icon
import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.OutlinedButton
@ -99,7 +98,6 @@ fun UserSelectScreen(
)
}
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable
private fun UserSelectScreenLayout(
uiState: UserSelectViewModel.UiState,
@ -204,7 +202,6 @@ private fun UserSelectScreenLayoutPreviewNoUsers() {
}
}
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable
private fun UserComponent(
user: User,

View file

@ -23,7 +23,6 @@ import androidx.compose.ui.unit.dp
import androidx.tv.material3.Border
import androidx.tv.material3.ClickableSurfaceDefaults
import androidx.tv.material3.ClickableSurfaceScale
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Surface
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.spacings
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable
fun EpisodeCard(
episode: FindroidEpisode,

View file

@ -21,7 +21,6 @@ import androidx.compose.ui.unit.dp
import androidx.tv.material3.Border
import androidx.tv.material3.ClickableSurfaceDefaults
import androidx.tv.material3.ClickableSurfaceScale
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Surface
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.spacings
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable
fun ItemCard(
item: FindroidItem,

View file

@ -6,7 +6,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme
import coil.compose.AsyncImage
import dev.jdtech.jellyfin.models.FindroidEpisode
@ -17,7 +16,6 @@ enum class Direction {
HORIZONTAL, VERTICAL
}
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable
fun ItemPoster(
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.width
import androidx.compose.ui.zIndex
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.TabRow
@ -35,7 +34,6 @@ import androidx.tv.material3.TabRow
*
* This component is adapted from androidx.tv.material3.TabRowDefaults.PillIndicator
*/
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable
fun PillBorderIndicator(
currentTabPosition: DpRect,

View file

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

View file

@ -14,7 +14,6 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.Icon
import androidx.tv.material3.MaterialTheme
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.core.R as CoreR
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable
fun ProgressBadge(
item: FindroidItem,

View file

@ -21,7 +21,6 @@ import androidx.compose.ui.unit.dp
import androidx.tv.material3.Border
import androidx.tv.material3.ClickableSurfaceDefaults
import androidx.tv.material3.ClickableSurfaceScale
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.Icon
import androidx.tv.material3.MaterialTheme
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.core.R as CoreR
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable
fun SettingsCategoryCard(
preference: PreferenceCategory,

View file

@ -22,7 +22,6 @@ import androidx.tv.foundation.lazy.list.TvLazyColumn
import androidx.tv.material3.Border
import androidx.tv.material3.ClickableSurfaceDefaults
import androidx.tv.material3.ClickableSurfaceScale
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.RadioButton
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.core.R as CoreR
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable
fun SettingsDetailsCard(
preference: PreferenceSelect,

View file

@ -21,7 +21,6 @@ import androidx.compose.ui.unit.dp
import androidx.tv.material3.Border
import androidx.tv.material3.ClickableSurfaceDefaults
import androidx.tv.material3.ClickableSurfaceScale
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.Icon
import androidx.tv.material3.MaterialTheme
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.core.R as CoreR
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable
fun SettingsSelectCard(
preference: PreferenceSelect,

View file

@ -21,7 +21,6 @@ import androidx.compose.ui.unit.dp
import androidx.tv.material3.Border
import androidx.tv.material3.ClickableSurfaceDefaults
import androidx.tv.material3.ClickableSurfaceScale
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.Icon
import androidx.tv.material3.MaterialTheme
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.spacings
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable
fun SettingsSwitchCard(
preference: PreferenceSwitch,

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -4,7 +4,6 @@ import androidx.compose.runtime.Immutable
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme
@Immutable
@ -17,9 +16,7 @@ data class Spacings(
val extraLarge: Dp = 64.dp,
)
@OptIn(ExperimentalTvMaterial3Api::class)
val MaterialTheme.spacings
get() = Spacings()
@OptIn(ExperimentalTvMaterial3Api::class)
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.Color
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.SurfaceDefaults
import androidx.tv.material3.MaterialTheme as MaterialThemeTv
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable
fun FindroidTheme(
content: @Composable BoxScope.() -> Unit,
@ -34,7 +32,7 @@ fun FindroidTheme(
shapes = shapesTv,
content = {
Surface(
colors = NonInteractiveSurfaceDefaults.colors(
colors = SurfaceDefaults.colors(
containerColor = androidx.tv.material3.MaterialTheme.colorScheme.background,
),
shape = RectangleShape,

View file

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

View file

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

View file

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

View file

@ -61,7 +61,7 @@ constructor(
parentId = parentId,
includeTypes = itemType,
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,
).cachedIn(viewModelScope)
_uiState.emit(UiState.Normal(items))

View file

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

View file

@ -185,4 +185,11 @@
<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="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>

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -9,7 +9,7 @@ fun List<Tracks.Group>.getTrackNames(): Array<String> {
val format = group.mediaTrackGroup.getFormat(0)
nameParts.run {
add(format.label)
add(format.language?.let { Locale(it).displayLanguage })
add(format.language?.let { Locale(it.split("-").last()).displayLanguage })
add(format.codecs)
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.BifUtil
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.delay
@ -37,7 +36,6 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import timber.log.Timber
import java.util.UUID
import javax.inject.Inject
@ -193,11 +191,6 @@ constructor(
currentMediaItemIndex,
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.play()
pollPosition(player)

View file

@ -139,20 +139,13 @@ class PlayerViewModel @Inject internal constructor(
mediaStream.isExternal && mediaStream.type == MediaStreamType.SUBTITLE && !mediaStream.path.isNullOrBlank()
}
.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(
mediaStream.title,
mediaStream.language,
Uri.parse(deliveryUrl),
Uri.parse(mediaStream.path!!),
when (mediaStream.codec) {
"subrip" -> MimeTypes.APPLICATION_SUBRIP
"webvtt" -> MimeTypes.TEXT_VTT
"webvtt" -> MimeTypes.APPLICATION_SUBRIP
"ass" -> MimeTypes.TEXT_SSA
else -> MimeTypes.TEXT_UNKNOWN
},

View file

@ -15,4 +15,5 @@
<string name="player_controls_progress">Pasek postępu</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="none">Brak</string>
</resources>