Show warning for future unsupported server version (#2115)
## Description Now that Jellyfin 12 has been out for over six weeks, it's time to start considering dropping support for Jellyfin 10 & 11 as part of #1640. This PR adds a warning message on the switch server, switch user, & preferences pages if the current server version is <12. ### Related issues See https://github.com/damontecres/Wholphin/discussions/1640 for further discussion! ### Testing Emulator w/ faked data ## Screenshots N/A, reuses the same error message space ## AI or LLM usage None
This commit is contained in:
parent
9218940a69
commit
6cde8ce8a6
10 changed files with 164 additions and 67 deletions
|
|
@ -122,5 +122,7 @@ class WholphinApplication :
|
||||||
private set
|
private set
|
||||||
|
|
||||||
val minimumServerVersion: ServerVersion = Jellyfin.minimumVersion
|
val minimumServerVersion: ServerVersion = Jellyfin.minimumVersion
|
||||||
|
|
||||||
|
val newMinimumServerVersion: ServerVersion = ServerVersion(12, 0, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ import androidx.compose.ui.text.AnnotatedString
|
||||||
import androidx.compose.ui.text.buildAnnotatedString
|
import androidx.compose.ui.text.buildAnnotatedString
|
||||||
import com.github.damontecres.wholphin.R
|
import com.github.damontecres.wholphin.R
|
||||||
import com.github.damontecres.wholphin.WholphinApplication
|
import com.github.damontecres.wholphin.WholphinApplication
|
||||||
|
import com.github.damontecres.wholphin.ui.setup.ServerVersionSupported
|
||||||
|
import org.jellyfin.sdk.model.ServerVersion
|
||||||
import org.jellyfin.sdk.model.api.BaseItemDto
|
import org.jellyfin.sdk.model.api.BaseItemDto
|
||||||
import org.jellyfin.sdk.model.api.BaseItemKind
|
import org.jellyfin.sdk.model.api.BaseItemKind
|
||||||
import org.jellyfin.sdk.model.api.MediaSegmentType
|
import org.jellyfin.sdk.model.api.MediaSegmentType
|
||||||
|
|
@ -319,3 +321,55 @@ fun Resources.formatDuration(duration: Duration): String =
|
||||||
else -> getString(R.string.duration_seconds, seconds)
|
else -> getString(R.string.duration_seconds, seconds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Resources.serverSupportedMessage(
|
||||||
|
serverVersionSupported: ServerVersionSupported,
|
||||||
|
serverVersion: ServerVersion?,
|
||||||
|
): String? {
|
||||||
|
val errorMsg =
|
||||||
|
when (serverVersionSupported) {
|
||||||
|
ServerVersionSupported.SUPPORTED -> {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerVersionSupported.NOT_SUPPORTED,
|
||||||
|
ServerVersionSupported.UNKNOWN,
|
||||||
|
-> {
|
||||||
|
getString(R.string.server_version_not_supported)
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerVersionSupported.NOT_SUPPORTED_IN_FUTURE -> {
|
||||||
|
getString(R.string.server_version_not_supported_future)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return errorMsg?.let {
|
||||||
|
val msg =
|
||||||
|
if (serverVersion != null) {
|
||||||
|
"$it: $serverVersion"
|
||||||
|
} else {
|
||||||
|
it + ": " + getString(R.string.unknown)
|
||||||
|
}
|
||||||
|
msg + "\n" +
|
||||||
|
when (serverVersionSupported) {
|
||||||
|
ServerVersionSupported.SUPPORTED -> {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerVersionSupported.NOT_SUPPORTED,
|
||||||
|
ServerVersionSupported.UNKNOWN,
|
||||||
|
-> {
|
||||||
|
getString(
|
||||||
|
R.string.server_version_required,
|
||||||
|
WholphinApplication.minimumServerVersion.toString(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerVersionSupported.NOT_SUPPORTED_IN_FUTURE -> {
|
||||||
|
getString(
|
||||||
|
R.string.server_version_required,
|
||||||
|
WholphinApplication.newMinimumServerVersion.toString(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,10 +36,12 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.focus.FocusRequester
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
import androidx.compose.ui.focus.focusRequester
|
import androidx.compose.ui.focus.focusRequester
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.platform.LocalResources
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||||
|
import androidx.tv.material3.ListItem
|
||||||
import androidx.tv.material3.MaterialTheme
|
import androidx.tv.material3.MaterialTheme
|
||||||
import androidx.tv.material3.Text
|
import androidx.tv.material3.Text
|
||||||
import androidx.tv.material3.surfaceColorAtElevation
|
import androidx.tv.material3.surfaceColorAtElevation
|
||||||
|
|
@ -78,6 +80,7 @@ import com.github.damontecres.wholphin.ui.nav.Destination
|
||||||
import com.github.damontecres.wholphin.ui.playOnClickSound
|
import com.github.damontecres.wholphin.ui.playOnClickSound
|
||||||
import com.github.damontecres.wholphin.ui.playSoundOnFocus
|
import com.github.damontecres.wholphin.ui.playSoundOnFocus
|
||||||
import com.github.damontecres.wholphin.ui.preferences.subtitle.SubtitleSettings
|
import com.github.damontecres.wholphin.ui.preferences.subtitle.SubtitleSettings
|
||||||
|
import com.github.damontecres.wholphin.ui.serverSupportedMessage
|
||||||
import com.github.damontecres.wholphin.ui.setup.ReleaseNotes
|
import com.github.damontecres.wholphin.ui.setup.ReleaseNotes
|
||||||
import com.github.damontecres.wholphin.ui.setup.UpdateViewModel
|
import com.github.damontecres.wholphin.ui.setup.UpdateViewModel
|
||||||
import com.github.damontecres.wholphin.ui.setup.seerr.AddSeerServerDialog
|
import com.github.damontecres.wholphin.ui.setup.seerr.AddSeerServerDialog
|
||||||
|
|
@ -102,6 +105,7 @@ fun PreferencesContent(
|
||||||
onFocus: (Int, Int) -> Unit = { _, _ -> },
|
onFocus: (Int, Int) -> Unit = { _, _ -> },
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
val resources = LocalResources.current
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val focusRequester = remember { FocusRequester() }
|
val focusRequester = remember { FocusRequester() }
|
||||||
val firstFocusRequester = remember { FocusRequester() }
|
val firstFocusRequester = remember { FocusRequester() }
|
||||||
|
|
@ -114,6 +118,11 @@ fun PreferencesContent(
|
||||||
var showPinFlow by remember { mutableStateOf(false) }
|
var showPinFlow by remember { mutableStateOf(false) }
|
||||||
var showVersionDialog by remember { mutableStateOf(false) }
|
var showVersionDialog by remember { mutableStateOf(false) }
|
||||||
val players by viewModel.externalPlayers.collectAsState()
|
val players by viewModel.externalPlayers.collectAsState()
|
||||||
|
val serverSupported by viewModel.serverSupported.collectAsState()
|
||||||
|
val serverVersionMessage =
|
||||||
|
remember(resources, serverSupported) {
|
||||||
|
resources.serverSupportedMessage(serverSupported.second, serverSupported.first)
|
||||||
|
}
|
||||||
|
|
||||||
var cacheUsage by remember { mutableStateOf(CacheUsage(0, 0, 0)) }
|
var cacheUsage by remember { mutableStateOf(CacheUsage(0, 0, 0)) }
|
||||||
val seerrConnection by viewModel.seerrConnection.collectAsState()
|
val seerrConnection by viewModel.seerrConnection.collectAsState()
|
||||||
|
|
@ -230,6 +239,19 @@ fun PreferencesContent(
|
||||||
contentPadding = PaddingValues(16.dp),
|
contentPadding = PaddingValues(16.dp),
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
) {
|
) {
|
||||||
|
serverVersionMessage?.let { message ->
|
||||||
|
item {
|
||||||
|
ListItem(
|
||||||
|
selected = false,
|
||||||
|
enabled = true,
|
||||||
|
onClick = {},
|
||||||
|
headlineContent = {
|
||||||
|
PreferenceTitle(message, color = MaterialTheme.colorScheme.error)
|
||||||
|
},
|
||||||
|
modifier = Modifier,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
if (showUpdate) {
|
if (showUpdate) {
|
||||||
item {
|
item {
|
||||||
val interactionSource = remember { MutableInteractionSource() }
|
val interactionSource = remember { MutableInteractionSource() }
|
||||||
|
|
@ -265,6 +287,7 @@ fun PreferencesContent(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prefList.forEachIndexed { groupIndex, group ->
|
prefList.forEachIndexed { groupIndex, group ->
|
||||||
item {
|
item {
|
||||||
Text(
|
Text(
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import androidx.datastore.core.DataStore
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.github.damontecres.wholphin.R
|
import com.github.damontecres.wholphin.R
|
||||||
|
import com.github.damontecres.wholphin.WholphinApplication
|
||||||
import com.github.damontecres.wholphin.data.ServerRepository
|
import com.github.damontecres.wholphin.data.ServerRepository
|
||||||
import com.github.damontecres.wholphin.data.model.JellyfinUser
|
import com.github.damontecres.wholphin.data.model.JellyfinUser
|
||||||
import com.github.damontecres.wholphin.preferences.AppPreferences
|
import com.github.damontecres.wholphin.preferences.AppPreferences
|
||||||
|
|
@ -25,6 +26,7 @@ import com.github.damontecres.wholphin.services.SeerrServerRepository
|
||||||
import com.github.damontecres.wholphin.services.ServerReportService
|
import com.github.damontecres.wholphin.services.ServerReportService
|
||||||
import com.github.damontecres.wholphin.services.UpdateChecker
|
import com.github.damontecres.wholphin.services.UpdateChecker
|
||||||
import com.github.damontecres.wholphin.ui.launchIO
|
import com.github.damontecres.wholphin.ui.launchIO
|
||||||
|
import com.github.damontecres.wholphin.ui.setup.ServerVersionSupported
|
||||||
import com.github.damontecres.wholphin.util.DataLoadingState
|
import com.github.damontecres.wholphin.util.DataLoadingState
|
||||||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||||
import com.github.damontecres.wholphin.util.LoadingState
|
import com.github.damontecres.wholphin.util.LoadingState
|
||||||
|
|
@ -33,6 +35,7 @@ import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.SharingStarted
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import org.jellyfin.sdk.api.client.ApiClient
|
import org.jellyfin.sdk.api.client.ApiClient
|
||||||
|
|
@ -76,6 +79,23 @@ class PreferencesViewModel
|
||||||
|
|
||||||
val externalPlayers = MutableStateFlow<List<ExternalPlayerApp>>(emptyList())
|
val externalPlayers = MutableStateFlow<List<ExternalPlayerApp>>(emptyList())
|
||||||
|
|
||||||
|
val serverSupported =
|
||||||
|
serverRepository.currentServerFlow
|
||||||
|
.map {
|
||||||
|
val serverVersion = it?.serverVersion
|
||||||
|
serverVersion to
|
||||||
|
when {
|
||||||
|
serverVersion == null -> ServerVersionSupported.NOT_SUPPORTED
|
||||||
|
serverVersion < WholphinApplication.minimumServerVersion -> ServerVersionSupported.NOT_SUPPORTED
|
||||||
|
serverVersion < WholphinApplication.newMinimumServerVersion -> ServerVersionSupported.NOT_SUPPORTED_IN_FUTURE
|
||||||
|
else -> ServerVersionSupported.SUPPORTED
|
||||||
|
}
|
||||||
|
}.stateIn(
|
||||||
|
viewModelScope,
|
||||||
|
SharingStarted.Eagerly,
|
||||||
|
null to ServerVersionSupported.SUPPORTED,
|
||||||
|
)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
viewModelScope.launchIO {
|
viewModelScope.launchIO {
|
||||||
val fakeIntent =
|
val fakeIntent =
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ import androidx.tv.material3.Surface
|
||||||
import androidx.tv.material3.Text
|
import androidx.tv.material3.Text
|
||||||
import com.github.damontecres.wholphin.R
|
import com.github.damontecres.wholphin.R
|
||||||
import com.github.damontecres.wholphin.data.model.JellyfinServer
|
import com.github.damontecres.wholphin.data.model.JellyfinServer
|
||||||
|
import com.github.damontecres.wholphin.ui.AppColors
|
||||||
import com.github.damontecres.wholphin.ui.Cards
|
import com.github.damontecres.wholphin.ui.Cards
|
||||||
import com.github.damontecres.wholphin.ui.components.CircularProgress
|
import com.github.damontecres.wholphin.ui.components.CircularProgress
|
||||||
import org.jellyfin.sdk.model.api.PublicSystemInfo
|
import org.jellyfin.sdk.model.api.PublicSystemInfo
|
||||||
|
|
@ -177,7 +178,12 @@ fun ServerIconCard(
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Default.Warning,
|
imageVector = Icons.Default.Warning,
|
||||||
contentDescription = (connectionStatus as? ServerConnectionStatus.Error)?.message,
|
contentDescription = (connectionStatus as? ServerConnectionStatus.Error)?.message,
|
||||||
tint = MaterialTheme.colorScheme.errorContainer,
|
tint =
|
||||||
|
if (serverVersionSupported == ServerVersionSupported.NOT_SUPPORTED_IN_FUTURE) {
|
||||||
|
AppColors.GoldenYellow
|
||||||
|
} else {
|
||||||
|
MaterialTheme.colorScheme.errorContainer
|
||||||
|
},
|
||||||
modifier = Modifier.size(cardSize * 0.3f),
|
modifier = Modifier.size(cardSize * 0.3f),
|
||||||
)
|
)
|
||||||
Text(
|
Text(
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import androidx.compose.animation.slideOutVertically
|
||||||
import androidx.compose.animation.togetherWith
|
import androidx.compose.animation.togetherWith
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.BoxScope
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
|
@ -69,8 +70,10 @@ import com.github.damontecres.wholphin.ui.dimAndBlur
|
||||||
import com.github.damontecres.wholphin.ui.ifElse
|
import com.github.damontecres.wholphin.ui.ifElse
|
||||||
import com.github.damontecres.wholphin.ui.isNotNullOrBlank
|
import com.github.damontecres.wholphin.ui.isNotNullOrBlank
|
||||||
import com.github.damontecres.wholphin.ui.rememberInt
|
import com.github.damontecres.wholphin.ui.rememberInt
|
||||||
|
import com.github.damontecres.wholphin.ui.serverSupportedMessage
|
||||||
import com.github.damontecres.wholphin.ui.tryRequestFocus
|
import com.github.damontecres.wholphin.ui.tryRequestFocus
|
||||||
import com.github.damontecres.wholphin.util.LoadingState
|
import com.github.damontecres.wholphin.util.LoadingState
|
||||||
|
import org.jellyfin.sdk.model.ServerVersion
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -235,20 +238,7 @@ private fun SwitchServerContentInternal(
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.align(Alignment.BottomCenter),
|
.align(Alignment.BottomCenter),
|
||||||
) { message ->
|
) { message ->
|
||||||
|
SwitchErrorMessage(message ?: "")
|
||||||
Text(
|
|
||||||
text = message ?: "",
|
|
||||||
color = MaterialTheme.colorScheme.error,
|
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
maxLines = 2,
|
|
||||||
overflow = TextOverflow.Ellipsis,
|
|
||||||
modifier =
|
|
||||||
Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(start = 32.dp, end = 32.dp, bottom = 32.dp)
|
|
||||||
.align(Alignment.BottomCenter),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete server dialog
|
// Delete server dialog
|
||||||
|
|
@ -491,21 +481,38 @@ fun serverErrorMessage(
|
||||||
server: ServerState?,
|
server: ServerState?,
|
||||||
resources: Resources,
|
resources: Resources,
|
||||||
): String? =
|
): String? =
|
||||||
when {
|
if (server == null || server.status == ServerConnectionStatus.Pending) {
|
||||||
server?.status is ServerConnectionStatus.Error -> {
|
null
|
||||||
server.status.message
|
} else if (server.status is ServerConnectionStatus.Success) {
|
||||||
}
|
resources.serverSupportedMessage(
|
||||||
|
server.versionSupported,
|
||||||
server?.status is ServerConnectionStatus.Success &&
|
server.status.systemInfo.version
|
||||||
server.versionSupported == ServerVersionSupported.NOT_SUPPORTED -> {
|
?.let { ServerVersion.fromString(it) },
|
||||||
resources.getString(R.string.server_version_not_supported) + ": ${server.status.systemInfo.version}"
|
)
|
||||||
}
|
} else if (server.status is ServerConnectionStatus.Error) {
|
||||||
|
server.status.message
|
||||||
server?.versionSupported == ServerVersionSupported.NOT_SUPPORTED -> {
|
} else {
|
||||||
resources.getString(R.string.server_version_not_supported)
|
resources.serverSupportedMessage(
|
||||||
}
|
server.versionSupported,
|
||||||
|
null,
|
||||||
else -> {
|
)
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun BoxScope.SwitchErrorMessage(message: String?) {
|
||||||
|
message?.let {
|
||||||
|
Text(
|
||||||
|
text = message,
|
||||||
|
color = MaterialTheme.colorScheme.error,
|
||||||
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
maxLines = 3,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
modifier =
|
||||||
|
Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(start = 32.dp, end = 32.dp, bottom = 32.dp)
|
||||||
|
.align(Alignment.BottomCenter),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,8 @@ class SwitchServerViewModel
|
||||||
result.systemInfo.version?.let { ServerVersion.fromString(it) }
|
result.systemInfo.version?.let { ServerVersion.fromString(it) }
|
||||||
if (serverVersion == null || serverVersion < WholphinApplication.minimumServerVersion) {
|
if (serverVersion == null || serverVersion < WholphinApplication.minimumServerVersion) {
|
||||||
ServerVersionSupported.NOT_SUPPORTED
|
ServerVersionSupported.NOT_SUPPORTED
|
||||||
|
} else if (serverVersion < WholphinApplication.newMinimumServerVersion) {
|
||||||
|
ServerVersionSupported.NOT_SUPPORTED_IN_FUTURE
|
||||||
} else {
|
} else {
|
||||||
ServerVersionSupported.SUPPORTED
|
ServerVersionSupported.SUPPORTED
|
||||||
}
|
}
|
||||||
|
|
@ -307,4 +309,5 @@ enum class ServerVersionSupported {
|
||||||
SUPPORTED,
|
SUPPORTED,
|
||||||
NOT_SUPPORTED,
|
NOT_SUPPORTED,
|
||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
|
NOT_SUPPORTED_IN_FUTURE,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@ import androidx.compose.ui.text.input.ImeAction
|
||||||
import androidx.compose.ui.text.input.KeyboardCapitalization
|
import androidx.compose.ui.text.input.KeyboardCapitalization
|
||||||
import androidx.compose.ui.text.input.KeyboardType
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.window.DialogProperties
|
import androidx.compose.ui.window.DialogProperties
|
||||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||||
|
|
@ -50,6 +49,7 @@ import com.github.damontecres.wholphin.ui.components.TextButton
|
||||||
import com.github.damontecres.wholphin.ui.dimAndBlur
|
import com.github.damontecres.wholphin.ui.dimAndBlur
|
||||||
import com.github.damontecres.wholphin.ui.isNotNullOrBlank
|
import com.github.damontecres.wholphin.ui.isNotNullOrBlank
|
||||||
import com.github.damontecres.wholphin.ui.nav.Destination
|
import com.github.damontecres.wholphin.ui.nav.Destination
|
||||||
|
import com.github.damontecres.wholphin.ui.serverSupportedMessage
|
||||||
import com.github.damontecres.wholphin.ui.tryRequestFocus
|
import com.github.damontecres.wholphin.ui.tryRequestFocus
|
||||||
import com.github.damontecres.wholphin.util.LoadingState
|
import com.github.damontecres.wholphin.util.LoadingState
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
@ -183,37 +183,15 @@ fun SwitchUserContent(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
when (state.serverVersionSupported) {
|
val resources = LocalResources.current
|
||||||
ServerVersionSupported.SUPPORTED -> {}
|
val message =
|
||||||
|
remember(resources, state.serverVersionSupported) {
|
||||||
ServerVersionSupported.NOT_SUPPORTED,
|
resources.serverSupportedMessage(
|
||||||
ServerVersionSupported.UNKNOWN,
|
state.serverVersionSupported,
|
||||||
-> {
|
state.serverVersion,
|
||||||
val resources = LocalResources.current
|
|
||||||
val message =
|
|
||||||
remember(resources) {
|
|
||||||
if (state.serverVersion.isNotNullOrBlank()) {
|
|
||||||
resources.getString(R.string.server_version_not_supported) + ": ${state.serverVersion}"
|
|
||||||
} else {
|
|
||||||
resources.getString(R.string.server_version_not_supported) + ": " +
|
|
||||||
resources.getString(R.string.unknown)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Text(
|
|
||||||
text = message,
|
|
||||||
color = MaterialTheme.colorScheme.error,
|
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
maxLines = 2,
|
|
||||||
overflow = TextOverflow.Ellipsis,
|
|
||||||
modifier =
|
|
||||||
Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(start = 32.dp, end = 32.dp, bottom = 32.dp)
|
|
||||||
.align(Alignment.BottomCenter),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
SwitchErrorMessage(message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -300,16 +300,18 @@ class SwitchUserViewModel
|
||||||
knownUsers + publicUsers
|
knownUsers + publicUsers
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun checkServerVersion(): Pair<String?, ServerVersionSupported> {
|
private suspend fun checkServerVersion(): Pair<ServerVersion?, ServerVersionSupported> {
|
||||||
val api = jellyfin.createApi(server.url)
|
val api = jellyfin.createApi(server.url)
|
||||||
val systemInfo by api.systemApi.getPublicSystemInfo()
|
val systemInfo by api.systemApi.getPublicSystemInfo()
|
||||||
val serverVersion = systemInfo.version?.let { ServerVersion.fromString(it) }
|
val serverVersion = systemInfo.version?.let { ServerVersion.fromString(it) }
|
||||||
return if (serverVersion == null) {
|
return if (serverVersion == null) {
|
||||||
systemInfo.version to ServerVersionSupported.UNKNOWN
|
serverVersion to ServerVersionSupported.UNKNOWN
|
||||||
} else if (serverVersion < WholphinApplication.minimumServerVersion) {
|
} else if (serverVersion < WholphinApplication.minimumServerVersion) {
|
||||||
systemInfo.version to ServerVersionSupported.NOT_SUPPORTED
|
serverVersion to ServerVersionSupported.NOT_SUPPORTED
|
||||||
|
} else if (serverVersion < WholphinApplication.newMinimumServerVersion) {
|
||||||
|
serverVersion to ServerVersionSupported.NOT_SUPPORTED_IN_FUTURE
|
||||||
} else {
|
} else {
|
||||||
systemInfo.version to ServerVersionSupported.SUPPORTED
|
serverVersion to ServerVersionSupported.SUPPORTED
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -341,7 +343,7 @@ data class SwitchUserState(
|
||||||
// LoadingState for while adding/switching users
|
// LoadingState for while adding/switching users
|
||||||
val switchUserState: LoadingState = LoadingState.Pending,
|
val switchUserState: LoadingState = LoadingState.Pending,
|
||||||
val loginAttempts: Int = 0,
|
val loginAttempts: Int = 0,
|
||||||
val serverVersion: String? = null,
|
val serverVersion: ServerVersion? = null,
|
||||||
val serverVersionSupported: ServerVersionSupported = ServerVersionSupported.UNKNOWN,
|
val serverVersionSupported: ServerVersionSupported = ServerVersionSupported.UNKNOWN,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -932,6 +932,8 @@
|
||||||
<string name="books">Books</string>
|
<string name="books">Books</string>
|
||||||
<string name="audio_books">Audio books</string>
|
<string name="audio_books">Audio books</string>
|
||||||
<string name="server_version_not_supported">Server version not supported</string>
|
<string name="server_version_not_supported">Server version not supported</string>
|
||||||
|
<string name="server_version_not_supported_future">Server version will not be supported soon</string>
|
||||||
|
<string name="server_version_required">Required server version: %1$s</string>
|
||||||
<string name="appears_on">Appears on</string>
|
<string name="appears_on">Appears on</string>
|
||||||
<string name="dim_after_delay">Dim screen after delay</string>
|
<string name="dim_after_delay">Dim screen after delay</string>
|
||||||
<string name="dim_percentage">Dim percentage</string>
|
<string name="dim_percentage">Dim percentage</string>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue