Update style for ktlint 1.8 (#390)

Updated `ktlint`, so lots of code style changes, no user facing changes
This commit is contained in:
damontecres 2025-12-06 18:11:07 -05:00 committed by GitHub
parent e9c54adaba
commit 9e7742034a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
54 changed files with 577 additions and 196 deletions

View file

@ -199,7 +199,10 @@ class MainActivity : AppCompatActivity() {
val initialDestination =
when {
current != null -> Destination.Home()
!appPreferences.signInAutomatically -> Destination.ServerList // TODO user list?
!appPreferences.signInAutomatically -> Destination.ServerList
// TODO user list?
else -> Destination.ServerList
}
val backStack = rememberNavBackStack(initialDestination)

View file

@ -81,15 +81,18 @@ data class BaseItem(
} ?: Destination.MediaItem(id, type, this)
}
BaseItemKind.SEASON ->
BaseItemKind.SEASON -> {
Destination.SeriesOverview(
data.seriesId!!,
BaseItemKind.SERIES,
this,
SeasonEpisodeIds(id, indexNumber, null, null),
)
}
else -> Destination.MediaItem(id, type, this)
else -> {
Destination.MediaItem(id, type, this)
}
}
return result
}

View file

@ -106,6 +106,7 @@ data class GetItemsFilter(
-> null
FilterVideoType.BLU_RAY -> VideoType.BLU_RAY
FilterVideoType.DVD -> VideoType.DVD
}
}

View file

@ -136,12 +136,13 @@ fun chooseSubtitleStream(
}
}
SubtitlePlaybackMode.ONLY_FORCED ->
SubtitlePlaybackMode.ONLY_FORCED -> {
if (subtitleLanguage != null) {
candidates.firstOrNull { it.language == subtitleLanguage && it.isForced }
} else {
candidates.firstOrNull { it.isForced }
}
}
SubtitlePlaybackMode.SMART -> {
val audioLanguage = prefs.userConfig.audioLanguagePreference
@ -161,7 +162,9 @@ fun chooseSubtitleStream(
)
}
SubtitlePlaybackMode.NONE -> null
SubtitlePlaybackMode.NONE -> {
null
}
}
}
}

View file

@ -76,7 +76,7 @@ class ImageUrlService
}
}
else ->
else -> {
getItemImageUrl(
itemId = itemId,
imageType = imageType,
@ -84,6 +84,7 @@ class ImageUrlService
fillHeight = fillHeight,
)
}
}
fun getItemImageUrl(
item: BaseItem?,

View file

@ -138,7 +138,7 @@ class PlaylistCreator
BaseItemKind.BOX_SET,
BaseItemKind.COLLECTION_FOLDER,
BaseItemKind.USER_VIEW,
->
-> {
PlaylistCreationResult.Success(
createFromCollection(
item = item,
@ -152,6 +152,7 @@ class PlaylistCreator
filter = filter,
),
)
}
BaseItemKind.EPISODE -> {
val seriesId = item.seriesId
@ -185,7 +186,7 @@ class PlaylistCreator
}
}
BaseItemKind.SERIES ->
BaseItemKind.SERIES -> {
PlaylistCreationResult.Success(
createFromEpisode(
seriesId = item.id,
@ -194,8 +195,9 @@ class PlaylistCreator
shuffled = shuffled,
),
)
}
BaseItemKind.PLAYLIST ->
BaseItemKind.PLAYLIST -> {
PlaylistCreationResult.Success(
createFromPlaylistId(
item.id,
@ -203,6 +205,7 @@ class PlaylistCreator
shuffled,
),
)
}
// Not support yet
// BaseItemKind.AGGREGATE_FOLDER -> TODO()
@ -212,7 +215,9 @@ class PlaylistCreator
// BaseItemKind.MUSIC_ALBUM -> TODO()
// BaseItemKind.MUSIC_ARTIST -> TODO()
else -> PlaylistCreationResult.Error(null, "Unsupported type: ${item.type}")
else -> {
PlaylistCreationResult.Error(null, "Unsupported type: ${item.type}")
}
}
suspend fun getServerPlaylists(

View file

@ -85,9 +85,13 @@ class ThemeSongPlayer
-> return
ThemeSongVolume.LOWEST -> .05f
ThemeSongVolume.LOW -> .1f
ThemeSongVolume.MEDIUM -> .25f
ThemeSongVolume.HIGH -> .5f
ThemeSongVolume.HIGHEST -> 75f
}
player.apply {

View file

@ -62,7 +62,7 @@ class TrailerService
navigateTo: (Destination) -> Unit,
) {
when (trailer) {
is LocalTrailer ->
is LocalTrailer -> {
navigateTo.invoke(
Destination.Playback(
itemId = trailer.baseItem.id,
@ -70,6 +70,7 @@ class TrailerService
positionMs = 0L,
),
)
}
is RemoteTrailer -> {
val intent = Intent(Intent.ACTION_VIEW, trailer.url.toUri())

View file

@ -299,6 +299,7 @@ class UpdateChecker
fun hasPermissions(): Boolean =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q ||
(
ContextCompat.checkSelfPermission(
context,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
@ -307,6 +308,7 @@ class UpdateChecker
context,
Manifest.permission.READ_EXTERNAL_STORAGE,
) == PackageManager.PERMISSION_GRANTED
)
/**
* Delete previously downloaded APKs

View file

@ -352,11 +352,12 @@ class CollectionFolderViewModel
FavoriteFilter,
PlayedFilter,
->
-> {
listOf(
FilterValueOption("True", null),
FilterValueOption("False", null),
)
}
OfficialRatingFilter -> {
api.localizationApi.getParentalRatings().content.map {
@ -364,10 +365,11 @@ class CollectionFolderViewModel
}
}
VideoTypeFilter ->
VideoTypeFilter -> {
FilterVideoType.entries.map {
FilterValueOption(it.readable, it)
}
}
YearFilter -> {
api.yearsApi
@ -400,11 +402,12 @@ class CollectionFolderViewModel
items.toList().sorted().map { FilterValueOption("$it's", it) }
}
CommunityRatingFilter ->
CommunityRatingFilter -> {
(1..10).map {
FilterValueOption("$it", it)
}
}
}
} catch (ex: Exception) {
Timber.e(ex, "Exception get filter value options for $filterOption")
listOf()
@ -418,7 +421,6 @@ class CollectionFolderViewModel
CollectionType.MOVIES -> listOf(BaseItemKind.MOVIE)
CollectionType.TVSHOWS -> listOf(BaseItemKind.SERIES)
CollectionType.HOMEVIDEOS -> listOf(BaseItemKind.VIDEO)
else -> listOf()
}
val request =
@ -535,10 +537,16 @@ fun CollectionFolderGrid(
val playlistState by playlistViewModel.playlistState.observeAsState(PlaylistLoadingState.Pending)
when (val state = loading) {
is LoadingState.Error -> ErrorMessage(state)
is LoadingState.Error -> {
ErrorMessage(state)
}
LoadingState.Loading,
LoadingState.Pending,
-> LoadingPage()
-> {
LoadingPage()
}
LoadingState.Success -> {
pager?.let { pager ->
Box(modifier = modifier) {
@ -920,18 +928,35 @@ data class CollectionFolderGridParameters(
val CollectionType.baseItemKinds: List<BaseItemKind>
get() =
when (this) {
CollectionType.MOVIES -> listOf(BaseItemKind.MOVIE)
CollectionType.TVSHOWS -> listOf(BaseItemKind.SERIES)
CollectionType.HOMEVIDEOS -> listOf(BaseItemKind.VIDEO)
CollectionType.MUSIC ->
CollectionType.MOVIES -> {
listOf(BaseItemKind.MOVIE)
}
CollectionType.TVSHOWS -> {
listOf(BaseItemKind.SERIES)
}
CollectionType.HOMEVIDEOS -> {
listOf(BaseItemKind.VIDEO)
}
CollectionType.MUSIC -> {
listOf(
BaseItemKind.AUDIO,
BaseItemKind.MUSIC_ARTIST,
BaseItemKind.MUSIC_ALBUM,
)
CollectionType.BOXSETS -> listOf(BaseItemKind.BOX_SET)
CollectionType.PLAYLISTS -> listOf(BaseItemKind.PLAYLIST)
else -> listOf()
}
CollectionType.BOXSETS -> {
listOf(BaseItemKind.BOX_SET)
}
CollectionType.PLAYLISTS -> {
listOf(BaseItemKind.PLAYLIST)
}
else -> {
listOf()
}
}

View file

@ -259,9 +259,11 @@ fun DialogPopupContent(
}
items(dialogItems) {
when (it) {
is DialogItemDivider -> HorizontalDivider(Modifier.height(16.dp))
is DialogItemDivider -> {
HorizontalDivider(Modifier.height(16.dp))
}
is DialogItem ->
is DialogItem -> {
ListItem(
selected = false,
enabled = !waiting && it.enabled,
@ -281,6 +283,7 @@ fun DialogPopupContent(
}
}
}
}
}
@Composable

View file

@ -206,7 +206,9 @@ fun FilterByButton(
FavoriteFilter,
PlayedFilter,
-> (currentValue as? Boolean) == value.name.toBoolean()
-> {
(currentValue as? Boolean) == value.name.toBoolean()
}
OfficialRatingFilter -> {
(currentValue as? List<String>)
@ -214,19 +216,23 @@ fun FilterByButton(
.contains(value.name)
}
VideoTypeFilter ->
VideoTypeFilter -> {
(currentValue as? List<FilterVideoType>)
.orEmpty()
.contains(value.value)
}
YearFilter,
DecadeFilter,
->
-> {
(currentValue as? List<Int>)
.orEmpty()
.contains(value.value)
}
CommunityRatingFilter -> (currentValue as? Int) == value.value
CommunityRatingFilter -> {
(currentValue as? Int) == value.value
}
}
}
val interactionSource = remember { MutableInteractionSource() }
@ -328,12 +334,13 @@ fun FilterByButton(
filterOption.set(newValue, current)
}
CommunityRatingFilter ->
CommunityRatingFilter -> {
filterOption.set(
value.value as? Int,
current,
)
}
}
onFilterChange.invoke(newFilter)
if (!filterOption.supportMultiple) {

View file

@ -94,11 +94,15 @@ fun GenreCardGrid(
when (val st = loading) {
LoadingState.Pending,
LoadingState.Loading,
-> LoadingPage(modifier.focusable())
-> {
LoadingPage(modifier.focusable())
}
is LoadingState.Error -> ErrorMessage(st, modifier.focusable())
is LoadingState.Error -> {
ErrorMessage(st, modifier.focusable())
}
LoadingState.Success ->
LoadingState.Success -> {
Box(modifier = modifier) {
LaunchedEffect(Unit) { gridFocusRequester.tryRequestFocus() }
CardGrid(
@ -133,4 +137,5 @@ fun GenreCardGrid(
)
}
}
}
}

View file

@ -94,10 +94,15 @@ fun ItemGrid(
val loading by viewModel.loading.observeAsState(LoadingState.Loading)
val items by viewModel.items.observeAsState(listOf())
when (val state = loading) {
is LoadingState.Error -> ErrorMessage(state)
is LoadingState.Error -> {
ErrorMessage(state)
}
LoadingState.Loading,
LoadingState.Pending,
-> LoadingPage()
-> {
LoadingPage()
}
LoadingState.Success -> {
val focusRequester = remember { FocusRequester() }

View file

@ -59,22 +59,24 @@ fun LoadingRow(
},
) {
when (val r = state) {
is RowLoadingState.Error ->
is RowLoadingState.Error -> {
LoadingRowPlaceholder(
title = title,
message = r.localizedMessage,
messageColor = MaterialTheme.colorScheme.error,
modifier = Modifier,
)
}
RowLoadingState.Pending,
RowLoadingState.Loading,
->
-> {
LoadingRowPlaceholder(
title = title,
message = stringResource(R.string.loading),
modifier = modifier,
)
}
is RowLoadingState.Success -> {
if (r.items.isNotEmpty()) {

View file

@ -256,8 +256,9 @@ fun StarRating(
if (playSoundOnFocus) playOnClickSound(context)
val newRating100 =
when (precision) {
StarRatingPrecision.FULL ->
StarRatingPrecision.FULL -> {
if (i == 1 && rating100 > 0 && rating100 <= 20) 0 else i * 20
}
StarRatingPrecision.HALF -> {
if (rating100 > i * 20) {

View file

@ -127,13 +127,17 @@ fun RecommendedContent(
val rows by viewModel.rows.collectAsState()
when (val state = loading) {
is LoadingState.Error -> ErrorMessage(state)
is LoadingState.Error -> {
ErrorMessage(state)
}
LoadingState.Loading,
LoadingState.Pending,
-> LoadingPage()
-> {
LoadingPage()
}
LoadingState.Success ->
LoadingState.Success -> {
HomePageContent(
homeRows = rows,
onClickItem = { _, item ->
@ -147,6 +151,7 @@ fun RecommendedContent(
modifier = modifier,
)
}
}
moreDialog.compose { (position, item) ->
DialogPopup(
showDialog = true,

View file

@ -128,22 +128,26 @@ fun SliderActiveColor(focused: Boolean): Color {
AppThemeColors.BLUE,
AppThemeColors.GREEN,
AppThemeColors.ORANGE,
-> MaterialTheme.colorScheme.border
-> {
MaterialTheme.colorScheme.border
}
AppThemeColors.BOLD_BLUE ->
AppThemeColors.BOLD_BLUE -> {
if (focused) {
MaterialTheme.colorScheme.border
} else {
MaterialTheme.colorScheme.border
}
}
AppThemeColors.OLED_BLACK ->
AppThemeColors.OLED_BLACK -> {
if (focused) {
MaterialTheme.colorScheme.primaryContainer
} else {
MaterialTheme.colorScheme.border
}
}
}
}
@Composable
@ -152,23 +156,27 @@ fun SliderInactiveColor(focused: Boolean): Color {
return when (theme) {
AppThemeColors.UNRECOGNIZED,
AppThemeColors.PURPLE,
->
-> {
MaterialTheme.colorScheme.border
.copy(alpha = .25f)
.compositeOver(MaterialTheme.colorScheme.surfaceVariant)
.copy(alpha = .66f)
}
AppThemeColors.BLUE,
AppThemeColors.GREEN,
AppThemeColors.ORANGE,
AppThemeColors.BOLD_BLUE,
-> MaterialTheme.colorScheme.secondaryContainer.copy(alpha = .66f)
-> {
MaterialTheme.colorScheme.secondaryContainer.copy(alpha = .66f)
}
AppThemeColors.OLED_BLACK ->
AppThemeColors.OLED_BLACK -> {
if (focused) {
MaterialTheme.colorScheme.tertiaryContainer
} else {
MaterialTheme.colorScheme.primaryContainer
}
}
}
}

View file

@ -260,9 +260,11 @@ fun formatVideoRange(
when (videoRange) {
VideoRange.UNKNOWN,
VideoRange.SDR, null,
-> null
-> {
null
}
VideoRange.HDR ->
VideoRange.HDR -> {
when (type) {
VideoRangeType.UNKNOWN,
VideoRangeType.SDR,
@ -270,7 +272,9 @@ fun formatVideoRange(
-> null
VideoRangeType.HDR10 -> "HDR10"
VideoRangeType.HDR10_PLUS -> "HDR10+"
VideoRangeType.HLG -> "HLG"
VideoRangeType.DOVI,
@ -280,6 +284,7 @@ fun formatVideoRange(
-> context.getString(R.string.dolby_vision)
}
}
}
fun formatAudioCodec(
context: Context,
@ -287,21 +292,33 @@ fun formatAudioCodec(
profile: String?,
): String? =
when {
profile?.contains("Dolby Atmos", true) == true -> context.getString(R.string.dolby_atmos)
profile?.contains("DTS:X", true) == true -> "DTS:X"
profile?.contains("DTS:HD", true) == true -> "DTS:HD"
else ->
profile?.contains("Dolby Atmos", true) == true -> {
context.getString(R.string.dolby_atmos)
}
profile?.contains("DTS:X", true) == true -> {
"DTS:X"
}
profile?.contains("DTS:HD", true) == true -> {
"DTS:HD"
}
else -> {
when (codec?.lowercase()) {
Codec.Audio.TRUEHD -> "TrueHD"
Codec.Audio.OGG,
Codec.Audio.OPUS,
Codec.Audio.VORBIS,
-> codec.replaceFirstChar { it.uppercase() }
null -> null
else -> codec.uppercase()
}
}
}
fun formatSubtitleCodec(codec: String?): String? =
when (codec?.lowercase()) {

View file

@ -107,7 +107,9 @@ fun getStringRes(sort: ItemSortBy): Int =
-> R.string.sort_by_name
ItemSortBy.PREMIERE_DATE -> R.string.sort_by_date_released
ItemSortBy.DATE_CREATED -> R.string.sort_by_date_added
ItemSortBy.DATE_LAST_CONTENT_ADDED -> R.string.sort_by_date_episode_added
ItemSortBy.DATE_PLAYED,
@ -115,12 +117,20 @@ fun getStringRes(sort: ItemSortBy): Int =
-> R.string.sort_by_date_played
ItemSortBy.RANDOM -> R.string.sort_by_random
ItemSortBy.COMMUNITY_RATING -> R.string.community_rating
ItemSortBy.CRITIC_RATING -> R.string.critic_rating
ItemSortBy.OFFICIAL_RATING -> R.string.official_rating
ItemSortBy.PLAY_COUNT -> R.string.play_count
ItemSortBy.AIRED_EPISODE_ORDER -> R.string.aired_episode_order
ItemSortBy.RUNTIME -> R.string.runtime_sort
ItemSortBy.DEFAULT -> R.string.default_track
else -> throw IllegalArgumentException("Unsupported sort option: $sort")
}

View file

@ -144,6 +144,7 @@ fun CollectionFolderLiveTv(
.focusRequester(focusRequester),
)
}
1 -> {
DvrSchedule(
true,

View file

@ -104,6 +104,7 @@ fun CollectionFolderMovie(
.focusRequester(focusRequester),
)
}
// Library
1 -> {
CollectionFolderGrid(
@ -131,6 +132,7 @@ fun CollectionFolderMovie(
playEnabled = true,
)
}
// Collections
2 -> {
CollectionFolderGrid(
@ -158,6 +160,7 @@ fun CollectionFolderMovie(
playEnabled = false,
)
}
// Genres
3 -> {
GenreCardGrid(
@ -169,7 +172,10 @@ fun CollectionFolderMovie(
.focusRequester(focusRequester),
)
}
else -> ErrorMessage("Invalid tab index $selectedTabIndex", null)
else -> {
ErrorMessage("Invalid tab index $selectedTabIndex", null)
}
}
}
}

View file

@ -107,6 +107,7 @@ fun CollectionFolderTv(
.focusRequester(focusRequester),
)
}
// Library
1 -> {
CollectionFolderGrid(
@ -134,6 +135,7 @@ fun CollectionFolderTv(
playEnabled = false,
)
}
// Genres
2 -> {
GenreCardGrid(
@ -145,7 +147,10 @@ fun CollectionFolderTv(
.focusRequester(focusRequester),
)
}
else -> ErrorMessage("Invalid tab index $selectedTabIndex", null)
else -> {
ErrorMessage("Invalid tab index $selectedTabIndex", null)
}
}
}
}

View file

@ -136,6 +136,7 @@ fun FavoritesPage(
filterOptions = DefaultForFavoritesFilterOptions,
)
}
// TV
1 -> {
CollectionFolderGrid(
@ -163,6 +164,7 @@ fun FavoritesPage(
filterOptions = DefaultForFavoritesFilterOptions,
)
}
// Episodes
2 -> {
CollectionFolderGrid(
@ -191,6 +193,7 @@ fun FavoritesPage(
filterOptions = DefaultForFavoritesFilterOptions,
)
}
// Videos
3 -> {
CollectionFolderGrid(
@ -218,6 +221,7 @@ fun FavoritesPage(
filterOptions = DefaultForFavoritesFilterOptions,
)
}
// Playlists
4 -> {
CollectionFolderGrid(
@ -245,6 +249,7 @@ fun FavoritesPage(
filterOptions = DefaultForFavoritesFilterOptions,
)
}
// People
5 -> {
CollectionFolderGrid(
@ -277,7 +282,10 @@ fun FavoritesPage(
filterOptions = listOf(),
)
}
else -> ErrorMessage("Invalid tab index $selectedTabIndex", null)
else -> {
ErrorMessage("Invalid tab index $selectedTabIndex", null)
}
}
}
}

View file

@ -178,10 +178,15 @@ fun PersonPage(
val loading by viewModel.loading.observeAsState(LoadingState.Loading)
when (val state = loading) {
is LoadingState.Error -> ErrorMessage(state, modifier)
is LoadingState.Error -> {
ErrorMessage(state, modifier)
}
LoadingState.Loading,
LoadingState.Pending,
-> LoadingPage(modifier)
-> {
LoadingPage(modifier)
}
LoadingState.Success -> {
person?.let { person ->

View file

@ -130,9 +130,15 @@ fun PlaylistDetails(
var longClickDialog by remember { mutableStateOf<DialogParams?>(null) }
when (val st = loading) {
is LoadingState.Error -> ErrorMessage(st, modifier)
LoadingState.Pending, LoadingState.Loading -> LoadingPage(modifier)
LoadingState.Success ->
is LoadingState.Error -> {
ErrorMessage(st, modifier)
}
LoadingState.Pending, LoadingState.Loading -> {
LoadingPage(modifier)
}
LoadingState.Success -> {
playlist?.let {
val focusRequester = remember { FocusRequester() }
LaunchedEffect(Unit) { focusRequester.tryRequestFocus() }
@ -190,6 +196,7 @@ fun PlaylistDetails(
)
}
}
}
longClickDialog?.let { params ->
DialogPopup(
params = params,

View file

@ -216,7 +216,7 @@ fun PlaylistDialog(
when (val s = state) {
PlaylistLoadingState.Pending,
PlaylistLoadingState.Loading,
->
-> {
CircularProgressIndicator(
color = MaterialTheme.colorScheme.border,
modifier =
@ -224,9 +224,11 @@ fun PlaylistDialog(
.align(Alignment.CenterHorizontally)
.size(48.dp),
)
}
is PlaylistLoadingState.Error ->
is PlaylistLoadingState.Error -> {
ErrorMessage(s.message, s.exception)
}
is PlaylistLoadingState.Success -> {
LaunchedEffect(Unit) { focusRequester.tryRequestFocus() }

View file

@ -102,10 +102,15 @@ fun EpisodeDetails(
)
when (val state = loading) {
is LoadingState.Error -> ErrorMessage(state)
is LoadingState.Error -> {
ErrorMessage(state)
}
LoadingState.Loading,
LoadingState.Pending,
-> LoadingPage()
-> {
LoadingPage()
}
LoadingState.Success -> {
item?.let { ep ->

View file

@ -124,11 +124,15 @@ fun DvrSchedule(
val active by viewModel.active.observeAsState(listOf())
val recordings by viewModel.scheduled.observeAsState(mapOf())
when (val state = loading) {
is LoadingState.Error -> ErrorMessage(state, modifier)
is LoadingState.Error -> {
ErrorMessage(state, modifier)
}
LoadingState.Loading,
LoadingState.Pending,
-> LoadingPage(modifier)
-> {
LoadingPage(modifier)
}
LoadingState.Success -> {
var showDialog by remember { mutableStateOf<BaseItem?>(null) }

View file

@ -76,17 +76,21 @@ fun ProgramDialog(
.padding(16.dp),
) {
when (val st = loading) {
is LoadingState.Error -> ErrorMessage(st)
is LoadingState.Error -> {
ErrorMessage(st)
}
LoadingState.Loading,
LoadingState.Pending,
->
-> {
CircularProgress(
Modifier
.padding(8.dp)
.size(48.dp),
)
}
LoadingState.Success ->
LoadingState.Success -> {
item?.let { item ->
val now = LocalDateTime.now()
val dto = item.data
@ -276,4 +280,5 @@ fun ProgramDialog(
}
}
}
}
}

View file

@ -77,9 +77,14 @@ fun TvGuideGrid(
// val programsByChannel by viewModel.programsByChannel.observeAsState(mapOf())
// val fetchedRange by viewModel.fetchedRange.observeAsState(0..0)
when (val state = loading) {
is LoadingState.Error -> ErrorMessage(state, modifier)
is LoadingState.Error -> {
ErrorMessage(state, modifier)
}
LoadingState.Pending,
-> LoadingPage(modifier)
-> {
LoadingPage(modifier)
}
LoadingState.Loading,
LoadingState.Success,

View file

@ -133,10 +133,16 @@ fun MovieDetails(
)
when (val state = loading) {
is LoadingState.Error -> ErrorMessage(state)
is LoadingState.Error -> {
ErrorMessage(state)
}
LoadingState.Loading,
LoadingState.Pending,
-> LoadingPage()
-> {
LoadingPage()
}
LoadingState.Success -> {
item?.let { movie ->
LifecycleStartEffect(destination.itemId) {
@ -565,7 +571,7 @@ fun TrailerRow(
Modifier
}
when (item) {
is LocalTrailer ->
is LocalTrailer -> {
SeasonCard(
item = item.baseItem,
onClick = { onClickTrailer.invoke(item) },
@ -575,6 +581,7 @@ fun TrailerRow(
showImageOverlay = false,
modifier = cardModifier,
)
}
is RemoteTrailer -> {
val subtitle =

View file

@ -112,10 +112,16 @@ fun SeriesDetails(
val playlistState by playlistViewModel.playlistState.observeAsState(PlaylistLoadingState.Pending)
when (val state = loading) {
is LoadingState.Error -> ErrorMessage(state)
is LoadingState.Error -> {
ErrorMessage(state)
}
LoadingState.Loading,
LoadingState.Pending,
-> LoadingPage()
-> {
LoadingPage()
}
LoadingState.Success -> {
item?.let { item ->
LifecycleStartEffect(destination.itemId) {

View file

@ -175,11 +175,15 @@ fun SeriesOverview(
val chosenStreams by viewModel.chosenStreams.observeAsState(null)
when (val state = loading) {
is LoadingState.Error -> ErrorMessage(state)
is LoadingState.Error -> {
ErrorMessage(state)
}
LoadingState.Loading,
LoadingState.Pending,
-> LoadingPage()
-> {
LoadingPage()
}
LoadingState.Success -> {
series?.let { series ->

View file

@ -172,8 +172,14 @@ fun SeriesOverviewContent(
key(position.seasonTabIndex) {
when (val eps = episodes) {
EpisodeList.Loading -> LoadingPage()
is EpisodeList.Error -> ErrorMessage(eps.message, eps.exception)
EpisodeList.Loading -> {
LoadingPage()
}
is EpisodeList.Error -> {
ErrorMessage(eps.message, eps.exception)
}
is EpisodeList.Success -> {
val state = rememberLazyListState()
OneTimeLaunchedEffect {

View file

@ -107,11 +107,15 @@ fun HomePage(
}
when (val state = loading) {
is LoadingState.Error -> ErrorMessage(state)
is LoadingState.Error -> {
ErrorMessage(state)
}
LoadingState.Loading,
LoadingState.Pending,
-> LoadingPage()
-> {
LoadingPage()
}
LoadingState.Success -> {
var dialog by remember { mutableStateOf<DialogParams?>(null) }
@ -391,7 +395,7 @@ fun HomePageContent(
when (loadingState) {
LoadingState.Pending,
LoadingState.Loading,
->
-> {
Box(
modifier =
Modifier
@ -401,6 +405,7 @@ fun HomePageContent(
) {
CircularProgress(Modifier.fillMaxSize())
}
}
else -> {}
}

View file

@ -325,24 +325,26 @@ fun LazyListScope.searchResultRow(
) {
item {
when (val r = result) {
is SearchResult.Error ->
is SearchResult.Error -> {
SearchResultPlaceholder(
title = title,
message = r.ex.localizedMessage ?: "Error occurred during search",
messageColor = MaterialTheme.colorScheme.error,
modifier = Modifier,
)
}
SearchResult.NoQuery -> {
// no-op
}
SearchResult.Searching ->
SearchResult.Searching -> {
SearchResultPlaceholder(
title = title,
message = stringResource(R.string.searching),
modifier = modifier,
)
}
is SearchResult.Success -> {
if (r.items.isEmpty()) {

View file

@ -44,70 +44,84 @@ fun DestinationContent(
modifier: Modifier = Modifier,
) {
when (destination) {
is Destination.Home ->
is Destination.Home -> {
HomePage(
preferences = preferences,
modifier = modifier,
)
}
is Destination.PlaybackList,
is Destination.Playback,
->
-> {
PlaybackPage(
preferences = preferences,
destination = destination,
modifier = modifier,
)
}
Destination.ServerList -> SwitchServerContent(modifier)
is Destination.UserList -> SwitchUserContent(destination.server, modifier)
Destination.ServerList -> {
SwitchServerContent(modifier)
}
is Destination.Settings ->
is Destination.UserList -> {
SwitchUserContent(destination.server, modifier)
}
is Destination.Settings -> {
PreferencesPage(
preferences.appPreferences,
destination.screen,
modifier,
)
}
is Destination.SeriesOverview ->
is Destination.SeriesOverview -> {
SeriesOverview(
preferences,
destination,
modifier,
initialSeasonEpisode = destination.seasonEpisode,
)
}
is Destination.MediaItem ->
is Destination.MediaItem -> {
when (destination.type) {
BaseItemKind.SERIES ->
BaseItemKind.SERIES -> {
SeriesDetails(
preferences,
destination,
modifier,
)
}
BaseItemKind.MOVIE ->
BaseItemKind.MOVIE -> {
MovieDetails(
preferences,
destination,
modifier,
)
}
BaseItemKind.VIDEO ->
BaseItemKind.VIDEO -> {
// TODO Use VideoDetails
MovieDetails(
preferences,
destination,
modifier,
)
}
BaseItemKind.EPISODE ->
BaseItemKind.EPISODE -> {
EpisodeDetails(
preferences,
destination,
modifier,
)
}
BaseItemKind.BOX_SET ->
BaseItemKind.BOX_SET -> {
CollectionFolderBoxSet(
preferences = preferences,
itemId = destination.itemId,
@ -116,14 +130,16 @@ fun DestinationContent(
playEnabled = true,
modifier = modifier,
)
}
BaseItemKind.PLAYLIST ->
BaseItemKind.PLAYLIST -> {
PlaylistDetails(
destination = destination,
modifier = modifier,
)
}
BaseItemKind.COLLECTION_FOLDER ->
BaseItemKind.COLLECTION_FOLDER -> {
CollectionFolder(
preferences = preferences,
destination = destination,
@ -132,8 +148,9 @@ fun DestinationContent(
recursiveOverride = null,
modifier = modifier,
)
}
BaseItemKind.FOLDER ->
BaseItemKind.FOLDER -> {
CollectionFolder(
preferences = preferences,
destination = destination,
@ -142,8 +159,9 @@ fun DestinationContent(
recursiveOverride = null,
modifier = modifier,
)
}
BaseItemKind.USER_VIEW ->
BaseItemKind.USER_VIEW -> {
CollectionFolder(
preferences = preferences,
destination = destination,
@ -152,21 +170,24 @@ fun DestinationContent(
recursiveOverride = true,
modifier = modifier,
)
}
BaseItemKind.PERSON ->
BaseItemKind.PERSON -> {
PersonPage(
preferences,
destination,
modifier,
)
}
else -> {
Timber.w("Unsupported item type: ${destination.type}")
Text("Unsupported item type: ${destination.type}")
}
}
}
is Destination.FilteredCollection ->
is Destination.FilteredCollection -> {
CollectionFolderGeneric(
preferences = preferences,
itemId = destination.itemId,
@ -177,38 +198,49 @@ fun DestinationContent(
filterOptions = DefaultForGenresFilterOptions,
modifier = modifier,
)
}
is Destination.Recordings ->
is Destination.Recordings -> {
CollectionFolderRecordings(
preferences,
destination.itemId,
false,
modifier,
)
}
is Destination.ItemGrid ->
is Destination.ItemGrid -> {
ItemGrid(
destination,
modifier,
)
}
Destination.Favorites ->
Destination.Favorites -> {
FavoritesPage(
preferences = preferences,
modifier = modifier,
)
}
Destination.UpdateApp -> InstallUpdatePage(preferences, modifier)
Destination.UpdateApp -> {
InstallUpdatePage(preferences, modifier)
}
Destination.License -> LicenseInfo(modifier)
Destination.License -> {
LicenseInfo(modifier)
}
Destination.Search ->
Destination.Search -> {
SearchPage(
userPreferences = preferences,
modifier = modifier,
)
}
Destination.Debug -> DebugPage(preferences, modifier)
Destination.Debug -> {
DebugPage(preferences, modifier)
}
}
}
@ -222,21 +254,23 @@ fun CollectionFolder(
modifier: Modifier = Modifier,
) {
when (collectionType) {
CollectionType.TVSHOWS ->
CollectionType.TVSHOWS -> {
CollectionFolderTv(
preferences,
destination,
modifier,
)
}
CollectionType.MOVIES ->
CollectionType.MOVIES -> {
CollectionFolderMovie(
preferences,
destination,
modifier,
)
}
CollectionType.BOXSETS ->
CollectionType.BOXSETS -> {
CollectionFolderGeneric(
preferences = preferences,
itemId = destination.itemId,
@ -246,8 +280,9 @@ fun CollectionFolder(
modifier = modifier,
sortOptions = MovieSortOptions,
)
}
CollectionType.PLAYLISTS ->
CollectionType.PLAYLISTS -> {
CollectionFolderPlaylist(
preferences,
destination.itemId,
@ -255,20 +290,22 @@ fun CollectionFolder(
true,
modifier,
)
}
CollectionType.LIVETV ->
CollectionType.LIVETV -> {
CollectionFolderLiveTv(
preferences = preferences,
destination = destination,
modifier = modifier,
)
}
CollectionType.HOMEVIDEOS,
CollectionType.MUSICVIDEOS,
CollectionType.MUSIC,
CollectionType.BOOKS,
CollectionType.PHOTOS,
->
-> {
CollectionFolderGeneric(
preferences,
destination.itemId,
@ -277,12 +314,13 @@ fun CollectionFolder(
playEnabled = true,
modifier = modifier,
)
}
CollectionType.FOLDERS,
CollectionType.TRAILERS,
CollectionType.UNKNOWN,
null,
->
-> {
CollectionFolderGeneric(
preferences,
destination.itemId,
@ -292,4 +330,5 @@ fun CollectionFolder(
modifier = modifier,
)
}
}
}

View file

@ -598,10 +598,15 @@ fun NavigationDrawerScope.NavItem(
val useFont = library !is ServerNavDrawerItem || library.type != CollectionType.LIVETV
val icon =
when (library) {
NavDrawerItem.Favorites -> R.string.fa_heart
NavDrawerItem.More -> R.string.fa_ellipsis
NavDrawerItem.Favorites -> {
R.string.fa_heart
}
is ServerNavDrawerItem ->
NavDrawerItem.More -> {
R.string.fa_ellipsis
}
is ServerNavDrawerItem -> {
when (library.type) {
CollectionType.MOVIES -> R.string.fa_film
CollectionType.TVSHOWS -> R.string.fa_tv
@ -613,6 +618,7 @@ fun NavigationDrawerScope.NavItem(
else -> R.string.fa_film
}
}
}
val focused by interactionSource.collectIsFocusedAsState()
NavigationDrawerItem(
modifier = modifier,
@ -686,7 +692,7 @@ fun navItemColor(
else -> .2f
}
return when {
selected && focused ->
selected && focused -> {
when (theme) {
AppThemeColors.UNRECOGNIZED,
AppThemeColors.PURPLE,
@ -699,10 +705,19 @@ fun navItemColor(
AppThemeColors.OLED_BLACK,
-> MaterialTheme.colorScheme.primary
}
}
selected -> MaterialTheme.colorScheme.border
focused -> LocalContentColor.current
else -> MaterialTheme.colorScheme.onSurface
selected -> {
MaterialTheme.colorScheme.border
}
focused -> {
LocalContentColor.current
}
else -> {
MaterialTheme.colorScheme.onSurface
}
}.copy(alpha = alpha)
}
}

View file

@ -75,7 +75,9 @@ fun DownloadSubtitlesContent(
}
}
is SubtitleSearch.Error -> Wrapper { ErrorMessage(null, s.ex, modifier) }
is SubtitleSearch.Error -> {
Wrapper { ErrorMessage(null, s.ex, modifier) }
}
is SubtitleSearch.Success -> {
val dialogItems = convertRemoteSubtitles(s.options, onClickDownload)
@ -133,9 +135,11 @@ fun DownloadSubtitlesContent(
) {
itemsIndexed(dialogItems) { index, item ->
when (item) {
is DialogItemDivider -> HorizontalDivider(Modifier.height(16.dp))
is DialogItemDivider -> {
HorizontalDivider(Modifier.height(16.dp))
}
is DialogItem ->
is DialogItem -> {
ListItem(
selected = false,
enabled = item.enabled,
@ -160,6 +164,7 @@ fun DownloadSubtitlesContent(
}
}
}
}
}
@Composable

View file

@ -117,7 +117,7 @@ fun PlaybackDialog(
)
}
PlaybackDialogType.AUDIO ->
PlaybackDialogType.AUDIO -> {
BottomDialog(
choices = settings.audioStreams.map { it.displayName },
currentChoice = settings.audioStreams.indexOfFirstOrNull { it.index == settings.audioIndex },
@ -134,8 +134,9 @@ fun PlaybackDialog(
},
gravity = Gravity.END,
)
}
PlaybackDialogType.PLAYBACK_SPEED ->
PlaybackDialogType.PLAYBACK_SPEED -> {
BottomDialog(
choices = playbackSpeedOptions,
currentChoice = playbackSpeedOptions.indexOf(settings.playbackSpeed.toString()),
@ -152,8 +153,9 @@ fun PlaybackDialog(
},
gravity = Gravity.END,
)
}
PlaybackDialogType.VIDEO_SCALE ->
PlaybackDialogType.VIDEO_SCALE -> {
BottomDialog(
choices = playbackScaleOptions.values.toList(),
currentChoice = playbackScaleOptions.keys.toList().indexOf(settings.contentScale),
@ -171,4 +173,5 @@ fun PlaybackDialog(
gravity = Gravity.END,
)
}
}
}

View file

@ -94,14 +94,29 @@ class PlaybackKeyHandler(
updateSkipIndicator(-seekBack.inWholeMilliseconds)
}
Key.MediaNext -> if (player.isCommandAvailable(Player.COMMAND_SEEK_TO_NEXT)) player.seekToNext()
Key.MediaPrevious -> if (player.isCommandAvailable(Player.COMMAND_SEEK_TO_PREVIOUS)) player.seekToPrevious()
Key.MediaNext -> {
if (player.isCommandAvailable(Player.COMMAND_SEEK_TO_NEXT)) player.seekToNext()
}
Key.Captions -> onPlaybackDialogTypeClick.invoke(PlaybackDialogType.CAPTIONS)
Key.MediaAudioTrack -> onPlaybackDialogTypeClick.invoke(PlaybackDialogType.AUDIO)
Key.MediaStop -> onStop.invoke()
Key.MediaPrevious -> {
if (player.isCommandAvailable(Player.COMMAND_SEEK_TO_PREVIOUS)) player.seekToPrevious()
}
else -> result = false
Key.Captions -> {
onPlaybackDialogTypeClick.invoke(PlaybackDialogType.CAPTIONS)
}
Key.MediaAudioTrack -> {
onPlaybackDialogTypeClick.invoke(PlaybackDialogType.AUDIO)
}
Key.MediaStop -> {
onStop.invoke()
}
else -> {
result = false
}
}
} else if (isEnterKey(it) && !controllerViewState.controlsVisible) {
controllerViewState.showControls()

View file

@ -183,7 +183,7 @@ fun PlaybackOverlay(
// Don't use key events because this control has vertical items so up/down is tough to manage
)
when (nextState) {
OverlayViewState.CHAPTERS ->
OverlayViewState.CHAPTERS -> {
Text(
text = stringResource(R.string.chapters),
style = MaterialTheme.typography.titleLarge,
@ -194,8 +194,9 @@ fun PlaybackOverlay(
if (it.isFocused) state = nextState
}.focusable(),
)
}
OverlayViewState.QUEUE ->
OverlayViewState.QUEUE -> {
Text(
text = stringResource(R.string.queue),
style = MaterialTheme.typography.titleLarge,
@ -206,8 +207,11 @@ fun PlaybackOverlay(
if (it.isFocused) state = nextState
}.focusable(),
)
}
else -> Spacer(Modifier.height(32.dp))
else -> {
Spacer(Modifier.height(32.dp))
}
}
}
}

View file

@ -109,10 +109,15 @@ fun PlaybackPage(
val loading by viewModel.loading.observeAsState(LoadingState.Loading)
when (val st = loading) {
is LoadingState.Error -> ErrorMessage(st, modifier)
is LoadingState.Error -> {
ErrorMessage(st, modifier)
}
LoadingState.Pending,
LoadingState.Loading,
-> LoadingPage(modifier.background(Color.Black))
-> {
LoadingPage(modifier.background(Color.Black))
}
LoadingState.Success -> {
val prefs = preferences.appPreferences.playbackPreferences
@ -177,7 +182,7 @@ fun PlaybackPage(
}
var skipPosition by remember { mutableLongStateOf(0L) }
val updateSkipIndicator = { delta: Long ->
if (skipIndicatorDuration > 0 && delta < 0 || skipIndicatorDuration < 0 && delta > 0) {
if ((skipIndicatorDuration > 0 && delta < 0) || (skipIndicatorDuration < 0 && delta > 0)) {
skipIndicatorDuration = 0
}
skipIndicatorDuration += delta
@ -216,8 +221,14 @@ fun PlaybackPage(
showDebugInfo = !showDebugInfo
}
PlaybackAction.ShowPlaylist -> TODO()
PlaybackAction.ShowVideoFilterDialog -> TODO()
PlaybackAction.ShowPlaylist -> {
TODO()
}
PlaybackAction.ShowVideoFilterDialog -> {
TODO()
}
is PlaybackAction.ToggleAudio -> {
viewModel.changeAudioStream(it.index)
}

View file

@ -213,7 +213,9 @@ class PlaybackViewModel
d.itemId
}
else -> throw IllegalArgumentException("Destination not supported: $destination")
else -> {
throw IllegalArgumentException("Destination not supported: $destination")
}
}
this.itemId = itemId
viewModelScope.launch(
@ -554,8 +556,11 @@ class PlaybackViewModel
when {
// playerBackend == PlayerBackend.MPV -> PlayMethod.DIRECT_PLAY
source.supportsDirectPlay -> PlayMethod.DIRECT_PLAY
source.supportsDirectStream -> PlayMethod.DIRECT_STREAM
source.supportsTranscoding -> PlayMethod.TRANSCODE
else -> throw Exception("No supported playback method")
}
Timber.v("Playback decision: $transcodeType")
@ -921,13 +926,14 @@ class PlaybackViewModel
viewModelScope.launch(Dispatchers.Main + ExceptionHandler()) {
currentPlayback.value?.let {
when (it.playMethod) {
PlayMethod.TRANSCODE ->
PlayMethod.TRANSCODE -> {
loading.setValueOnMain(
LoadingState.Error(
"Error during playback",
error,
),
)
}
PlayMethod.DIRECT_STREAM, PlayMethod.DIRECT_PLAY -> {
Timber.w("Playback error during ${it.playMethod}, falling back to transcoding")
@ -968,28 +974,45 @@ class PlaybackViewModel
navigationManager.goBack()
}
PlaystateCommand.PAUSE -> player.pause()
PlaystateCommand.UNPAUSE -> player.play()
PlaystateCommand.NEXT_TRACK -> playNextUp()
PlaystateCommand.PREVIOUS_TRACK -> playPrevious()
PlaystateCommand.SEEK ->
PlaystateCommand.PAUSE -> {
player.pause()
}
PlaystateCommand.UNPAUSE -> {
player.play()
}
PlaystateCommand.NEXT_TRACK -> {
playNextUp()
}
PlaystateCommand.PREVIOUS_TRACK -> {
playPrevious()
}
PlaystateCommand.SEEK -> {
it.seekPositionTicks?.ticks?.let {
player.seekTo(
it.inWholeMilliseconds,
)
}
}
PlaystateCommand.REWIND ->
PlaystateCommand.REWIND -> {
player.seekBack(
preferences.appPreferences.playbackPreferences.skipBackMs.milliseconds,
)
}
PlaystateCommand.FAST_FORWARD ->
PlaystateCommand.FAST_FORWARD -> {
player.seekForward(
preferences.appPreferences.playbackPreferences.skipForwardMs.milliseconds,
)
}
PlaystateCommand.PLAY_PAUSE -> if (player.isPlaying) player.pause() else player.play()
PlaystateCommand.PLAY_PAUSE -> {
if (player.isPlaying) player.pause() else player.play()
}
}
}
}

View file

@ -153,8 +153,14 @@ object TrackSelectionUtils {
// TODO MPV could use literal indexes because they are stored in the track format ID
PlayerBackend.MPV -> {
when (type) {
MediaStreamType.VIDEO -> serverIndex - externalSubtitleCount + 1
MediaStreamType.AUDIO -> serverIndex - externalSubtitleCount - videoStreamCount + 1
MediaStreamType.VIDEO -> {
serverIndex - externalSubtitleCount + 1
}
MediaStreamType.AUDIO -> {
serverIndex - externalSubtitleCount - videoStreamCount + 1
}
MediaStreamType.SUBTITLE -> {
if (subtitleIsExternal) {
serverIndex + embeddedSubtitleCount + 1
@ -162,7 +168,10 @@ object TrackSelectionUtils {
serverIndex - externalSubtitleCount - videoStreamCount - audioStreamCount + 1
}
}
else -> throw UnsupportedOperationException("Cannot calculate index for $type")
else -> {
throw UnsupportedOperationException("Cannot calculate index for $type")
}
}
}
}

View file

@ -102,7 +102,7 @@ fun <T> ComposablePreference(
)
}
is AppDestinationPreference ->
is AppDestinationPreference -> {
ClickPreference(
title = title,
onClick = {
@ -112,8 +112,9 @@ fun <T> ComposablePreference(
interactionSource = interactionSource,
modifier = modifier,
)
}
is AppClickablePreference ->
is AppClickablePreference -> {
ClickPreference(
title = title,
onClick = { onClickPreference.invoke(preference) },
@ -122,8 +123,9 @@ fun <T> ComposablePreference(
interactionSource = interactionSource,
modifier = modifier,
)
}
is AppSwitchPreference ->
is AppSwitchPreference -> {
SwitchPreference(
title = title,
value = value as Boolean,
@ -132,8 +134,9 @@ fun <T> ComposablePreference(
interactionSource = interactionSource,
modifier = modifier,
)
}
is AppStringPreference ->
is AppStringPreference -> {
ClickPreference(
title = title,
onClick = {
@ -164,6 +167,7 @@ fun <T> ComposablePreference(
interactionSource = interactionSource,
modifier = modifier,
)
}
is AppChoicePreference -> {
val values = stringArrayResource(preference.displayValues).toList()

View file

@ -456,7 +456,7 @@ fun PreferencesPage(
PreferenceScreenOption.BASIC,
PreferenceScreenOption.ADVANCED,
PreferenceScreenOption.USER_INTERFACE,
->
-> {
PreferencesContent(
initialPreferences,
preferenceScreenOption,
@ -465,13 +465,15 @@ fun PreferencesPage(
.fillMaxHeight()
.align(Alignment.TopEnd),
)
}
PreferenceScreenOption.SUBTITLES ->
PreferenceScreenOption.SUBTITLES -> {
SubtitleStylePage(
initialPreferences,
)
}
}
}
}
data class CacheUsage(

View file

@ -71,17 +71,19 @@ fun SwitchColors(): SwitchColors {
AppThemeColors.UNRECOGNIZED,
AppThemeColors.PURPLE,
AppThemeColors.BLUE,
->
-> {
SwitchDefaults.colors()
}
AppThemeColors.GREEN,
AppThemeColors.ORANGE,
AppThemeColors.BOLD_BLUE,
AppThemeColors.OLED_BLACK,
->
-> {
SwitchDefaults.colors(
checkedThumbColor = MaterialTheme.colorScheme.onPrimary,
uncheckedThumbColor = MaterialTheme.colorScheme.onPrimary,
)
}
}
}

View file

@ -279,7 +279,7 @@ object SubtitleSettings {
val bg = combine(backgroundColor, backgroundOpacity)
return CaptionStyleCompat(
combine(fontColor, fontOpacity),
if (backgroundStyle == BackgroundStyle.BG_WRAP)bg else 0,
if (backgroundStyle == BackgroundStyle.BG_WRAP) bg else 0,
if (backgroundStyle == BackgroundStyle.BG_BOXED) bg else 0,
when (edgeStyle) {
EdgeStyle.EDGE_NONE, EdgeStyle.UNRECOGNIZED -> CaptionStyleCompat.EDGE_TYPE_NONE
@ -355,6 +355,7 @@ object SubtitleSettings {
-> "outline-and-shadow"
BackgroundStyle.BG_WRAP -> "opaque-box"
BackgroundStyle.BG_BOXED -> "background-box"
}
MPVLib.setPropertyString("sub-border-style", borderStyle)

View file

@ -174,10 +174,15 @@ fun InstallUpdatePage(
}
}
when (val state = loading) {
is LoadingState.Error -> ErrorMessage(state, modifier)
is LoadingState.Error -> {
ErrorMessage(state, modifier)
}
LoadingState.Loading,
LoadingState.Pending,
-> LoadingPage(modifier)
-> {
LoadingPage(modifier)
}
LoadingState.Success -> {
release?.let {

View file

@ -72,11 +72,13 @@ fun ServerList(
leadingContent = {
when (status) {
is ServerConnectionStatus.Success -> {}
ServerConnectionStatus.Pending -> {
CircularProgress(
Modifier.size(IconButtonDefaults.MediumIconSize),
)
}
is ServerConnectionStatus.Error -> {
Icon(
imageVector = Icons.Default.Warning,
@ -88,9 +90,15 @@ fun ServerList(
},
onClick = {
when (status) {
is ServerConnectionStatus.Success -> onSwitchServer.invoke(server)
is ServerConnectionStatus.Success -> {
onSwitchServer.invoke(server)
}
ServerConnectionStatus.Pending -> {}
is ServerConnectionStatus.Error -> onTestServer.invoke(server)
is ServerConnectionStatus.Error -> {
onTestServer.invoke(server)
}
}
},
onLongClick = {

View file

@ -30,15 +30,42 @@ data class TrackSupport(
} else {
val type =
when (codecs) {
MimeTypes.TEXT_VTT -> "vtt"
MimeTypes.APPLICATION_VOBSUB -> "vobsub"
MimeTypes.APPLICATION_SUBRIP -> "srt"
MimeTypes.TEXT_SSA -> "ssa"
MimeTypes.APPLICATION_PGS -> "pgs"
MimeTypes.APPLICATION_DVBSUBS -> "dvd"
MimeTypes.APPLICATION_TTML -> "ttml"
MimeTypes.TEXT_UNKNOWN -> "unknown"
null -> "unknown"
MimeTypes.TEXT_VTT -> {
"vtt"
}
MimeTypes.APPLICATION_VOBSUB -> {
"vobsub"
}
MimeTypes.APPLICATION_SUBRIP -> {
"srt"
}
MimeTypes.TEXT_SSA -> {
"ssa"
}
MimeTypes.APPLICATION_PGS -> {
"pgs"
}
MimeTypes.APPLICATION_DVBSUBS -> {
"dvd"
}
MimeTypes.APPLICATION_TTML -> {
"ttml"
}
MimeTypes.TEXT_UNKNOWN -> {
"unknown"
}
null -> {
"unknown"
}
else -> {
val split = codecs.split("/")
if (split.size > 1) split[1] else codecs

View file

@ -70,13 +70,19 @@ fun createDeviceProfile(
) = buildDeviceProfile {
val allowedAudioCodecs =
when {
downMixAudio -> downmixSupportedAudioCodecs
!isAC3Enabled ->
downMixAudio -> {
downmixSupportedAudioCodecs
}
!isAC3Enabled -> {
supportedAudioCodecs
.filterNot { it == Codec.Audio.EAC3 || it == Codec.Audio.AC3 }
.toTypedArray()
}
else -> supportedAudioCodecs
else -> {
supportedAudioCodecs
}
}
val supportsHevc = mediaTest.supportsHevc()
@ -193,8 +199,11 @@ fun createDeviceProfile(
conditions {
when {
!supportsAVC -> ProfileConditionValue.VIDEO_PROFILE equals "none"
else ->
!supportsAVC -> {
ProfileConditionValue.VIDEO_PROFILE equals "none"
}
else -> {
ProfileConditionValue.VIDEO_PROFILE inCollection
listOfNotNull(
"high",
@ -206,6 +215,7 @@ fun createDeviceProfile(
}
}
}
}
if (supportsAVC) {
codecProfile {
type = CodecType.VIDEO
@ -276,8 +286,11 @@ fun createDeviceProfile(
conditions {
when {
!supportsHevc -> ProfileConditionValue.VIDEO_PROFILE equals "none"
else ->
!supportsHevc -> {
ProfileConditionValue.VIDEO_PROFILE equals "none"
}
else -> {
ProfileConditionValue.VIDEO_PROFILE inCollection
listOfNotNull(
"main",
@ -286,6 +299,7 @@ fun createDeviceProfile(
}
}
}
}
if (supportsHevc) {
codecProfile {
type = CodecType.VIDEO