mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-09 16:11:20 +02:00
Fix some IO related crashes (#1008)
## Description - Catch network exceptions when querying to populate the nav drawer - Perform screensaver work on IO thread - Fix possible crash if screensaver service runs while regular activity is destroyed - Fix genre images & backdrop images not loading This PR also adds an Jellyfin SDK `ApiClient` wrapper to push all network calls onto the IO thread. And tries to use a more strict network-on-main policy for debug builds. ### Related issues Fixes #994 Fixes #1001 Should fix #1003 ### Testing Emulator with simulated exception throws ## Screenshots N/A ## AI or LLM usage None
This commit is contained in:
parent
37d52ef57e
commit
9b995bf6ba
11 changed files with 147 additions and 42 deletions
|
|
@ -52,7 +52,7 @@ class BackdropService
|
|||
if (item.type == BaseItemKind.GENRE) {
|
||||
item.imageUrlOverride
|
||||
} else {
|
||||
imageUrlService.getItemImageUrl(item, ImageType.BACKDROP)!!
|
||||
imageUrlService.getItemImageUrl(item, ImageType.BACKDROP)
|
||||
}
|
||||
submit(item.id.toString(), imageUrl)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,11 +28,11 @@ class ImageUrlService
|
|||
itemType: BaseItemKind,
|
||||
seriesId: UUID?,
|
||||
useSeriesForPrimary: Boolean,
|
||||
imageTags: Map<ImageType, String?>,
|
||||
imageType: ImageType,
|
||||
imageTags: Map<ImageType, String?>,
|
||||
backdropTags: List<String>,
|
||||
parentThumbId: UUID? = null,
|
||||
parentBackdropId: UUID? = null,
|
||||
backdropTags: List<String> = emptyList(),
|
||||
fillWidth: Int? = null,
|
||||
fillHeight: Int? = null,
|
||||
): String? =
|
||||
|
|
|
|||
|
|
@ -11,11 +11,13 @@ import com.github.damontecres.wholphin.ui.main.settings.Library
|
|||
import com.github.damontecres.wholphin.ui.nav.Destination
|
||||
import com.github.damontecres.wholphin.ui.nav.NavDrawerItem
|
||||
import com.github.damontecres.wholphin.ui.nav.ServerNavDrawerItem
|
||||
import com.github.damontecres.wholphin.ui.showToast
|
||||
import com.github.damontecres.wholphin.util.supportedCollectionTypes
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
|
|
@ -60,7 +62,11 @@ class NavDrawerService
|
|||
if (user != null && userDto != null && user.id == userDto.id) {
|
||||
updateNavDrawer(user, userDto)
|
||||
}
|
||||
}.catch { ex ->
|
||||
Timber.e(ex, "Error updating nav drawer")
|
||||
showToast(context, "Error fetching user's views")
|
||||
}.launchIn(coroutineScope)
|
||||
|
||||
seerrServerRepository.active
|
||||
.onEach { discoverActive ->
|
||||
_state.update { it.copy(discoverEnabled = discoverActive) }
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
package com.github.damontecres.wholphin.services
|
||||
|
||||
import android.content.Context
|
||||
import android.view.WindowManager
|
||||
import coil3.imageLoader
|
||||
import coil3.request.ImageRequest
|
||||
import com.github.damontecres.wholphin.MainActivity
|
||||
import com.github.damontecres.wholphin.services.hilt.DefaultCoroutineScope
|
||||
import com.github.damontecres.wholphin.ui.components.CurrentItem
|
||||
import com.github.damontecres.wholphin.ui.formatDate
|
||||
import com.github.damontecres.wholphin.ui.launchDefault
|
||||
import com.github.damontecres.wholphin.util.ApiRequestPager
|
||||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||
import com.github.damontecres.wholphin.util.GetItemsRequestHandler
|
||||
|
|
@ -23,11 +22,11 @@ import kotlinx.coroutines.flow.StateFlow
|
|||
import kotlinx.coroutines.flow.cancellable
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.jellyfin.sdk.api.client.ApiClient
|
||||
import org.jellyfin.sdk.api.client.extensions.libraryApi
|
||||
import org.jellyfin.sdk.model.api.BaseItemKind
|
||||
|
|
@ -52,6 +51,8 @@ class ScreensaverService
|
|||
private val _state = MutableStateFlow(ScreensaverState(false, false, false, false))
|
||||
val state: StateFlow<ScreensaverState> = _state
|
||||
|
||||
val keepScreenOn = MutableStateFlow(false)
|
||||
|
||||
private var waitJob: Job? = null
|
||||
|
||||
init {
|
||||
|
|
@ -114,7 +115,7 @@ class ScreensaverService
|
|||
}
|
||||
|
||||
fun keepScreenOn(keep: Boolean) {
|
||||
scope.launch {
|
||||
scope.launchDefault {
|
||||
val screensaverEnabled = _state.value.enabled
|
||||
Timber.d("Keep screen on: %s, screensaverEnabled=%s", keep, screensaverEnabled)
|
||||
if (screensaverEnabled) {
|
||||
|
|
@ -131,15 +132,9 @@ class ScreensaverService
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun keepScreenOnInternal(keep: Boolean) =
|
||||
withContext(Dispatchers.Main) {
|
||||
val window = MainActivity.instance.window
|
||||
if (keep) {
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||
} else {
|
||||
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||
}
|
||||
}
|
||||
private fun keepScreenOnInternal(keep: Boolean) {
|
||||
keepScreenOn.update { keep }
|
||||
}
|
||||
|
||||
fun createItemFlow(scope: CoroutineScope): Flow<CurrentItem?> =
|
||||
flow {
|
||||
|
|
@ -186,7 +181,7 @@ class ScreensaverService
|
|||
}
|
||||
val logoUrl = imageUrlService.getItemImageUrl(item, ImageType.LOGO)
|
||||
if (backdropUrl != null) {
|
||||
val result =
|
||||
try {
|
||||
context.imageLoader
|
||||
.enqueue(
|
||||
ImageRequest
|
||||
|
|
@ -195,7 +190,6 @@ class ScreensaverService
|
|||
.build(),
|
||||
).job
|
||||
.await()
|
||||
try {
|
||||
emit(CurrentItem(item, backdropUrl, logoUrl, title ?: ""))
|
||||
} catch (_: CancellationException) {
|
||||
break
|
||||
|
|
@ -211,7 +205,7 @@ class ScreensaverService
|
|||
index++
|
||||
}
|
||||
}
|
||||
}.cancellable()
|
||||
}.flowOn(Dispatchers.Default).cancellable()
|
||||
}
|
||||
|
||||
data class ScreensaverState(
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import com.github.damontecres.wholphin.preferences.AppPreferences
|
|||
import com.github.damontecres.wholphin.preferences.UserPreferences
|
||||
import com.github.damontecres.wholphin.preferences.updateInterfacePreferences
|
||||
import com.github.damontecres.wholphin.services.SeerrApi
|
||||
import com.github.damontecres.wholphin.util.CoroutineContextApiClientFactory
|
||||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||
import com.github.damontecres.wholphin.util.RememberTabManager
|
||||
import dagger.Module
|
||||
|
|
@ -111,12 +112,12 @@ object AppModule {
|
|||
@Singleton
|
||||
fun okHttpFactory(
|
||||
@StandardOkHttpClient okHttpClient: OkHttpClient,
|
||||
) = OkHttpFactory(okHttpClient)
|
||||
) = CoroutineContextApiClientFactory(OkHttpFactory(okHttpClient))
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun jellyfin(
|
||||
okHttpFactory: OkHttpFactory,
|
||||
okHttpFactory: CoroutineContextApiClientFactory,
|
||||
@ApplicationContext context: Context,
|
||||
clientInfo: ClientInfo,
|
||||
deviceInfo: DeviceInfo,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue