From dc3193e2dcb8327ad9e0ee6dbe8c6d2705342182 Mon Sep 17 00:00:00 2001 From: damontecres <154766448+damontecres@users.noreply.github.com> Date: Sat, 18 Oct 2025 18:45:08 -0400 Subject: [PATCH] Various fixes (#33) Fixes a few issues to prepare for a release. --- README.md | 4 ++ .../wholphin/data/ItemPlaybackRepository.kt | 16 ++++++- .../wholphin/data/JellyfinServer.kt | 15 ++++++- .../wholphin/data/ServerRepository.kt | 3 +- .../damontecres/wholphin/ui/UiConstants.kt | 13 ++++++ .../ui/components/CollectionFolderGrid.kt | 4 +- .../wholphin/ui/components/GenreCardGrid.kt | 4 +- .../ui/components/RecommendedMovie.kt | 10 ++--- .../ui/components/RecommendedTvShow.kt | 12 +++--- .../wholphin/ui/detail/DetailUtils.kt | 9 ++-- .../wholphin/ui/detail/SeriesViewModel.kt | 9 +++- .../wholphin/ui/main/HomeViewModel.kt | 8 ++-- .../wholphin/ui/main/SearchPage.kt | 8 ++-- .../wholphin/ui/playback/PlaybackViewModel.kt | 7 ++-- .../wholphin/ui/setup/SwitchUserContent.kt | 22 ++++++---- .../wholphin/ui/setup/SwitchUserViewModel.kt | 42 +++++++++++-------- app/src/main/res/values/fa_strings.xml | 2 + 17 files changed, 127 insertions(+), 61 deletions(-) diff --git a/README.md b/README.md index 388d6c8b..7b03d2ab 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,10 @@ This is not a fork of the [official client](https://github.com/jellyfin/jellyfin - Subtly show playback position along the bottom of the screen while seeking w/ D-Pad - Force Continue Watching & Next Up TV episodes to use their Series posters +### Roadmap + +See [here for the roadmap](https://github.com/damontecres/Wholphin/wiki#roadmap) + ## Installation Downloader Code: `8668671` diff --git a/app/src/main/java/com/github/damontecres/wholphin/data/ItemPlaybackRepository.kt b/app/src/main/java/com/github/damontecres/wholphin/data/ItemPlaybackRepository.kt index 0a455bf9..27a12d13 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/data/ItemPlaybackRepository.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/data/ItemPlaybackRepository.kt @@ -106,9 +106,21 @@ class ItemPlaybackRepository saveItemPlayback(toSave) } + /** + * Saves the [ItemPlayback] into the database, returning the same object with the rowId updated if needed + */ suspend fun saveItemPlayback(itemPlayback: ItemPlayback): ItemPlayback { - val rowId = itemPlaybackDao.saveItem(itemPlayback) - return itemPlayback.copy(rowId = rowId) + val toSave = + if (itemPlayback.userId < 0) { + val userRowId = + serverRepository.currentUser?.rowId?.takeIf { it >= 0 } + ?: throw IllegalStateException("Trying to save an ItemPlayback without a user, but there is no current user") + itemPlayback.copy(userId = userRowId) + } else { + itemPlayback + } + val id = itemPlaybackDao.saveItem(toSave) + return toSave.copy(rowId = id) } } diff --git a/app/src/main/java/com/github/damontecres/wholphin/data/JellyfinServer.kt b/app/src/main/java/com/github/damontecres/wholphin/data/JellyfinServer.kt index 6451526d..5f00bda7 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/data/JellyfinServer.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/data/JellyfinServer.kt @@ -84,10 +84,23 @@ interface JellyfinServerDao { fun addOrUpdateUser(user: JellyfinUser) { val result = addUser(user) if (result == -1L) { - updateUser(user) + val toSave = + if (user.rowId <= 0) { + val temp = getUser(user.serverId, user.id)!! + user.copy(rowId = temp.rowId) + } else { + user + } + updateUser(toSave) } } + @Query("SELECT * FROM users WHERE serverId = :serverId AND id = :userId") + fun getUser( + serverId: UUID, + userId: UUID, + ): JellyfinUser? + @Query("DELETE FROM servers WHERE id = :serverId") fun deleteServer(serverId: UUID) diff --git a/app/src/main/java/com/github/damontecres/wholphin/data/ServerRepository.kt b/app/src/main/java/com/github/damontecres/wholphin/data/ServerRepository.kt index 1e96f647..d6279eb5 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/data/ServerRepository.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/data/ServerRepository.kt @@ -87,6 +87,8 @@ class ServerRepository id = userDto.id, name = userDto.name, ) + if (updatedUser.rowId <= 0) { + } serverDao.addOrUpdateServer(updatedServer) serverDao.addOrUpdateUser(updatedUser) userPreferencesDataStore.updateData { @@ -119,7 +121,6 @@ class ServerRepository serverDao.getServer(serverId) } if (serverAndUsers != null) { - _currentServer = serverAndUsers.server val user = serverAndUsers.users.firstOrNull { it.id == userId } if (user != null) { changeUser(serverAndUsers.server, user) diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/UiConstants.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/UiConstants.kt index 9f880250..b03d5950 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/UiConstants.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/UiConstants.kt @@ -39,6 +39,19 @@ val DefaultItemFields = ItemFields.TRICKPLAY, ItemFields.SORT_NAME, ItemFields.CHAPTERS, + ItemFields.MEDIA_SOURCES, + ) + +/** + * [ItemFields] for higher level displays such as grids or rows + */ +val SlimItemFields = + listOf( + ItemFields.PRIMARY_IMAGE_ASPECT_RATIO, + ItemFields.SEASON_USER_DATA, + ItemFields.CHILD_COUNT, + ItemFields.OVERVIEW, + ItemFields.SORT_NAME, ) val DefaultButtonPadding = diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/components/CollectionFolderGrid.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/components/CollectionFolderGrid.kt index c771ce57..394ed3ca 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/components/CollectionFolderGrid.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/components/CollectionFolderGrid.kt @@ -29,8 +29,8 @@ import androidx.tv.material3.Text import com.github.damontecres.wholphin.data.model.BaseItem import com.github.damontecres.wholphin.data.model.GetItemsFilter import com.github.damontecres.wholphin.preferences.UserPreferences -import com.github.damontecres.wholphin.ui.DefaultItemFields import com.github.damontecres.wholphin.ui.OneTimeLaunchedEffect +import com.github.damontecres.wholphin.ui.SlimItemFields import com.github.damontecres.wholphin.ui.data.MovieSortOptions import com.github.damontecres.wholphin.ui.data.SeriesSortOptions import com.github.damontecres.wholphin.ui.data.SortAndDirection @@ -135,7 +135,7 @@ class CollectionFolderViewModel SortOrder.ASCENDING, SortOrder.ASCENDING, ), - fields = DefaultItemFields, + fields = SlimItemFields, ), ) val newPager = diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/components/GenreCardGrid.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/components/GenreCardGrid.kt index 7ad6a5ec..94710301 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/components/GenreCardGrid.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/components/GenreCardGrid.kt @@ -16,8 +16,8 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.github.damontecres.wholphin.data.model.BaseItem import com.github.damontecres.wholphin.data.model.GetItemsFilter -import com.github.damontecres.wholphin.ui.DefaultItemFields import com.github.damontecres.wholphin.ui.OneTimeLaunchedEffect +import com.github.damontecres.wholphin.ui.SlimItemFields import com.github.damontecres.wholphin.ui.cards.GridCard import com.github.damontecres.wholphin.ui.detail.CardGrid import com.github.damontecres.wholphin.ui.nav.Destination @@ -54,7 +54,7 @@ class GenreViewModel val request = GetGenresRequest( parentId = itemId, - fields = DefaultItemFields, + fields = SlimItemFields, ) val pager = ApiRequestPager(api, request, GetGenresRequestHandler, viewModelScope).init() withContext(Dispatchers.Main) { diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/components/RecommendedMovie.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/components/RecommendedMovie.kt index 8f643616..d9969914 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/components/RecommendedMovie.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/components/RecommendedMovie.kt @@ -10,8 +10,8 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.github.damontecres.wholphin.data.model.BaseItem import com.github.damontecres.wholphin.preferences.UserPreferences -import com.github.damontecres.wholphin.ui.DefaultItemFields import com.github.damontecres.wholphin.ui.OneTimeLaunchedEffect +import com.github.damontecres.wholphin.ui.SlimItemFields import com.github.damontecres.wholphin.ui.main.HomePageContent import com.github.damontecres.wholphin.ui.main.HomeRow import com.github.damontecres.wholphin.ui.main.HomeSection @@ -52,7 +52,7 @@ class RecommendedMovieViewModel val resumeItemsRequest = GetResumeItemsRequest( parentId = parentId, - fields = DefaultItemFields, + fields = SlimItemFields, includeItemTypes = listOf(BaseItemKind.MOVIE), enableUserData = true, ) @@ -62,7 +62,7 @@ class RecommendedMovieViewModel val recentlyReleasedRequest = GetItemsRequest( parentId = parentId, - fields = DefaultItemFields, + fields = SlimItemFields, includeItemTypes = listOf(BaseItemKind.MOVIE), recursive = true, enableUserData = true, @@ -75,7 +75,7 @@ class RecommendedMovieViewModel val recentlyAddedRequest = GetItemsRequest( parentId = parentId, - fields = DefaultItemFields, + fields = SlimItemFields, includeItemTypes = listOf(BaseItemKind.MOVIE), recursive = true, enableUserData = true, @@ -94,7 +94,7 @@ class RecommendedMovieViewModel val unwatchedTopRatedRequest = GetItemsRequest( parentId = parentId, - fields = DefaultItemFields, + fields = SlimItemFields, includeItemTypes = listOf(BaseItemKind.MOVIE), recursive = true, enableUserData = true, diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/components/RecommendedTvShow.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/components/RecommendedTvShow.kt index 804349a6..96117e4d 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/components/RecommendedTvShow.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/components/RecommendedTvShow.kt @@ -10,8 +10,8 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.github.damontecres.wholphin.data.model.BaseItem import com.github.damontecres.wholphin.preferences.UserPreferences -import com.github.damontecres.wholphin.ui.DefaultItemFields import com.github.damontecres.wholphin.ui.OneTimeLaunchedEffect +import com.github.damontecres.wholphin.ui.SlimItemFields import com.github.damontecres.wholphin.ui.main.HomePageContent import com.github.damontecres.wholphin.ui.main.HomeRow import com.github.damontecres.wholphin.ui.main.HomeSection @@ -54,7 +54,7 @@ class RecommendedTvShowViewModel val resumeItemsRequest = GetResumeItemsRequest( parentId = parentId, - fields = DefaultItemFields, + fields = SlimItemFields, includeItemTypes = listOf(BaseItemKind.EPISODE), enableUserData = true, ) @@ -64,7 +64,7 @@ class RecommendedTvShowViewModel val nextUpRequest = GetNextUpRequest( parentId = parentId, - fields = DefaultItemFields, + fields = SlimItemFields, enableUserData = true, ) val nextUpItems = ApiRequestPager(api, nextUpRequest, GetNextUpRequestHandler, viewModelScope, useSeriesForPrimary = true) @@ -72,7 +72,7 @@ class RecommendedTvShowViewModel val recentlyReleasedRequest = GetItemsRequest( parentId = parentId, - fields = DefaultItemFields, + fields = SlimItemFields, includeItemTypes = listOf(BaseItemKind.EPISODE), recursive = true, enableUserData = true, @@ -85,7 +85,7 @@ class RecommendedTvShowViewModel val recentlyAddedRequest = GetItemsRequest( parentId = parentId, - fields = DefaultItemFields, + fields = SlimItemFields, includeItemTypes = listOf(BaseItemKind.EPISODE), recursive = true, enableUserData = true, @@ -104,7 +104,7 @@ class RecommendedTvShowViewModel val unwatchedTopRatedRequest = GetItemsRequest( parentId = parentId, - fields = DefaultItemFields, + fields = SlimItemFields, includeItemTypes = listOf(BaseItemKind.SERIES), recursive = true, enableUserData = true, diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/DetailUtils.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/DetailUtils.kt index eef242b2..a5b1a58b 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/DetailUtils.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/DetailUtils.kt @@ -2,9 +2,7 @@ package com.github.damontecres.wholphin.ui.detail import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowForward -import androidx.compose.material.icons.filled.ArrowForward import androidx.compose.material.icons.filled.PlayArrow -import androidx.compose.material.icons.filled.Settings import androidx.compose.ui.graphics.Color import com.github.damontecres.wholphin.R import com.github.damontecres.wholphin.data.model.BaseItem @@ -87,8 +85,7 @@ fun buildMoreDialogItems( add( DialogItem( "Choose Version", - Icons.Default.ArrowForward, - iconColor = Color.Green.copy(alpha = .8f), + R.string.fa_file_video, ) { onChooseVersion.invoke() }, @@ -104,7 +101,7 @@ fun buildMoreDialogItems( add( DialogItem( "Choose audio", - Icons.Default.Settings, + R.string.fa_volume_low, ) { onChooseTracks.invoke(MediaStreamType.AUDIO) }, @@ -114,7 +111,7 @@ fun buildMoreDialogItems( add( DialogItem( "Choose subtitles", - Icons.Default.Settings, + R.string.fa_closed_captioning, ) { onChooseTracks.invoke(MediaStreamType.SUBTITLE) }, diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/SeriesViewModel.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/SeriesViewModel.kt index 848ea109..266322d3 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/SeriesViewModel.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/SeriesViewModel.kt @@ -30,6 +30,7 @@ import com.github.damontecres.wholphin.util.GetEpisodesRequestHandler import com.github.damontecres.wholphin.util.GetItemsRequestHandler import com.github.damontecres.wholphin.util.LoadingExceptionHandler import com.github.damontecres.wholphin.util.LoadingState +import com.github.damontecres.wholphin.util.profile.Codec import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.Dispatchers @@ -135,7 +136,13 @@ class SeriesViewModel val url = api.universalAudioApi.getUniversalAudioStreamUrl( theme.id, - container = listOf("opus", "mp3", "aaa", "flac"), + container = + listOf( + Codec.Audio.OPUS, + Codec.Audio.MP3, + Codec.Audio.AAC, + Codec.Audio.FLAC, + ), ) Timber.Forest.v("Found theme song for series $seriesId") withContext(Dispatchers.Main) { diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/main/HomeViewModel.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/main/HomeViewModel.kt index 86d6aa72..e962e165 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/main/HomeViewModel.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/main/HomeViewModel.kt @@ -5,7 +5,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.github.damontecres.wholphin.data.model.BaseItem import com.github.damontecres.wholphin.preferences.UserPreferences -import com.github.damontecres.wholphin.ui.DefaultItemFields +import com.github.damontecres.wholphin.ui.SlimItemFields import com.github.damontecres.wholphin.ui.nav.NavigationManager import com.github.damontecres.wholphin.util.LoadingExceptionHandler import com.github.damontecres.wholphin.util.LoadingState @@ -119,7 +119,7 @@ class HomeViewModel val request = GetResumeItemsRequest( userId = userId, - fields = DefaultItemFields, + fields = SlimItemFields, limit = limit, includeItemTypes = supportItemKinds, ) @@ -140,7 +140,7 @@ class HomeViewModel val request = GetNextUpRequest( userId = userId, - fields = DefaultItemFields, + fields = SlimItemFields, imageTypeLimit = 1, parentId = null, limit = limit, @@ -176,7 +176,7 @@ class HomeViewModel view.name?.let { "Recently Added in $it" } val request = GetLatestMediaRequest( - fields = DefaultItemFields, + fields = SlimItemFields, imageTypeLimit = 1, parentId = view.id, groupItems = true, diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/main/SearchPage.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/main/SearchPage.kt index 646b213a..27382274 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/main/SearchPage.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/main/SearchPage.kt @@ -26,7 +26,7 @@ import androidx.lifecycle.viewModelScope import com.github.damontecres.wholphin.data.model.BaseItem import com.github.damontecres.wholphin.preferences.UserPreferences import com.github.damontecres.wholphin.ui.Cards -import com.github.damontecres.wholphin.ui.DefaultItemFields +import com.github.damontecres.wholphin.ui.SlimItemFields import com.github.damontecres.wholphin.ui.cards.EpisodeCard import com.github.damontecres.wholphin.ui.cards.ItemRow import com.github.damontecres.wholphin.ui.cards.SeasonCard @@ -78,7 +78,7 @@ class SearchViewModel searchTerm = query, recursive = true, includeItemTypes = listOf(BaseItemKind.MOVIE), - fields = DefaultItemFields, + fields = SlimItemFields, limit = 25, ) val pager = ApiRequestPager(api, request, GetItemsRequestHandler, viewModelScope) @@ -93,7 +93,7 @@ class SearchViewModel searchTerm = query, recursive = true, includeItemTypes = listOf(BaseItemKind.SERIES), - fields = DefaultItemFields, + fields = SlimItemFields, limit = 25, ) val pager = ApiRequestPager(api, request, GetItemsRequestHandler, viewModelScope) @@ -108,7 +108,7 @@ class SearchViewModel searchTerm = query, recursive = true, includeItemTypes = listOf(BaseItemKind.EPISODE), - fields = DefaultItemFields, + fields = SlimItemFields, limit = 25, ) val pager = ApiRequestPager(api, request, GetItemsRequestHandler, viewModelScope) diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/PlaybackViewModel.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/PlaybackViewModel.kt index 42f99791..4805868a 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/PlaybackViewModel.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/PlaybackViewModel.kt @@ -17,6 +17,7 @@ import androidx.media3.common.Tracks import androidx.media3.common.util.UnstableApi import androidx.media3.exoplayer.ExoPlayer import com.github.damontecres.wholphin.data.ItemPlaybackDao +import com.github.damontecres.wholphin.data.ItemPlaybackRepository import com.github.damontecres.wholphin.data.ServerRepository import com.github.damontecres.wholphin.data.model.BaseItem import com.github.damontecres.wholphin.data.model.Chapter @@ -100,6 +101,7 @@ class PlaybackViewModel val navigationManager: NavigationManager, val itemPlaybackDao: ItemPlaybackDao, val serverRepository: ServerRepository, + val itemPlaybackRepository: ItemPlaybackRepository, ) : ViewModel(), Player.Listener { val player: ExoPlayer = @@ -461,10 +463,9 @@ class PlaybackViewModel if (userInitiated) { viewModelScope.launch(Dispatchers.IO + ExceptionHandler()) { Timber.v("Saving user initiated item playback: %s", itemPlayback) - val rowId = itemPlaybackDao.saveItem(itemPlayback) + val updated = itemPlaybackRepository.saveItemPlayback(itemPlayback) withContext(Dispatchers.Main) { - this@PlaybackViewModel.currentItemPlayback.value = - itemPlayback.copy(rowId = rowId) + this@PlaybackViewModel.currentItemPlayback.value = updated } } } diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/setup/SwitchUserContent.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/setup/SwitchUserContent.kt index b7e656b2..32db86d0 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/setup/SwitchUserContent.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/setup/SwitchUserContent.kt @@ -125,9 +125,7 @@ fun SwitchUserContent( LaunchedEffect(Unit) { viewModel.clearSwitchUserState() if (useQuickConnect) { - viewModel.initiateQuickConnect(server) { - viewModel.navigationManager.goToHome() - } + viewModel.initiateQuickConnect(server) } } BasicDialog( @@ -180,10 +178,18 @@ fun SwitchUserContent( ) when (val s = userState) { is LoadingState.Error -> { - Text( - text = s.message ?: s.exception?.localizedMessage ?: "Error", - color = MaterialTheme.colorScheme.error, - ) + s.message?.let { + Text( + text = it, + color = MaterialTheme.colorScheme.error, + ) + } + s.exception?.localizedMessage?.let { + Text( + text = it, + color = MaterialTheme.colorScheme.error, + ) + } } else -> {} @@ -208,6 +214,7 @@ fun SwitchUserContent( autoCorrectEnabled = false, keyboardType = KeyboardType.Text, ), + isInputValid = { userState !is LoadingState.Error }, modifier = Modifier.focusRequester(focusRequester), ) } @@ -235,6 +242,7 @@ fun SwitchUserContent( KeyboardActions( onDone = { onSubmit.invoke() }, ), + isInputValid = { userState !is LoadingState.Error }, modifier = Modifier, ) } diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/setup/SwitchUserViewModel.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/setup/SwitchUserViewModel.kt index 83244068..852e4add 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/setup/SwitchUserViewModel.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/setup/SwitchUserViewModel.kt @@ -154,7 +154,7 @@ class SwitchUserViewModel } } catch (ex: Exception) { Timber.e(ex, "Error switching user") - setError(ex) + setError("Error switching user", ex) } } } @@ -178,15 +178,19 @@ class SwitchUserViewModel } } catch (ex: Exception) { Timber.e(ex, "Error logging in user") - setError(ex) + if (ex is InvalidStatusException && ex.status == 401) { + withContext(Dispatchers.Main) { + switchUserState.value = + LoadingState.Error("Invalid username or password") + } + } else { + setError("Error during login", ex) + } } } } - fun initiateQuickConnect( - server: JellyfinServer, - onAuthenticated: () -> Unit, - ) { + fun initiateQuickConnect(server: JellyfinServer) { quickConnectJob?.cancel() viewModelScope.launchIO { try { @@ -218,19 +222,21 @@ class SwitchUserViewModel ) serverRepository.changeUser(server.url, authenticationResult) withContext(Dispatchers.Main) { - onAuthenticated.invoke() + navigationManager.goToHome() } } } catch (ex: Exception) { Timber.e(ex, "Error during quick connect") if (ex is InvalidStatusException && ex.status == 401) { - quickConnectState.value = null - serverQuickConnect.value = - serverQuickConnect.value!!.toMutableMap().apply { - put(server.id, false) - } + withContext(Dispatchers.Main) { + quickConnectState.value = null + serverQuickConnect.value = + serverQuickConnect.value!!.toMutableMap().apply { + put(server.id, false) + } + } } - setError(ex) + setError("Error with Quick Connect", ex) } } } @@ -329,8 +335,10 @@ class SwitchUserViewModel } } - private suspend fun setError(ex: Exception) = - withContext(Dispatchers.Main) { - switchUserState.value = LoadingState.Error(ex) - } + private suspend fun setError( + msg: String? = null, + ex: Exception? = null, + ) = withContext(Dispatchers.Main) { + switchUserState.value = LoadingState.Error(msg, ex) + } } diff --git a/app/src/main/res/values/fa_strings.xml b/app/src/main/res/values/fa_strings.xml index 68a0990e..8d09fb92 100644 --- a/app/src/main/res/values/fa_strings.xml +++ b/app/src/main/res/values/fa_strings.xml @@ -34,4 +34,6 @@ + +