Makes search view in TopBar
This commit is contained in:
parent
f356e2262b
commit
5f6a79e496
3 changed files with 136 additions and 75 deletions
|
|
@ -2,11 +2,7 @@
|
||||||
|
|
||||||
package io.element.android.x.features.roomlist
|
package io.element.android.x.features.roomlist
|
||||||
|
|
||||||
import androidx.compose.animation.animateContentSize
|
|
||||||
import androidx.compose.animation.core.tween
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.LazyListState
|
import androidx.compose.foundation.lazy.LazyListState
|
||||||
|
|
@ -21,7 +17,6 @@ import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.airbnb.mvrx.Loading
|
import com.airbnb.mvrx.Loading
|
||||||
import com.airbnb.mvrx.Success
|
import com.airbnb.mvrx.Success
|
||||||
import com.airbnb.mvrx.compose.collectAsState
|
import com.airbnb.mvrx.compose.collectAsState
|
||||||
|
|
@ -30,7 +25,6 @@ import io.element.android.x.core.compose.LogCompositions
|
||||||
import io.element.android.x.designsystem.ElementXTheme
|
import io.element.android.x.designsystem.ElementXTheme
|
||||||
import io.element.android.x.designsystem.components.ProgressDialog
|
import io.element.android.x.designsystem.components.ProgressDialog
|
||||||
import io.element.android.x.designsystem.components.avatar.AvatarData
|
import io.element.android.x.designsystem.components.avatar.AvatarData
|
||||||
import io.element.android.x.features.roomlist.components.RoomFilter
|
|
||||||
import io.element.android.x.features.roomlist.components.RoomItem
|
import io.element.android.x.features.roomlist.components.RoomItem
|
||||||
import io.element.android.x.features.roomlist.components.RoomListTopBar
|
import io.element.android.x.features.roomlist.components.RoomListTopBar
|
||||||
import io.element.android.x.features.roomlist.model.MatrixUser
|
import io.element.android.x.features.roomlist.model.MatrixUser
|
||||||
|
|
@ -82,19 +76,16 @@ fun RoomListContent(
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||||
topBar = {
|
topBar = {
|
||||||
RoomListTopBar(matrixUser, onLogoutClicked, scrollBehavior)
|
RoomListTopBar(
|
||||||
|
matrixUser = matrixUser,
|
||||||
|
filter = filter,
|
||||||
|
onFilterChanged = onFilterChanged,
|
||||||
|
onLogoutClicked = onLogoutClicked,
|
||||||
|
scrollBehavior = scrollBehavior
|
||||||
|
)
|
||||||
},
|
},
|
||||||
content = { padding ->
|
content = { padding ->
|
||||||
Column(modifier = Modifier.padding(padding)) {
|
Column(modifier = Modifier.padding(padding)) {
|
||||||
RoomFilter(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.animateContentSize(animationSpec = tween(durationMillis = 300))
|
|
||||||
.height(if (lazyListState.isScrolled()) 0.dp else 56.dp)
|
|
||||||
.padding(horizontal = 16.dp, vertical = 4.dp),
|
|
||||||
filter = filter,
|
|
||||||
onFilterChanged = onFilterChanged
|
|
||||||
)
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
state = lazyListState,
|
state = lazyListState,
|
||||||
|
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
package io.element.android.x.features.roomlist.components
|
|
||||||
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.filled.Clear
|
|
||||||
import androidx.compose.material.icons.filled.Search
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.material3.IconButton
|
|
||||||
import androidx.compose.material3.TextField
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
|
||||||
@Composable
|
|
||||||
fun RoomFilter(
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
filter: String,
|
|
||||||
onFilterChanged: (String) -> Unit
|
|
||||||
) {
|
|
||||||
TextField(
|
|
||||||
modifier = modifier,
|
|
||||||
value = filter,
|
|
||||||
onValueChange = onFilterChanged,
|
|
||||||
//label = {
|
|
||||||
// Text(text = "Search")
|
|
||||||
//},
|
|
||||||
leadingIcon = {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Filled.Search,
|
|
||||||
contentDescription = null
|
|
||||||
)
|
|
||||||
},
|
|
||||||
trailingIcon = if (filter.isNotEmpty()) {
|
|
||||||
{
|
|
||||||
IconButton(onClick = { onFilterChanged("") }) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Filled.Clear,
|
|
||||||
contentDescription = null
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else null
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
@Preview
|
|
||||||
private fun RoomFilterPreview() {
|
|
||||||
RoomFilter(
|
|
||||||
filter = "",
|
|
||||||
onFilterChanged = {}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
@ -3,15 +3,25 @@
|
||||||
package io.element.android.x.features.roomlist.components
|
package io.element.android.x.features.roomlist.components
|
||||||
|
|
||||||
import Avatar
|
import Avatar
|
||||||
|
import androidx.activity.compose.BackHandler
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.material.ContentAlpha
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.ExitToApp
|
import androidx.compose.material.icons.filled.ArrowBack
|
||||||
|
import androidx.compose.material.icons.filled.Close
|
||||||
|
import androidx.compose.material.icons.filled.Logout
|
||||||
|
import androidx.compose.material.icons.filled.Search
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
|
import androidx.compose.ui.focus.focusRequester
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
import io.element.android.x.core.compose.LogCompositions
|
import io.element.android.x.core.compose.LogCompositions
|
||||||
import io.element.android.x.designsystem.components.dialogs.ConfirmationDialog
|
import io.element.android.x.designsystem.components.dialogs.ConfirmationDialog
|
||||||
import io.element.android.x.features.roomlist.model.MatrixUser
|
import io.element.android.x.features.roomlist.model.MatrixUser
|
||||||
|
|
@ -19,10 +29,119 @@ import io.element.android.x.features.roomlist.model.MatrixUser
|
||||||
@Composable
|
@Composable
|
||||||
fun RoomListTopBar(
|
fun RoomListTopBar(
|
||||||
matrixUser: MatrixUser?,
|
matrixUser: MatrixUser?,
|
||||||
|
filter: String,
|
||||||
|
onFilterChanged: (String) -> Unit,
|
||||||
onLogoutClicked: () -> Unit,
|
onLogoutClicked: () -> Unit,
|
||||||
scrollBehavior: TopAppBarScrollBehavior
|
scrollBehavior: TopAppBarScrollBehavior
|
||||||
) {
|
) {
|
||||||
LogCompositions(tag = "RoomListScreen", msg = "TopBar")
|
LogCompositions(tag = "RoomListScreen", msg = "TopBar")
|
||||||
|
var searchWidgetStateIsOpened by rememberSaveable { mutableStateOf(false) }
|
||||||
|
BackHandler(enabled = searchWidgetStateIsOpened) {
|
||||||
|
searchWidgetStateIsOpened = false
|
||||||
|
}
|
||||||
|
if (searchWidgetStateIsOpened) {
|
||||||
|
SearchRoomListTopBar(
|
||||||
|
text = filter,
|
||||||
|
onFilterChanged = onFilterChanged,
|
||||||
|
onCloseClicked = {
|
||||||
|
searchWidgetStateIsOpened = false
|
||||||
|
},
|
||||||
|
scrollBehavior = scrollBehavior,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
DefaultRoomListTopBar(
|
||||||
|
matrixUser = matrixUser,
|
||||||
|
onLogoutClicked = onLogoutClicked,
|
||||||
|
onSearchClicked = {
|
||||||
|
searchWidgetStateIsOpened = true
|
||||||
|
},
|
||||||
|
scrollBehavior = scrollBehavior,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SearchRoomListTopBar(
|
||||||
|
text: String,
|
||||||
|
onFilterChanged: (String) -> Unit,
|
||||||
|
onCloseClicked: () -> Unit,
|
||||||
|
scrollBehavior: TopAppBarScrollBehavior
|
||||||
|
) {
|
||||||
|
val focusRequester = remember { FocusRequester() }
|
||||||
|
TopAppBar(
|
||||||
|
modifier = Modifier
|
||||||
|
.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||||
|
title = {
|
||||||
|
TextField(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.focusRequester(focusRequester),
|
||||||
|
value = text,
|
||||||
|
textStyle = TextStyle(
|
||||||
|
fontSize = 17.sp
|
||||||
|
),
|
||||||
|
onValueChange = {
|
||||||
|
onFilterChanged(it)
|
||||||
|
},
|
||||||
|
placeholder = {
|
||||||
|
Text(
|
||||||
|
text = "Search",
|
||||||
|
color = MaterialTheme.colorScheme.onBackground.copy(alpha = ContentAlpha.medium)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
singleLine = true,
|
||||||
|
trailingIcon = {
|
||||||
|
if (text.isNotEmpty()) {
|
||||||
|
IconButton(
|
||||||
|
onClick = {
|
||||||
|
onFilterChanged("")
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.Close,
|
||||||
|
contentDescription = "close",
|
||||||
|
tint = MaterialTheme.colorScheme.onBackground
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
colors = TextFieldDefaults.textFieldColors(
|
||||||
|
textColor = MaterialTheme.colorScheme.onBackground,
|
||||||
|
containerColor = Color.Transparent,
|
||||||
|
cursorColor = MaterialTheme.colorScheme.onBackground.copy(alpha = ContentAlpha.medium),
|
||||||
|
focusedIndicatorColor = Color.Transparent,
|
||||||
|
unfocusedIndicatorColor = Color.Transparent,
|
||||||
|
disabledIndicatorColor = Color.Transparent
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
navigationIcon = {
|
||||||
|
IconButton(
|
||||||
|
onClick = {
|
||||||
|
onCloseClicked()
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.ArrowBack,
|
||||||
|
contentDescription = "close",
|
||||||
|
tint = MaterialTheme.colorScheme.onBackground
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
focusRequester.requestFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun DefaultRoomListTopBar(
|
||||||
|
matrixUser: MatrixUser?,
|
||||||
|
onLogoutClicked: () -> Unit,
|
||||||
|
onSearchClicked: () -> Unit,
|
||||||
|
scrollBehavior: TopAppBarScrollBehavior
|
||||||
|
) {
|
||||||
val openDialog = remember { mutableStateOf(false) }
|
val openDialog = remember { mutableStateOf(false) }
|
||||||
MediumTopAppBar(
|
MediumTopAppBar(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|
@ -41,10 +160,15 @@ fun RoomListTopBar(
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
|
IconButton(
|
||||||
|
onClick = onSearchClicked
|
||||||
|
) {
|
||||||
|
Icon(Icons.Default.Search, contentDescription = "search")
|
||||||
|
}
|
||||||
IconButton(
|
IconButton(
|
||||||
onClick = { openDialog.value = true }
|
onClick = { openDialog.value = true }
|
||||||
) {
|
) {
|
||||||
Icon(Icons.Default.ExitToApp, contentDescription = "logout")
|
Icon(Icons.Default.Logout, contentDescription = "logout")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
scrollBehavior = scrollBehavior,
|
scrollBehavior = scrollBehavior,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue