kopia lustrzana https://github.com/meshtastic/Meshtastic-Android
refactor: handle selected contacts in a local variable
rodzic
56d9f03748
commit
2b4b1d7683
|
@ -11,12 +11,9 @@ import com.geeksville.mesh.database.entity.Packet
|
|||
import com.geeksville.mesh.repository.datastore.ChannelSetRepository
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted.Companion.WhileSubscribed
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.flow.updateAndGet
|
||||
import kotlinx.coroutines.launch
|
||||
import java.text.DateFormat
|
||||
import java.util.Date
|
||||
|
@ -53,21 +50,6 @@ class ContactsViewModel @Inject constructor(
|
|||
private val packetRepository: PacketRepository,
|
||||
) : ViewModel(), Logging {
|
||||
|
||||
private val _selectedContacts = MutableStateFlow(emptySet<String>())
|
||||
val selectedContacts get() = _selectedContacts.asStateFlow()
|
||||
|
||||
fun updateSelectedContacts(contact: String) = _selectedContacts.updateAndGet {
|
||||
if (it.contains(contact)) {
|
||||
it.minus(contact)
|
||||
} else {
|
||||
it.plus(contact)
|
||||
}
|
||||
}
|
||||
|
||||
fun clearSelectedContacts() {
|
||||
_selectedContacts.value = emptySet()
|
||||
}
|
||||
|
||||
val contactList = combine(
|
||||
nodeDB.myNodeInfo,
|
||||
packetRepository.getContacts(),
|
||||
|
@ -124,4 +106,4 @@ class ContactsViewModel @Inject constructor(
|
|||
fun deleteContacts(contacts: List<String>) = viewModelScope.launch(Dispatchers.IO) {
|
||||
packetRepository.deleteContacts(contacts)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.geeksville.mesh.ui
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
|
@ -27,7 +26,7 @@ import androidx.compose.ui.res.vectorResource
|
|||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewLightDark
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.geeksville.mesh.R
|
||||
import com.geeksville.mesh.model.Contact
|
||||
|
@ -122,8 +121,7 @@ fun ContactItem(
|
|||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@PreviewLightDark
|
||||
@Composable
|
||||
private fun ContactItemPreview() {
|
||||
AppTheme {
|
||||
|
|
|
@ -18,13 +18,13 @@ import androidx.compose.foundation.lazy.LazyColumn
|
|||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.toMutableStateList
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.compose.ui.platform.ViewCompositionStrategy
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.geeksville.mesh.android.Logging
|
||||
import com.geeksville.mesh.R
|
||||
|
@ -43,7 +43,7 @@ class ContactsFragment : ScreenFragment("Messages"), Logging {
|
|||
private val model: ContactsViewModel by viewModels()
|
||||
|
||||
private val contacts get() = model.contactList.value
|
||||
private val selectedList get() = model.selectedContacts.value.toList()
|
||||
private val selectedList = emptyList<String>().toMutableStateList()
|
||||
|
||||
private val selectedContacts get() = contacts.filter { it.contactKey in selectedList }
|
||||
private val isAllMuted get() = selectedContacts.all { it.isMuted }
|
||||
|
@ -63,13 +63,15 @@ class ContactsFragment : ScreenFragment("Messages"), Logging {
|
|||
actionMode = (activity as AppCompatActivity).startSupportActionMode(actionModeCallback)
|
||||
}
|
||||
|
||||
val selected = model.updateSelectedContacts(contact.contactKey)
|
||||
if (selected.isEmpty()) {
|
||||
selectedList.apply {
|
||||
if (!remove(contact.contactKey)) add(contact.contactKey)
|
||||
}
|
||||
if (selectedList.isEmpty()) {
|
||||
// finish action mode when no items selected
|
||||
actionMode?.finish()
|
||||
} else {
|
||||
// show total items selected on action mode title
|
||||
actionMode?.title = selected.size.toString()
|
||||
actionMode?.title = selectedList.size.toString()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,8 +88,15 @@ class ContactsFragment : ScreenFragment("Messages"), Logging {
|
|||
return ComposeView(requireContext()).apply {
|
||||
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
|
||||
setContent {
|
||||
val contacts by model.contactList.collectAsStateWithLifecycle()
|
||||
|
||||
AppTheme {
|
||||
ContactsScreen(model, ::onClick, ::onLongClick)
|
||||
ContactListView(
|
||||
contacts = contacts,
|
||||
selectedList = selectedList,
|
||||
onClick = ::onClick,
|
||||
onLongClick = ::onLongClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -171,14 +180,12 @@ class ContactsFragment : ScreenFragment("Messages"), Logging {
|
|||
R.id.selectAllButton -> {
|
||||
// if all selected -> unselect all
|
||||
if (selectedList.size == contacts.size) {
|
||||
model.clearSelectedContacts()
|
||||
selectedList.clear()
|
||||
mode.finish()
|
||||
} else {
|
||||
// else --> select all
|
||||
model.clearSelectedContacts()
|
||||
contacts.forEach {
|
||||
model.updateSelectedContacts(it.contactKey)
|
||||
}
|
||||
selectedList.clear()
|
||||
selectedList.addAll(contacts.map { it.contactKey })
|
||||
actionMode?.title = contacts.size.toString()
|
||||
}
|
||||
}
|
||||
|
@ -187,7 +194,7 @@ class ContactsFragment : ScreenFragment("Messages"), Logging {
|
|||
}
|
||||
|
||||
override fun onDestroyActionMode(mode: ActionMode) {
|
||||
model.clearSelectedContacts()
|
||||
selectedList.clear()
|
||||
actionMode = null
|
||||
}
|
||||
}
|
||||
|
@ -195,26 +202,25 @@ class ContactsFragment : ScreenFragment("Messages"), Logging {
|
|||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
fun ContactsScreen(
|
||||
model: ContactsViewModel = hiltViewModel(),
|
||||
fun ContactListView(
|
||||
contacts: List<Contact>,
|
||||
selectedList: List<String>,
|
||||
onClick: (Contact) -> Unit,
|
||||
onLongClick: (Contact) -> Unit,
|
||||
) {
|
||||
val contacts by model.contactList.collectAsStateWithLifecycle(emptyList())
|
||||
val selectedKeys by model.selectedContacts.collectAsStateWithLifecycle()
|
||||
// val inSelectionMode by remember { derivedStateOf { selectedContacts.isNotEmpty() } }
|
||||
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(6.dp),
|
||||
) {
|
||||
items(contacts, key = { it.contactKey }) { contact ->
|
||||
val selected = selectedKeys.contains(contact.contactKey)
|
||||
val selected = selectedList.contains(contact.contactKey)
|
||||
val selectedColor = if (selected) Color.Gray else MaterialTheme.colors.background
|
||||
|
||||
ContactItem(
|
||||
contact = contact,
|
||||
modifier = Modifier
|
||||
.background(color = if (selected) Color.Gray else MaterialTheme.colors.background)
|
||||
.background(color = selectedColor)
|
||||
.combinedClickable(
|
||||
onClick = { onClick(contact) },
|
||||
onLongClick = { onLongClick(contact) },
|
||||
|
|
Ładowanie…
Reference in New Issue