mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 23:51:21 +02:00
Fix crash when changing seasons & improve error page (#94)
Related to #64 If an error occurred while querying for a season's episodes, the app would crash instead of display the error message. This PR fixes the app crash, but not the underlying query issue. It also changes the error page to show a button for sending logs to the server immediately.
This commit is contained in:
parent
50b0b0a508
commit
3ab9eafc7c
4 changed files with 88 additions and 42 deletions
|
|
@ -1,14 +1,39 @@
|
|||
package com.github.damontecres.wholphin.ui.components
|
||||
|
||||
import android.content.Context
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.tv.material3.Button
|
||||
import androidx.tv.material3.MaterialTheme
|
||||
import androidx.tv.material3.Text
|
||||
import com.github.damontecres.wholphin.ui.detail.DebugViewModel.Companion.sendAppLogs
|
||||
import com.github.damontecres.wholphin.util.LoadingState
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import org.jellyfin.sdk.api.client.ApiClient
|
||||
import org.jellyfin.sdk.model.ClientInfo
|
||||
import org.jellyfin.sdk.model.DeviceInfo
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class ErrorViewModel
|
||||
@Inject
|
||||
constructor(
|
||||
@param:ApplicationContext private val context: Context,
|
||||
private val api: ApiClient,
|
||||
private val clientInfo: ClientInfo,
|
||||
private val deviceInfo: DeviceInfo,
|
||||
) : ViewModel() {
|
||||
fun sendLogs() {
|
||||
sendAppLogs(context, api, clientInfo, deviceInfo)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays an error message and/or exception
|
||||
|
|
@ -18,40 +43,48 @@ fun ErrorMessage(
|
|||
message: String?,
|
||||
exception: Throwable?,
|
||||
modifier: Modifier = Modifier,
|
||||
viewModel: ErrorViewModel = hiltViewModel(),
|
||||
) {
|
||||
LazyColumn(
|
||||
contentPadding = PaddingValues(16.dp),
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||
modifier = modifier,
|
||||
modifier = modifier.padding(16.dp),
|
||||
) {
|
||||
Text(
|
||||
text = "An error occurred! Press the button to send logs to your server.",
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
)
|
||||
Button(
|
||||
onClick = {
|
||||
viewModel.sendLogs()
|
||||
},
|
||||
) {
|
||||
Text(
|
||||
text = "Send Logs",
|
||||
)
|
||||
}
|
||||
message?.let {
|
||||
item {
|
||||
Text(
|
||||
text = it,
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
)
|
||||
}
|
||||
Text(
|
||||
text = it,
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
)
|
||||
}
|
||||
exception?.localizedMessage?.let {
|
||||
item {
|
||||
Text(
|
||||
text = it,
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
)
|
||||
}
|
||||
Text(
|
||||
text = it,
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
)
|
||||
}
|
||||
var cause = exception?.cause
|
||||
while (cause != null) {
|
||||
cause.localizedMessage?.let {
|
||||
item {
|
||||
Text(
|
||||
text = "Caused by: $it",
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
)
|
||||
}
|
||||
Text(
|
||||
text = "Caused by: $it",
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
)
|
||||
}
|
||||
cause = cause.cause
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.github.damontecres.wholphin.ui.detail
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.focusable
|
||||
|
|
@ -34,11 +35,16 @@ import com.github.damontecres.wholphin.data.ServerRepository
|
|||
import com.github.damontecres.wholphin.data.model.ItemPlayback
|
||||
import com.github.damontecres.wholphin.preferences.UserPreferences
|
||||
import com.github.damontecres.wholphin.ui.launchIO
|
||||
import com.github.damontecres.wholphin.ui.showToast
|
||||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.jellyfin.sdk.api.client.ApiClient
|
||||
import org.jellyfin.sdk.api.client.extensions.clientLogApi
|
||||
import org.jellyfin.sdk.model.ClientInfo
|
||||
import org.jellyfin.sdk.model.DeviceInfo
|
||||
import java.io.BufferedReader
|
||||
import java.io.InputStreamReader
|
||||
import javax.inject.Inject
|
||||
|
|
@ -110,6 +116,26 @@ class DebugViewModel
|
|||
}
|
||||
return logLines
|
||||
}
|
||||
|
||||
fun ViewModel.sendAppLogs(
|
||||
context: Context,
|
||||
api: ApiClient,
|
||||
clientInfo: ClientInfo?,
|
||||
deviceInfo: DeviceInfo?,
|
||||
) {
|
||||
viewModelScope.launchIO(ExceptionHandler(true)) {
|
||||
val logcat = getLogCatLines().joinToString("\n") { it.text }
|
||||
val body =
|
||||
"""
|
||||
Send App Logs
|
||||
clientInfo=$clientInfo
|
||||
deviceInfo=$deviceInfo
|
||||
|
||||
""".trimIndent() + logcat
|
||||
val response by api.clientLogApi.logFile(body)
|
||||
showToast(context, "Sent! Filename=${response.fileName}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ class SeriesViewModel
|
|||
)
|
||||
val pager = ApiRequestPager(api, request, GetEpisodesRequestHandler, viewModelScope)
|
||||
pager.init()
|
||||
Timber.Forest.v("Loaded ${pager.size} episodes for season $season")
|
||||
Timber.v("Loaded ${pager.size} episodes for season $season")
|
||||
return EpisodeList.Success(convertPager(pager))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,18 +12,16 @@ import com.github.damontecres.wholphin.data.isPinned
|
|||
import com.github.damontecres.wholphin.data.model.NavDrawerPinnedItem
|
||||
import com.github.damontecres.wholphin.data.model.NavPinType
|
||||
import com.github.damontecres.wholphin.preferences.AppPreferences
|
||||
import com.github.damontecres.wholphin.ui.detail.DebugViewModel
|
||||
import com.github.damontecres.wholphin.ui.detail.DebugViewModel.Companion.sendAppLogs
|
||||
import com.github.damontecres.wholphin.ui.launchIO
|
||||
import com.github.damontecres.wholphin.ui.nav.NavDrawerItem
|
||||
import com.github.damontecres.wholphin.ui.nav.NavigationManager
|
||||
import com.github.damontecres.wholphin.ui.setValueOnMain
|
||||
import com.github.damontecres.wholphin.ui.showToast
|
||||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||
import com.github.damontecres.wholphin.util.RememberTabManager
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import org.jellyfin.sdk.api.client.ApiClient
|
||||
import org.jellyfin.sdk.api.client.extensions.clientLogApi
|
||||
import org.jellyfin.sdk.model.ClientInfo
|
||||
import org.jellyfin.sdk.model.DeviceInfo
|
||||
import javax.inject.Inject
|
||||
|
|
@ -91,17 +89,6 @@ class PreferencesViewModel
|
|||
}
|
||||
|
||||
fun sendAppLogs() {
|
||||
viewModelScope.launchIO(ExceptionHandler(true)) {
|
||||
val logcat = DebugViewModel.getLogCatLines().joinToString("\n") { it.text }
|
||||
val body =
|
||||
"""
|
||||
Send App Logs
|
||||
$clientInfo
|
||||
$deviceInfo
|
||||
|
||||
""".trimIndent() + logcat
|
||||
val response by api.clientLogApi.logFile(body)
|
||||
showToast(context, "Sent! Filename=${response.fileName}")
|
||||
}
|
||||
sendAppLogs(context, api, clientInfo, deviceInfo)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue