fix: import target picker uses the standard grouped-list format
The 'Add to calendar' picker rendered bare OptionCards with no calendar colour and no account grouping. Reuse the same account-grouped GroupedRow layout as the event editor's calendar picker — coloured chip per calendar, account sub-headers, a check on the selected row — so it matches the rest of the app. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.padding
|
|||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.Check
|
||||||
import androidx.compose.material.icons.filled.Close
|
import androidx.compose.material.icons.filled.Close
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
@@ -38,8 +39,10 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|||||||
import de.jeanlucmakiola.calendula.R
|
import de.jeanlucmakiola.calendula.R
|
||||||
import de.jeanlucmakiola.calendula.domain.EventForm
|
import de.jeanlucmakiola.calendula.domain.EventForm
|
||||||
import de.jeanlucmakiola.calendula.domain.ics.IcsParseWarning
|
import de.jeanlucmakiola.calendula.domain.ics.IcsParseWarning
|
||||||
|
import de.jeanlucmakiola.calendula.ui.common.CalendarColorChip
|
||||||
|
import de.jeanlucmakiola.calendula.ui.common.GroupedRow
|
||||||
|
import de.jeanlucmakiola.calendula.ui.common.positionOf
|
||||||
import de.jeanlucmakiola.calendula.ui.common.predictiveBack
|
import de.jeanlucmakiola.calendula.ui.common.predictiveBack
|
||||||
import de.jeanlucmakiola.calendula.ui.common.OptionCard
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles an opened/received `.ics` file. A single event is handed straight to
|
* Handles an opened/received `.ics` file. A single event is handed straight to
|
||||||
@@ -106,33 +109,73 @@ private fun ManyContent(state: ImportUiState.Many, onImport: (Long) -> Unit) {
|
|||||||
}
|
}
|
||||||
var selected by rememberSaveable { mutableStateOf(state.calendars.first().id) }
|
var selected by rememberSaveable { mutableStateOf(state.calendars.first().id) }
|
||||||
|
|
||||||
|
// Group by owning account, the same shape the event editor's calendar picker
|
||||||
|
// uses — coloured chip per calendar, a check on the selected one.
|
||||||
|
val groups = remember(state.calendars) {
|
||||||
|
state.calendars
|
||||||
|
.groupBy {
|
||||||
|
it.accountName.takeIf(String::isNotBlank)
|
||||||
|
?: it.accountType.takeIf(String::isNotBlank)
|
||||||
|
?: it.displayName
|
||||||
|
}
|
||||||
|
.toList()
|
||||||
|
}
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
Modifier.fillMaxSize().verticalScroll(rememberScrollState())
|
Modifier.fillMaxSize().verticalScroll(rememberScrollState())
|
||||||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
.padding(vertical = 8.dp),
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
pluralStringResource(R.plurals.import_event_count, state.events.size, state.events.size),
|
pluralStringResource(R.plurals.import_event_count, state.events.size, state.events.size),
|
||||||
style = MaterialTheme.typography.bodyLarge,
|
style = MaterialTheme.typography.bodyLarge,
|
||||||
modifier = Modifier.padding(vertical = 8.dp),
|
modifier = Modifier.padding(horizontal = 24.dp, vertical = 8.dp),
|
||||||
)
|
)
|
||||||
Text(
|
Text(
|
||||||
stringResource(R.string.import_target_header),
|
stringResource(R.string.import_target_header),
|
||||||
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
|
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||||
|
modifier = Modifier.padding(start = 24.dp, end = 24.dp, bottom = 4.dp),
|
||||||
|
)
|
||||||
|
groups.forEach { (account, cals) ->
|
||||||
|
Text(
|
||||||
|
text = account,
|
||||||
style = MaterialTheme.typography.labelLarge,
|
style = MaterialTheme.typography.labelLarge,
|
||||||
color = MaterialTheme.colorScheme.primary,
|
color = MaterialTheme.colorScheme.primary,
|
||||||
|
modifier = Modifier.padding(start = 24.dp, end = 24.dp, top = 16.dp, bottom = 4.dp),
|
||||||
)
|
)
|
||||||
state.calendars.forEach { calendar ->
|
cals.forEachIndexed { index, calendar ->
|
||||||
OptionCard(
|
val isSelected = calendar.id == selected
|
||||||
label = calendar.displayName,
|
GroupedRow(
|
||||||
onClick = { selected = calendar.id },
|
title = calendar.displayName,
|
||||||
selected = calendar.id == selected,
|
position = positionOf(index, cals.size),
|
||||||
icon = null,
|
selected = isSelected,
|
||||||
|
leading = { CalendarColorChip(calendar.color) },
|
||||||
|
trailing = if (isSelected) {
|
||||||
|
{
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.Check,
|
||||||
|
contentDescription = null,
|
||||||
|
tint = MaterialTheme.colorScheme.primary,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
},
|
||||||
|
onClick = { selected = calendar.id },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (state.warnings.isNotEmpty()) {
|
||||||
|
Column(
|
||||||
|
Modifier.padding(horizontal = 24.dp, vertical = 8.dp),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||||
|
) {
|
||||||
state.warnings.forEach { WarningText(it) }
|
state.warnings.forEach { WarningText(it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
Button(
|
Button(
|
||||||
onClick = { onImport(selected) },
|
onClick = { onImport(selected) },
|
||||||
modifier = Modifier.fillMaxWidth().padding(top = 8.dp),
|
modifier = Modifier.fillMaxWidth().padding(start = 16.dp, end = 16.dp, top = 8.dp),
|
||||||
) {
|
) {
|
||||||
Text(pluralStringResource(R.plurals.import_action, state.events.size, state.events.size))
|
Text(pluralStringResource(R.plurals.import_action, state.events.size, state.events.size))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user