|
@@ -43,9 +43,12 @@ import io.legado.app.ui.widget.components.JsonRawEditor
|
|
|
import io.legado.app.ui.widget.components.alert.AppAlertDialog
|
|
import io.legado.app.ui.widget.components.alert.AppAlertDialog
|
|
|
import io.legado.app.ui.widget.components.button.SecondaryButton
|
|
import io.legado.app.ui.widget.components.button.SecondaryButton
|
|
|
import io.legado.app.ui.widget.components.button.SmallIconButton
|
|
import io.legado.app.ui.widget.components.button.SmallIconButton
|
|
|
|
|
+import io.legado.app.ui.widget.components.card.GlassCard
|
|
|
import io.legado.app.ui.widget.components.card.ReorderableSelectionItem
|
|
import io.legado.app.ui.widget.components.card.ReorderableSelectionItem
|
|
|
import io.legado.app.ui.widget.components.card.SelectionItemCard
|
|
import io.legado.app.ui.widget.components.card.SelectionItemCard
|
|
|
import io.legado.app.ui.widget.components.divider.PillDivider
|
|
import io.legado.app.ui.widget.components.divider.PillDivider
|
|
|
|
|
+import io.legado.app.ui.widget.components.divider.PillHeaderDivider
|
|
|
|
|
+import io.legado.app.ui.widget.components.explore.ExploreKindSelectSheet
|
|
|
import io.legado.app.ui.widget.components.icon.AppIcon
|
|
import io.legado.app.ui.widget.components.icon.AppIcon
|
|
|
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu
|
|
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu
|
|
|
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem
|
|
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem
|
|
@@ -84,6 +87,7 @@ fun <T> HomepageModuleManageSheet(
|
|
|
onGetAllModulesGroupedBySource: () -> Map<String, List<HomepageModuleManageUi>> = { emptyMap() },
|
|
onGetAllModulesGroupedBySource: () -> Map<String, List<HomepageModuleManageUi>> = { emptyMap() },
|
|
|
onGetSourceName: (String) -> String = { it },
|
|
onGetSourceName: (String) -> String = { it },
|
|
|
onAssignModuleToCustomSet: (String, String?) -> Unit = { _, _ -> },
|
|
onAssignModuleToCustomSet: (String, String?) -> Unit = { _, _ -> },
|
|
|
|
|
+ onSyncSourceModules: (String) -> Unit = {},
|
|
|
) {
|
|
) {
|
|
|
var selectingSetUrl by remember(data != null) { mutableStateOf<String?>(null) }
|
|
var selectingSetUrl by remember(data != null) { mutableStateOf<String?>(null) }
|
|
|
var browsingSourceUrl by remember(data != null) { mutableStateOf<String?>(null) }
|
|
var browsingSourceUrl by remember(data != null) { mutableStateOf<String?>(null) }
|
|
@@ -102,6 +106,7 @@ fun <T> HomepageModuleManageSheet(
|
|
|
var browseModuleType by remember(data != null) { mutableStateOf("card") }
|
|
var browseModuleType by remember(data != null) { mutableStateOf("card") }
|
|
|
var selectedKindTitles by remember(data != null) { mutableStateOf<Set<String>>(emptySet()) }
|
|
var selectedKindTitles by remember(data != null) { mutableStateOf<Set<String>>(emptySet()) }
|
|
|
var showCustomSetAddModules by remember(data != null) { mutableStateOf(false) }
|
|
var showCustomSetAddModules by remember(data != null) { mutableStateOf(false) }
|
|
|
|
|
+ var showKindSelect by remember(data != null) { mutableStateOf(false) }
|
|
|
var showAddButtonGroupDialog by remember(data != null) { mutableStateOf(false) }
|
|
var showAddButtonGroupDialog by remember(data != null) { mutableStateOf(false) }
|
|
|
val defaultQuickActionsTitle = stringResource(R.string.homepage_quick_actions)
|
|
val defaultQuickActionsTitle = stringResource(R.string.homepage_quick_actions)
|
|
|
var tempButtonGroupTitle by remember(data != null) { mutableStateOf(defaultQuickActionsTitle) }
|
|
var tempButtonGroupTitle by remember(data != null) { mutableStateOf(defaultQuickActionsTitle) }
|
|
@@ -204,18 +209,27 @@ fun <T> HomepageModuleManageSheet(
|
|
|
val setUrl = selectingSetUrl
|
|
val setUrl = selectingSetUrl
|
|
|
val browseUrl = browsingSourceUrl
|
|
val browseUrl = browsingSourceUrl
|
|
|
val isBrowsing = showSourceBrowser || browseUrl != null
|
|
val isBrowsing = showSourceBrowser || browseUrl != null
|
|
|
|
|
+
|
|
|
|
|
+ LaunchedEffect(browseUrl) {
|
|
|
|
|
+ browseUrl?.let { onSyncSourceModules(it) }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
when {
|
|
when {
|
|
|
browseUrl != null && browsingDetail -> {
|
|
browseUrl != null && browsingDetail -> {
|
|
|
// 三级:浏览书源的模块列表(已加入 / 书源模块 / 发现)
|
|
// 三级:浏览书源的模块列表(已加入 / 书源模块 / 发现)
|
|
|
val displaySetUrl =
|
|
val displaySetUrl =
|
|
|
selectingSetUrl ?: HomepageViewModel.customSetUrl("src_$browseUrl")
|
|
selectingSetUrl ?: HomepageViewModel.customSetUrl("src_$browseUrl")
|
|
|
val currentSetId = HomepageViewModel.customSetIdFromUrl(displaySetUrl)
|
|
val currentSetId = HomepageViewModel.customSetIdFromUrl(displaySetUrl)
|
|
|
- val joinedModules = onGetModulesInSet(displaySetUrl)
|
|
|
|
|
|
|
+ val joinedModules = remember(displaySetUrl, sets, browseSources) {
|
|
|
|
|
+ onGetModulesInSet(displaySetUrl).distinctBy { it.id }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- val standardModules =
|
|
|
|
|
|
|
+ val standardModules = remember(joinedModules) {
|
|
|
joinedModules.filter { !HomepageViewModel.isInfinite(it.type, it.layoutConfig) }
|
|
joinedModules.filter { !HomepageViewModel.isInfinite(it.type, it.layoutConfig) }
|
|
|
- val infiniteModules =
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+ val infiniteModules = remember(joinedModules) {
|
|
|
joinedModules.filter { HomepageViewModel.isInfinite(it.type, it.layoutConfig) }
|
|
joinedModules.filter { HomepageViewModel.isInfinite(it.type, it.layoutConfig) }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
val joinedKeys = joinedModules.map { it.moduleKey }.toSet()
|
|
val joinedKeys = joinedModules.map { it.moduleKey }.toSet()
|
|
|
val sourceModules = onGetSourceModules(browseUrl, currentSetId)
|
|
val sourceModules = onGetSourceModules(browseUrl, currentSetId)
|
|
@@ -243,9 +257,9 @@ fun <T> HomepageModuleManageSheet(
|
|
|
AppText(stringResource(R.string.homepage_no_joined_modules))
|
|
AppText(stringResource(R.string.homepage_no_joined_modules))
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
- var listData by remember(displaySetUrl) {
|
|
|
|
|
|
|
+ var listData by remember(displaySetUrl, standardModules) {
|
|
|
mutableStateOf(
|
|
mutableStateOf(
|
|
|
- standardModules
|
|
|
|
|
|
|
+ standardModules.distinctBy { it.id }
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
val listState = rememberLazyListState()
|
|
val listState = rememberLazyListState()
|
|
@@ -264,7 +278,7 @@ fun <T> HomepageModuleManageSheet(
|
|
|
LaunchedEffect(reorderableState.isAnyItemDragging) {
|
|
LaunchedEffect(reorderableState.isAnyItemDragging) {
|
|
|
if (!reorderableState.isAnyItemDragging) {
|
|
if (!reorderableState.isAnyItemDragging) {
|
|
|
val orderedIds =
|
|
val orderedIds =
|
|
|
- listData.map { it.id } + infiniteModules.map { it.id }
|
|
|
|
|
|
|
+ (listData.map { it.id } + infiniteModules.map { it.id }).distinct()
|
|
|
if (orderedIds != joinedModules.map { it.id }) {
|
|
if (orderedIds != joinedModules.map { it.id }) {
|
|
|
onReorderModules(orderedIds)
|
|
onReorderModules(orderedIds)
|
|
|
}
|
|
}
|
|
@@ -310,8 +324,7 @@ fun <T> HomepageModuleManageSheet(
|
|
|
onClick = { deleteConfirmId = module.id },
|
|
onClick = { deleteConfirmId = module.id },
|
|
|
imageVector = Icons.Default.Delete
|
|
imageVector = Icons.Default.Delete
|
|
|
)
|
|
)
|
|
|
- },
|
|
|
|
|
- modifier = Modifier.padding(horizontal = 4.dp)
|
|
|
|
|
|
|
+ }
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -353,8 +366,7 @@ fun <T> HomepageModuleManageSheet(
|
|
|
onClick = { deleteConfirmId = module.id },
|
|
onClick = { deleteConfirmId = module.id },
|
|
|
imageVector = Icons.Default.Delete
|
|
imageVector = Icons.Default.Delete
|
|
|
)
|
|
)
|
|
|
- },
|
|
|
|
|
- modifier = Modifier.padding(horizontal = 4.dp)
|
|
|
|
|
|
|
+ }
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -398,8 +410,7 @@ fun <T> HomepageModuleManageSheet(
|
|
|
sourceUrl = browseUrl,
|
|
sourceUrl = browseUrl,
|
|
|
)
|
|
)
|
|
|
)
|
|
)
|
|
|
- },
|
|
|
|
|
- modifier = Modifier.padding(horizontal = 4.dp)
|
|
|
|
|
|
|
+ }
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -408,90 +419,76 @@ fun <T> HomepageModuleManageSheet(
|
|
|
|
|
|
|
|
2 -> {
|
|
2 -> {
|
|
|
val isButtonGroup = browseModuleType == "buttonGroup"
|
|
val isButtonGroup = browseModuleType == "buttonGroup"
|
|
|
- val selectableKinds = exploreKinds
|
|
|
|
|
Column {
|
|
Column {
|
|
|
val typeList = remember {
|
|
val typeList = remember {
|
|
|
HomepageModuleType.entries.filter { it != HomepageModuleType.Unknown }
|
|
HomepageModuleType.entries.filter { it != HomepageModuleType.Unknown }
|
|
|
}
|
|
}
|
|
|
- CompactDropdownSettingItem(
|
|
|
|
|
- title = stringResource(R.string.homepage_module_type),
|
|
|
|
|
- selectedValue = browseModuleType,
|
|
|
|
|
- displayEntries = typeList.map { it.title }.toTypedArray(),
|
|
|
|
|
- entryValues = typeList.map { it.key }.toTypedArray(),
|
|
|
|
|
- onValueChange = {
|
|
|
|
|
- browseModuleType = it; selectedKindTitles = emptySet()
|
|
|
|
|
- }
|
|
|
|
|
- )
|
|
|
|
|
- if (selectableKinds.isEmpty()) {
|
|
|
|
|
- Box(
|
|
|
|
|
- modifier = Modifier
|
|
|
|
|
- .fillMaxWidth()
|
|
|
|
|
- .padding(24.dp),
|
|
|
|
|
- contentAlignment = Alignment.Center
|
|
|
|
|
- ) {
|
|
|
|
|
- AppText(
|
|
|
|
|
- stringResource(R.string.homepage_source_no_discover),
|
|
|
|
|
- color = LegadoTheme.colorScheme.onSurfaceVariant
|
|
|
|
|
|
|
+
|
|
|
|
|
+ GlassCard(
|
|
|
|
|
+ containerColor = LegadoTheme.colorScheme.onSheetContent,
|
|
|
|
|
+ cornerRadius = 12.dp
|
|
|
|
|
+ ) {
|
|
|
|
|
+ CompactDropdownSettingItem(
|
|
|
|
|
+ title = stringResource(R.string.homepage_module_type),
|
|
|
|
|
+ selectedValue = browseModuleType,
|
|
|
|
|
+ displayEntries = typeList.map { it.title }.toTypedArray(),
|
|
|
|
|
+ entryValues = typeList.map { it.key }.toTypedArray(),
|
|
|
|
|
+ onValueChange = {
|
|
|
|
|
+ browseModuleType = it; selectedKindTitles = emptySet()
|
|
|
|
|
+ }
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Spacer(modifier = Modifier.height(16.dp))
|
|
|
|
|
+
|
|
|
|
|
+ SelectionItemCard(
|
|
|
|
|
+ title = stringResource(R.string.homepage_select_from_kinds),
|
|
|
|
|
+ subtitle = if (isButtonGroup) {
|
|
|
|
|
+ if (selectedKindTitles.isEmpty()) stringResource(R.string.homepage_select_multiple_kinds)
|
|
|
|
|
+ else stringResource(
|
|
|
|
|
+ R.string.homepage_n_selected,
|
|
|
|
|
+ selectedKindTitles.size
|
|
|
)
|
|
)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ stringResource(R.string.homepage_select_one_kind)
|
|
|
|
|
+ },
|
|
|
|
|
+ containerColor = LegadoTheme.colorScheme.onSheetContent,
|
|
|
|
|
+ onToggleSelection = { showKindSelect = true },
|
|
|
|
|
+ trailingAction = {
|
|
|
|
|
+ if (isButtonGroup && selectedKindTitles.isNotEmpty()) {
|
|
|
|
|
+ SmallIconButton(
|
|
|
|
|
+ onClick = { showAddButtonGroupDialog = true },
|
|
|
|
|
+ imageVector = Icons.Default.Check
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- } else {
|
|
|
|
|
- AppText(
|
|
|
|
|
- stringResource(R.string.homepage_select_items),
|
|
|
|
|
- style = LegadoTheme.typography.labelMedium,
|
|
|
|
|
- modifier = Modifier.padding(
|
|
|
|
|
- horizontal = 16.dp,
|
|
|
|
|
- vertical = 4.dp
|
|
|
|
|
- )
|
|
|
|
|
- )
|
|
|
|
|
- LazyColumn(
|
|
|
|
|
- modifier = Modifier
|
|
|
|
|
- .fillMaxWidth()
|
|
|
|
|
- .weight(1f),
|
|
|
|
|
- verticalArrangement = Arrangement.spacedBy(4.dp)
|
|
|
|
|
- ) {
|
|
|
|
|
- items(
|
|
|
|
|
- selectableKinds.distinctBy { it.first + it.second },
|
|
|
|
|
- key = { it.first + it.second }) { (kindTitle, kindUrl) ->
|
|
|
|
|
- if (isButtonGroup) {
|
|
|
|
|
- val isSelected = kindTitle in selectedKindTitles
|
|
|
|
|
- SelectionItemCard(
|
|
|
|
|
- title = kindTitle,
|
|
|
|
|
- subtitle = kindUrl.take(60),
|
|
|
|
|
- containerColor = LegadoTheme.colorScheme.onSheetContent,
|
|
|
|
|
- isSelected = isSelected,
|
|
|
|
|
- inSelectionMode = true,
|
|
|
|
|
- onToggleSelection = {
|
|
|
|
|
- selectedKindTitles =
|
|
|
|
|
- if (isSelected) selectedKindTitles - kindTitle
|
|
|
|
|
- else selectedKindTitles + kindTitle
|
|
|
|
|
- },
|
|
|
|
|
- modifier = Modifier.padding(horizontal = 4.dp)
|
|
|
|
|
- )
|
|
|
|
|
- } else {
|
|
|
|
|
- val isJoined = joinedKeys.contains(kindTitle)
|
|
|
|
|
- SelectionItemCard(
|
|
|
|
|
- title = kindTitle,
|
|
|
|
|
- subtitle = kindUrl.take(60) + if (isJoined) stringResource(
|
|
|
|
|
- R.string.homepage_status_joined
|
|
|
|
|
- ) else "",
|
|
|
|
|
- containerColor = LegadoTheme.colorScheme.onSheetContent,
|
|
|
|
|
- isSelected = isJoined,
|
|
|
|
|
- inSelectionMode = true,
|
|
|
|
|
- onToggleSelection = {
|
|
|
|
|
- if (!isJoined) addDialogPrefill =
|
|
|
|
|
- AddDialogPrefill(
|
|
|
|
|
- kindTitle,
|
|
|
|
|
- kindUrl,
|
|
|
|
|
- browseModuleType
|
|
|
|
|
- )
|
|
|
|
|
- },
|
|
|
|
|
- modifier = Modifier.padding(horizontal = 4.dp)
|
|
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ ExploreKindSelectSheet(
|
|
|
|
|
+ show = showKindSelect,
|
|
|
|
|
+ onDismissRequest = { showKindSelect = false },
|
|
|
|
|
+ sourceUrl = browseUrl,
|
|
|
|
|
+ multiple = isButtonGroup,
|
|
|
|
|
+ initialSelectedTitles = selectedKindTitles.toList(),
|
|
|
|
|
+ onSelected = { kinds ->
|
|
|
|
|
+ if (isButtonGroup) {
|
|
|
|
|
+ selectedKindTitles = kinds.map { it.title }.toSet()
|
|
|
|
|
+ } else {
|
|
|
|
|
+ kinds.firstOrNull()?.let { kind ->
|
|
|
|
|
+ addDialogPrefill = AddDialogPrefill(
|
|
|
|
|
+ title = kind.title,
|
|
|
|
|
+ url = kind.url ?: "",
|
|
|
|
|
+ type = browseModuleType
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
- Spacer(modifier = Modifier.height(12.dp))
|
|
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ PillDivider(
|
|
|
|
|
+ modifier = Modifier.padding(vertical = 12.dp)
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
SecondaryButton(
|
|
SecondaryButton(
|
|
|
text = stringResource(R.string.homepage_manual_add),
|
|
text = stringResource(R.string.homepage_manual_add),
|
|
|
onClick = {
|
|
onClick = {
|
|
@@ -526,7 +523,7 @@ fun <T> HomepageModuleManageSheet(
|
|
|
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
|
|
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
- items(modules, key = { it.sourceUrl + it.moduleKey }) { module ->
|
|
|
|
|
|
|
+ items(modules, key = { it.id }) { module ->
|
|
|
val instanceIdInCurrentSet = joinedInCurrent[module.moduleKey]
|
|
val instanceIdInCurrentSet = joinedInCurrent[module.moduleKey]
|
|
|
val inCurrentSet = instanceIdInCurrentSet != null
|
|
val inCurrentSet = instanceIdInCurrentSet != null
|
|
|
SelectionItemCard(
|
|
SelectionItemCard(
|
|
@@ -544,8 +541,7 @@ fun <T> HomepageModuleManageSheet(
|
|
|
joinedInCurrent =
|
|
joinedInCurrent =
|
|
|
joinedInCurrent + (module.moduleKey to "temp_${module.id}")
|
|
joinedInCurrent + (module.moduleKey to "temp_${module.id}")
|
|
|
}
|
|
}
|
|
|
- },
|
|
|
|
|
- modifier = Modifier.padding(horizontal = 4.dp)
|
|
|
|
|
|
|
+ }
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -554,11 +550,14 @@ fun <T> HomepageModuleManageSheet(
|
|
|
|
|
|
|
|
isBrowsing -> {
|
|
isBrowsing -> {
|
|
|
// 二级:浏览书源列表
|
|
// 二级:浏览书源列表
|
|
|
|
|
+ val sources = remember(filteredBrowseSources) {
|
|
|
|
|
+ filteredBrowseSources.distinctBy { it.sourceUrl }
|
|
|
|
|
+ }
|
|
|
LazyColumn(
|
|
LazyColumn(
|
|
|
modifier = Modifier.fillMaxWidth(),
|
|
modifier = Modifier.fillMaxWidth(),
|
|
|
verticalArrangement = Arrangement.spacedBy(8.dp)
|
|
verticalArrangement = Arrangement.spacedBy(8.dp)
|
|
|
) {
|
|
) {
|
|
|
- items(filteredBrowseSources, key = { it.sourceUrl }) { source ->
|
|
|
|
|
|
|
+ items(sources, key = { it.sourceUrl }) { source ->
|
|
|
val moduleCount = onGetSourceModules(source.sourceUrl, null).size
|
|
val moduleCount = onGetSourceModules(source.sourceUrl, null).size
|
|
|
SelectionItemCard(
|
|
SelectionItemCard(
|
|
|
title = source.sourceName,
|
|
title = source.sourceName,
|
|
@@ -567,8 +566,7 @@ fun <T> HomepageModuleManageSheet(
|
|
|
onToggleSelection = {
|
|
onToggleSelection = {
|
|
|
browsingSourceUrl = source.sourceUrl
|
|
browsingSourceUrl = source.sourceUrl
|
|
|
browsingDetail = true
|
|
browsingDetail = true
|
|
|
- },
|
|
|
|
|
- modifier = Modifier.padding(horizontal = 4.dp)
|
|
|
|
|
|
|
+ }
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -577,12 +575,16 @@ fun <T> HomepageModuleManageSheet(
|
|
|
setUrl != null && HomepageViewModel.isCustomSetUrl(setUrl) -> {
|
|
setUrl != null && HomepageViewModel.isCustomSetUrl(setUrl) -> {
|
|
|
// 二级:集详情
|
|
// 二级:集详情
|
|
|
val setId = HomepageViewModel.customSetIdFromUrl(setUrl)
|
|
val setId = HomepageViewModel.customSetIdFromUrl(setUrl)
|
|
|
- val modules = onGetModulesInSet(setUrl)
|
|
|
|
|
|
|
+ val modules = remember(setUrl, sets) {
|
|
|
|
|
+ onGetModulesInSet(setUrl).distinctBy { it.id }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- val standardModules =
|
|
|
|
|
|
|
+ val standardModules = remember(modules) {
|
|
|
modules.filter { !HomepageViewModel.isInfinite(it.type, it.layoutConfig) }
|
|
modules.filter { !HomepageViewModel.isInfinite(it.type, it.layoutConfig) }
|
|
|
- val infiniteModules =
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+ val infiniteModules = remember(modules) {
|
|
|
modules.filter { HomepageViewModel.isInfinite(it.type, it.layoutConfig) }
|
|
modules.filter { HomepageViewModel.isInfinite(it.type, it.layoutConfig) }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
if (modules.isEmpty()) {
|
|
if (modules.isEmpty()) {
|
|
|
Column(
|
|
Column(
|
|
@@ -605,7 +607,9 @@ fun <T> HomepageModuleManageSheet(
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
- var listData by remember(setUrl) { mutableStateOf(standardModules) }
|
|
|
|
|
|
|
+ var listData by remember(setUrl, standardModules) {
|
|
|
|
|
+ mutableStateOf(standardModules)
|
|
|
|
|
+ }
|
|
|
val listState = rememberLazyListState()
|
|
val listState = rememberLazyListState()
|
|
|
val reorderableState = rememberReorderableLazyListState(listState) { from, to ->
|
|
val reorderableState = rememberReorderableLazyListState(listState) { from, to ->
|
|
|
listData = listData.toMutableList().apply {
|
|
listData = listData.toMutableList().apply {
|
|
@@ -617,11 +621,12 @@ fun <T> HomepageModuleManageSheet(
|
|
|
|
|
|
|
|
LaunchedEffect(standardModules) {
|
|
LaunchedEffect(standardModules) {
|
|
|
if (!reorderableState.isAnyItemDragging) listData =
|
|
if (!reorderableState.isAnyItemDragging) listData =
|
|
|
- standardModules.distinctBy { it.id }
|
|
|
|
|
|
|
+ standardModules
|
|
|
}
|
|
}
|
|
|
LaunchedEffect(reorderableState.isAnyItemDragging) {
|
|
LaunchedEffect(reorderableState.isAnyItemDragging) {
|
|
|
if (!reorderableState.isAnyItemDragging) {
|
|
if (!reorderableState.isAnyItemDragging) {
|
|
|
- val orderedIds = listData.map { it.id } + infiniteModules.map { it.id }
|
|
|
|
|
|
|
+ val orderedIds =
|
|
|
|
|
+ (listData.map { it.id } + infiniteModules.map { it.id }).distinct()
|
|
|
if (orderedIds != modules.map { it.id }) onReorderModules(orderedIds)
|
|
if (orderedIds != modules.map { it.id }) onReorderModules(orderedIds)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -662,8 +667,7 @@ fun <T> HomepageModuleManageSheet(
|
|
|
onClick = { deleteConfirmId = module.id },
|
|
onClick = { deleteConfirmId = module.id },
|
|
|
imageVector = Icons.Default.Delete
|
|
imageVector = Icons.Default.Delete
|
|
|
)
|
|
)
|
|
|
- },
|
|
|
|
|
- modifier = Modifier.padding(horizontal = 4.dp)
|
|
|
|
|
|
|
+ }
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -694,8 +698,7 @@ fun <T> HomepageModuleManageSheet(
|
|
|
onClick = { deleteConfirmId = module.id },
|
|
onClick = { deleteConfirmId = module.id },
|
|
|
imageVector = Icons.Default.Delete
|
|
imageVector = Icons.Default.Delete
|
|
|
)
|
|
)
|
|
|
- },
|
|
|
|
|
- modifier = Modifier.padding(horizontal = 4.dp)
|
|
|
|
|
|
|
+ }
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -720,7 +723,9 @@ fun <T> HomepageModuleManageSheet(
|
|
|
|
|
|
|
|
else -> {
|
|
else -> {
|
|
|
// 一级:集列表
|
|
// 一级:集列表
|
|
|
- var localSets by remember(data != null) { mutableStateOf(sets) }
|
|
|
|
|
|
|
+ var localSets by remember(data != null, sets) {
|
|
|
|
|
+ mutableStateOf(sets.distinctBy { it.sourceUrl })
|
|
|
|
|
+ }
|
|
|
val setsListState = rememberLazyListState()
|
|
val setsListState = rememberLazyListState()
|
|
|
val setsReorderableState =
|
|
val setsReorderableState =
|
|
|
rememberReorderableLazyListState(setsListState) { from, to ->
|
|
rememberReorderableLazyListState(setsListState) { from, to ->
|
|
@@ -770,8 +775,12 @@ fun <T> HomepageModuleManageSheet(
|
|
|
onClick = { deleteSetConfirmId = set.sourceUrl },
|
|
onClick = { deleteSetConfirmId = set.sourceUrl },
|
|
|
imageVector = Icons.Default.Delete
|
|
imageVector = Icons.Default.Delete
|
|
|
)
|
|
)
|
|
|
- },
|
|
|
|
|
- modifier = Modifier.padding(horizontal = 4.dp)
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+ item {
|
|
|
|
|
+ PillDivider(
|
|
|
|
|
+ modifier = Modifier.padding(vertical = 12.dp)
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
item(key = "create_set") {
|
|
item(key = "create_set") {
|
|
@@ -1001,41 +1010,51 @@ fun <T> AddCustomModuleDialog(
|
|
|
.fillMaxWidth()
|
|
.fillMaxWidth()
|
|
|
.height(400.dp)
|
|
.height(400.dp)
|
|
|
.verticalScroll(rememberScrollState()),
|
|
.verticalScroll(rememberScrollState()),
|
|
|
- verticalArrangement = Arrangement.spacedBy(4.dp)
|
|
|
|
|
|
|
+ verticalArrangement = Arrangement.spacedBy(8.dp),
|
|
|
|
|
+ horizontalAlignment = Alignment.CenterHorizontally
|
|
|
) {
|
|
) {
|
|
|
AppTextField(
|
|
AppTextField(
|
|
|
value = title,
|
|
value = title,
|
|
|
onValueChange = { title = it },
|
|
onValueChange = { title = it },
|
|
|
|
|
+ backgroundColor = LegadoTheme.colorScheme.onSheetContent,
|
|
|
label = stringResource(R.string.homepage_title_label),
|
|
label = stringResource(R.string.homepage_title_label),
|
|
|
modifier = Modifier.fillMaxWidth()
|
|
modifier = Modifier.fillMaxWidth()
|
|
|
)
|
|
)
|
|
|
AppTextField(
|
|
AppTextField(
|
|
|
value = url,
|
|
value = url,
|
|
|
onValueChange = { url = it },
|
|
onValueChange = { url = it },
|
|
|
|
|
+ backgroundColor = LegadoTheme.colorScheme.onSheetContent,
|
|
|
label = "URL",
|
|
label = "URL",
|
|
|
modifier = Modifier.fillMaxWidth()
|
|
modifier = Modifier.fillMaxWidth()
|
|
|
)
|
|
)
|
|
|
val typeList = remember {
|
|
val typeList = remember {
|
|
|
HomepageModuleType.entries.filter { it != HomepageModuleType.Unknown }
|
|
HomepageModuleType.entries.filter { it != HomepageModuleType.Unknown }
|
|
|
}
|
|
}
|
|
|
- DropdownListSettingItem(
|
|
|
|
|
- title = stringResource(R.string.homepage_type_label),
|
|
|
|
|
- selectedValue = type,
|
|
|
|
|
- displayEntries = typeList.map { it.title }.toTypedArray(),
|
|
|
|
|
- entryValues = typeList.map { it.key }.toTypedArray(),
|
|
|
|
|
- onValueChange = { type = it }
|
|
|
|
|
- )
|
|
|
|
|
|
|
+
|
|
|
|
|
+ GlassCard(
|
|
|
|
|
+ containerColor = LegadoTheme.colorScheme.onSheetContent
|
|
|
|
|
+ ) {
|
|
|
|
|
+ DropdownListSettingItem(
|
|
|
|
|
+ title = stringResource(R.string.homepage_type_label),
|
|
|
|
|
+ selectedValue = type,
|
|
|
|
|
+ displayEntries = typeList.map { it.title }.toTypedArray(),
|
|
|
|
|
+ entryValues = typeList.map { it.key }.toTypedArray(),
|
|
|
|
|
+ onValueChange = { type = it }
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
AppTextField(
|
|
AppTextField(
|
|
|
value = args,
|
|
value = args,
|
|
|
onValueChange = { args = it },
|
|
onValueChange = { args = it },
|
|
|
|
|
+ backgroundColor = LegadoTheme.colorScheme.onSheetContent,
|
|
|
label = "Args (JSON)",
|
|
label = "Args (JSON)",
|
|
|
modifier = Modifier.fillMaxWidth()
|
|
modifier = Modifier.fillMaxWidth()
|
|
|
)
|
|
)
|
|
|
- AppText(
|
|
|
|
|
- text = stringResource(R.string.homepage_layout_config_label),
|
|
|
|
|
- style = LegadoTheme.typography.labelMedium,
|
|
|
|
|
- modifier = Modifier.padding(top = 16.dp, bottom = 4.dp)
|
|
|
|
|
|
|
+
|
|
|
|
|
+ PillHeaderDivider(
|
|
|
|
|
+ title = stringResource(R.string.homepage_layout_config_label)
|
|
|
)
|
|
)
|
|
|
|
|
+
|
|
|
if (hasVisualizableKeys) {
|
|
if (hasVisualizableKeys) {
|
|
|
JsonConfigEditor(
|
|
JsonConfigEditor(
|
|
|
jsonString = layoutConfig,
|
|
jsonString = layoutConfig,
|