Remove built-in Komikku repo (#286)
* Add Help to Repo EmptyScreen * Migration: insert Official Repo for old users * button to auto fill official KMK extension repo * 'More extensions' button to go to Repo page * Remove default official repo * fix spotless
This commit is contained in:
parent
3b8752930e
commit
2536e5a77e
12 changed files with 168 additions and 41 deletions
|
|
@ -40,6 +40,7 @@ class SourcePreferences(
|
||||||
|
|
||||||
fun hideInLibraryItems() = preferenceStore.getBoolean("browse_hide_in_library_items", false)
|
fun hideInLibraryItems() = preferenceStore.getBoolean("browse_hide_in_library_items", false)
|
||||||
|
|
||||||
|
@Deprecated("Use ExtensionRepoRepository instead", replaceWith = ReplaceWith("ExtensionRepoRepository.getAll()"))
|
||||||
fun extensionRepos() = preferenceStore.getStringSet("extension_repos", emptySet())
|
fun extensionRepos() = preferenceStore.getStringSet("extension_repos", emptySet())
|
||||||
|
|
||||||
fun extensionUpdatesCount() = preferenceStore.getInt("ext_updates_count", 0)
|
fun extensionUpdatesCount() = preferenceStore.getInt("ext_updates_count", 0)
|
||||||
|
|
|
||||||
|
|
@ -157,6 +157,9 @@ private fun ExtensionContent(
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
var trustState by remember { mutableStateOf<Extension.Untrusted?>(null) }
|
var trustState by remember { mutableStateOf<Extension.Untrusted?>(null) }
|
||||||
val installGranted = rememberRequestPackageInstallsPermissionState(initialValue = true)
|
val installGranted = rememberRequestPackageInstallsPermissionState(initialValue = true)
|
||||||
|
// KMK -->
|
||||||
|
val navigator = LocalNavigator.current
|
||||||
|
// KMK <--
|
||||||
|
|
||||||
FastScrollLazyColumn(
|
FastScrollLazyColumn(
|
||||||
contentPadding = contentPadding + topSmallPaddingValues,
|
contentPadding = contentPadding + topSmallPaddingValues,
|
||||||
|
|
@ -180,19 +183,36 @@ private fun ExtensionContent(
|
||||||
when (header) {
|
when (header) {
|
||||||
is ExtensionUiModel.Header.Resource -> {
|
is ExtensionUiModel.Header.Resource -> {
|
||||||
val action: @Composable RowScope.() -> Unit =
|
val action: @Composable RowScope.() -> Unit =
|
||||||
if (header.textRes == MR.strings.ext_updates_pending) {
|
when (header.textRes) {
|
||||||
{
|
MR.strings.ext_updates_pending -> {
|
||||||
Button(onClick = { onClickUpdateAll() }) {
|
{
|
||||||
Text(
|
Button(onClick = { onClickUpdateAll() }) {
|
||||||
text = stringResource(MR.strings.ext_update_all),
|
Text(
|
||||||
style = LocalTextStyle.current.copy(
|
text = stringResource(MR.strings.ext_update_all),
|
||||||
color = MaterialTheme.colorScheme.onPrimary,
|
style = LocalTextStyle.current.copy(
|
||||||
),
|
color = MaterialTheme.colorScheme.onPrimary,
|
||||||
)
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
// KMK -->
|
||||||
{}
|
KMR.strings.extensions_page_more -> {
|
||||||
|
{
|
||||||
|
Button(onClick = { navigator?.push(ExtensionReposScreen()) }) {
|
||||||
|
Text(
|
||||||
|
text = stringResource(MR.strings.action_add_repo),
|
||||||
|
style = LocalTextStyle.current.copy(
|
||||||
|
color = MaterialTheme.colorScheme.onPrimary,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// KMK <--
|
||||||
|
else -> {
|
||||||
|
{}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ExtensionHeader(
|
ExtensionHeader(
|
||||||
textRes = header.textRes,
|
textRes = header.textRes,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
package eu.kanade.presentation.more.settings.screen.browse.components
|
package eu.kanade.presentation.more.settings.screen.browse.components
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material3.AlertDialog
|
||||||
import androidx.compose.material3.OutlinedTextField
|
import androidx.compose.material3.OutlinedTextField
|
||||||
|
|
@ -12,12 +15,16 @@ import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.focus.FocusRequester
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
import androidx.compose.ui.focus.focusRequester
|
import androidx.compose.ui.focus.focusRequester
|
||||||
import androidx.compose.ui.text.input.KeyboardType
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import kotlinx.collections.immutable.ImmutableSet
|
import kotlinx.collections.immutable.ImmutableSet
|
||||||
|
import kotlinx.collections.immutable.persistentSetOf
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
import mihon.domain.extensionrepo.interactor.CreateExtensionRepo.Companion.OFFICIAL_REPO_BASE_URL
|
||||||
import mihon.domain.extensionrepo.model.ExtensionRepo
|
import mihon.domain.extensionrepo.model.ExtensionRepo
|
||||||
import tachiyomi.i18n.MR
|
import tachiyomi.i18n.MR
|
||||||
import tachiyomi.presentation.core.i18n.stringResource
|
import tachiyomi.presentation.core.i18n.stringResource
|
||||||
|
|
@ -37,19 +44,37 @@ fun ExtensionRepoCreateDialog(
|
||||||
AlertDialog(
|
AlertDialog(
|
||||||
onDismissRequest = onDismissRequest,
|
onDismissRequest = onDismissRequest,
|
||||||
confirmButton = {
|
confirmButton = {
|
||||||
TextButton(
|
// KMK -->
|
||||||
enabled = name.isNotEmpty() && !nameAlreadyExists,
|
Row(
|
||||||
onClick = {
|
modifier = Modifier.fillMaxWidth(),
|
||||||
onCreate(name)
|
horizontalArrangement = Arrangement.SpaceBetween, // Distribute space between items
|
||||||
onDismissRequest()
|
verticalAlignment = Alignment.CenterVertically, // Align items vertically
|
||||||
},
|
|
||||||
) {
|
) {
|
||||||
Text(text = stringResource(MR.strings.action_add))
|
TextButton(
|
||||||
}
|
onClick = {
|
||||||
},
|
name = "$OFFICIAL_REPO_BASE_URL/index.min.json"
|
||||||
dismissButton = {
|
},
|
||||||
TextButton(onClick = onDismissRequest) {
|
) {
|
||||||
Text(text = stringResource(MR.strings.action_cancel))
|
Text(text = stringResource(MR.strings.label_default))
|
||||||
|
}
|
||||||
|
Row(
|
||||||
|
// Group the right-aligned elements
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
) {
|
||||||
|
TextButton(onClick = onDismissRequest) {
|
||||||
|
Text(text = stringResource(MR.strings.action_cancel))
|
||||||
|
}
|
||||||
|
// KMK <--
|
||||||
|
TextButton(
|
||||||
|
enabled = name.isNotEmpty() && !nameAlreadyExists,
|
||||||
|
onClick = {
|
||||||
|
onCreate(name)
|
||||||
|
onDismissRequest()
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
Text(text = stringResource(MR.strings.action_add))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
title = {
|
title = {
|
||||||
|
|
@ -90,6 +115,14 @@ fun ExtensionRepoCreateDialog(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KMK -->
|
||||||
|
@Preview(showBackground = true)
|
||||||
|
@Composable
|
||||||
|
fun ExtensionRepoCreateDialogPreview() {
|
||||||
|
ExtensionRepoCreateDialog({ }, { }, persistentSetOf())
|
||||||
|
}
|
||||||
|
// KMK <--
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ExtensionRepoDeleteDialog(
|
fun ExtensionRepoDeleteDialog(
|
||||||
onDismissRequest: () -> Unit,
|
onDismissRequest: () -> Unit,
|
||||||
|
|
|
||||||
|
|
@ -3,18 +3,28 @@
|
||||||
package eu.kanade.presentation.more.settings.screen.browse.components
|
package eu.kanade.presentation.more.settings.screen.browse.components
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.automirrored.outlined.Help
|
||||||
import androidx.compose.material.icons.outlined.Refresh
|
import androidx.compose.material.icons.outlined.Refresh
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextButton
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import eu.kanade.presentation.category.components.CategoryFloatingActionButton
|
import eu.kanade.presentation.category.components.CategoryFloatingActionButton
|
||||||
import eu.kanade.presentation.components.AppBar
|
import eu.kanade.presentation.components.AppBar
|
||||||
import eu.kanade.presentation.more.settings.screen.browse.RepoScreenState
|
import eu.kanade.presentation.more.settings.screen.browse.RepoScreenState
|
||||||
|
import eu.kanade.tachiyomi.util.system.openInBrowser
|
||||||
|
import kotlinx.collections.immutable.persistentSetOf
|
||||||
|
import mihon.domain.extensionrepo.interactor.CreateExtensionRepo.Companion.OFFICIAL_REPO_WEBSITE
|
||||||
import mihon.domain.extensionrepo.model.ExtensionRepo
|
import mihon.domain.extensionrepo.model.ExtensionRepo
|
||||||
import tachiyomi.i18n.MR
|
import tachiyomi.i18n.MR
|
||||||
import tachiyomi.presentation.core.components.material.Scaffold
|
import tachiyomi.presentation.core.components.material.Scaffold
|
||||||
|
|
@ -58,9 +68,20 @@ fun ExtensionReposScreen(
|
||||||
},
|
},
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
if (state.isEmpty) {
|
if (state.isEmpty) {
|
||||||
|
val context = LocalContext.current
|
||||||
EmptyScreen(
|
EmptyScreen(
|
||||||
MR.strings.information_empty_repos,
|
MR.strings.information_empty_repos,
|
||||||
modifier = Modifier.padding(paddingValues),
|
modifier = Modifier.padding(paddingValues),
|
||||||
|
help = {
|
||||||
|
TextButton(
|
||||||
|
onClick = { context.openInBrowser(OFFICIAL_REPO_WEBSITE) },
|
||||||
|
modifier = Modifier.padding(top = MaterialTheme.padding.small),
|
||||||
|
) {
|
||||||
|
Icon(imageVector = Icons.AutoMirrored.Outlined.Help, contentDescription = null)
|
||||||
|
Spacer(modifier = Modifier.width(MaterialTheme.padding.extraSmall))
|
||||||
|
Text(text = stringResource(MR.strings.label_help))
|
||||||
|
}
|
||||||
|
},
|
||||||
)
|
)
|
||||||
return@Scaffold
|
return@Scaffold
|
||||||
}
|
}
|
||||||
|
|
@ -75,3 +96,19 @@ fun ExtensionReposScreen(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KMK -->
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
private fun ExtensionReposScreenPreview() {
|
||||||
|
val state = RepoScreenState.Success(repos = persistentSetOf())
|
||||||
|
ExtensionReposScreen(
|
||||||
|
state = state,
|
||||||
|
onClickCreate = { },
|
||||||
|
onOpenWebsite = { },
|
||||||
|
onClickDelete = { },
|
||||||
|
onClickRefresh = { },
|
||||||
|
navigateUp = { },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
// KMK <--
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,6 @@ import kotlinx.coroutines.awaitAll
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
import mihon.domain.extensionrepo.interactor.CreateExtensionRepo.Companion.OFFICIAL_REPO_BASE_URL
|
|
||||||
import mihon.domain.extensionrepo.interactor.CreateExtensionRepo.Companion.OFFICIAL_REPO_SIGNATURE
|
|
||||||
import mihon.domain.extensionrepo.interactor.GetExtensionRepo
|
import mihon.domain.extensionrepo.interactor.GetExtensionRepo
|
||||||
import mihon.domain.extensionrepo.interactor.UpdateExtensionRepo
|
import mihon.domain.extensionrepo.interactor.UpdateExtensionRepo
|
||||||
import mihon.domain.extensionrepo.model.ExtensionRepo
|
import mihon.domain.extensionrepo.model.ExtensionRepo
|
||||||
|
|
@ -48,22 +46,11 @@ internal class ExtensionApi {
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun findExtensions(): List<Extension.Available> {
|
suspend fun findExtensions(): List<Extension.Available> {
|
||||||
val officialRepo = ExtensionRepo(
|
|
||||||
baseUrl = OFFICIAL_REPO_BASE_URL,
|
|
||||||
name = "Komikku Official Extensions Repo",
|
|
||||||
shortName = "Komikku Official",
|
|
||||||
website = "https://komikku-app.github.io",
|
|
||||||
signingKeyFingerprint = OFFICIAL_REPO_SIGNATURE,
|
|
||||||
)
|
|
||||||
return withIOContext {
|
return withIOContext {
|
||||||
buildList {
|
getExtensionRepo.getAll()
|
||||||
// Combine built-in OFFICIAL repo's extensions list with repo's list
|
.map { async { getExtensions(it) } }
|
||||||
addAll(getExtensions(officialRepo))
|
.awaitAll()
|
||||||
getExtensionRepo.getAll()
|
.flatten()
|
||||||
.map { async { getExtensions(it) } }
|
|
||||||
.awaitAll()
|
|
||||||
.flatten()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import tachiyomi.core.common.util.lang.launchIO
|
import tachiyomi.core.common.util.lang.launchIO
|
||||||
import tachiyomi.i18n.MR
|
import tachiyomi.i18n.MR
|
||||||
|
import tachiyomi.i18n.kmk.KMR
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import kotlin.time.Duration.Companion.seconds
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
|
@ -130,6 +131,11 @@ class ExtensionsScreenModel(
|
||||||
if (languagesWithExtensions.isNotEmpty()) {
|
if (languagesWithExtensions.isNotEmpty()) {
|
||||||
itemsGroups.putAll(languagesWithExtensions)
|
itemsGroups.putAll(languagesWithExtensions)
|
||||||
}
|
}
|
||||||
|
// KMK -->
|
||||||
|
if (_available.isEmpty()) {
|
||||||
|
itemsGroups[ExtensionUiModel.Header.Resource(KMR.strings.extensions_page_more)] = emptyList()
|
||||||
|
}
|
||||||
|
// KMK <--
|
||||||
|
|
||||||
itemsGroups
|
itemsGroups
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package mihon.core.migration
|
package mihon.core.migration
|
||||||
|
|
||||||
interface Migration {
|
interface Migration {
|
||||||
|
/** Begin version of this Migration */
|
||||||
val version: Float
|
val version: Float
|
||||||
|
|
||||||
suspend operator fun invoke(migrationContext: MigrationContext): Boolean
|
suspend operator fun invoke(migrationContext: MigrationContext): Boolean
|
||||||
|
|
|
||||||
|
|
@ -45,4 +45,7 @@ val migrations: List<Migration>
|
||||||
MoveCacheToDiskSettingMigration(),
|
MoveCacheToDiskSettingMigration(),
|
||||||
MoveEncryptionSettingsToAppStateMigration(),
|
MoveEncryptionSettingsToAppStateMigration(),
|
||||||
TrustExtensionRepositoryMigration(),
|
TrustExtensionRepositoryMigration(),
|
||||||
|
// KMK -->
|
||||||
|
OfficialExtensionRepositoryMigration(),
|
||||||
|
// KMK <--
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
package mihon.core.migration.migrations
|
||||||
|
|
||||||
|
import logcat.LogPriority
|
||||||
|
import mihon.core.migration.Migration
|
||||||
|
import mihon.core.migration.MigrationContext
|
||||||
|
import mihon.domain.extensionrepo.exception.SaveExtensionRepoException
|
||||||
|
import mihon.domain.extensionrepo.interactor.CreateExtensionRepo
|
||||||
|
import mihon.domain.extensionrepo.repository.ExtensionRepoRepository
|
||||||
|
import tachiyomi.core.common.util.lang.withIOContext
|
||||||
|
import tachiyomi.core.common.util.system.logcat
|
||||||
|
|
||||||
|
class OfficialExtensionRepositoryMigration : Migration {
|
||||||
|
override val version: Float = 70f
|
||||||
|
|
||||||
|
override suspend fun invoke(migrationContext: MigrationContext): Boolean = withIOContext {
|
||||||
|
val extensionRepositoryRepository =
|
||||||
|
migrationContext.get<ExtensionRepoRepository>() ?: return@withIOContext false
|
||||||
|
try {
|
||||||
|
extensionRepositoryRepository.upsertRepo(
|
||||||
|
baseUrl = CreateExtensionRepo.OFFICIAL_REPO_BASE_URL,
|
||||||
|
name = "Komikku Official",
|
||||||
|
shortName = "Komikku",
|
||||||
|
website = "https://komikku-app.github.io",
|
||||||
|
signingKeyFingerprint = CreateExtensionRepo.OFFICIAL_REPO_SIGNATURE,
|
||||||
|
)
|
||||||
|
} catch (e: SaveExtensionRepoException) {
|
||||||
|
logcat(LogPriority.ERROR, e) { "Error inserting Official Extension Repo" }
|
||||||
|
return@withIOContext false
|
||||||
|
}
|
||||||
|
return@withIOContext true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -15,7 +15,7 @@ class CreateExtensionRepo(
|
||||||
|
|
||||||
suspend fun await(repoUrl: String): Result {
|
suspend fun await(repoUrl: String): Result {
|
||||||
// Do not allow invalid formats & avoid adding duplicating official repo
|
// Do not allow invalid formats & avoid adding duplicating official repo
|
||||||
if (!repoUrl.matches(repoRegex) || repoUrl.startsWith(OFFICIAL_REPO_BASE_URL)) {
|
if (!repoUrl.matches(repoRegex)) {
|
||||||
return Result.InvalidUrl
|
return Result.InvalidUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,6 +70,7 @@ class CreateExtensionRepo(
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
const val OFFICIAL_REPO_WEBSITE = "https://komikku-app.github.io"
|
||||||
const val OFFICIAL_REPO_BASE_URL = "https://raw.githubusercontent.com/komikku-app/extensions/repo"
|
const val OFFICIAL_REPO_BASE_URL = "https://raw.githubusercontent.com/komikku-app/extensions/repo"
|
||||||
|
|
||||||
// cuong-tran's key
|
// cuong-tran's key
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@
|
||||||
<!-- Extension section -->
|
<!-- Extension section -->
|
||||||
<string name="ext_unofficial">Unofficial</string>
|
<string name="ext_unofficial">Unofficial</string>
|
||||||
<string name="unofficial_extension_message">This extension is not from the official repo.</string>
|
<string name="unofficial_extension_message">This extension is not from the official repo.</string>
|
||||||
|
<string name="extensions_page_more">More extensions...</string>
|
||||||
|
|
||||||
<!-- Extension repos -->
|
<!-- Extension repos -->
|
||||||
<!-- Downloads section -->
|
<!-- Downloads section -->
|
||||||
|
|
|
||||||
|
|
@ -40,11 +40,13 @@ fun EmptyScreen(
|
||||||
stringRes: StringResource,
|
stringRes: StringResource,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
actions: ImmutableList<EmptyScreenAction>? = null,
|
actions: ImmutableList<EmptyScreenAction>? = null,
|
||||||
|
help: @Composable (() -> Unit)? = null,
|
||||||
) {
|
) {
|
||||||
EmptyScreen(
|
EmptyScreen(
|
||||||
message = stringResource(stringRes),
|
message = stringResource(stringRes),
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
actions = actions,
|
actions = actions,
|
||||||
|
help = help,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -53,6 +55,7 @@ fun EmptyScreen(
|
||||||
message: String,
|
message: String,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
actions: ImmutableList<EmptyScreenAction>? = null,
|
actions: ImmutableList<EmptyScreenAction>? = null,
|
||||||
|
help: @Composable (() -> Unit)? = null,
|
||||||
) {
|
) {
|
||||||
val face = remember { getRandomErrorFace() }
|
val face = remember { getRandomErrorFace() }
|
||||||
Column(
|
Column(
|
||||||
|
|
@ -80,6 +83,8 @@ fun EmptyScreen(
|
||||||
textAlign = TextAlign.Center,
|
textAlign = TextAlign.Center,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
help?.let { help() }
|
||||||
|
|
||||||
if (!actions.isNullOrEmpty()) {
|
if (!actions.isNullOrEmpty()) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue