mirror of
https://github.com/aniyomiorg/aniyomi.git
synced 2024-11-26 14:53:41 +03:00
feat(app): Add ability to open available extension websites in WebView
Closes #8628
This commit is contained in:
parent
637f11652b
commit
6135798471
4 changed files with 183 additions and 60 deletions
|
@ -14,6 +14,11 @@ import androidx.compose.foundation.layout.size
|
|||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.Close
|
||||
import androidx.compose.material.icons.outlined.GetApp
|
||||
import androidx.compose.material.icons.outlined.Public
|
||||
import androidx.compose.material.icons.outlined.Refresh
|
||||
import androidx.compose.material.icons.outlined.Settings
|
||||
import androidx.compose.material.icons.outlined.VerifiedUser
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.Icon
|
||||
|
@ -61,6 +66,7 @@ fun AnimeExtensionScreen(
|
|||
searchQuery: String?,
|
||||
onLongClickItem: (AnimeExtension) -> Unit,
|
||||
onClickItemCancel: (AnimeExtension) -> Unit,
|
||||
onClickItemWebView: (AnimeExtension.Available) -> Unit,
|
||||
onInstallExtension: (AnimeExtension.Available) -> Unit,
|
||||
onUninstallExtension: (AnimeExtension) -> Unit,
|
||||
onUpdateExtension: (AnimeExtension.Installed) -> Unit,
|
||||
|
@ -93,6 +99,7 @@ fun AnimeExtensionScreen(
|
|||
contentPadding = contentPadding,
|
||||
onLongClickItem = onLongClickItem,
|
||||
onClickItemCancel = onClickItemCancel,
|
||||
onClickItemWebView = onClickItemWebView,
|
||||
onInstallExtension = onInstallExtension,
|
||||
onUninstallExtension = onUninstallExtension,
|
||||
onUpdateExtension = onUpdateExtension,
|
||||
|
@ -110,6 +117,7 @@ private fun AnimeExtensionContent(
|
|||
state: AnimeExtensionsScreenModel.State,
|
||||
contentPadding: PaddingValues,
|
||||
onLongClickItem: (AnimeExtension) -> Unit,
|
||||
onClickItemWebView: (AnimeExtension.Available) -> Unit,
|
||||
onClickItemCancel: (AnimeExtension) -> Unit,
|
||||
onInstallExtension: (AnimeExtension.Available) -> Unit,
|
||||
onUninstallExtension: (AnimeExtension) -> Unit,
|
||||
|
@ -177,6 +185,7 @@ private fun AnimeExtensionContent(
|
|||
},
|
||||
onLongClickItem = onLongClickItem,
|
||||
onClickItemCancel = onClickItemCancel,
|
||||
onClickItemWebView = onClickItemWebView,
|
||||
onClickItemAction = {
|
||||
when (it) {
|
||||
is AnimeExtension.Available -> onInstallExtension(it)
|
||||
|
@ -219,6 +228,7 @@ private fun AnimeExtensionItem(
|
|||
item: AnimeExtensionUiModel.Item,
|
||||
onClickItem: (AnimeExtension) -> Unit,
|
||||
onLongClickItem: (AnimeExtension) -> Unit,
|
||||
onClickItemWebView: (AnimeExtension.Available) -> Unit,
|
||||
onClickItemCancel: (AnimeExtension) -> Unit,
|
||||
onClickItemAction: (AnimeExtension) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
|
@ -262,6 +272,7 @@ private fun AnimeExtensionItem(
|
|||
AnimeExtensionItemActions(
|
||||
extension = extension,
|
||||
installStep = installStep,
|
||||
onClickItemWebView = onClickItemWebView,
|
||||
onClickItemCancel = onClickItemCancel,
|
||||
onClickItemAction = onClickItemAction,
|
||||
)
|
||||
|
@ -348,43 +359,82 @@ private fun AnimeExtensionItemActions(
|
|||
extension: AnimeExtension,
|
||||
installStep: InstallStep,
|
||||
modifier: Modifier = Modifier,
|
||||
onClickItemWebView: (AnimeExtension.Available) -> Unit = {},
|
||||
onClickItemCancel: (AnimeExtension) -> Unit = {},
|
||||
onClickItemAction: (AnimeExtension) -> Unit = {},
|
||||
) {
|
||||
val isIdle = installStep.isCompleted()
|
||||
Row(modifier = modifier) {
|
||||
if (isIdle) {
|
||||
TextButton(
|
||||
onClick = { onClickItemAction(extension) },
|
||||
) {
|
||||
Text(
|
||||
text = when (installStep) {
|
||||
InstallStep.Installed -> stringResource(MR.strings.ext_installed)
|
||||
InstallStep.Error -> stringResource(MR.strings.action_retry)
|
||||
InstallStep.Idle -> {
|
||||
when (extension) {
|
||||
is AnimeExtension.Installed -> {
|
||||
if (extension.hasUpdate) {
|
||||
stringResource(MR.strings.ext_update)
|
||||
} else {
|
||||
stringResource(MR.strings.action_settings)
|
||||
}
|
||||
}
|
||||
is AnimeExtension.Untrusted -> stringResource(MR.strings.ext_trust)
|
||||
is AnimeExtension.Available -> stringResource(MR.strings.ext_install)
|
||||
|
||||
Row(
|
||||
modifier = modifier,
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
when {
|
||||
!isIdle -> {
|
||||
IconButton(onClick = { onClickItemCancel(extension) }) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Close,
|
||||
contentDescription = stringResource(MR.strings.action_cancel),
|
||||
)
|
||||
}
|
||||
}
|
||||
installStep == InstallStep.Error -> {
|
||||
IconButton(onClick = { onClickItemAction(extension) }) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Refresh,
|
||||
contentDescription = stringResource(MR.strings.action_retry),
|
||||
)
|
||||
}
|
||||
}
|
||||
installStep == InstallStep.Idle -> {
|
||||
when (extension) {
|
||||
is AnimeExtension.Installed -> {
|
||||
if (extension.hasUpdate) {
|
||||
IconButton(onClick = { onClickItemAction(extension) }) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.GetApp,
|
||||
contentDescription = stringResource(MR.strings.ext_update),
|
||||
)
|
||||
}
|
||||
}
|
||||
else -> error("Must not show install process text")
|
||||
},
|
||||
)
|
||||
}
|
||||
} else {
|
||||
IconButton(onClick = { onClickItemCancel(extension) }) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Close,
|
||||
contentDescription = stringResource(MR.strings.action_cancel),
|
||||
)
|
||||
|
||||
IconButton(onClick = { onClickItemAction(extension) }) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Settings,
|
||||
contentDescription = stringResource(MR.strings.action_settings),
|
||||
)
|
||||
}
|
||||
}
|
||||
is AnimeExtension.Untrusted -> {
|
||||
IconButton(onClick = { onClickItemAction(extension) }) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.VerifiedUser,
|
||||
contentDescription = stringResource(MR.strings.ext_trust),
|
||||
)
|
||||
}
|
||||
}
|
||||
is AnimeExtension.Available -> {
|
||||
if (extension.sources.isNotEmpty()) {
|
||||
IconButton(
|
||||
onClick = { onClickItemWebView(extension) },
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Public,
|
||||
contentDescription = stringResource(MR.strings.action_open_in_web_view),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
IconButton(onClick = { onClickItemAction(extension) }) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.GetApp,
|
||||
contentDescription = stringResource(MR.strings.ext_install),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,11 @@ import androidx.compose.foundation.layout.size
|
|||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.Close
|
||||
import androidx.compose.material.icons.outlined.GetApp
|
||||
import androidx.compose.material.icons.outlined.Public
|
||||
import androidx.compose.material.icons.outlined.Refresh
|
||||
import androidx.compose.material.icons.outlined.Settings
|
||||
import androidx.compose.material.icons.outlined.VerifiedUser
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
|
@ -62,6 +67,7 @@ fun MangaExtensionScreen(
|
|||
searchQuery: String?,
|
||||
onLongClickItem: (MangaExtension) -> Unit,
|
||||
onClickItemCancel: (MangaExtension) -> Unit,
|
||||
onClickItemWebView: (MangaExtension.Available) -> Unit,
|
||||
onInstallExtension: (MangaExtension.Available) -> Unit,
|
||||
onUninstallExtension: (MangaExtension) -> Unit,
|
||||
onUpdateExtension: (MangaExtension.Installed) -> Unit,
|
||||
|
@ -94,6 +100,7 @@ fun MangaExtensionScreen(
|
|||
contentPadding = contentPadding,
|
||||
onLongClickItem = onLongClickItem,
|
||||
onClickItemCancel = onClickItemCancel,
|
||||
onClickItemWebView = onClickItemWebView,
|
||||
onInstallExtension = onInstallExtension,
|
||||
onUninstallExtension = onUninstallExtension,
|
||||
onUpdateExtension = onUpdateExtension,
|
||||
|
@ -111,6 +118,7 @@ private fun ExtensionContent(
|
|||
state: MangaExtensionsScreenModel.State,
|
||||
contentPadding: PaddingValues,
|
||||
onLongClickItem: (MangaExtension) -> Unit,
|
||||
onClickItemWebView: (MangaExtension.Available) -> Unit,
|
||||
onClickItemCancel: (MangaExtension) -> Unit,
|
||||
onInstallExtension: (MangaExtension.Available) -> Unit,
|
||||
onUninstallExtension: (MangaExtension) -> Unit,
|
||||
|
@ -177,6 +185,7 @@ private fun ExtensionContent(
|
|||
}
|
||||
},
|
||||
onLongClickItem = onLongClickItem,
|
||||
onClickItemWebView = onClickItemWebView,
|
||||
onClickItemCancel = onClickItemCancel,
|
||||
onClickItemAction = {
|
||||
when (it) {
|
||||
|
@ -220,6 +229,7 @@ private fun ExtensionItem(
|
|||
item: MangaExtensionUiModel.Item,
|
||||
onClickItem: (MangaExtension) -> Unit,
|
||||
onLongClickItem: (MangaExtension) -> Unit,
|
||||
onClickItemWebView: (MangaExtension.Available) -> Unit,
|
||||
onClickItemCancel: (MangaExtension) -> Unit,
|
||||
onClickItemAction: (MangaExtension) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
|
@ -263,6 +273,7 @@ private fun ExtensionItem(
|
|||
ExtensionItemActions(
|
||||
extension = extension,
|
||||
installStep = installStep,
|
||||
onClickItemWebView = onClickItemWebView,
|
||||
onClickItemCancel = onClickItemCancel,
|
||||
onClickItemAction = onClickItemAction,
|
||||
)
|
||||
|
@ -349,42 +360,80 @@ private fun ExtensionItemActions(
|
|||
extension: MangaExtension,
|
||||
installStep: InstallStep,
|
||||
modifier: Modifier = Modifier,
|
||||
onClickItemWebView: (MangaExtension.Available) -> Unit = {},
|
||||
onClickItemCancel: (MangaExtension) -> Unit = {},
|
||||
onClickItemAction: (MangaExtension) -> Unit = {},
|
||||
) {
|
||||
val isIdle = installStep.isCompleted()
|
||||
Row(modifier = modifier) {
|
||||
if (isIdle) {
|
||||
TextButton(
|
||||
onClick = { onClickItemAction(extension) },
|
||||
) {
|
||||
Text(
|
||||
text = when (installStep) {
|
||||
InstallStep.Installed -> stringResource(MR.strings.ext_installed)
|
||||
InstallStep.Error -> stringResource(MR.strings.action_retry)
|
||||
InstallStep.Idle -> {
|
||||
when (extension) {
|
||||
is MangaExtension.Installed -> {
|
||||
if (extension.hasUpdate) {
|
||||
stringResource(MR.strings.ext_update)
|
||||
} else {
|
||||
stringResource(MR.strings.action_settings)
|
||||
}
|
||||
}
|
||||
is MangaExtension.Untrusted -> stringResource(MR.strings.ext_trust)
|
||||
is MangaExtension.Available -> stringResource(MR.strings.ext_install)
|
||||
|
||||
Row(
|
||||
modifier = modifier,
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
when {
|
||||
!isIdle -> {
|
||||
IconButton(onClick = { onClickItemCancel(extension) }) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Close,
|
||||
contentDescription = stringResource(MR.strings.action_cancel),
|
||||
)
|
||||
}
|
||||
}
|
||||
installStep == InstallStep.Error -> {
|
||||
IconButton(onClick = { onClickItemAction(extension) }) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Refresh,
|
||||
contentDescription = stringResource(MR.strings.action_retry),
|
||||
)
|
||||
}
|
||||
}
|
||||
installStep == InstallStep.Idle -> {
|
||||
when (extension) {
|
||||
is MangaExtension.Installed -> {
|
||||
if (extension.hasUpdate) {
|
||||
IconButton(onClick = { onClickItemAction(extension) }) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.GetApp,
|
||||
contentDescription = stringResource(MR.strings.ext_update),
|
||||
)
|
||||
}
|
||||
}
|
||||
else -> error("Must not show install process text")
|
||||
},
|
||||
)
|
||||
}
|
||||
} else {
|
||||
IconButton(onClick = { onClickItemCancel(extension) }) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Close,
|
||||
contentDescription = stringResource(MR.strings.action_cancel),
|
||||
)
|
||||
|
||||
IconButton(onClick = { onClickItemAction(extension) }) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Settings,
|
||||
contentDescription = stringResource(MR.strings.action_settings),
|
||||
)
|
||||
}
|
||||
}
|
||||
is MangaExtension.Untrusted -> {
|
||||
IconButton(onClick = { onClickItemAction(extension) }) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.VerifiedUser,
|
||||
contentDescription = stringResource(MR.strings.ext_trust),
|
||||
)
|
||||
}
|
||||
}
|
||||
is MangaExtension.Available -> {
|
||||
if (extension.sources.isNotEmpty()) {
|
||||
IconButton(
|
||||
onClick = { onClickItemWebView(extension) },
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Public,
|
||||
contentDescription = stringResource(MR.strings.action_open_in_web_view),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
IconButton(onClick = { onClickItemAction(extension) }) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.GetApp,
|
||||
contentDescription = stringResource(MR.strings.ext_install),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package eu.kanade.tachiyomi.ui.browse.anime.extension
|
||||
|
||||
import eu.kanade.tachiyomi.ui.webview.WebViewScreen
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.Translate
|
||||
import androidx.compose.runtime.Composable
|
||||
|
@ -53,6 +54,17 @@ fun animeExtensionsTab(
|
|||
},
|
||||
onClickItemCancel = extensionsScreenModel::cancelInstallUpdateExtension,
|
||||
onClickUpdateAll = extensionsScreenModel::updateAllExtensions,
|
||||
onClickItemWebView = { extension ->
|
||||
extension.sources.getOrNull(0)?.let {
|
||||
navigator.push(
|
||||
WebViewScreen(
|
||||
url = it.baseUrl,
|
||||
initialTitle = it.name,
|
||||
sourceId = it.id,
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
onInstallExtension = extensionsScreenModel::installExtension,
|
||||
onOpenExtension = { navigator.push(AnimeExtensionDetailsScreen(it.pkgName)) },
|
||||
onTrustExtension = { extensionsScreenModel.trustSignature(it.signatureHash) },
|
||||
|
|
|
@ -12,6 +12,7 @@ import eu.kanade.presentation.components.AppBar
|
|||
import eu.kanade.presentation.components.TabContent
|
||||
import eu.kanade.tachiyomi.extension.manga.model.MangaExtension
|
||||
import eu.kanade.tachiyomi.ui.browse.manga.extension.details.MangaExtensionDetailsScreen
|
||||
import eu.kanade.tachiyomi.ui.webview.WebViewScreen
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import tachiyomi.i18n.MR
|
||||
import tachiyomi.presentation.core.i18n.stringResource
|
||||
|
@ -49,6 +50,17 @@ fun mangaExtensionsTab(
|
|||
},
|
||||
onClickItemCancel = extensionsScreenModel::cancelInstallUpdateExtension,
|
||||
onClickUpdateAll = extensionsScreenModel::updateAllExtensions,
|
||||
onClickItemWebView = { extension ->
|
||||
extension.sources.getOrNull(0)?.let {
|
||||
navigator.push(
|
||||
WebViewScreen(
|
||||
url = it.baseUrl,
|
||||
initialTitle = it.name,
|
||||
sourceId = it.id,
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
onInstallExtension = extensionsScreenModel::installExtension,
|
||||
onOpenExtension = { navigator.push(MangaExtensionDetailsScreen(it.pkgName)) },
|
||||
onTrustExtension = { extensionsScreenModel.trustSignature(it.signatureHash) },
|
||||
|
|
Loading…
Reference in a new issue