Merge branch 'jarnedemeulemeester:main' into Skip-credit
This commit is contained in:
commit
0999823d6d
61 changed files with 110 additions and 159 deletions
4
.github/workflows/build.yaml
vendored
4
.github/workflows/build.yaml
vendored
|
@ -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:
|
||||||
|
|
2
.github/workflows/publish.yaml
vendored
2
.github/workflows/publish.yaml
vendored
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 &&
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
4
app/tv/proguard-rules.pro
vendored
4
app/tv/proguard-rules.pro
vendored
|
@ -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.**
|
|
@ -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)
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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 = {},
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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?,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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 }
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
|
@ -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)
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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 =
|
||||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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 {
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
|
@ -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" }
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 = " - ")
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
},
|
},
|
||||||
|
|
|
@ -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>
|
Loading…
Reference in a new issue