diff --git a/app/build.gradle b/app/build.gradle index 8a623112..14099906 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -42,6 +42,7 @@ android { buildFeatures { dataBinding true + viewBinding true } } diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/EpisodeBottomSheetFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/EpisodeBottomSheetFragment.kt index a81beae0..123391e0 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/EpisodeBottomSheetFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/EpisodeBottomSheetFragment.kt @@ -110,7 +110,7 @@ class EpisodeBottomSheetFragment : BottomSheetDialogFragment() { }) binding.playerItemsErrorDetails.setOnClickListener { - ErrorDialogFragment(viewModel.playerItemsError.value ?: "Unknown error").show(parentFragmentManager, "errordialog") + ErrorDialogFragment(viewModel.playerItemsError.value ?: getString(R.string.unknown_error)).show(parentFragmentManager, "errordialog") } viewModel.loadEpisode(args.episodeId) diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/FavoriteFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/FavoriteFragment.kt index d66f7011..d92e5a04 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/FavoriteFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/FavoriteFragment.kt @@ -7,13 +7,13 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController -import com.google.android.material.snackbar.Snackbar import dagger.hilt.android.AndroidEntryPoint import dev.jdtech.jellyfin.R import dev.jdtech.jellyfin.adapters.FavoritesListAdapter import dev.jdtech.jellyfin.adapters.HomeEpisodeListAdapter import dev.jdtech.jellyfin.adapters.ViewItemListAdapter import dev.jdtech.jellyfin.databinding.FragmentFavoriteBinding +import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment import dev.jdtech.jellyfin.viewmodels.FavoriteViewModel import org.jellyfin.sdk.model.api.BaseItemDto @@ -29,16 +29,6 @@ class FavoriteFragment : Fragment() { ): View { binding = FragmentFavoriteBinding.inflate(inflater, container, false) - val snackbar = - Snackbar.make( - binding.mainLayout, - getString(R.string.error_loading_data), - Snackbar.LENGTH_INDEFINITE - ) - snackbar.setAction(getString(R.string.retry)) { - viewModel.loadData() - } - binding.lifecycleOwner = viewLifecycleOwner binding.viewModel = viewModel binding.favoritesRecyclerView.adapter = FavoritesListAdapter( @@ -53,11 +43,23 @@ class FavoriteFragment : Fragment() { }) viewModel.error.observe(viewLifecycleOwner, { error -> - if (error) { - snackbar.show() + if (error != null) { + binding.errorLayout.errorPanel.visibility = View.VISIBLE + binding.favoritesRecyclerView.visibility = View.GONE + } else { + binding.errorLayout.errorPanel.visibility = View.GONE + binding.favoritesRecyclerView.visibility = View.VISIBLE } }) + binding.errorLayout.errorRetryButton.setOnClickListener { + viewModel.loadData() + } + + binding.errorLayout.errorDetailsButton.setOnClickListener { + ErrorDialogFragment(viewModel.error.value ?: getString(R.string.unknown_error)).show(parentFragmentManager, "errordialog") + } + viewModel.favoriteSections.observe(viewLifecycleOwner, { sections -> if (sections.isEmpty()) { binding.noFavoritesText.visibility = View.VISIBLE diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/HomeFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/HomeFragment.kt index f2bc3b74..78891d63 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/HomeFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/HomeFragment.kt @@ -5,13 +5,13 @@ import android.view.* import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController -import com.google.android.material.snackbar.Snackbar import dagger.hilt.android.AndroidEntryPoint import dev.jdtech.jellyfin.R import dev.jdtech.jellyfin.adapters.HomeEpisodeListAdapter import dev.jdtech.jellyfin.adapters.ViewItemListAdapter import dev.jdtech.jellyfin.adapters.ViewListAdapter import dev.jdtech.jellyfin.databinding.FragmentHomeBinding +import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment import dev.jdtech.jellyfin.viewmodels.HomeViewModel import org.jellyfin.sdk.model.api.BaseItemDto @@ -49,12 +49,6 @@ class HomeFragment : Fragment() { ): View { binding = FragmentHomeBinding.inflate(inflater, container, false) - val snackbar = - Snackbar.make(binding.mainLayout, getString(R.string.error_loading_data), Snackbar.LENGTH_INDEFINITE) - snackbar.setAction(getString(R.string.retry)) { - viewModel.loadData() - } - binding.lifecycleOwner = viewLifecycleOwner binding.viewModel = viewModel binding.viewsRecyclerView.adapter = ViewListAdapter(ViewListAdapter.OnClickListener { @@ -78,11 +72,23 @@ class HomeFragment : Fragment() { }) viewModel.error.observe(viewLifecycleOwner, { error -> - if (error) { - snackbar.show() + if (error != null) { + binding.errorLayout.errorPanel.visibility = View.VISIBLE + binding.viewsRecyclerView.visibility = View.GONE + } else { + binding.errorLayout.errorPanel.visibility = View.GONE + binding.viewsRecyclerView.visibility = View.VISIBLE } }) + binding.errorLayout.errorRetryButton.setOnClickListener { + viewModel.loadData() + } + + binding.errorLayout.errorDetailsButton.setOnClickListener { + ErrorDialogFragment(viewModel.error.value ?: getString(R.string.unknown_error)).show(parentFragmentManager, "errordialog") + } + return binding.root } diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/LibraryFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/LibraryFragment.kt index 5858ca06..3eba789f 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/LibraryFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/LibraryFragment.kt @@ -8,12 +8,12 @@ import android.view.ViewGroup import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.navArgs -import com.google.android.material.snackbar.Snackbar import dagger.hilt.android.AndroidEntryPoint import dev.jdtech.jellyfin.R import dev.jdtech.jellyfin.viewmodels.LibraryViewModel import dev.jdtech.jellyfin.adapters.ViewItemListAdapter import dev.jdtech.jellyfin.databinding.FragmentLibraryBinding +import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment import org.jellyfin.sdk.model.api.BaseItemDto @AndroidEntryPoint @@ -39,21 +39,23 @@ class LibraryFragment : Fragment() { super.onViewCreated(view, savedInstanceState) binding.viewModel = viewModel - val snackbar = - Snackbar.make( - binding.mainLayout, - getString(R.string.error_loading_data), - Snackbar.LENGTH_INDEFINITE - ) - snackbar.setAction(getString(R.string.retry)) { + viewModel.error.observe(viewLifecycleOwner, { error -> + if (error != null) { + binding.errorLayout.errorPanel.visibility = View.VISIBLE + binding.itemsRecyclerView.visibility = View.GONE + } else { + binding.errorLayout.errorPanel.visibility = View.GONE + binding.itemsRecyclerView.visibility = View.VISIBLE + } + }) + + binding.errorLayout.errorRetryButton.setOnClickListener { viewModel.loadItems(args.libraryId) } - viewModel.error.observe(viewLifecycleOwner, { error -> - if (error) { - snackbar.show() - } - }) + binding.errorLayout.errorDetailsButton.setOnClickListener { + ErrorDialogFragment(viewModel.error.value ?: getString(R.string.unknown_error)).show(parentFragmentManager, "errordialog") + } viewModel.finishedLoading.observe(viewLifecycleOwner, { binding.loadingIndicator.visibility = if (it) View.GONE else View.VISIBLE diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaFragment.kt index 94a185ee..cb6b35d0 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaFragment.kt @@ -6,11 +6,11 @@ import androidx.appcompat.widget.SearchView import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController -import com.google.android.material.snackbar.Snackbar import dagger.hilt.android.AndroidEntryPoint import dev.jdtech.jellyfin.R import dev.jdtech.jellyfin.adapters.CollectionListAdapter import dev.jdtech.jellyfin.databinding.FragmentMediaBinding +import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment import dev.jdtech.jellyfin.viewmodels.MediaViewModel import org.jellyfin.sdk.model.api.BaseItemDto @@ -53,16 +53,6 @@ class MediaFragment : Fragment() { ): View { binding = FragmentMediaBinding.inflate(inflater, container, false) - val snackbar = - Snackbar.make( - binding.mainLayout, - getString(R.string.error_loading_data), - Snackbar.LENGTH_INDEFINITE - ) - snackbar.setAction(getString(R.string.retry)) { - viewModel.loadData() - } - binding.lifecycleOwner = viewLifecycleOwner binding.viewModel = viewModel binding.viewsRecyclerView.adapter = @@ -75,11 +65,23 @@ class MediaFragment : Fragment() { }) viewModel.error.observe(viewLifecycleOwner, { error -> - if (error) { - snackbar.show() + if (error != null) { + binding.errorLayout.errorPanel.visibility = View.VISIBLE + binding.viewsRecyclerView.visibility = View.GONE + } else { + binding.errorLayout.errorPanel.visibility = View.GONE + binding.viewsRecyclerView.visibility = View.VISIBLE } }) + binding.errorLayout.errorRetryButton.setOnClickListener { + viewModel.loadData() + } + + binding.errorLayout.errorDetailsButton.setOnClickListener { + ErrorDialogFragment(viewModel.error.value ?: getString(R.string.unknown_error)).show(parentFragmentManager, "errordialog") + } + return binding.root } diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaInfoFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaInfoFragment.kt index b9d7bb13..a94aa985 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaInfoFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaInfoFragment.kt @@ -11,7 +11,6 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.navArgs -import com.google.android.material.snackbar.Snackbar import dagger.hilt.android.AndroidEntryPoint import dev.jdtech.jellyfin.R import dev.jdtech.jellyfin.adapters.PersonListAdapter @@ -45,24 +44,26 @@ class MediaInfoFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - val snackbar = - Snackbar.make( - binding.mainLayout, - getString(R.string.error_loading_data), - Snackbar.LENGTH_INDEFINITE - ) - snackbar.setAction(getString(R.string.retry)) { - viewModel.loadData(args.itemId, args.itemType) - } - binding.viewModel = viewModel viewModel.error.observe(viewLifecycleOwner, { error -> - if (error) { - snackbar.show() + if (error != null) { + binding.errorLayout.errorPanel.visibility = View.VISIBLE + binding.mediaInfoScrollview.visibility = View.GONE + } else { + binding.errorLayout.errorPanel.visibility = View.GONE + binding.mediaInfoScrollview.visibility = View.VISIBLE } }) + binding.errorLayout.errorRetryButton.setOnClickListener { + viewModel.loadData(args.itemId, args.itemType) + } + + binding.errorLayout.errorDetailsButton.setOnClickListener { + ErrorDialogFragment(viewModel.error.value ?: getString(R.string.unknown_error)).show(parentFragmentManager, "errordialog") + } + viewModel.item.observe(viewLifecycleOwner, { item -> if (item.originalTitle != item.name) { binding.originalTitle.visibility = View.VISIBLE @@ -136,7 +137,7 @@ class MediaInfoFragment : Fragment() { }) binding.playerItemsErrorDetails.setOnClickListener { - ErrorDialogFragment(viewModel.playerItemsError.value ?: "Unknown error").show(parentFragmentManager, "errordialog") + ErrorDialogFragment(viewModel.playerItemsError.value ?: getString(R.string.unknown_error)).show(parentFragmentManager, "errordialog") } binding.trailerButton.setOnClickListener { diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/SearchResultFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/SearchResultFragment.kt index ca1b6374..f13de478 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/SearchResultFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/SearchResultFragment.kt @@ -8,13 +8,13 @@ import android.view.ViewGroup import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.navArgs -import com.google.android.material.snackbar.Snackbar import dagger.hilt.android.AndroidEntryPoint import dev.jdtech.jellyfin.R import dev.jdtech.jellyfin.adapters.FavoritesListAdapter import dev.jdtech.jellyfin.adapters.HomeEpisodeListAdapter import dev.jdtech.jellyfin.adapters.ViewItemListAdapter import dev.jdtech.jellyfin.databinding.FragmentSearchResultBinding +import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment import dev.jdtech.jellyfin.viewmodels.SearchResultViewModel import org.jellyfin.sdk.model.api.BaseItemDto @@ -32,16 +32,6 @@ class SearchResultFragment : Fragment() { ): View { binding = FragmentSearchResultBinding.inflate(inflater, container, false) - val snackbar = - Snackbar.make( - binding.mainLayout, - getString(R.string.error_loading_data), - Snackbar.LENGTH_INDEFINITE - ) - snackbar.setAction(getString(R.string.retry)) { - viewModel.loadData(args.query) - } - binding.lifecycleOwner = viewLifecycleOwner binding.viewModel = viewModel binding.searchResultsRecyclerView.adapter = FavoritesListAdapter( @@ -56,11 +46,23 @@ class SearchResultFragment : Fragment() { }) viewModel.error.observe(viewLifecycleOwner, { error -> - if (error) { - snackbar.show() + if (error != null) { + binding.errorLayout.errorPanel.visibility = View.VISIBLE + binding.searchResultsRecyclerView.visibility = View.GONE + } else { + binding.errorLayout.errorPanel.visibility = View.GONE + binding.searchResultsRecyclerView.visibility = View.VISIBLE } }) + binding.errorLayout.errorRetryButton.setOnClickListener { + viewModel.loadData(args.query) + } + + binding.errorLayout.errorDetailsButton.setOnClickListener { + ErrorDialogFragment(viewModel.error.value ?: getString(R.string.unknown_error)).show(parentFragmentManager, "errordialog") + } + viewModel.sections.observe(viewLifecycleOwner, { sections -> if (sections.isEmpty()) { binding.noSearchResultsText.visibility = View.VISIBLE diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/SeasonFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/SeasonFragment.kt index 32500867..7ae52879 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/SeasonFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/SeasonFragment.kt @@ -8,11 +8,11 @@ import android.view.ViewGroup import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.navArgs -import com.google.android.material.snackbar.Snackbar import dagger.hilt.android.AndroidEntryPoint import dev.jdtech.jellyfin.R import dev.jdtech.jellyfin.adapters.EpisodeListAdapter import dev.jdtech.jellyfin.databinding.FragmentSeasonBinding +import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment import dev.jdtech.jellyfin.viewmodels.SeasonViewModel import org.jellyfin.sdk.model.api.BaseItemDto @@ -37,21 +37,23 @@ class SeasonFragment : Fragment() { super.onViewCreated(view, savedInstanceState) binding.viewModel = viewModel - val snackbar = - Snackbar.make( - binding.mainLayout, - getString(R.string.error_loading_data), - Snackbar.LENGTH_INDEFINITE - ) - snackbar.setAction(getString(R.string.retry)) { + viewModel.error.observe(viewLifecycleOwner, { error -> + if (error != null) { + binding.errorLayout.errorPanel.visibility = View.VISIBLE + binding.episodesRecyclerView.visibility = View.GONE + } else { + binding.errorLayout.errorPanel.visibility = View.GONE + binding.episodesRecyclerView.visibility = View.VISIBLE + } + }) + + binding.errorLayout.errorRetryButton.setOnClickListener { viewModel.loadEpisodes(args.seriesId, args.seasonId) } - viewModel.error.observe(viewLifecycleOwner, { error -> - if (error) { - snackbar.show() - } - }) + binding.errorLayout.errorDetailsButton.setOnClickListener { + ErrorDialogFragment(viewModel.error.value ?: getString(R.string.unknown_error)).show(parentFragmentManager, "errordialog") + } viewModel.finishedLoading.observe(viewLifecycleOwner, { binding.loadingIndicator.visibility = if (it) View.GONE else View.VISIBLE diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/ServerSelectFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/ServerSelectFragment.kt index d082b145..886db38a 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/ServerSelectFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/ServerSelectFragment.kt @@ -8,7 +8,6 @@ import android.view.ViewGroup import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController import dagger.hilt.android.AndroidEntryPoint -import dev.jdtech.jellyfin.R import dev.jdtech.jellyfin.databinding.FragmentServerSelectBinding import dev.jdtech.jellyfin.dialogs.DeleteServerDialogFragment import dev.jdtech.jellyfin.adapters.ServerGridAdapter diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/FavoriteViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/FavoriteViewModel.kt index e9138d09..eb339dc7 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/FavoriteViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/FavoriteViewModel.kt @@ -26,15 +26,15 @@ constructor( private val _finishedLoading = MutableLiveData() val finishedLoading: LiveData = _finishedLoading - private val _error = MutableLiveData() - val error: LiveData = _error + private val _error = MutableLiveData() + val error: LiveData = _error init { loadData() } fun loadData() { - _error.value = false + _error.value = null _finishedLoading.value = false viewModelScope.launch { try { @@ -78,7 +78,7 @@ constructor( _favoriteSections.value = tempFavoriteSections } catch (e: Exception) { Timber.e(e) - _error.value = true + _error.value = e.message } _finishedLoading.value = true } diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/HomeViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/HomeViewModel.kt index cfba9866..73efc889 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/HomeViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/HomeViewModel.kt @@ -38,15 +38,15 @@ constructor( private val _finishedLoading = MutableLiveData() val finishedLoading: LiveData = _finishedLoading - private val _error = MutableLiveData() - val error: LiveData = _error + private val _error = MutableLiveData() + val error: LiveData = _error init { loadData() } fun loadData() { - _error.value = false + _error.value = null _finishedLoading.value = false viewModelScope.launch { try { @@ -87,7 +87,7 @@ constructor( } catch (e: Exception) { Timber.e(e) - _error.value = true + _error.value = e.message } _finishedLoading.value = true } diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/LibraryViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/LibraryViewModel.kt index 04c48f53..ac0d75e9 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/LibraryViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/LibraryViewModel.kt @@ -20,18 +20,18 @@ constructor(private val jellyfinRepository: JellyfinRepository) : ViewModel() { private val _finishedLoading = MutableLiveData() val finishedLoading: LiveData = _finishedLoading - private val _error = MutableLiveData() - val error: LiveData = _error + private val _error = MutableLiveData() + val error: LiveData = _error fun loadItems(parentId: UUID) { - _error.value = false + _error.value = null _finishedLoading.value = false viewModelScope.launch { try { _items.value = jellyfinRepository.getItems(parentId) } catch (e: Exception) { Timber.e(e) - _error.value = true + _error.value = e.message } _finishedLoading.value = true } diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MainViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MainViewModel.kt index 92cab80b..f319617a 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MainViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MainViewModel.kt @@ -1,12 +1,10 @@ package dev.jdtech.jellyfin.viewmodels -import android.app.Application import android.content.SharedPreferences import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import androidx.preference.PreferenceManager import dagger.hilt.android.lifecycle.HiltViewModel import dev.jdtech.jellyfin.api.JellyfinApi import dev.jdtech.jellyfin.database.Server diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaInfoViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaInfoViewModel.kt index 0e77c612..ea564c2d 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaInfoViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaInfoViewModel.kt @@ -64,8 +64,8 @@ constructor(private val jellyfinRepository: JellyfinRepository) : ViewModel() { private val _favorite = MutableLiveData() val favorite: LiveData = _favorite - private val _error = MutableLiveData() - val error: LiveData = _error + private val _error = MutableLiveData() + val error: LiveData = _error var playerItems: MutableList = mutableListOf() @@ -73,7 +73,7 @@ constructor(private val jellyfinRepository: JellyfinRepository) : ViewModel() { val playerItemsError: LiveData = _playerItemsError fun loadData(itemId: UUID, itemType: String) { - _error.value = false + _error.value = null viewModelScope.launch { try { _item.value = jellyfinRepository.getItem(itemId) @@ -96,7 +96,7 @@ constructor(private val jellyfinRepository: JellyfinRepository) : ViewModel() { } } catch (e: Exception) { Timber.e(e) - _error.value = true + _error.value = e.message } } } diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaViewModel.kt index a23f9607..412ea745 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaViewModel.kt @@ -21,8 +21,8 @@ constructor( private val _finishedLoading = MutableLiveData() val finishedLoading: LiveData = _finishedLoading - private val _error = MutableLiveData() - val error: LiveData = _error + private val _error = MutableLiveData() + val error: LiveData = _error init { loadData() @@ -30,7 +30,7 @@ constructor( fun loadData() { _finishedLoading.value = false - _error.value = false + _error.value = null viewModelScope.launch { try { val items = jellyfinRepository.getItems() @@ -43,7 +43,7 @@ constructor( } } catch (e: Exception) { Timber.e(e) - _error.value = true + _error.value = e.message } _finishedLoading.value = true } diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SearchResultViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SearchResultViewModel.kt index f5f8f925..b9fc1e47 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SearchResultViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SearchResultViewModel.kt @@ -26,11 +26,11 @@ constructor( private val _finishedLoading = MutableLiveData() val finishedLoading: LiveData = _finishedLoading - private val _error = MutableLiveData() - val error: LiveData = _error + private val _error = MutableLiveData() + val error: LiveData = _error fun loadData(query: String) { - _error.value = false + _error.value = null _finishedLoading.value = false viewModelScope.launch { try { @@ -74,7 +74,7 @@ constructor( _sections.value = tempSections } catch (e: Exception) { Timber.e(e) - _error.value = true + _error.value = e.message } _finishedLoading.value = true } diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SeasonViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SeasonViewModel.kt index cf15b182..39f7525c 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SeasonViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SeasonViewModel.kt @@ -24,18 +24,18 @@ constructor(private val jellyfinRepository: JellyfinRepository) : ViewModel() { private val _finishedLoading = MutableLiveData() val finishedLoading: LiveData = _finishedLoading - private val _error = MutableLiveData() - val error: LiveData = _error + private val _error = MutableLiveData() + val error: LiveData = _error fun loadEpisodes(seriesId: UUID, seasonId: UUID) { - _error.value = false + _error.value = null _finishedLoading.value = false viewModelScope.launch { try { _episodes.value = getEpisodes(seriesId, seasonId) } catch (e: Exception) { Timber.e(e) - _error.value = true + _error.value = e.message } _finishedLoading.value = true } diff --git a/app/src/main/res/drawable/ic_alert_circle.xml b/app/src/main/res/drawable/ic_alert_circle.xml new file mode 100644 index 00000000..961d2ac4 --- /dev/null +++ b/app/src/main/res/drawable/ic_alert_circle.xml @@ -0,0 +1,28 @@ + + + + + diff --git a/app/src/main/res/layout/activity_player.xml b/app/src/main/res/layout/activity_player.xml index 49020401..19680665 100644 --- a/app/src/main/res/layout/activity_player.xml +++ b/app/src/main/res/layout/activity_player.xml @@ -1,5 +1,5 @@ - - + diff --git a/app/src/main/res/layout/episode_bottom_sheet.xml b/app/src/main/res/layout/episode_bottom_sheet.xml index 501acc53..f7168564 100644 --- a/app/src/main/res/layout/episode_bottom_sheet.xml +++ b/app/src/main/res/layout/episode_bottom_sheet.xml @@ -190,7 +190,7 @@ android:id="@+id/player_items_error_details" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="@string/view_details" + android:text="@string/view_details_underlined" android:textAppearance="@style/TextAppearance.AppCompat.Body1" android:textColor="@color/red" /> diff --git a/app/src/main/res/layout/error_panel.xml b/app/src/main/res/layout/error_panel.xml new file mode 100644 index 00000000..33ea0c78 --- /dev/null +++ b/app/src/main/res/layout/error_panel.xml @@ -0,0 +1,53 @@ + + + + + + + + + +