mirror of
https://github.com/twofas/2fas-android.git
synced 2025-01-05 14:05:30 +01:00
Reorder list
This commit is contained in:
parent
91fb8328f5
commit
108654541e
@ -46,7 +46,7 @@ internal class ServicesRepositoryImpl(
|
||||
override fun observeServicesTicker(): Flow<List<Service>> {
|
||||
return combine(
|
||||
isTickerEnabled,
|
||||
tickerFlow(1000L),
|
||||
tickerFlow(1_000L),
|
||||
observeServices(),
|
||||
) { a, b, c -> Pair(a, c) }
|
||||
// .filter { it.first } // TODO: ticker
|
||||
|
@ -1,5 +1,7 @@
|
||||
package com.twofasapp.feature.home.ui.services
|
||||
|
||||
import com.twofasapp.data.services.domain.Group
|
||||
import com.twofasapp.data.services.domain.Service
|
||||
import com.twofasapp.designsystem.lazy.ListItem
|
||||
|
||||
sealed class ServicesListItem(
|
||||
@ -11,6 +13,6 @@ sealed class ServicesListItem(
|
||||
object EmptySearch : ServicesListItem("EmptySearch", "EmptySearch")
|
||||
object SyncNoticeBar : ServicesListItem("SyncNoticeBar", "SyncNoticeBar")
|
||||
object SyncReminder : ServicesListItem("SyncReminder", "SyncReminder")
|
||||
data class Service(val id: Long) : ServicesListItem("Service:$id", "Service")
|
||||
data class Group(val id: String?) : ServicesListItem("Group:${id ?: "Default"}", "Group")
|
||||
data class ServiceItem(val service: Service) : ServicesListItem("Service:${service.id}", "Service")
|
||||
data class GroupItem(val group: Group) : ServicesListItem("Group:${group.id ?: "Default"}", "Group")
|
||||
}
|
@ -104,7 +104,7 @@ internal fun ServicesRoute(
|
||||
onMoveDownGroup = { viewModel.moveDownGroup(it) },
|
||||
onEditGroup = { id, name -> viewModel.editGroup(id, name) },
|
||||
onDeleteGroup = { viewModel.deleteGroup(it) },
|
||||
onSwapServices = { from, to -> viewModel.swapServices(from, to) },
|
||||
onDragEnd = { viewModel.onDragEnd(it) },
|
||||
onSortChange = { viewModel.updateSort(it) },
|
||||
onSearchQueryChange = { viewModel.search(it) },
|
||||
onSearchFocusChange = { viewModel.searchFocused(it) },
|
||||
@ -130,7 +130,7 @@ private fun ServicesScreen(
|
||||
onMoveDownGroup: (String) -> Unit = {},
|
||||
onEditGroup: (String, String) -> Unit = { _, _ -> },
|
||||
onDeleteGroup: (String) -> Unit = {},
|
||||
onSwapServices: (Int, Int) -> Unit = { _, _ -> },
|
||||
onDragEnd: (List<ServicesListItem>) -> Unit = { },
|
||||
onSortChange: (Int) -> Unit = {},
|
||||
onSearchQueryChange: (String) -> Unit,
|
||||
onSearchFocusChange: (Boolean) -> Unit,
|
||||
@ -155,18 +155,29 @@ private fun ServicesScreen(
|
||||
val activity = LocalContext.currentActivity
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
var isDragging by remember { mutableStateOf(false) }
|
||||
val data = remember { mutableStateOf(List(100) { "Item $it" }) }
|
||||
val reorderableData = remember { mutableStateOf(uiState.items) }
|
||||
val listState = rememberLazyListState()
|
||||
val reorderableState = rememberReorderableLazyListState(listState = listState, onMove = { from, to ->
|
||||
onSwapServices(from.index, to.index)
|
||||
|
||||
println("Order: From: $from -> To: $to")
|
||||
// onSwapServices((from.key as String).split(":")[1].toLong(), (to.key as String).split(":")[1].toLong())
|
||||
// println("order: ${listState.layoutInfo.visibleItemsInfo.map { it.key }}")
|
||||
// data.value = data.value.toMutableList().apply {
|
||||
// add(to.index, removeAt(from.index))
|
||||
// }
|
||||
})
|
||||
val reorderableState = rememberReorderableLazyListState(
|
||||
listState = listState,
|
||||
onMove = { from, to ->
|
||||
isDragging = true
|
||||
val fromItem = reorderableData.value[from.index]
|
||||
val toItem = reorderableData.value[to.index]
|
||||
if (fromItem is ServicesListItem.ServiceItem) {
|
||||
if (toItem is ServicesListItem.ServiceItem || (toItem is ServicesListItem.GroupItem && toItem.group.id != null)) {
|
||||
reorderableData.value = reorderableData.value.toMutableList().apply {
|
||||
add(to.index, removeAt(from.index))
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
onDragEnd = { _, _ ->
|
||||
isDragging = false
|
||||
onDragEnd(reorderableData.value)
|
||||
},
|
||||
)
|
||||
|
||||
val serviceContainerColor = if (uiState.totalGroups == 1) {
|
||||
TwTheme.color.background
|
||||
@ -177,7 +188,7 @@ private fun ServicesScreen(
|
||||
val serviceContainerColorBlinking = remember { Animatable(serviceContainerColor) }
|
||||
|
||||
var recentlyAddedService by remember { mutableStateOf<Long?>(null) }
|
||||
|
||||
reorderableData.value = uiState.items
|
||||
|
||||
uiState.events.firstOrNull()?.let {
|
||||
when (it) {
|
||||
@ -358,34 +369,36 @@ private fun ServicesScreen(
|
||||
return@LazyColumn
|
||||
}
|
||||
|
||||
if (uiState.showSyncNoticeBar) {
|
||||
listItem(ServicesListItem.SyncNoticeBar) {
|
||||
SyncNoticeBar(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 8.dp),
|
||||
onOpenBackupClick = onOpenBackupClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
reorderableData.value.forEach { item ->
|
||||
|
||||
if (uiState.showSyncReminder) {
|
||||
listItem(ServicesListItem.SyncReminder) {
|
||||
SyncReminder(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 16.dp),
|
||||
onOpenBackupClick = onOpenBackupClick,
|
||||
onDismissClick = onDismissSyncReminderClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
when (item) {
|
||||
ServicesListItem.SyncNoticeBar -> {
|
||||
listItem(item) {
|
||||
SyncNoticeBar(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 8.dp),
|
||||
onOpenBackupClick = onOpenBackupClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
uiState.groups.forEach { group ->
|
||||
ServicesListItem.SyncReminder -> {
|
||||
listItem(item) {
|
||||
SyncReminder(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 16.dp),
|
||||
onOpenBackupClick = onOpenBackupClick,
|
||||
onDismissClick = onDismissSyncReminderClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (uiState.groups.size > 1) {
|
||||
if (group.id != null || (uiState.services.count { it.groupId == null } > 0)) {
|
||||
listItem(ServicesListItem.Group(group.id)) {
|
||||
is ServicesListItem.GroupItem -> {
|
||||
val group = item.group
|
||||
|
||||
listItem(item) {
|
||||
ServicesGroup(
|
||||
id = group.id,
|
||||
name = group.name ?: TwLocale.strings.servicesMyTokens,
|
||||
@ -394,7 +407,13 @@ private fun ServicesScreen(
|
||||
editMode = uiState.isInEditMode,
|
||||
modifier = Modifier
|
||||
.animateContentSize()
|
||||
.animateItemPlacement(),
|
||||
.then(
|
||||
if (isDragging) {
|
||||
Modifier
|
||||
} else {
|
||||
Modifier.animateItemPlacement()
|
||||
}
|
||||
),
|
||||
onClick = { onToggleGroupExpand(group.id) },
|
||||
onExpandClick = { onToggleGroupExpand(group.id) },
|
||||
onMoveUpClick = { onMoveUpGroup(group.id.orEmpty()) },
|
||||
@ -410,20 +429,26 @@ private fun ServicesScreen(
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (group.isExpanded || uiState.isInEditMode) {
|
||||
uiState.services.filter { it.groupId == group.id }.forEach { service ->
|
||||
listItem(ServicesListItem.Service(service.id)) {
|
||||
is ServicesListItem.ServiceItem -> {
|
||||
val service = item.service
|
||||
|
||||
listItem(item) {
|
||||
ReorderableItem(
|
||||
state = reorderableState,
|
||||
key = ServicesListItem.Service(service.id).key,
|
||||
key = item.key,
|
||||
modifier = Modifier
|
||||
.animateItemPlacement()
|
||||
.animateContentSize(),
|
||||
.animateContentSize()
|
||||
.then(
|
||||
if (isDragging) {
|
||||
Modifier
|
||||
} else {
|
||||
Modifier.animateItemPlacement()
|
||||
}
|
||||
),
|
||||
) { isDragging ->
|
||||
val state = service.asState()
|
||||
|
||||
DsService(
|
||||
state = state,
|
||||
style = when (uiState.appSettings.servicesStyle) {
|
||||
@ -457,96 +482,98 @@ private fun ServicesScreen(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (showAddGroupDialog) {
|
||||
InputDialog(title = TwLocale.strings.groupsAdd,
|
||||
onDismissRequest = { showAddGroupDialog = false },
|
||||
positive = TwLocale.strings.commonAdd,
|
||||
negative = TwLocale.strings.commonCancel,
|
||||
hint = TwLocale.strings.groupsName,
|
||||
showCounter = true,
|
||||
minLength = 1,
|
||||
maxLength = 32,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
capitalization = KeyboardCapitalization.Sentences,
|
||||
keyboardType = KeyboardType.Text,
|
||||
),
|
||||
onPositiveClick = { onAddGroup(it) })
|
||||
}
|
||||
if (showAddGroupDialog) {
|
||||
InputDialog(title = TwLocale.strings.groupsAdd,
|
||||
onDismissRequest = { showAddGroupDialog = false },
|
||||
positive = TwLocale.strings.commonAdd,
|
||||
negative = TwLocale.strings.commonCancel,
|
||||
hint = TwLocale.strings.groupsName,
|
||||
showCounter = true,
|
||||
minLength = 1,
|
||||
maxLength = 32,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
capitalization = KeyboardCapitalization.Sentences,
|
||||
keyboardType = KeyboardType.Text,
|
||||
),
|
||||
onPositiveClick = { onAddGroup(it) })
|
||||
}
|
||||
|
||||
if (showEditGroupDialog) {
|
||||
InputDialog(title = TwLocale.strings.groupsEdit,
|
||||
onDismissRequest = { showEditGroupDialog = false },
|
||||
positive = TwLocale.strings.commonSave,
|
||||
negative = TwLocale.strings.commonCancel,
|
||||
hint = TwLocale.strings.groupsName,
|
||||
prefill = clickedGroup?.name.orEmpty(),
|
||||
showCounter = true,
|
||||
minLength = 1,
|
||||
maxLength = 32,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
capitalization = KeyboardCapitalization.Sentences,
|
||||
keyboardType = KeyboardType.Text,
|
||||
),
|
||||
onPositiveClick = { onEditGroup(clickedGroup?.id.orEmpty(), it) })
|
||||
}
|
||||
if (showEditGroupDialog) {
|
||||
InputDialog(title = TwLocale.strings.groupsEdit,
|
||||
onDismissRequest = { showEditGroupDialog = false },
|
||||
positive = TwLocale.strings.commonSave,
|
||||
negative = TwLocale.strings.commonCancel,
|
||||
hint = TwLocale.strings.groupsName,
|
||||
prefill = clickedGroup?.name.orEmpty(),
|
||||
showCounter = true,
|
||||
minLength = 1,
|
||||
maxLength = 32,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
capitalization = KeyboardCapitalization.Sentences,
|
||||
keyboardType = KeyboardType.Text,
|
||||
),
|
||||
onPositiveClick = { onEditGroup(clickedGroup?.id.orEmpty(), it) })
|
||||
}
|
||||
|
||||
if (showDeleteGroupDialog) {
|
||||
ConfirmDialog(
|
||||
onDismissRequest = { showDeleteGroupDialog = false },
|
||||
title = TwLocale.strings.commonDelete,
|
||||
body = TwLocale.strings.groupsDelete,
|
||||
onConfirm = { onDeleteGroup(clickedGroup?.id.orEmpty()) },
|
||||
)
|
||||
}
|
||||
if (showDeleteGroupDialog) {
|
||||
ConfirmDialog(
|
||||
onDismissRequest = { showDeleteGroupDialog = false },
|
||||
title = TwLocale.strings.commonDelete,
|
||||
body = TwLocale.strings.groupsDelete,
|
||||
onConfirm = { onDeleteGroup(clickedGroup?.id.orEmpty()) },
|
||||
)
|
||||
}
|
||||
|
||||
if (showSortDialog) {
|
||||
ListRadioDialog(
|
||||
onDismissRequest = { showSortDialog = false },
|
||||
title = TwLocale.strings.servicesSortBy,
|
||||
options = TwLocale.strings.servicesSortByOptions,
|
||||
selectedIndex = when (uiState.appSettings.servicesSort) {
|
||||
ServicesSort.Alphabetical -> 0
|
||||
ServicesSort.Manual -> 1
|
||||
},
|
||||
onOptionSelected = { index, _ -> onSortChange(index) }
|
||||
)
|
||||
}
|
||||
if (showSortDialog) {
|
||||
ListRadioDialog(
|
||||
onDismissRequest = { showSortDialog = false },
|
||||
title = TwLocale.strings.servicesSortBy,
|
||||
options = TwLocale.strings.servicesSortByOptions,
|
||||
selectedIndex = when (uiState.appSettings.servicesSort) {
|
||||
ServicesSort.Alphabetical -> 0
|
||||
ServicesSort.Manual -> 1
|
||||
},
|
||||
onOptionSelected = { index, _ -> onSortChange(index) }
|
||||
)
|
||||
}
|
||||
|
||||
if (showQrFromGalleryDialog) {
|
||||
ConfirmDialog(
|
||||
onDismissRequest = { showQrFromGalleryDialog = false },
|
||||
title = TwLocale.strings.servicesQrFromGalleryTitle,
|
||||
positive = TwLocale.strings.servicesQrFromGalleryCta,
|
||||
negative = null,
|
||||
bodyAnnotated = buildAnnotatedString {
|
||||
append(TwLocale.strings.servicesQrFromGalleryBody1)
|
||||
if (showQrFromGalleryDialog) {
|
||||
ConfirmDialog(
|
||||
onDismissRequest = { showQrFromGalleryDialog = false },
|
||||
title = TwLocale.strings.servicesQrFromGalleryTitle,
|
||||
positive = TwLocale.strings.servicesQrFromGalleryCta,
|
||||
negative = null,
|
||||
bodyAnnotated = buildAnnotatedString {
|
||||
append(TwLocale.strings.servicesQrFromGalleryBody1)
|
||||
|
||||
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
|
||||
append(TwLocale.strings.servicesQrFromGalleryBody2)
|
||||
}
|
||||
|
||||
append(TwLocale.strings.servicesQrFromGalleryBody3)
|
||||
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
|
||||
append(TwLocale.strings.servicesQrFromGalleryBody2)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if (askForPermission) {
|
||||
RequestPermission(
|
||||
permission = Manifest.permission.CAMERA,
|
||||
onGranted = {
|
||||
askForPermission = false
|
||||
listener.openAddQrService(activity)
|
||||
},
|
||||
onDismissRequest = { askForPermission = false },
|
||||
rationaleTitle = TwLocale.strings.permissionCameraTitle,
|
||||
rationaleText = TwLocale.strings.permissionCameraBody,
|
||||
)
|
||||
}
|
||||
append(TwLocale.strings.servicesQrFromGalleryBody3)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if (askForPermission) {
|
||||
RequestPermission(
|
||||
permission = Manifest.permission.CAMERA,
|
||||
onGranted = {
|
||||
askForPermission = false
|
||||
listener.openAddQrService(activity)
|
||||
},
|
||||
onDismissRequest = { askForPermission = false },
|
||||
rationaleTitle = TwLocale.strings.permissionCameraTitle,
|
||||
rationaleText = TwLocale.strings.permissionCameraBody,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,9 @@
|
||||
package com.twofasapp.feature.home.ui.services
|
||||
|
||||
import com.twofasapp.data.services.domain.Group
|
||||
import com.twofasapp.data.services.domain.Service
|
||||
import com.twofasapp.data.session.domain.AppSettings
|
||||
|
||||
data class ServicesUiState(
|
||||
val groups: List<Group> = emptyList(),
|
||||
val services: List<Service> = emptyList(),
|
||||
val totalGroups: Int = 0,
|
||||
val totalServices: Int = 0,
|
||||
@ -17,10 +15,10 @@ data class ServicesUiState(
|
||||
val showSyncReminder: Boolean = true,
|
||||
val appSettings: AppSettings = AppSettings(),
|
||||
val events: List<ServicesStateEvent> = listOf(),
|
||||
val items: List<ServicesListItem> = emptyList()
|
||||
val items: List<ServicesListItem> = mutableListOf()
|
||||
) {
|
||||
fun getService(id: Long): Service? {
|
||||
return services.firstOrNull() { it.id == id }
|
||||
return services.firstOrNull { it.id == id }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,9 +11,11 @@ import com.twofasapp.data.session.SessionRepository
|
||||
import com.twofasapp.data.session.SettingsRepository
|
||||
import com.twofasapp.data.session.domain.AppSettings
|
||||
import com.twofasapp.data.session.domain.ServicesSort
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.update
|
||||
import java.util.Collections
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
internal class ServicesViewModel(
|
||||
@ -60,11 +62,6 @@ internal class ServicesViewModel(
|
||||
|
||||
uiState.update { state ->
|
||||
state.copy(
|
||||
groups = if (result.searchQuery.isEmpty()) {
|
||||
result.groups
|
||||
} else {
|
||||
result.groups.map { it.copy(isExpanded = true) }
|
||||
},
|
||||
services = result.services
|
||||
.sortedBy {
|
||||
when (result.appSettings.servicesSort) {
|
||||
@ -81,19 +78,44 @@ internal class ServicesViewModel(
|
||||
isInEditMode = result.isInEditMode,
|
||||
appSettings = result.appSettings,
|
||||
items = buildList {
|
||||
result.groups.forEach { group ->
|
||||
if (showSyncNoticeBar) {
|
||||
add(ServicesListItem.SyncNoticeBar)
|
||||
|
||||
if (showSyncNoticeBar) {
|
||||
add(ServicesListItem.SyncNoticeBar)
|
||||
}
|
||||
|
||||
if (showSyncReminder) {
|
||||
add(ServicesListItem.SyncReminder)
|
||||
}
|
||||
|
||||
val groupedServices: Map<Group, List<Service>> = buildMap {
|
||||
result.groups.forEach { group ->
|
||||
put(
|
||||
key = group,
|
||||
value = result.services
|
||||
.filter { it.groupId == group.id }
|
||||
.sortedBy {
|
||||
when (result.appSettings.servicesSort) {
|
||||
ServicesSort.Alphabetical -> it.name.lowercase()
|
||||
ServicesSort.Manual -> null
|
||||
}
|
||||
}
|
||||
.filter { service -> service.isMatchingQuery(result.searchQuery) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
groupedServices.forEach { (group, services) ->
|
||||
|
||||
if (groupedServices.size > 1) {
|
||||
if (group.id != null || services.isNotEmpty() || result.searchQuery.isNotEmpty()) {
|
||||
add(ServicesListItem.GroupItem(result.groups.first { it.id == group.id }))
|
||||
}
|
||||
}
|
||||
|
||||
if (showSyncReminder) {
|
||||
add(ServicesListItem.SyncReminder)
|
||||
}
|
||||
|
||||
add(ServicesListItem.Group(group.id))
|
||||
|
||||
result.services.filter { it.groupId == group.id }.forEach { service ->
|
||||
add(ServicesListItem.Service(service.id))
|
||||
if (group.isExpanded || result.isInEditMode) {
|
||||
services.forEach { service ->
|
||||
add(ServicesListItem.ServiceItem(service))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -154,31 +176,48 @@ internal class ServicesViewModel(
|
||||
}
|
||||
|
||||
fun swapServices(from: Int, to: Int) {
|
||||
var items = uiState.value.items.toMutableList()
|
||||
val items = uiState.value.items.toMutableList()
|
||||
|
||||
val fromItem = items[from]
|
||||
val toItem = items[to]
|
||||
|
||||
if (fromItem is ServicesListItem.Service && toItem is ServicesListItem.Service) {
|
||||
// Swap items
|
||||
items = items.apply { add(to, removeAt(from)) }
|
||||
if (fromItem is ServicesListItem.ServiceItem && toItem is ServicesListItem.ServiceItem) {
|
||||
|
||||
servicesRepository.updateServicesOrder(
|
||||
ids = items.filterIsInstance<ServicesListItem.Service>().map { it.id }
|
||||
)
|
||||
Collections.swap(uiState.value.items, from, to)
|
||||
|
||||
// uiState.update { it.copy(items = items) }
|
||||
|
||||
// servicesRepository.updateServicesOrder(
|
||||
// ids = items.filterIsInstance<ServicesListItem.ServiceItem>().map { it.service.id }
|
||||
// )
|
||||
}
|
||||
|
||||
if (fromItem is ServicesListItem.Service && toItem is ServicesListItem.Group) {
|
||||
val groupId = if (from < to) {
|
||||
toItem.id
|
||||
} else {
|
||||
items.subList(0, to)
|
||||
.filterIsInstance<ServicesListItem.Group>()
|
||||
.asReversed()
|
||||
.firstOrNull()?.id
|
||||
}
|
||||
|
||||
launchScoped { servicesRepository.setServiceGroup(fromItem.id, groupId) }
|
||||
}
|
||||
// var items = uiState.value.items.toMutableList()
|
||||
// val fromItem = items[from]
|
||||
// val toItem = items[to]
|
||||
//
|
||||
// if (fromItem is ServicesListItem.ServiceItem && toItem is ServicesListItem.ServiceItem) {
|
||||
// // Swap items
|
||||
// items = items.apply { add(to, removeAt(from)) }
|
||||
//
|
||||
// servicesRepository.updateServicesOrder(
|
||||
// ids = items.filterIsInstance<ServicesListItem.ServiceItem>().map { it.id }
|
||||
// )
|
||||
// }
|
||||
//
|
||||
// if (fromItem is ServicesListItem.ServiceItem && toItem is ServicesListItem.GroupItem) {
|
||||
// val groupId = if (from < to) {
|
||||
// toItem.id
|
||||
// } else {
|
||||
// items.subList(0, to)
|
||||
// .filterIsInstance<ServicesListItem.GroupItem>()
|
||||
// .asReversed()
|
||||
// .firstOrNull()?.id
|
||||
// }
|
||||
//
|
||||
// launchScoped { servicesRepository.setServiceGroup(fromItem.id, groupId) }
|
||||
// }
|
||||
}
|
||||
|
||||
fun updateSort(index: Int) {
|
||||
@ -216,6 +255,28 @@ internal class ServicesViewModel(
|
||||
tags.contains(query.lowercase())
|
||||
}
|
||||
|
||||
fun onDragEnd(data: List<ServicesListItem>) {
|
||||
launchScoped(Dispatchers.IO) {
|
||||
var groupId: String? = null
|
||||
|
||||
data.forEach { item ->
|
||||
if (item is ServicesListItem.GroupItem) {
|
||||
groupId = item.group.id
|
||||
}
|
||||
|
||||
if (item is ServicesListItem.ServiceItem && item.service.groupId != groupId) {
|
||||
launchScoped {
|
||||
servicesRepository.setServiceGroup(item.service.id, groupId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
servicesRepository.updateServicesOrder(
|
||||
ids = data.filterIsInstance<ServicesListItem.ServiceItem>().map { it.service.id }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
data class CombinedResult(
|
||||
val groups: List<Group>,
|
||||
val services: List<Service>,
|
||||
|
@ -2,10 +2,10 @@
|
||||
accompanist = "0.27.0"
|
||||
agp = "7.4.1"
|
||||
coil = "2.2.2"
|
||||
compose = "1.4.0-rc01"
|
||||
composeActivity = "1.6.1"
|
||||
composeCompiler = "1.4.3"
|
||||
core = "1.9.0"
|
||||
compose = "1.4.1"
|
||||
composeActivity = "1.7.0"
|
||||
composeCompiler = "1.4.4"
|
||||
core = "1.10.0"
|
||||
espresso = "3.5.1"
|
||||
koin = "3.3.2"
|
||||
koinAndroid = "3.4.1"
|
||||
@ -15,9 +15,9 @@ kotlinCoroutines = "1.6.4"
|
||||
kotlinKsp = "1.8.10-1.0.9"
|
||||
ktlint = "3.12.0"
|
||||
ktor = "2.2.2"
|
||||
material3 = "1.1.0-alpha08"
|
||||
room = "2.5.0"
|
||||
viewModel = "2.6.0"
|
||||
material3 = "1.1.0-beta02"
|
||||
room = "2.5.1"
|
||||
viewModel = "2.6.1"
|
||||
|
||||
[libraries]
|
||||
appcompat = "androidx.appcompat:appcompat:1.6.1"
|
||||
|
Loading…
Reference in New Issue
Block a user