mirror of
https://github.com/mihonapp/mihon.git
synced 2024-11-14 20:39:59 -05:00
Make migration changes
This commit is contained in:
parent
298a1134e6
commit
17d9e47b11
9 changed files with 154 additions and 87 deletions
|
@ -358,14 +358,14 @@ fun FailedUpdatesBottomActionMenu(
|
||||||
.padding(horizontal = 8.dp, vertical = 12.dp),
|
.padding(horizontal = 8.dp, vertical = 12.dp),
|
||||||
) {
|
) {
|
||||||
Button(
|
Button(
|
||||||
title = stringResource(R.string.action_delete),
|
title = stringResource(MR.strings.action_delete),
|
||||||
icon = Icons.Outlined.Delete,
|
icon = Icons.Outlined.Delete,
|
||||||
toConfirm = confirm[0],
|
toConfirm = confirm[0],
|
||||||
onLongClick = { onLongClickItem(0) },
|
onLongClick = { onLongClickItem(0) },
|
||||||
onClick = onDeleteClicked,
|
onClick = onDeleteClicked,
|
||||||
)
|
)
|
||||||
Button(
|
Button(
|
||||||
title = stringResource(R.string.action_dismiss),
|
title = stringResource(MR.strings.action_dismiss),
|
||||||
icon = Icons.Outlined.VisibilityOff,
|
icon = Icons.Outlined.VisibilityOff,
|
||||||
toConfirm = confirm[1],
|
toConfirm = confirm[1],
|
||||||
onLongClick = { onLongClickItem(1) },
|
onLongClick = { onLongClickItem(1) },
|
||||||
|
@ -373,7 +373,7 @@ fun FailedUpdatesBottomActionMenu(
|
||||||
)
|
)
|
||||||
if (groupingMode == GroupByMode.NONE && selected.size <= 1) {
|
if (groupingMode == GroupByMode.NONE && selected.size <= 1) {
|
||||||
Button(
|
Button(
|
||||||
title = stringResource(R.string.action_info),
|
title = stringResource(MR.strings.action_info),
|
||||||
icon = Icons.Outlined.Info,
|
icon = Icons.Outlined.Info,
|
||||||
toConfirm = confirm[2],
|
toConfirm = confirm[2],
|
||||||
onLongClick = { onLongClickItem(2) },
|
onLongClick = { onLongClickItem(2) },
|
||||||
|
|
|
@ -30,6 +30,7 @@ import eu.kanade.tachiyomi.data.download.model.Download
|
||||||
import eu.kanade.tachiyomi.ui.updates.UpdatesItem
|
import eu.kanade.tachiyomi.ui.updates.UpdatesItem
|
||||||
import eu.kanade.tachiyomi.ui.updates.UpdatesScreenModel
|
import eu.kanade.tachiyomi.ui.updates.UpdatesScreenModel
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import tachiyomi.i18n.MR
|
import tachiyomi.i18n.MR
|
||||||
|
@ -152,26 +153,33 @@ private fun UpdatesAppBar(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
title = stringResource(MR.strings.label_recent_updates),
|
title = stringResource(MR.strings.label_recent_updates),
|
||||||
actions = {
|
actions = {
|
||||||
val actions = mutableListOf<AppBar.Action>()
|
val actions = mutableListOf<AppBar.Action>().apply {
|
||||||
if (hasFailedUpdates) { // only add the warning icon if it is enabled
|
if (hasFailedUpdates) {
|
||||||
actions += AppBar.Action(
|
add(
|
||||||
title = stringResource(R.string.action_update_warning),
|
AppBar.Action(
|
||||||
icon = Icons.Rounded.Warning,
|
title = stringResource(MR.strings.action_update_warning),
|
||||||
onClick = onUpdateWarning,
|
icon = Icons.Rounded.Warning,
|
||||||
iconTint = warningIconTint,
|
onClick = onUpdateWarning,
|
||||||
|
iconTint = warningIconTint,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
add(
|
||||||
|
AppBar.Action(
|
||||||
|
title = stringResource(MR.strings.action_view_upcoming),
|
||||||
|
icon = Icons.Outlined.CalendarMonth,
|
||||||
|
onClick = onCalendarClicked,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
add(
|
||||||
|
AppBar.Action(
|
||||||
|
title = stringResource(MR.strings.action_update_library),
|
||||||
|
icon = Icons.Outlined.Refresh,
|
||||||
|
onClick = onUpdateLibrary,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
actions += AppBar.Action(
|
AppBarActions(actions.toImmutableList())
|
||||||
title = stringResource(MR.strings.action_view_upcoming),
|
|
||||||
icon = Icons.Outlined.CalendarMonth,
|
|
||||||
onClick = onCalendarClicked,
|
|
||||||
)
|
|
||||||
actions += AppBar.Action(
|
|
||||||
title = stringResource(R.string.action_update_library),
|
|
||||||
icon = Icons.Outlined.Refresh,
|
|
||||||
onClick = onUpdateLibrary,
|
|
||||||
)
|
|
||||||
AppBarActions(actions)
|
|
||||||
},
|
},
|
||||||
actionModeCounter = actionModeCounter,
|
actionModeCounter = actionModeCounter,
|
||||||
onCancelActionMode = onCancelActionMode,
|
onCancelActionMode = onCancelActionMode,
|
||||||
|
|
|
@ -27,9 +27,9 @@ import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.foundation.shape.CornerSize
|
import androidx.compose.foundation.shape.CornerSize
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.Dangerous
|
||||||
import androidx.compose.material.icons.filled.KeyboardArrowUp
|
import androidx.compose.material.icons.filled.KeyboardArrowUp
|
||||||
import androidx.compose.material.icons.rounded.Warning
|
import androidx.compose.material.icons.rounded.Warning
|
||||||
import androidx.compose.material.ripple.rememberRipple
|
|
||||||
import androidx.compose.material3.CardDefaults
|
import androidx.compose.material3.CardDefaults
|
||||||
import androidx.compose.material3.ElevatedCard
|
import androidx.compose.material3.ElevatedCard
|
||||||
import androidx.compose.material3.HorizontalDivider
|
import androidx.compose.material3.HorizontalDivider
|
||||||
|
@ -38,6 +38,7 @@ import androidx.compose.material3.LocalContentColor
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.minimumInteractiveComponentSize
|
import androidx.compose.material3.minimumInteractiveComponentSize
|
||||||
|
import androidx.compose.material3.ripple
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
@ -49,6 +50,7 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.draw.rotate
|
import androidx.compose.ui.draw.rotate
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.graphics.ColorFilter
|
||||||
import androidx.compose.ui.graphics.ImageBitmap
|
import androidx.compose.ui.graphics.ImageBitmap
|
||||||
import androidx.compose.ui.graphics.asImageBitmap
|
import androidx.compose.ui.graphics.asImageBitmap
|
||||||
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
||||||
|
@ -244,6 +246,15 @@ fun LazyListScope.failedUpdatesGroupUiItem(
|
||||||
.height(50.dp)
|
.height(50.dp)
|
||||||
.aspectRatio(1f),
|
.aspectRatio(1f),
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
Image(
|
||||||
|
imageVector = Icons.Filled.Dangerous,
|
||||||
|
contentDescription = null,
|
||||||
|
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.error),
|
||||||
|
modifier = Modifier
|
||||||
|
.height(50.dp)
|
||||||
|
.aspectRatio(1f),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
@ -313,11 +324,13 @@ fun LazyListScope.failedUpdatesGroupUiItem(
|
||||||
if (expanded[errorMessageHeaderId] == null) {
|
if (expanded[errorMessageHeaderId] == null) {
|
||||||
onExpandedMapChange(errorMessageHeaderId, true)
|
onExpandedMapChange(errorMessageHeaderId, true)
|
||||||
} else {
|
} else {
|
||||||
onExpandedMapChange(errorMessageHeaderId, !expanded[errorMessageHeaderId]!!)
|
onExpandedMapChange(
|
||||||
|
errorMessageHeaderId,
|
||||||
|
!expanded[errorMessageHeaderId]!!,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onLongClick =
|
onLongClick = { onGroupSelected(items) },
|
||||||
{ onGroupSelected(items) },
|
|
||||||
)
|
)
|
||||||
.padding(
|
.padding(
|
||||||
horizontal = 12.dp,
|
horizontal = 12.dp,
|
||||||
|
@ -390,7 +403,9 @@ fun LazyListScope.failedUpdatesGroupUiItem(
|
||||||
val isLastItem = index == items.lastIndex
|
val isLastItem = index == items.lastIndex
|
||||||
AnimatedVisibility(
|
AnimatedVisibility(
|
||||||
modifier = Modifier,
|
modifier = Modifier,
|
||||||
visible = expanded[errorMessageHeaderId] == true && expanded[GroupKey(id, Pair("", ""))] == true,
|
visible =
|
||||||
|
expanded[errorMessageHeaderId] == true &&
|
||||||
|
expanded[GroupKey(id, Pair("", ""))] == true,
|
||||||
) {
|
) {
|
||||||
FailedUpdatesUiItem(
|
FailedUpdatesUiItem(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
@ -443,10 +458,12 @@ fun CustomIconButton(
|
||||||
enabled = enabled,
|
enabled = enabled,
|
||||||
role = Role.Button,
|
role = Role.Button,
|
||||||
interactionSource = interactionSource,
|
interactionSource = interactionSource,
|
||||||
indication = rememberRipple(
|
indication = remember {
|
||||||
bounded = false,
|
ripple(
|
||||||
radius = 20.dp,
|
bounded = false,
|
||||||
),
|
radius = 20.dp,
|
||||||
|
)
|
||||||
|
},
|
||||||
),
|
),
|
||||||
contentAlignment = Alignment.Center,
|
contentAlignment = Alignment.Center,
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -32,7 +32,7 @@ fun ErrorMessageDialog(
|
||||||
TextButton(onClick = {
|
TextButton(onClick = {
|
||||||
onCopyClick()
|
onCopyClick()
|
||||||
onDismissRequest()
|
onDismissRequest()
|
||||||
},) {
|
}) {
|
||||||
Text(text = stringResource(R.string.copy))
|
Text(text = stringResource(R.string.copy))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -51,7 +51,9 @@ import eu.kanade.presentation.util.Screen
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaScreen
|
import eu.kanade.tachiyomi.ui.manga.MangaScreen
|
||||||
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||||
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
import tachiyomi.i18n.MR
|
||||||
import tachiyomi.presentation.core.components.FastScrollLazyColumn
|
import tachiyomi.presentation.core.components.FastScrollLazyColumn
|
||||||
import tachiyomi.presentation.core.components.Pill
|
import tachiyomi.presentation.core.components.Pill
|
||||||
import tachiyomi.presentation.core.components.SortItem
|
import tachiyomi.presentation.core.components.SortItem
|
||||||
|
@ -59,8 +61,6 @@ import tachiyomi.presentation.core.components.material.ExtendedFloatingActionBut
|
||||||
import tachiyomi.presentation.core.components.material.Scaffold
|
import tachiyomi.presentation.core.components.material.Scaffold
|
||||||
import tachiyomi.presentation.core.screens.EmptyScreen
|
import tachiyomi.presentation.core.screens.EmptyScreen
|
||||||
import tachiyomi.presentation.core.screens.LoadingScreen
|
import tachiyomi.presentation.core.screens.LoadingScreen
|
||||||
import tachiyomi.presentation.core.util.isScrolledToEnd
|
|
||||||
import tachiyomi.presentation.core.util.isScrollingUp
|
|
||||||
import tachiyomi.source.local.isLocal
|
import tachiyomi.source.local.isLocal
|
||||||
|
|
||||||
class FailedUpdatesScreen : Screen() {
|
class FailedUpdatesScreen : Screen() {
|
||||||
|
@ -120,7 +120,8 @@ class FailedUpdatesScreen : Screen() {
|
||||||
text = { Text(text = stringResource(R.string.label_help)) },
|
text = { Text(text = stringResource(R.string.label_help)) },
|
||||||
icon = { Icon(imageVector = Icons.Outlined.HelpOutline, contentDescription = null) },
|
icon = { Icon(imageVector = Icons.Outlined.HelpOutline, contentDescription = null) },
|
||||||
onClick = { uriHandler.openUri("https://tachiyomi.org/help/guides/troubleshooting") },
|
onClick = { uriHandler.openUri("https://tachiyomi.org/help/guides/troubleshooting") },
|
||||||
expanded = failedUpdatesListState.isScrollingUp() || failedUpdatesListState.isScrolledToEnd(),
|
// Revisit
|
||||||
|
// expanded = failedUpdatesListState.isScrollingUp() || failedUpdatesListState.isScrolledToEnd(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -129,7 +130,7 @@ class FailedUpdatesScreen : Screen() {
|
||||||
state.isLoading -> LoadingScreen(modifier = Modifier.padding(contentPadding))
|
state.isLoading -> LoadingScreen(modifier = Modifier.padding(contentPadding))
|
||||||
|
|
||||||
state.items.isEmpty() -> EmptyScreen(
|
state.items.isEmpty() -> EmptyScreen(
|
||||||
textResource = R.string.information_no_update_errors,
|
stringRes = MR.strings.information_no_update_errors,
|
||||||
modifier = Modifier.padding(contentPadding),
|
modifier = Modifier.padding(contentPadding),
|
||||||
happyFace = true,
|
happyFace = true,
|
||||||
)
|
)
|
||||||
|
@ -363,7 +364,7 @@ private fun FailedUpdatesAppBar(
|
||||||
onClick = { onClickGroup(GroupByMode.NONE) },
|
onClick = { onClickGroup(GroupByMode.NONE) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
AppBarActions(actions)
|
AppBarActions(actions.toImmutableList())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
scrollBehavior = scrollBehavior,
|
scrollBehavior = scrollBehavior,
|
||||||
|
@ -399,7 +400,7 @@ private fun FailedUpdatesActionAppBar(
|
||||||
icon = Icons.Outlined.FlipToBack,
|
icon = Icons.Outlined.FlipToBack,
|
||||||
onClick = onInvertSelection,
|
onClick = onInvertSelection,
|
||||||
),
|
),
|
||||||
),
|
).toImmutableList(),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
scrollBehavior = scrollBehavior,
|
scrollBehavior = scrollBehavior,
|
||||||
|
|
|
@ -4,11 +4,10 @@ import android.content.Context
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import cafe.adriel.voyager.core.model.StateScreenModel
|
import cafe.adriel.voyager.core.model.StateScreenModel
|
||||||
import cafe.adriel.voyager.core.model.coroutineScope
|
import cafe.adriel.voyager.core.model.screenModelScope
|
||||||
import eu.kanade.core.util.addOrRemove
|
import eu.kanade.core.util.addOrRemove
|
||||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||||
import eu.kanade.domain.source.interactor.GetSourcesWithFavoriteCount
|
import eu.kanade.domain.source.interactor.GetSourcesWithFavoriteCount
|
||||||
import eu.kanade.tachiyomi.R
|
|
||||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||||
|
@ -20,11 +19,11 @@ import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.receiveAsFlow
|
import kotlinx.coroutines.flow.receiveAsFlow
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
import tachiyomi.core.preference.PreferenceStore
|
import tachiyomi.core.common.preference.PreferenceStore
|
||||||
import tachiyomi.core.preference.getEnum
|
import tachiyomi.core.common.preference.getEnum
|
||||||
import tachiyomi.core.util.lang.launchIO
|
import tachiyomi.core.common.util.lang.launchIO
|
||||||
import tachiyomi.core.util.lang.launchNonCancellable
|
import tachiyomi.core.common.util.lang.launchNonCancellable
|
||||||
import tachiyomi.core.util.system.logcat
|
import tachiyomi.core.common.util.system.logcat
|
||||||
import tachiyomi.domain.category.interactor.GetCategories
|
import tachiyomi.domain.category.interactor.GetCategories
|
||||||
import tachiyomi.domain.category.model.Category
|
import tachiyomi.domain.category.model.Category
|
||||||
import tachiyomi.domain.failed.repository.FailedUpdatesRepository
|
import tachiyomi.domain.failed.repository.FailedUpdatesRepository
|
||||||
|
@ -56,7 +55,7 @@ class FailedUpdatesScreenModel(
|
||||||
val channel = _channel.receiveAsFlow()
|
val channel = _channel.receiveAsFlow()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
coroutineScope.launchIO {
|
screenModelScope.launchIO {
|
||||||
val sortMode = preferenceStore.getEnum("sort_mode", SortingMode.BY_ALPHABET).get()
|
val sortMode = preferenceStore.getEnum("sort_mode", SortingMode.BY_ALPHABET).get()
|
||||||
combine(
|
combine(
|
||||||
getSourcesWithFavoriteCount.subscribe(),
|
getSourcesWithFavoriteCount.subscribe(),
|
||||||
|
@ -79,10 +78,12 @@ class FailedUpdatesScreenModel(
|
||||||
items = libraryManga.filter { libraryManga ->
|
items = libraryManga.filter { libraryManga ->
|
||||||
failedUpdates.any { it.mangaId == libraryManga.manga.id }
|
failedUpdates.any { it.mangaId == libraryManga.manga.id }
|
||||||
}.map { libraryManga ->
|
}.map { libraryManga ->
|
||||||
val source = sourceManager.get(libraryManga.manga.source)!!
|
// Untrusted Extensions cause null crash
|
||||||
|
val source = sourceManager.getOrStub(libraryManga.manga.source)
|
||||||
val failedUpdate = failedUpdates.find { it.mangaId == libraryManga.manga.id }!!
|
val failedUpdate = failedUpdates.find { it.mangaId == libraryManga.manga.id }!!
|
||||||
val errorMessage = failedUpdate.errorMessage
|
val errorMessage = failedUpdate.errorMessage
|
||||||
val simplifiedErrorMessage = simplifyErrorMessage(errorMessage.substringBefore(":"), failedUpdate.isOnline)
|
val simplifiedErrorMessage =
|
||||||
|
simplifyErrorMessage(errorMessage.substringBefore(":"), failedUpdate.isOnline)
|
||||||
FailedUpdatesManga(
|
FailedUpdatesManga(
|
||||||
libraryManga = libraryManga,
|
libraryManga = libraryManga,
|
||||||
errorMessage = errorMessage,
|
errorMessage = errorMessage,
|
||||||
|
@ -106,42 +107,56 @@ class FailedUpdatesScreenModel(
|
||||||
private fun simplifyErrorMessage(exception: String, isOnline: Long): String {
|
private fun simplifyErrorMessage(exception: String, isOnline: Long): String {
|
||||||
return when (exception) {
|
return when (exception) {
|
||||||
// General networking exceptions
|
// General networking exceptions
|
||||||
"SocketException" -> context.getString(R.string.exception_socket_error)
|
// Hold your arses this is temporary and for testing purposes only
|
||||||
"BindException" -> context.getString(R.string.exception_bind_port)
|
"SocketException" -> "Socket Exception"
|
||||||
"InterruptedIOException" -> context.getString(R.string.exception_io_interrupted)
|
"BindException" -> "Bind Exception"
|
||||||
"HttpRetryException" -> context.getString(R.string.exception_http_retry)
|
"InterruptedIOException" -> "Interrupted IO Exception"
|
||||||
"PortUnreachableException" -> context.getString(R.string.exception_port_unreachable)
|
"HttpRetryException" -> "HTTP Retry Exception"
|
||||||
|
"PortUnreachableException" -> "Port Unreachable Exception"
|
||||||
// General IO-related exceptions
|
// General IO-related exceptions
|
||||||
"IOException" -> if (isOnline == 1L) context.getString(R.string.exception_io_error) else context.getString(R.string.exception_internet_connection)
|
"IOException" -> if (isOnline ==
|
||||||
"TimeoutException" -> context.getString(R.string.exception_timed_out)
|
1L
|
||||||
|
) {
|
||||||
|
"IO Exception"
|
||||||
|
} else {
|
||||||
|
"IOException: No Internet"
|
||||||
|
}
|
||||||
|
"TimeoutException" -> "Timeout Exception"
|
||||||
// SSL & Security-related
|
// SSL & Security-related
|
||||||
"SSLException" -> context.getString(R.string.exception_ssl_connection)
|
"SSLException" -> "SSL Exception"
|
||||||
"CertificateExpiredException" -> context.getString(R.string.exception_ssl_certificate)
|
"CertificateExpiredException" -> "Certificate Expired Exception"
|
||||||
"CertificateNotYetValidException" -> context.getString(R.string.exception_ssl_not_valid)
|
"CertificateNotYetValidException" -> "Certificate Not Yet Valid Exception"
|
||||||
"CertificateParsingException" -> context.getString(R.string.exception_ssl_parsing)
|
"CertificateParsingException" -> "Certificate Parsing Exception"
|
||||||
"CertificateEncodingException" -> context.getString(R.string.exception_ssl_encoding)
|
"CertificateEncodingException" -> "Certificate Encoding Exception"
|
||||||
"UnrecoverableKeyException" -> context.getString(R.string.exception_unrecoverable_key)
|
"UnrecoverableKeyException" -> "Unrecoverable Key Exception"
|
||||||
"KeyManagementException" -> context.getString(R.string.exception_key_management)
|
"KeyManagementException" -> "Key Management Exception"
|
||||||
"NoSuchAlgorithmException" -> context.getString(R.string.exception_algorithm)
|
"NoSuchAlgorithmException" -> "No Such Algorithm Exception"
|
||||||
"KeyStoreException" -> context.getString(R.string.exception_keystore)
|
"KeyStoreException" -> "Key Store Exception"
|
||||||
"NoSuchProviderException" -> context.getString(R.string.exception_security_provider)
|
"NoSuchProviderException" -> "No Such Provider Exception"
|
||||||
"SignatureException" -> context.getString(R.string.exception_signature_validation)
|
"SignatureException" -> "Signature Exception"
|
||||||
"InvalidKeySpecException" -> context.getString(R.string.exception_key_specification)
|
"InvalidKeySpecException" -> "Invalid Key Spec Exception"
|
||||||
// Host & DNS-related
|
// Host & DNS-related
|
||||||
"UnknownHostException" -> if (isOnline == 1L) context.getString(R.string.exception_domain) else context.getString(R.string.exception_internet_connection)
|
"UnknownHostException" -> if (isOnline ==
|
||||||
"NoRouteToHostException" -> context.getString(R.string.exception_route_to_host)
|
1L
|
||||||
|
) {
|
||||||
|
"Unknown Host Exception"
|
||||||
|
} else {
|
||||||
|
"Unknown Host Exception: No Internet"
|
||||||
|
}
|
||||||
|
"ConnectException" -> "Connect Exception"
|
||||||
|
"NoRouteToHostException" -> "No Route To Host Exception"
|
||||||
// URL & URI related
|
// URL & URI related
|
||||||
"URISyntaxException" -> context.getString(R.string.exception_uri_syntax)
|
"URISyntaxException" -> "URI Syntax Exception"
|
||||||
"MalformedURLException" -> context.getString(R.string.exception_malformed_url)
|
"MalformedURLException" -> "Malformed URL Exception"
|
||||||
// Authentication & Proxy
|
// Authentication & Proxy
|
||||||
"ProtocolException" -> context.getString(R.string.exception_protocol_proxy_type)
|
"ProtocolException" -> "Protocol Exception"
|
||||||
// Concurrency & Operation-related
|
// Concurrency & Operation-related
|
||||||
"CancellationException" -> context.getString(R.string.exception_cancelled)
|
"CancellationException" -> "Cancellation Exception"
|
||||||
"InterruptedException" -> context.getString(R.string.exception_interrupted)
|
"InterruptedException" -> "Interrupted Exception"
|
||||||
"IllegalStateException" -> context.getString(R.string.exception_unexpected_state)
|
"IllegalStateException" -> "Illegal State Exception"
|
||||||
"UnsupportedOperationException" -> context.getString(R.string.exception_not_supported)
|
"UnsupportedOperationException" -> "Unsupported Operation Exception"
|
||||||
"IllegalArgumentException" -> context.getString(R.string.exception_invalid_argument)
|
"IllegalArgumentException" -> "Illegal Argument Exception"
|
||||||
else -> ""
|
else -> "Unknown: $exception"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,7 +178,13 @@ class FailedUpdatesScreenModel(
|
||||||
val descendingOrder = if (state.sortMode == SortingMode.BY_ALPHABET) !state.descendingOrder else false
|
val descendingOrder = if (state.sortMode == SortingMode.BY_ALPHABET) !state.descendingOrder else false
|
||||||
preferenceStore.getBoolean("descending_order", false).set(descendingOrder)
|
preferenceStore.getBoolean("descending_order", false).set(descendingOrder)
|
||||||
state.copy(
|
state.copy(
|
||||||
items = if (descendingOrder) state.items.sortedByDescending { it.libraryManga.manga.title } else state.items.sortedBy { it.libraryManga.manga.title },
|
items = if (descendingOrder) {
|
||||||
|
state.items.sortedByDescending {
|
||||||
|
it.libraryManga.manga.title
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
state.items.sortedBy { it.libraryManga.manga.title }
|
||||||
|
},
|
||||||
descendingOrder = descendingOrder,
|
descendingOrder = descendingOrder,
|
||||||
sortMode = SortingMode.BY_ALPHABET,
|
sortMode = SortingMode.BY_ALPHABET,
|
||||||
)
|
)
|
||||||
|
@ -172,7 +193,12 @@ class FailedUpdatesScreenModel(
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun categoryMap(items: List<FailedUpdatesManga>, groupMode: GroupByMode, sortMode: SortingMode, descendingOrder: Boolean): Map<String, Map<Pair<String, String>, List<FailedUpdatesManga>>> {
|
fun categoryMap(
|
||||||
|
items: List<FailedUpdatesManga>,
|
||||||
|
groupMode: GroupByMode,
|
||||||
|
sortMode: SortingMode,
|
||||||
|
descendingOrder: Boolean,
|
||||||
|
): Map<String, Map<Pair<String, String>, List<FailedUpdatesManga>>> {
|
||||||
val unsortedMap = when (groupMode) {
|
val unsortedMap = when (groupMode) {
|
||||||
GroupByMode.BY_SOURCE -> items.groupBy { it.source.name }
|
GroupByMode.BY_SOURCE -> items.groupBy { it.source.name }
|
||||||
.mapValues { entry -> entry.value.groupBy { Pair(it.errorMessage, it.simplifiedErrorMessage) } }
|
.mapValues { entry -> entry.value.groupBy { Pair(it.errorMessage, it.simplifiedErrorMessage) } }
|
||||||
|
@ -180,7 +206,14 @@ class FailedUpdatesScreenModel(
|
||||||
}
|
}
|
||||||
return when (sortMode) {
|
return when (sortMode) {
|
||||||
SortingMode.BY_ALPHABET -> {
|
SortingMode.BY_ALPHABET -> {
|
||||||
val sortedMap = TreeMap<String, Map<Pair<String, String>, List<FailedUpdatesManga>>>(if (descendingOrder) { compareByDescending { it } } else { compareBy { it } })
|
val sortedMap =
|
||||||
|
TreeMap<String, Map<Pair<String, String>, List<FailedUpdatesManga>>>(
|
||||||
|
if (descendingOrder) {
|
||||||
|
compareByDescending { it }
|
||||||
|
} else {
|
||||||
|
compareBy { it }
|
||||||
|
},
|
||||||
|
)
|
||||||
sortedMap.putAll(unsortedMap)
|
sortedMap.putAll(unsortedMap)
|
||||||
sortedMap
|
sortedMap
|
||||||
}
|
}
|
||||||
|
@ -276,7 +309,11 @@ class FailedUpdatesScreenModel(
|
||||||
|
|
||||||
range.forEach {
|
range.forEach {
|
||||||
val inBetweenItem = getOrNull(it)
|
val inBetweenItem = getOrNull(it)
|
||||||
if (inBetweenItem != null && !inBetweenItem.selected && inBetweenItem.errorMessage == firstErrorMessage && inBetweenItem.errorMessage == lastErrorMessage) {
|
if (inBetweenItem != null &&
|
||||||
|
!inBetweenItem.selected &&
|
||||||
|
inBetweenItem.errorMessage == firstErrorMessage &&
|
||||||
|
inBetweenItem.errorMessage == lastErrorMessage
|
||||||
|
) {
|
||||||
selectedMangaIds.add(inBetweenItem.libraryManga.manga.id)
|
selectedMangaIds.add(inBetweenItem.libraryManga.manga.id)
|
||||||
set(it, inBetweenItem.copy(selected = true))
|
set(it, inBetweenItem.copy(selected = true))
|
||||||
}
|
}
|
||||||
|
@ -325,7 +362,7 @@ class FailedUpdatesScreenModel(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeMangas(mangaList: List<Manga>, deleteFromLibrary: Boolean, deleteChapters: Boolean) {
|
fun removeMangas(mangaList: List<Manga>, deleteFromLibrary: Boolean, deleteChapters: Boolean) {
|
||||||
coroutineScope.launchNonCancellable {
|
screenModelScope.launchNonCancellable {
|
||||||
val mangaToDelete = mangaList.distinctBy { it.id }
|
val mangaToDelete = mangaList.distinctBy { it.id }
|
||||||
|
|
||||||
if (deleteFromLibrary) {
|
if (deleteFromLibrary) {
|
||||||
|
@ -368,7 +405,7 @@ class FailedUpdatesScreenModel(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
coroutineScope.launchNonCancellable { failedUpdatesManager.removeFailedUpdatesByMangaIds(listOfMangaIds) }
|
screenModelScope.launchNonCancellable { failedUpdatesManager.removeFailedUpdatesByMangaIds(listOfMangaIds) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun openDeleteMangaDialog(selected: List<FailedUpdatesManga>) {
|
fun openDeleteMangaDialog(selected: List<FailedUpdatesManga>) {
|
||||||
|
|
|
@ -289,7 +289,7 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
|
||||||
is SourceNotInstalledException -> context.stringResource(
|
is SourceNotInstalledException -> context.stringResource(
|
||||||
MR.strings.loader_not_implemented_error,
|
MR.strings.loader_not_implemented_error,
|
||||||
)
|
)
|
||||||
else -> e.message ?: context.getString(MR.strings.exception_unknown)
|
else -> e.message ?: "context.getString(MR.strings.exception_unknown)"
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
failedUpdatesCount.getAndIncrement()
|
failedUpdatesCount.getAndIncrement()
|
||||||
|
@ -322,7 +322,6 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
|
||||||
failedUpdatesCount.get(),
|
failedUpdatesCount.get(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun downloadChapters(manga: Manga, chapters: List<Chapter>) {
|
private fun downloadChapters(manga: Manga, chapters: List<Chapter>) {
|
||||||
|
|
|
@ -41,7 +41,12 @@ object NotificationHandler {
|
||||||
flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
|
flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
|
||||||
action = Constants.SHORTCUT_FAILED
|
action = Constants.SHORTCUT_FAILED
|
||||||
}
|
}
|
||||||
return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
|
return PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
0,
|
||||||
|
intent,
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4,7 +4,7 @@ import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
import tachiyomi.core.util.system.logcat
|
import tachiyomi.core.common.util.system.logcat
|
||||||
import tachiyomi.data.DatabaseHandler
|
import tachiyomi.data.DatabaseHandler
|
||||||
import tachiyomi.domain.failed.model.FailedUpdate
|
import tachiyomi.domain.failed.model.FailedUpdate
|
||||||
import tachiyomi.domain.failed.repository.FailedUpdatesRepository
|
import tachiyomi.domain.failed.repository.FailedUpdatesRepository
|
||||||
|
|
Loading…
Reference in a new issue