Skip to content

Commit

Permalink
search, sort alphabetically
Browse files Browse the repository at this point in the history
  • Loading branch information
crc-32 committed Oct 5, 2024
1 parent c2a7b7c commit 67644df
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class LockerSyncJob: KoinComponent {
}

private suspend fun syncToDevice(): Boolean {
val entries = lockerDao.getEntriesForSync()
val entries = lockerDao.getEntriesForSync().sortedBy { it.entry.title }
val connectedWatch = ConnectionStateManager.connectionState.value.watchOrNull
connectedWatch?.let {
val connectedWatchType = WatchHardwarePlatform
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ object RebbleIcons {
@Composable
fun plusAdd(modifier: Modifier = Modifier.width(24.dp)) = TextIcon(font(), Char(0xe814), modifier = modifier)
@Composable
fun search(modifier: Modifier = Modifier.width(24.dp)) = TextIcon(font(), Char(0xe815), modifier = modifier)
fun search(modifier: Modifier = Modifier.width(24.dp)) = TextIcon(font(), Char(0xe815), modifier = modifier, contentDescription = "Search")
@Composable
fun dictationMicrophone(modifier: Modifier = Modifier.width(24.dp)) = TextIcon(font(), Char(0xe816), modifier = modifier)
@Composable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package io.rebble.cobble.shared.ui.view.home

import androidx.compose.foundation.interaction.PressInteraction
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.unit.dp
import io.rebble.cobble.shared.ui.common.RebbleIcons
import io.rebble.cobble.shared.ui.nav.Routes
Expand All @@ -22,6 +25,7 @@ open class HomePage {
fun HomeScaffold(page: HomePage, onNavChange: (String) -> Unit) {
val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()
val searchingState = remember { mutableStateOf(false) }
Scaffold(
snackbarHost = { SnackbarHost(snackbarHostState) },
/*topBar = {
Expand All @@ -48,11 +52,27 @@ fun HomeScaffold(page: HomePage, onNavChange: (String) -> Unit) {
)
}
},
floatingActionButton = {
when (page) {
is HomePage.Locker -> {
FloatingActionButton(
modifier = Modifier
.padding(16.dp),
onClick = {
searchingState.value = true
},
content = {
RebbleIcons.search()
},
)
}
}
}
) { innerPadding ->
Box(modifier = Modifier.padding(innerPadding)) {
when (page) {
is HomePage.Locker -> {
Locker(page.tab, onTabChanged = {
Locker(searchingState, page.tab, onTabChanged = {
onNavChange(it.navRoute)
})
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
package io.rebble.cobble.shared.ui.view.home.locker

import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.PressInteraction
import androidx.compose.foundation.layout.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment.Companion.CenterHorizontally
import androidx.compose.ui.Alignment.Companion.CenterVertically
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import io.rebble.cobble.shared.database.dao.LockerDao
import io.rebble.cobble.shared.database.entity.SyncedLockerEntryWithPlatforms
import io.rebble.cobble.shared.ui.nav.Routes
import io.rebble.cobble.shared.ui.viewmodel.LockerItemViewModel
import io.rebble.cobble.shared.ui.viewmodel.LockerViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.launch
import org.koin.compose.getKoin

enum class LockerTabs(val label: String, val navRoute: String) {
Expand All @@ -23,20 +27,49 @@ enum class LockerTabs(val label: String, val navRoute: String) {
}

@Composable
fun Locker(page: LockerTabs, lockerDao: LockerDao = getKoin().get(), viewModel: LockerViewModel = viewModel { LockerViewModel(lockerDao) }, onTabChanged: (LockerTabs) -> Unit) {
fun Locker(searchingState: MutableState<Boolean>, page: LockerTabs, lockerDao: LockerDao = getKoin().get(), viewModel: LockerViewModel = viewModel { LockerViewModel(lockerDao) }, onTabChanged: (LockerTabs) -> Unit) {
val entriesState: LockerViewModel.LockerEntriesState by viewModel.entriesState.collectAsState()
val modalSheetState by viewModel.modalSheetState.collectAsState()
val watchIsConnected by viewModel.watchIsConnected.collectAsState()
val searchQuery: String? by viewModel.searchQuery.collectAsState()
val focusRequester = remember { FocusRequester() }
val (searching, setSearching) = searchingState

Column {
Surface {
Row(modifier = Modifier.fillMaxWidth().height(64.dp)) {
LockerTabs.entries.forEachIndexed { index, it ->
NavigationBarItem(
selected = page == it,
onClick = { onTabChanged(it) },
icon = { Text(it.label) },
if (searching) {
TextField(
value = searchQuery ?: "",
onValueChange = { viewModel.searchQuery.value = it },
label = { Text("Search") },
modifier = Modifier.fillMaxWidth().padding(8.dp)
.focusRequester(focusRequester)
.onGloballyPositioned {
focusRequester.requestFocus()
},
singleLine = true,
trailingIcon = {
IconButton(
onClick = {
viewModel.searchQuery.value = null
setSearching(false)
},
modifier = Modifier.align(CenterVertically),
content = {
Icon(Icons.Default.Close, contentDescription = "Clear search")
},
)
}
)
} else {
LockerTabs.entries.forEachIndexed { index, it ->
NavigationBarItem(
selected = page == it,
onClick = { onTabChanged(it) },
icon = { Text(it.label) },
)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ fun LockerAppList(viewModel: LockerViewModel, onOpenModalSheet: (LockerItemViewM
val lazyListState = rememberLazyListState()
val koin = getKoin()
val entriesState by viewModel.entriesState.collectAsState()
val entries = ((entriesState as? LockerViewModel.LockerEntriesState.Loaded)?.entries ?: emptyList()).filter { it.entry.type == "watchapp" }
val searchQuery: String? by viewModel.searchQuery.collectAsState()
val entries = ((entriesState as? LockerViewModel.LockerEntriesState.Loaded)?.entries ?: emptyList())
.filter { it.entry.type == "watchapp" }
.filter { searchQuery == null || it.entry.title.contains(searchQuery!!, ignoreCase = true) || it.entry.developerName.contains(searchQuery!!, ignoreCase = true) }
val reorderableLazyListState = rememberReorderableLazyListState(lazyListState) { from, to ->
val entry = entries.first { it.entry.id == from.key }
val nwList = entries.toMutableList()
Expand All @@ -41,11 +44,13 @@ fun LockerAppList(viewModel: LockerViewModel, onOpenModalSheet: (LockerItemViewM
items(entries.size, key = { i -> entries[i].entry.id }) { i ->
ReorderableItem(state = reorderableLazyListState, key = entries[i].entry.id) { isDragging ->
LockerListItem(koin.get(), entries[i], onOpenModalSheet = onOpenModalSheet, dragHandle = {
IconButton(
modifier = Modifier.draggableHandle(),
content = { RebbleIcons.dragHandle() },
onClick = {}
)
if (searchQuery == null) {
IconButton(
modifier = Modifier.draggableHandle(),
content = { RebbleIcons.dragHandle() },
onClick = {}
)
}
})
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.SmallFloatingActionButton
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
Expand All @@ -19,8 +20,12 @@ import io.rebble.cobble.shared.ui.viewmodel.LockerViewModel

@Composable
fun LockerWatchfaceList(viewModel: LockerViewModel, onOpenModalSheet: (LockerItemViewModel) -> Unit) {
val searchQuery: String? by viewModel.searchQuery.collectAsState()
val entriesState: LockerViewModel.LockerEntriesState by viewModel.entriesState.collectAsState()
val entries = ((entriesState as? LockerViewModel.LockerEntriesState.Loaded)?.entries ?: emptyList()).filter { it.entry.type == "watchface" }
val entries = ((entriesState as? LockerViewModel.LockerEntriesState.Loaded)?.entries ?: emptyList())
.filter { it.entry.type == "watchface" }
.filter { searchQuery == null || it.entry.title.contains(searchQuery!!, ignoreCase = true) || it.entry.developerName.contains(searchQuery!!, ignoreCase = true) }
.sortedBy { it.entry.title }
val connectedState: Boolean by viewModel.watchIsConnected.collectAsState()

LazyVerticalGrid(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class LockerViewModel(private val lockerDao: LockerDao): ViewModel() {
private val _modalSheetState = MutableStateFlow<ModalSheetState>(ModalSheetState.Closed)
val modalSheetState: StateFlow<ModalSheetState> = _modalSheetState
val watchIsConnected = ConnectionStateManager.isConnected
val searchQuery = MutableStateFlow<String?>(null)

suspend fun updateOrder(entries: List<SyncedLockerEntryWithPlatforms>) {
lastJob?.cancel()
Expand Down

0 comments on commit 67644df

Please sign in to comment.