Fix no sources while migrating alongside UI and code cleanup (mihonapp/mihon#2155)
(cherry picked from commit 5919f34fc96f254724bd3042ac2b91ac65912930) (cherry picked from commit f0e6103f44d5a59e19decbd3ff48269009d782fc) Co-authored-by: Cuong-Tran <16017808+cuong-tran@users.noreply.github.com>
This commit is contained in:
parent
c328b37675
commit
2196c84a0c
7 changed files with 55 additions and 40 deletions
|
|
@ -21,7 +21,7 @@ import eu.kanade.tachiyomi.util.system.toast
|
||||||
import exh.util.overEq
|
import exh.util.overEq
|
||||||
import exh.util.underEq
|
import exh.util.underEq
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import mihon.feature.migration.MigrateMangaConfigScreen
|
import mihon.feature.migration.config.MigrationConfigScreen
|
||||||
import tachiyomi.core.common.i18n.pluralStringResource
|
import tachiyomi.core.common.i18n.pluralStringResource
|
||||||
import tachiyomi.core.common.util.lang.withUIContext
|
import tachiyomi.core.common.util.lang.withUIContext
|
||||||
import tachiyomi.i18n.sy.SYMR
|
import tachiyomi.i18n.sy.SYMR
|
||||||
|
|
@ -76,7 +76,7 @@ class MigrationListScreen(private val config: MigrationProcedureConfig) : Screen
|
||||||
val newStack = navigator.items.filter {
|
val newStack = navigator.items.filter {
|
||||||
it !is MangaScreen &&
|
it !is MangaScreen &&
|
||||||
it !is MigrationListScreen &&
|
it !is MigrationListScreen &&
|
||||||
it !is MigrateMangaConfigScreen
|
it !is MigrationConfigScreen
|
||||||
} + MangaScreen(mangaId)
|
} + MangaScreen(mangaId)
|
||||||
navigator replaceAll newStack.first()
|
navigator replaceAll newStack.first()
|
||||||
navigator.push(newStack.drop(1))
|
navigator.push(newStack.drop(1))
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import eu.kanade.presentation.util.Screen
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaScreen
|
import eu.kanade.tachiyomi.ui.manga.MangaScreen
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
import mihon.feature.migration.MigrateMangaConfigScreen
|
import mihon.feature.migration.config.MigrationConfigScreen
|
||||||
import tachiyomi.i18n.MR
|
import tachiyomi.i18n.MR
|
||||||
import tachiyomi.presentation.core.screens.LoadingScreen
|
import tachiyomi.presentation.core.screens.LoadingScreen
|
||||||
|
|
||||||
|
|
@ -38,14 +38,14 @@ data class MigrateMangaScreen(
|
||||||
navigateUp = navigator::pop,
|
navigateUp = navigator::pop,
|
||||||
title = state.source?.name ?: "???",
|
title = state.source?.name ?: "???",
|
||||||
state = state,
|
state = state,
|
||||||
onClickItem = { navigator.push(MigrateMangaConfigScreen(listOf(it.id))) },
|
onClickItem = { navigator.push(MigrationConfigScreen(listOf(it.id))) },
|
||||||
onClickCover = { navigator.push(MangaScreen(it.id)) },
|
onClickCover = { navigator.push(MangaScreen(it.id)) },
|
||||||
// KMK -->
|
// KMK -->
|
||||||
onMultiMigrateClicked = {
|
onMultiMigrateClicked = {
|
||||||
if (state.selectionMode) {
|
if (state.selectionMode) {
|
||||||
navigator.push(MigrateMangaConfigScreen(state.selected.map { it.manga.id }))
|
navigator.push(MigrationConfigScreen(state.selected.map { it.manga.id }))
|
||||||
} else {
|
} else {
|
||||||
navigator.push(MigrateMangaConfigScreen(state.titles.map { it.manga.id }))
|
navigator.push(MigrationConfigScreen(state.titles.map { it.manga.id }))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onSelectAll = screenModel::toggleAllSelection,
|
onSelectAll = screenModel::toggleAllSelection,
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ import kotlinx.coroutines.channels.Channel
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
import kotlinx.coroutines.flow.receiveAsFlow
|
import kotlinx.coroutines.flow.receiveAsFlow
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import mihon.feature.migration.MigrateMangaConfigScreen
|
import mihon.feature.migration.config.MigrationConfigScreen
|
||||||
import tachiyomi.core.common.i18n.stringResource
|
import tachiyomi.core.common.i18n.stringResource
|
||||||
import tachiyomi.core.common.util.lang.launchIO
|
import tachiyomi.core.common.util.lang.launchIO
|
||||||
import tachiyomi.domain.category.model.Category
|
import tachiyomi.domain.category.model.Category
|
||||||
|
|
@ -210,7 +210,7 @@ data object LibraryTab : Tab {
|
||||||
.map { it.id }
|
.map { it.id }
|
||||||
screenModel.clearSelection()
|
screenModel.clearSelection()
|
||||||
if (selectedMangaIds.isNotEmpty()) {
|
if (selectedMangaIds.isNotEmpty()) {
|
||||||
navigator.push(MigrateMangaConfigScreen(selectedMangaIds))
|
navigator.push(MigrationConfigScreen(selectedMangaIds))
|
||||||
} else {
|
} else {
|
||||||
context.toast(SYMR.strings.no_valid_entry)
|
context.toast(SYMR.strings.no_valid_entry)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import cafe.adriel.voyager.navigator.currentOrThrow
|
||||||
import eu.kanade.presentation.libraryUpdateError.LibraryUpdateErrorScreen
|
import eu.kanade.presentation.libraryUpdateError.LibraryUpdateErrorScreen
|
||||||
import eu.kanade.presentation.util.Screen
|
import eu.kanade.presentation.util.Screen
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaScreen
|
import eu.kanade.tachiyomi.ui.manga.MangaScreen
|
||||||
import mihon.feature.migration.MigrateMangaConfigScreen
|
import mihon.feature.migration.config.MigrationConfigScreen
|
||||||
|
|
||||||
class LibraryUpdateErrorScreen : Screen() {
|
class LibraryUpdateErrorScreen : Screen() {
|
||||||
|
|
||||||
|
|
@ -22,11 +22,11 @@ class LibraryUpdateErrorScreen : Screen() {
|
||||||
LibraryUpdateErrorScreen(
|
LibraryUpdateErrorScreen(
|
||||||
state = state,
|
state = state,
|
||||||
onClick = { item ->
|
onClick = { item ->
|
||||||
navigator.push(MigrateMangaConfigScreen(listOf(item.error.mangaId)))
|
navigator.push(MigrationConfigScreen(listOf(item.error.mangaId)))
|
||||||
},
|
},
|
||||||
onClickCover = { item -> navigator.push(MangaScreen(item.error.mangaId)) },
|
onClickCover = { item -> navigator.push(MangaScreen(item.error.mangaId)) },
|
||||||
onMultiMigrateClicked = {
|
onMultiMigrateClicked = {
|
||||||
navigator.push(MigrateMangaConfigScreen(state.selected.map { it.error.mangaId }))
|
navigator.push(MigrationConfigScreen(state.selected.map { it.error.mangaId }))
|
||||||
},
|
},
|
||||||
onSelectAll = screenModel::toggleAllSelection,
|
onSelectAll = screenModel::toggleAllSelection,
|
||||||
onInvertSelection = screenModel::invertSelection,
|
onInvertSelection = screenModel::invertSelection,
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.flow.take
|
import kotlinx.coroutines.flow.take
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
import mihon.feature.migration.MigrateMangaConfigScreen
|
import mihon.feature.migration.config.MigrationConfigScreen
|
||||||
import tachiyomi.core.common.i18n.stringResource
|
import tachiyomi.core.common.i18n.stringResource
|
||||||
import tachiyomi.core.common.util.lang.launchIO
|
import tachiyomi.core.common.util.lang.launchIO
|
||||||
import tachiyomi.core.common.util.lang.launchUI
|
import tachiyomi.core.common.util.lang.launchUI
|
||||||
|
|
@ -366,7 +366,7 @@ class MangaScreen(
|
||||||
successState.manga.favorite
|
successState.manga.favorite
|
||||||
},
|
},
|
||||||
onMigrateClicked = {
|
onMigrateClicked = {
|
||||||
navigator.push(MigrateMangaConfigScreen(listOf(successState.manga.id)))
|
navigator.push(MigrationConfigScreen(listOf(successState.manga.id)))
|
||||||
}.takeIf { successState.manga.favorite },
|
}.takeIf { successState.manga.favorite },
|
||||||
// SY -->
|
// SY -->
|
||||||
previewsRowCount = successState.previewsRowCount,
|
previewsRowCount = successState.previewsRowCount,
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,16 @@ object LocaleHelper {
|
||||||
return Locale.forLanguageTag(normalizedLang).displayName
|
return Locale.forLanguageTag(normalizedLang).displayName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getShortDisplayName(lang: String?): String {
|
||||||
|
return when (lang) {
|
||||||
|
null -> ""
|
||||||
|
"es-419" -> "es-la"
|
||||||
|
"zh-CN" -> "zh-hans"
|
||||||
|
"zh-TW" -> "zh-hant"
|
||||||
|
else -> lang
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns display name of a string language code.
|
* Returns display name of a string language code.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package mihon.feature.migration
|
package mihon.feature.migration.config
|
||||||
|
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
|
|
@ -38,7 +38,6 @@ import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.alpha
|
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
|
@ -66,7 +65,7 @@ import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.updateAndGet
|
import kotlinx.coroutines.flow.update
|
||||||
import sh.calvin.reorderable.ReorderableCollectionItemScope
|
import sh.calvin.reorderable.ReorderableCollectionItemScope
|
||||||
import sh.calvin.reorderable.ReorderableItem
|
import sh.calvin.reorderable.ReorderableItem
|
||||||
import sh.calvin.reorderable.ReorderableLazyListState
|
import sh.calvin.reorderable.ReorderableLazyListState
|
||||||
|
|
@ -79,7 +78,6 @@ import tachiyomi.i18n.kmk.KMR
|
||||||
import tachiyomi.i18n.sy.SYMR
|
import tachiyomi.i18n.sy.SYMR
|
||||||
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.material.DISABLED_ALPHA
|
|
||||||
import tachiyomi.presentation.core.components.material.Scaffold
|
import tachiyomi.presentation.core.components.material.Scaffold
|
||||||
import tachiyomi.presentation.core.components.material.padding
|
import tachiyomi.presentation.core.components.material.padding
|
||||||
import tachiyomi.presentation.core.i18n.stringResource
|
import tachiyomi.presentation.core.i18n.stringResource
|
||||||
|
|
@ -96,7 +94,7 @@ import uy.kohesive.injekt.api.get
|
||||||
*
|
*
|
||||||
* @param mangaIds IDs of the manga that will be migrated using the sources configured on this screen.
|
* @param mangaIds IDs of the manga that will be migrated using the sources configured on this screen.
|
||||||
*/
|
*/
|
||||||
class MigrateMangaConfigScreen(private val mangaIds: List<Long>) : Screen() {
|
class MigrationConfigScreen(private val mangaIds: List<Long>) : Screen() {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
|
|
@ -174,6 +172,7 @@ class MigrateMangaConfigScreen(private val mangaIds: List<Long>) : Screen() {
|
||||||
text = { Text(text = stringResource(MR.strings.migrationConfigScreen_continueButtonText)) },
|
text = { Text(text = stringResource(MR.strings.migrationConfigScreen_continueButtonText)) },
|
||||||
icon = { Icon(imageVector = Icons.AutoMirrored.Outlined.ArrowForward, contentDescription = null) },
|
icon = { Icon(imageVector = Icons.AutoMirrored.Outlined.ArrowForward, contentDescription = null) },
|
||||||
onClick = {
|
onClick = {
|
||||||
|
screenModel.saveSources()
|
||||||
// KMK -->
|
// KMK -->
|
||||||
screenModel.onMigrationSheet(true)
|
screenModel.onMigrationSheet(true)
|
||||||
// KMK <--
|
// KMK <--
|
||||||
|
|
@ -232,9 +231,8 @@ class MigrateMangaConfigScreen(private val mangaIds: List<Long>) : Screen() {
|
||||||
SourceItemContainer(
|
SourceItemContainer(
|
||||||
firstItem = index == 0,
|
firstItem = index == 0,
|
||||||
lastItem = index == (sources.size - 1),
|
lastItem = index == (sources.size - 1),
|
||||||
source = item.source,
|
source = item,
|
||||||
showLanguage = showLanguage,
|
showLanguage = showLanguage,
|
||||||
isSelected = item.isSelected,
|
|
||||||
dragEnabled = selectedSourceList && sources.size > 1,
|
dragEnabled = selectedSourceList && sources.size > 1,
|
||||||
state = reorderableState,
|
state = reorderableState,
|
||||||
key = { if (selectedSourceList) it.id else "available-${it.id}" },
|
key = { if (selectedSourceList) it.id else "available-${it.id}" },
|
||||||
|
|
@ -289,12 +287,11 @@ class MigrateMangaConfigScreen(private val mangaIds: List<Long>) : Screen() {
|
||||||
private fun LazyItemScope.SourceItemContainer(
|
private fun LazyItemScope.SourceItemContainer(
|
||||||
firstItem: Boolean,
|
firstItem: Boolean,
|
||||||
lastItem: Boolean,
|
lastItem: Boolean,
|
||||||
source: Source,
|
source: MigrationSource,
|
||||||
showLanguage: Boolean,
|
showLanguage: Boolean,
|
||||||
isSelected: Boolean,
|
|
||||||
dragEnabled: Boolean,
|
dragEnabled: Boolean,
|
||||||
state: ReorderableLazyListState,
|
state: ReorderableLazyListState,
|
||||||
key: (Source) -> Any,
|
key: (MigrationSource) -> Any,
|
||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
) {
|
) {
|
||||||
val shape = remember(firstItem, lastItem) {
|
val shape = remember(firstItem, lastItem) {
|
||||||
|
|
@ -317,7 +314,6 @@ class MigrateMangaConfigScreen(private val mangaIds: List<Long>) : Screen() {
|
||||||
SourceItem(
|
SourceItem(
|
||||||
source = source,
|
source = source,
|
||||||
showLanguage = showLanguage,
|
showLanguage = showLanguage,
|
||||||
isSelected = isSelected,
|
|
||||||
dragEnabled = dragEnabled,
|
dragEnabled = dragEnabled,
|
||||||
scope = this@ReorderableItem,
|
scope = this@ReorderableItem,
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
|
|
@ -332,9 +328,8 @@ class MigrateMangaConfigScreen(private val mangaIds: List<Long>) : Screen() {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun SourceItem(
|
private fun SourceItem(
|
||||||
source: Source,
|
source: MigrationSource,
|
||||||
showLanguage: Boolean,
|
showLanguage: Boolean,
|
||||||
isSelected: Boolean,
|
|
||||||
dragEnabled: Boolean,
|
dragEnabled: Boolean,
|
||||||
scope: ReorderableCollectionItemScope,
|
scope: ReorderableCollectionItemScope,
|
||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
|
|
@ -345,7 +340,7 @@ class MigrateMangaConfigScreen(private val mangaIds: List<Long>) : Screen() {
|
||||||
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
|
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
) {
|
) {
|
||||||
SourceIcon(source = source)
|
SourceIcon(source = source.source)
|
||||||
Text(
|
Text(
|
||||||
text = source.name,
|
text = source.name,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
|
|
@ -355,7 +350,9 @@ class MigrateMangaConfigScreen(private val mangaIds: List<Long>) : Screen() {
|
||||||
)
|
)
|
||||||
if (showLanguage) {
|
if (showLanguage) {
|
||||||
Pill(
|
Pill(
|
||||||
text = FlagEmoji.getEmojiLangFlag(source.lang) + " (${LocaleHelper.getLocalizedDisplayName(source.lang)})",
|
// KMK -->
|
||||||
|
text = FlagEmoji.getEmojiLangFlag(source.shortLanguage) + " (${source.upperShortLanguage})",
|
||||||
|
// KMK <--
|
||||||
style = MaterialTheme.typography.bodySmall,
|
style = MaterialTheme.typography.bodySmall,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -377,9 +374,7 @@ class MigrateMangaConfigScreen(private val mangaIds: List<Long>) : Screen() {
|
||||||
colors = ListItemDefaults.colors(
|
colors = ListItemDefaults.colors(
|
||||||
containerColor = Color.Transparent,
|
containerColor = Color.Transparent,
|
||||||
),
|
),
|
||||||
modifier = Modifier
|
modifier = Modifier.clickable(onClick = onClick),
|
||||||
.clickable(onClick = onClick)
|
|
||||||
.alpha(if (isSelected) 1f else DISABLED_ALPHA),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -414,12 +409,12 @@ class MigrateMangaConfigScreen(private val mangaIds: List<Long>) : Screen() {
|
||||||
// { !it.isSelected },
|
// { !it.isSelected },
|
||||||
{ includedSources[it.source.id] ?: Int.MAX_VALUE },
|
{ includedSources[it.source.id] ?: Int.MAX_VALUE },
|
||||||
// KMK <--
|
// KMK <--
|
||||||
{ with(it.source) { "$name (${LocaleHelper.getLocalizedDisplayName(lang)})" } },
|
{ with(it) { "$name ($shortLanguage)" } },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateSources(save: Boolean = true, action: (List<MigrationSource>) -> List<MigrationSource>) {
|
private fun updateSources(save: Boolean = true, action: (List<MigrationSource>) -> List<MigrationSource>) {
|
||||||
val state = mutableState.updateAndGet { state ->
|
mutableState.update { state ->
|
||||||
val updatedSources = action(state.sources)
|
val updatedSources = action(state.sources)
|
||||||
val includedSources = updatedSources.mapNotNull { if (!it.isSelected) null else it.id }
|
val includedSources = updatedSources.mapNotNull { if (!it.isSelected) null else it.id }
|
||||||
// KMK -->
|
// KMK -->
|
||||||
|
|
@ -427,11 +422,7 @@ class MigrateMangaConfigScreen(private val mangaIds: List<Long>) : Screen() {
|
||||||
// KMK <--
|
// KMK <--
|
||||||
state.copy(sources = updatedSources.sortedWith(sourcesComparator(includedSources)))
|
state.copy(sources = updatedSources.sortedWith(sourcesComparator(includedSources)))
|
||||||
}
|
}
|
||||||
if (!save) return
|
if (save) saveSources()
|
||||||
state.sources
|
|
||||||
.filter { source -> source.isSelected }
|
|
||||||
.map { source -> source.source.id }
|
|
||||||
.let { sources -> sourcePreferences.migrationSources().set(sources) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initSources() {
|
private fun initSources() {
|
||||||
|
|
@ -506,6 +497,13 @@ class MigrateMangaConfigScreen(private val mangaIds: List<Long>) : Screen() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun saveSources() {
|
||||||
|
state.value.sources
|
||||||
|
.filter { source -> source.isSelected }
|
||||||
|
.map { source -> source.source.id }
|
||||||
|
.let { sources -> sourcePreferences.migrationSources().set(sources) }
|
||||||
|
}
|
||||||
|
|
||||||
data class State(
|
data class State(
|
||||||
val sources: List<MigrationSource> = emptyList(),
|
val sources: List<MigrationSource> = emptyList(),
|
||||||
)
|
)
|
||||||
|
|
@ -521,8 +519,15 @@ class MigrateMangaConfigScreen(private val mangaIds: List<Long>) : Screen() {
|
||||||
data class MigrationSource(
|
data class MigrationSource(
|
||||||
val source: Source,
|
val source: Source,
|
||||||
val isSelected: Boolean,
|
val isSelected: Boolean,
|
||||||
|
// KMK -->
|
||||||
|
val shortLanguage: String = LocaleHelper.getShortDisplayName(source.lang),
|
||||||
|
val upperShortLanguage: String = shortLanguage.uppercase(),
|
||||||
|
// KMK <--
|
||||||
) {
|
) {
|
||||||
val id = source.id
|
val id: Long
|
||||||
val visualName = source.visualName
|
inline get() = source.id
|
||||||
|
|
||||||
|
val name: String
|
||||||
|
inline get() = source.name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in a new issue