View detailed error message for playerItemsError
This commit is contained in:
parent
306c3b02c2
commit
f2ce030856
9 changed files with 148 additions and 43 deletions
|
@ -0,0 +1,33 @@
|
||||||
|
package dev.jdtech.jellyfin.dialogs
|
||||||
|
|
||||||
|
import android.app.Dialog
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.fragment.app.DialogFragment
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
import dev.jdtech.jellyfin.R
|
||||||
|
import java.lang.IllegalStateException
|
||||||
|
|
||||||
|
class ErrorDialogFragment(private val errorMessage: String) : DialogFragment() {
|
||||||
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||||
|
return activity?.let {
|
||||||
|
val builder = MaterialAlertDialogBuilder(it, R.style.ErrorDialogStyle)
|
||||||
|
builder
|
||||||
|
.setMessage(errorMessage)
|
||||||
|
.setPositiveButton("close") { _, _ ->
|
||||||
|
}
|
||||||
|
.setNeutralButton("share") { _, _ ->
|
||||||
|
val sendIntent: Intent = Intent().apply {
|
||||||
|
action = Intent.ACTION_SEND
|
||||||
|
putExtra(Intent.EXTRA_TEXT, errorMessage)
|
||||||
|
type = "text/plain"
|
||||||
|
}
|
||||||
|
|
||||||
|
val shareIntent = Intent.createChooser(sendIntent, null)
|
||||||
|
startActivity(shareIntent)
|
||||||
|
|
||||||
|
}
|
||||||
|
builder.create()
|
||||||
|
} ?: throw IllegalStateException("Activity cannot be null")
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,6 +13,7 @@ import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import dev.jdtech.jellyfin.R
|
import dev.jdtech.jellyfin.R
|
||||||
import dev.jdtech.jellyfin.databinding.EpisodeBottomSheetBinding
|
import dev.jdtech.jellyfin.databinding.EpisodeBottomSheetBinding
|
||||||
|
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
|
||||||
import dev.jdtech.jellyfin.models.PlayerItem
|
import dev.jdtech.jellyfin.models.PlayerItem
|
||||||
import dev.jdtech.jellyfin.viewmodels.EpisodeBottomSheetViewModel
|
import dev.jdtech.jellyfin.viewmodels.EpisodeBottomSheetViewModel
|
||||||
|
|
||||||
|
@ -98,17 +99,20 @@ class EpisodeBottomSheetFragment : BottomSheetDialogFragment() {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
viewModel.playerItemsError.observe(viewLifecycleOwner, {
|
viewModel.playerItemsError.observe(viewLifecycleOwner, { errorMessage ->
|
||||||
when (it) {
|
if (errorMessage != null) {
|
||||||
true -> {
|
binding.playerItemsError.visibility = View.VISIBLE
|
||||||
binding.playerItemsError.visibility = View.VISIBLE
|
binding.playButton.setImageDrawable(ContextCompat.getDrawable(requireActivity(), R.drawable.ic_play))
|
||||||
binding.playButton.setImageDrawable(ContextCompat.getDrawable(requireActivity(), R.drawable.ic_play))
|
binding.progressCircular.visibility = View.INVISIBLE
|
||||||
binding.progressCircular.visibility = View.INVISIBLE
|
} else {
|
||||||
}
|
binding.playerItemsError.visibility = View.GONE
|
||||||
false -> binding.playerItemsError.visibility = View.GONE
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
binding.playerItemsErrorDetails.setOnClickListener {
|
||||||
|
ErrorDialogFragment(viewModel.playerItemsError.value ?: "Unknown error").show(parentFragmentManager, "errordialog")
|
||||||
|
}
|
||||||
|
|
||||||
viewModel.loadEpisode(args.episodeId)
|
viewModel.loadEpisode(args.episodeId)
|
||||||
|
|
||||||
return binding.root
|
return binding.root
|
||||||
|
|
|
@ -17,6 +17,7 @@ import dev.jdtech.jellyfin.R
|
||||||
import dev.jdtech.jellyfin.adapters.PersonListAdapter
|
import dev.jdtech.jellyfin.adapters.PersonListAdapter
|
||||||
import dev.jdtech.jellyfin.adapters.ViewItemListAdapter
|
import dev.jdtech.jellyfin.adapters.ViewItemListAdapter
|
||||||
import dev.jdtech.jellyfin.databinding.FragmentMediaInfoBinding
|
import dev.jdtech.jellyfin.databinding.FragmentMediaInfoBinding
|
||||||
|
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
|
||||||
import dev.jdtech.jellyfin.dialogs.VideoVersionDialogFragment
|
import dev.jdtech.jellyfin.dialogs.VideoVersionDialogFragment
|
||||||
import dev.jdtech.jellyfin.models.PlayerItem
|
import dev.jdtech.jellyfin.models.PlayerItem
|
||||||
import dev.jdtech.jellyfin.viewmodels.MediaInfoViewModel
|
import dev.jdtech.jellyfin.viewmodels.MediaInfoViewModel
|
||||||
|
@ -91,7 +92,12 @@ class MediaInfoFragment : Fragment() {
|
||||||
viewModel.item.value!!.userData!!.playbackPositionTicks.div(10000)
|
viewModel.item.value!!.userData!!.playbackPositionTicks.div(10000)
|
||||||
)
|
)
|
||||||
viewModel.doneNavigatingToPlayer()
|
viewModel.doneNavigatingToPlayer()
|
||||||
binding.playButton.setImageDrawable(ContextCompat.getDrawable(requireActivity(), R.drawable.ic_play))
|
binding.playButton.setImageDrawable(
|
||||||
|
ContextCompat.getDrawable(
|
||||||
|
requireActivity(),
|
||||||
|
R.drawable.ic_play
|
||||||
|
)
|
||||||
|
)
|
||||||
binding.progressCircular.visibility = View.INVISIBLE
|
binding.progressCircular.visibility = View.INVISIBLE
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -114,17 +120,25 @@ class MediaInfoFragment : Fragment() {
|
||||||
binding.favoriteButton.setImageResource(drawable)
|
binding.favoriteButton.setImageResource(drawable)
|
||||||
})
|
})
|
||||||
|
|
||||||
viewModel.playerItemsError.observe(viewLifecycleOwner, {
|
viewModel.playerItemsError.observe(viewLifecycleOwner, { errorMessage ->
|
||||||
when (it) {
|
if (errorMessage != null) {
|
||||||
true -> {
|
binding.playerItemsError.visibility = View.VISIBLE
|
||||||
binding.playerItemsError.visibility = View.VISIBLE
|
binding.playButton.setImageDrawable(
|
||||||
binding.playButton.setImageDrawable(ContextCompat.getDrawable(requireActivity(), R.drawable.ic_play))
|
ContextCompat.getDrawable(
|
||||||
binding.progressCircular.visibility = View.INVISIBLE
|
requireActivity(),
|
||||||
}
|
R.drawable.ic_play
|
||||||
false -> binding.playerItemsError.visibility = View.GONE
|
)
|
||||||
|
)
|
||||||
|
binding.progressCircular.visibility = View.INVISIBLE
|
||||||
|
} else {
|
||||||
|
binding.playerItemsError.visibility = View.GONE
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
binding.playerItemsErrorDetails.setOnClickListener {
|
||||||
|
ErrorDialogFragment(viewModel.playerItemsError.value ?: "Unknown error").show(parentFragmentManager, "errordialog")
|
||||||
|
}
|
||||||
|
|
||||||
binding.trailerButton.setOnClickListener {
|
binding.trailerButton.setOnClickListener {
|
||||||
val intent = Intent(
|
val intent = Intent(
|
||||||
Intent.ACTION_VIEW,
|
Intent.ACTION_VIEW,
|
||||||
|
@ -155,10 +169,20 @@ class MediaInfoFragment : Fragment() {
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
navigateToPlayerActivity(
|
navigateToPlayerActivity(
|
||||||
arrayOf(PlayerItem(args.itemId, viewModel.mediaSources.value!![0].id!!)),
|
arrayOf(
|
||||||
|
PlayerItem(
|
||||||
|
args.itemId,
|
||||||
|
viewModel.mediaSources.value!![0].id!!
|
||||||
|
)
|
||||||
|
),
|
||||||
viewModel.item.value!!.userData!!.playbackPositionTicks.div(10000),
|
viewModel.item.value!!.userData!!.playbackPositionTicks.div(10000),
|
||||||
)
|
)
|
||||||
binding.playButton.setImageDrawable(ContextCompat.getDrawable(requireActivity(), R.drawable.ic_play))
|
binding.playButton.setImageDrawable(
|
||||||
|
ContextCompat.getDrawable(
|
||||||
|
requireActivity(),
|
||||||
|
R.drawable.ic_play
|
||||||
|
)
|
||||||
|
)
|
||||||
binding.progressCircular.visibility = View.INVISIBLE
|
binding.progressCircular.visibility = View.INVISIBLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,8 +43,8 @@ constructor(
|
||||||
|
|
||||||
var playerItems: MutableList<PlayerItem> = mutableListOf()
|
var playerItems: MutableList<PlayerItem> = mutableListOf()
|
||||||
|
|
||||||
private val _playerItemsError = MutableLiveData<Boolean>()
|
private val _playerItemsError = MutableLiveData<String>()
|
||||||
val playerItemsError: LiveData<Boolean> = _playerItemsError
|
val playerItemsError: LiveData<String> = _playerItemsError
|
||||||
|
|
||||||
fun loadEpisode(episodeId: UUID) {
|
fun loadEpisode(episodeId: UUID) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
|
@ -62,13 +62,13 @@ constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun preparePlayer() {
|
fun preparePlayer() {
|
||||||
_playerItemsError.value = false
|
_playerItemsError.value = null
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
try {
|
try {
|
||||||
createPlayerItems(_item.value!!)
|
createPlayerItems(_item.value!!)
|
||||||
_navigateToPlayer.value = true
|
_navigateToPlayer.value = true
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
_playerItemsError.value = true
|
_playerItemsError.value = e.message
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,8 +69,8 @@ constructor(private val jellyfinRepository: JellyfinRepository) : ViewModel() {
|
||||||
|
|
||||||
var playerItems: MutableList<PlayerItem> = mutableListOf()
|
var playerItems: MutableList<PlayerItem> = mutableListOf()
|
||||||
|
|
||||||
private val _playerItemsError = MutableLiveData<Boolean>()
|
private val _playerItemsError = MutableLiveData<String>()
|
||||||
val playerItemsError: LiveData<Boolean> = _playerItemsError
|
val playerItemsError: LiveData<String> = _playerItemsError
|
||||||
|
|
||||||
fun loadData(itemId: UUID, itemType: String) {
|
fun loadData(itemId: UUID, itemType: String) {
|
||||||
_error.value = false
|
_error.value = false
|
||||||
|
@ -184,13 +184,13 @@ constructor(private val jellyfinRepository: JellyfinRepository) : ViewModel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun preparePlayer() {
|
fun preparePlayer() {
|
||||||
_playerItemsError.value = false
|
_playerItemsError.value = null
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
try {
|
try {
|
||||||
createPlayerItems(_item.value!!)
|
createPlayerItems(_item.value!!)
|
||||||
_navigateToPlayer.value = playerItems.toTypedArray()
|
_navigateToPlayer.value = playerItems.toTypedArray()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
_playerItemsError.value = true
|
_playerItemsError.value = e.message
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,10 +136,10 @@
|
||||||
android:id="@+id/progress_circular"
|
android:id="@+id/progress_circular"
|
||||||
android:layout_width="48dp"
|
android:layout_width="48dp"
|
||||||
android:layout_height="48dp"
|
android:layout_height="48dp"
|
||||||
android:elevation="8dp"
|
|
||||||
android:padding="8dp"
|
|
||||||
android:layout_centerHorizontal="true"
|
android:layout_centerHorizontal="true"
|
||||||
|
android:elevation="8dp"
|
||||||
android:indeterminateTint="@color/white"
|
android:indeterminateTint="@color/white"
|
||||||
|
android:padding="8dp"
|
||||||
android:visibility="invisible" />
|
android:visibility="invisible" />
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
|
@ -163,21 +163,37 @@
|
||||||
android:src="@drawable/ic_heart" />
|
android:src="@drawable/ic_heart" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView
|
<LinearLayout
|
||||||
android:id="@+id/player_items_error"
|
android:id="@+id/player_items_error"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginHorizontal="24dp"
|
android:layout_marginHorizontal="24dp"
|
||||||
android:layout_marginTop="12dp"
|
android:layout_marginTop="12dp"
|
||||||
android:layout_marginBottom="12dp"
|
android:layout_marginBottom="12dp"
|
||||||
app:layout_constraintTop_toBottomOf="@id/buttons"
|
android:orientation="horizontal"
|
||||||
android:text="@string/error_preparing_player_items"
|
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
|
||||||
android:textColor="@color/red"
|
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible" />
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/buttons"
|
||||||
|
tools:visibility="visible">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/player_items_error_text"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:text="@string/error_preparing_player_items"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||||
|
android:textColor="@color/red" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/player_items_error_details"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/view_details"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||||
|
android:textColor="@color/red" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
|
|
|
@ -185,18 +185,35 @@
|
||||||
android:src="@drawable/ic_heart" />
|
android:src="@drawable/ic_heart" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView
|
<LinearLayout
|
||||||
android:id="@+id/player_items_error"
|
android:id="@+id/player_items_error"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginHorizontal="24dp"
|
android:layout_marginHorizontal="24dp"
|
||||||
android:layout_marginTop="-12dp"
|
android:layout_marginTop="-12dp"
|
||||||
android:layout_marginBottom="12dp"
|
android:layout_marginBottom="12dp"
|
||||||
android:text="@string/error_preparing_player_items"
|
android:orientation="horizontal"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
|
||||||
android:textColor="@color/red"
|
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/player_items_error_text"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:text="@string/error_preparing_player_items"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||||
|
android:textColor="@color/red" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/player_items_error_details"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/view_details"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||||
|
android:textColor="@color/red" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/info"
|
android:id="@+id/info"
|
||||||
|
|
|
@ -49,7 +49,8 @@
|
||||||
<string name="manage_servers">Manage servers</string>
|
<string name="manage_servers">Manage servers</string>
|
||||||
<string name="settings_category_appearance">Appearance</string>
|
<string name="settings_category_appearance">Appearance</string>
|
||||||
<string name="theme">Theme</string>
|
<string name="theme">Theme</string>
|
||||||
<string name="error_preparing_player_items">Error preparing player items</string>
|
<string name="error_preparing_player_items">Error preparing player items.</string>
|
||||||
|
<string name="view_details"><u>View details</u></string>
|
||||||
<string name="about">About</string>
|
<string name="about">About</string>
|
||||||
<string name="privacy_policy">Privacy policy</string>
|
<string name="privacy_policy">Privacy policy</string>
|
||||||
<string name="app_info">App info</string>
|
<string name="app_info">App info</string>
|
||||||
|
|
|
@ -10,4 +10,14 @@
|
||||||
<item name="cornerFamily">rounded</item>
|
<item name="cornerFamily">rounded</item>
|
||||||
<item name="cornerSize">10dp</item>
|
<item name="cornerSize">10dp</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="ErrorDialogStyle" parent="MaterialAlertDialog.MaterialComponents">
|
||||||
|
<item name="materialAlertDialogBodyTextStyle">@style/AlertDialogBodyText</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="AlertDialogBodyText" parent="MaterialAlertDialog.MaterialComponents.Body.Text">
|
||||||
|
<item name="android:fontFamily">monospace</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
Loading…
Reference in a new issue