Merge pull request #3396 from Bnyro/master

Fix various crashes in the player
This commit is contained in:
Bnyro 2023-03-26 11:12:10 +02:00 committed by GitHub
commit 555a0bee59
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 52 additions and 46 deletions

View File

@ -14,7 +14,7 @@ import com.github.libretube.db.obj.LocalPlaylist
import com.github.libretube.enums.PlaylistType
import com.github.libretube.extensions.TAG
import com.github.libretube.extensions.toID
import com.github.libretube.extensions.toastFromMainThread
import com.github.libretube.extensions.toastFromMainDispatcher
import com.github.libretube.helpers.PreferenceHelper
import com.github.libretube.helpers.ProxyHelper
import com.github.libretube.obj.ImportPlaylist
@ -68,24 +68,22 @@ object PlaylistsHelper {
}
suspend fun createPlaylist(playlistName: String, appContext: Context?): String? {
if (!loggedIn) {
return if (!loggedIn) {
val playlist = LocalPlaylist(name = playlistName, thumbnailUrl = "")
DatabaseHolder.Database.localPlaylistsDao().createPlaylist(playlist)
return DatabaseHolder.Database.localPlaylistsDao().getAll()
.last().playlist.id.toString()
DatabaseHolder.Database.localPlaylistsDao().createPlaylist(playlist).toString()
} else {
return try {
try {
RetrofitInstance.authApi.createPlaylist(token, Playlists(name = playlistName))
} catch (e: IOException) {
appContext?.toastFromMainThread(R.string.unknown_error)
appContext?.toastFromMainDispatcher(R.string.unknown_error)
return null
} catch (e: HttpException) {
Log.e(TAG(), e.toString())
appContext?.toastFromMainThread(R.string.server_error)
appContext?.toastFromMainDispatcher(R.string.server_error)
return null
}.playlistId.also {
appContext?.toastFromMainThread(R.string.playlistCreated)
}
}.playlistId
}.also {
appContext?.toastFromMainDispatcher(R.string.playlistCreated)
}
}
@ -206,7 +204,7 @@ object PlaylistsHelper {
val playlist = try {
RetrofitInstance.api.getPlaylist(playlistId)
} catch (e: Exception) {
appContext.toastFromMainThread(R.string.server_error)
appContext.toastFromMainDispatcher(R.string.server_error)
return null
}
val newPlaylist = createPlaylist(playlist.name ?: "Unknown name", appContext) ?: return null

View File

@ -17,7 +17,7 @@ interface LocalPlaylistsDao {
suspend fun getAll(): List<LocalPlaylistWithVideos>
@Insert
suspend fun createPlaylist(playlist: LocalPlaylist)
suspend fun createPlaylist(playlist: LocalPlaylist): Long
@Update
suspend fun updatePlaylist(playlist: LocalPlaylist)

View File

@ -21,10 +21,12 @@ fun Context.toastFromMainThread(stringId: Int) {
toastFromMainThread(getString(stringId))
}
suspend fun Context.toastFromMainDispatcher(text: String) = withContext(Dispatchers.Main) {
Toast.makeText(this@toastFromMainDispatcher, text, Toast.LENGTH_SHORT).show()
suspend fun Context.toastFromMainDispatcher(text: String, length: Int = Toast.LENGTH_SHORT) = withContext(
Dispatchers.Main
) {
Toast.makeText(this@toastFromMainDispatcher, text, length).show()
}
suspend fun Context.toastFromMainDispatcher(stringId: Int) {
toastFromMainDispatcher(getString(stringId))
suspend fun Context.toastFromMainDispatcher(stringId: Int, length: Int = Toast.LENGTH_SHORT) {
toastFromMainDispatcher(getString(stringId), length)
}

View File

@ -13,7 +13,7 @@ import com.github.libretube.api.PlaylistsHelper
import com.github.libretube.api.RetrofitInstance
import com.github.libretube.databinding.DialogAddToPlaylistBinding
import com.github.libretube.extensions.TAG
import com.github.libretube.extensions.toastFromMainThread
import com.github.libretube.extensions.toastFromMainDispatcher
import com.github.libretube.ui.models.PlaylistViewModel
import com.github.libretube.util.PlayingQueue
import com.google.android.material.dialog.MaterialAlertDialogBuilder
@ -90,10 +90,10 @@ class AddToPlaylistDialog(
PlaylistsHelper.addToPlaylist(playlistId, *streams.toTypedArray())
} catch (e: Exception) {
Log.e(TAG(), e.toString())
appContext.toastFromMainThread(R.string.unknown_error)
appContext.toastFromMainDispatcher(R.string.unknown_error)
return
}
appContext.toastFromMainThread(
appContext.toastFromMainDispatcher(
if (success) R.string.added_to_playlist else R.string.fail
)
}

View File

@ -8,7 +8,7 @@ import androidx.lifecycle.lifecycleScope
import com.github.libretube.R
import com.github.libretube.api.PlaylistsHelper
import com.github.libretube.databinding.DialogCreatePlaylistBinding
import com.github.libretube.extensions.toastFromMainThread
import com.github.libretube.extensions.toastFromMainDispatcher
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@ -34,7 +34,7 @@ class CreatePlaylistDialog(
if (playlistId != null) {
onSuccess()
}
appContext?.toastFromMainThread(
appContext?.toastFromMainDispatcher(
if (playlistId != null) R.string.playlistCloned else R.string.server_error
)
dismiss()

View File

@ -14,8 +14,11 @@ import com.github.libretube.api.obj.Login
import com.github.libretube.api.obj.Token
import com.github.libretube.databinding.DialogLoginBinding
import com.github.libretube.extensions.TAG
import com.github.libretube.extensions.toastFromMainDispatcher
import com.github.libretube.helpers.PreferenceHelper
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.serialization.decodeFromString
import retrofit2.HttpException
@ -62,7 +65,7 @@ class LoginDialog(
private fun signIn(username: String, password: String, createNewAccount: Boolean = false) {
val login = Login(username, password)
lifecycleScope.launchWhenCreated {
lifecycleScope.launch(Dispatchers.IO) {
val response = try {
if (createNewAccount) {
RetrofitInstance.authApi.register(login)
@ -73,25 +76,23 @@ class LoginDialog(
val errorMessage = e.response()?.errorBody()?.string()?.runCatching {
JsonHelper.json.decodeFromString<Token>(this).error
}?.getOrNull() ?: context?.getString(R.string.server_error) ?: ""
Toast.makeText(context, errorMessage, Toast.LENGTH_SHORT).show()
return@launchWhenCreated
context?.toastFromMainDispatcher(errorMessage)
return@launch
} catch (e: Exception) {
Log.e(TAG(), e.toString())
Toast.makeText(context, e.localizedMessage, Toast.LENGTH_SHORT).show()
return@launchWhenCreated
context?.toastFromMainDispatcher(e.localizedMessage.orEmpty())
return@launch
}
if (response.error != null) {
Toast.makeText(context, response.error, Toast.LENGTH_SHORT).show()
return@launchWhenCreated
context?.toastFromMainDispatcher(response.error)
return@launch
}
if (response.token == null) return@launchWhenCreated
if (response.token == null) return@launch
Toast.makeText(
context,
if (createNewAccount) R.string.registered else R.string.loggedIn,
Toast.LENGTH_SHORT
).show()
context?.toastFromMainDispatcher(
if (createNewAccount) R.string.registered else R.string.loggedIn
)
PreferenceHelper.setToken(response.token)
PreferenceHelper.setUsername(login.username)

View File

@ -12,7 +12,7 @@ import com.github.libretube.R
import com.github.libretube.api.PlaylistsHelper
import com.github.libretube.databinding.DialogTextPreferenceBinding
import com.github.libretube.extensions.TAG
import com.github.libretube.extensions.toastFromMainThread
import com.github.libretube.extensions.toastFromMainDispatcher
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@ -57,14 +57,14 @@ class RenamePlaylistDialog(
}
} catch (e: Exception) {
Log.e(TAG(), e.toString())
e.localizedMessage?.let { appContext.toastFromMainThread(it) }
e.localizedMessage?.let { appContext.toastFromMainDispatcher(it) }
return@launch
}
if (success) {
appContext.toastFromMainThread(R.string.success)
appContext.toastFromMainDispatcher(R.string.success)
onSuccess.invoke(newPlaylistName)
} else {
appContext.toastFromMainThread(R.string.server_error)
appContext.toastFromMainDispatcher(R.string.server_error)
}
dismiss()
}

View File

@ -60,6 +60,7 @@ import com.github.libretube.enums.ShareObjectType
import com.github.libretube.extensions.formatShort
import com.github.libretube.extensions.hideKeyboard
import com.github.libretube.extensions.toID
import com.github.libretube.extensions.toastFromMainDispatcher
import com.github.libretube.extensions.updateParameters
import com.github.libretube.helpers.BackgroundHelper
import com.github.libretube.helpers.DashHelper
@ -295,6 +296,8 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
endId: Int,
progress: Float
) {
if (_binding == null) return
mainMotionLayout.progress = abs(progress)
binding.player.hideController()
binding.player.useController = false
@ -303,6 +306,8 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
}
override fun onTransitionCompleted(motionLayout: MotionLayout?, currentId: Int) {
if (_binding == null) return
if (currentId == eId) {
viewModel.isMiniPlayerVisible.value = true
// disable captions
@ -662,13 +667,13 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
streams = try {
RetrofitInstance.api.getStreams(videoId!!)
} catch (e: IOException) {
Toast.makeText(context, R.string.unknown_error, Toast.LENGTH_LONG).show()
context?.toastFromMainDispatcher(R.string.unknown_error, Toast.LENGTH_LONG)
return@launch
} catch (e: HttpException) {
val errorMessage = e.response()?.errorBody()?.string()?.runCatching {
JsonHelper.json.decodeFromString<Message>(this).message
}?.getOrNull() ?: context?.getString(R.string.server_error) ?: ""
Toast.makeText(context, errorMessage, Toast.LENGTH_LONG).show()
context?.toastFromMainDispatcher(errorMessage, Toast.LENGTH_LONG)
return@launch
}
@ -1200,7 +1205,7 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
// set the name of the video chapter in the exoPlayerView
private fun setCurrentChapterName() {
// return if chapters are empty to avoid crashes
if (chapters.isEmpty()) return
if (chapters.isEmpty() || _binding == null) return
// call the function again in 100ms
binding.player.postDelayed(this::setCurrentChapterName, 100)

View File

@ -14,7 +14,7 @@ import com.github.libretube.constants.FALLBACK_INSTANCES_URL
import com.github.libretube.constants.PIPED_INSTANCES_URL
import com.github.libretube.constants.PreferenceKeys
import com.github.libretube.db.DatabaseHolder.Database
import com.github.libretube.extensions.toastFromMainThread
import com.github.libretube.extensions.toastFromMainDispatcher
import com.github.libretube.helpers.PreferenceHelper
import com.github.libretube.ui.base.BasePreferenceFragment
import com.github.libretube.ui.dialogs.CustomInstanceDialog
@ -142,7 +142,7 @@ class InstanceSettings : BasePreferenceFragment() {
}.getOrNull() ?: runCatching {
RetrofitInstance.externalApi.getInstances(FALLBACK_INSTANCES_URL).toMutableList()
}.getOrNull() ?: run {
appContext.toastFromMainThread(R.string.failed_fetching_instances)
appContext.toastFromMainDispatcher(R.string.failed_fetching_instances)
val instanceNames = resources.getStringArray(R.array.instances)
resources.getStringArray(R.array.instancesValue).mapIndexed { index, instanceValue ->
Instances(instanceNames[index], instanceValue)

View File

@ -8,7 +8,7 @@ import com.github.libretube.db.DatabaseHolder
import com.github.libretube.enums.PlaylistType
import com.github.libretube.enums.ShareObjectType
import com.github.libretube.extensions.toID
import com.github.libretube.extensions.toastFromMainThread
import com.github.libretube.extensions.toastFromMainDispatcher
import com.github.libretube.helpers.BackgroundHelper
import com.github.libretube.obj.ShareData
import com.github.libretube.ui.dialogs.DeletePlaylistDialog
@ -70,7 +70,7 @@ class PlaylistOptionsBottomSheet(
val playlistId = withContext(Dispatchers.IO) {
PlaylistsHelper.clonePlaylist(context, playlistId)
}
context.toastFromMainThread(
context.toastFromMainDispatcher(
if (playlistId != null) R.string.playlistCloned else R.string.server_error
)
}