diff --git a/CHANGELOG.md b/CHANGELOG.md index 8840ee571d7..f356ff1c470 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## 0.4.12 +* `Selector` + * Project created + ## 0.4.11 * `Common` diff --git a/README.md b/README.md index 1c11fb08176..0686112a8cf 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ You always can look at the { + val selectedItems: List + val itemSelected: SharedFlow + val itemUnselected: SharedFlow + + suspend fun toggleSelection(element: T) +} + +@Suppress("NOTHING_TO_INLINE") +inline operator fun Selector.contains(element: T) = selectedItems.contains(element) +@Suppress("NOTHING_TO_INLINE") +inline fun Selector.nothingSelected(): Boolean = selectedItems.isEmpty() + +class SingleSelector( + selectedItem: T? = null, + useMutex: Boolean = true +) : Selector { + var selectedItem: T? = selectedItem + private set + override val selectedItems: List + get() = selectedItem ?.let { listOf(it) } ?: emptyList() + + private val _itemSelected = MutableSharedFlow() + override val itemSelected: SharedFlow = _itemSelected.asSharedFlow() + private val _itemUnselected = MutableSharedFlow() + override val itemUnselected: SharedFlow = _itemUnselected.asSharedFlow() + + private val mutex = if (useMutex) { + Mutex() + } else { + null + } + + override suspend fun toggleSelection(element: T) { + mutex ?.lock() + if (selectedItem == element) { + selectedItem = null + _itemUnselected.emit(element) + } else { + val previouslySelected = selectedItem + selectedItem = null + if (previouslySelected != null) { + _itemUnselected.emit(previouslySelected) + } + selectedItem = element + _itemSelected.emit(element) + } + mutex ?.unlock() + } +} + +class MultipleSelector( + selectedItems: List, + useMutex: Boolean = true +) : Selector { + private val _selectedItems: MutableList = selectedItems.toMutableList() + override val selectedItems: List = _selectedItems + + private val _itemSelected = MutableSharedFlow() + override val itemSelected: SharedFlow = _itemSelected.asSharedFlow() + private val _itemUnselected = MutableSharedFlow() + override val itemUnselected: SharedFlow = _itemUnselected.asSharedFlow() + + private val mutex = if (useMutex) { + Mutex() + } else { + null + } + + override suspend fun toggleSelection(element: T) { + mutex ?.lock() + if (_selectedItems.remove(element)) { + _itemUnselected.emit(element) + } else { + _selectedItems.add(element) + _itemSelected.emit(element) + } + mutex ?.unlock() + } +} diff --git a/selector/common/src/main/AndroidManifest.xml b/selector/common/src/main/AndroidManifest.xml new file mode 100644 index 00000000000..af2679c3813 --- /dev/null +++ b/selector/common/src/main/AndroidManifest.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 320b82da2da..c438c68de35 100644 --- a/settings.gradle +++ b/settings.gradle @@ -2,6 +2,7 @@ rootProject.name='micro_utils' String[] includes = [ ":common", + ":selector:common", ":pagination:common", ":pagination:exposed", ":pagination:ktor:common",