@@ -13,6 +13,8 @@ import androidx.compose.foundation.shape.RoundedCornerShape
1313import androidx.compose.material.icons.Icons
1414import androidx.compose.material.icons.filled.*
1515import androidx.compose.material.icons.outlined.Folder
16+ import androidx.compose.material.icons.rounded.Search
17+ import androidx.compose.material.icons.rounded.Close
1618import androidx.compose.material3.*
1719import androidx.compose.material3.HorizontalDivider
1820import androidx.compose.runtime.*
@@ -77,12 +79,26 @@ fun BrowseScreen(
7779 var showCreateFolderDialog by remember { mutableStateOf(false ) }
7880 var newFolderName by remember { mutableStateOf(" " ) }
7981 var folderError by remember { mutableStateOf(" " ) }
82+ var searchQuery by remember { mutableStateOf(" " ) }
83+ var isSearchActive by remember { mutableStateOf(false ) }
8084
8185 BackHandler (enabled = currentPath != " /" && currentPath.isNotEmpty()) {
8286 onNavigate(parentPath.ifEmpty { " /" })
8387 }
8488
85- LaunchedEffect (currentPath) { selectedFiles = emptySet() }
89+ LaunchedEffect (currentPath) {
90+ selectedFiles = emptySet()
91+ searchQuery = " "
92+ isSearchActive = false
93+ }
94+
95+ val displayFiles = remember(files, searchQuery) {
96+ if (searchQuery.isBlank()) {
97+ files
98+ } else {
99+ files.filter { it.name.contains(searchQuery, ignoreCase = true ) }
100+ }
101+ }
86102
87103 val filePickerLauncher = rememberLauncherForActivityResult(contract = ActivityResultContracts .GetMultipleContents ()) { uris: List <Uri > ->
88104 if (uris.isNotEmpty()) onUploadFiles(uris)
@@ -211,10 +227,48 @@ fun BrowseScreen(
211227 Column (modifier = Modifier .fillMaxSize()) {
212228
213229 Surface (color = BgBase , modifier = Modifier .fillMaxWidth()) {
214- Row (modifier = Modifier .padding(horizontal = 16 .dp, vertical = 16 .dp), verticalAlignment = Alignment .CenterVertically ) {
215- DeviceIcon (activeDeviceOS, GreenAccent , Modifier .size(20 .dp))
216- Spacer (modifier = Modifier .width(12 .dp))
217- Text (activeDeviceName, color = TextPrimary , fontWeight = FontWeight .Black , fontSize = 18 .sp, modifier = Modifier .weight(1f ))
230+ // ── DYNAMIC HEADER: Device Name OR Search Bar ──
231+ if (isSearchActive) {
232+ OutlinedTextField (
233+ value = searchQuery,
234+ onValueChange = { searchQuery = it },
235+ placeholder = { Text (" Search files..." , color = TextMuted ) },
236+ singleLine = true ,
237+ textStyle = androidx.compose.ui.text.TextStyle (color = TextPrimary , fontSize = 14 .sp),
238+ colors = OutlinedTextFieldDefaults .colors(
239+ focusedBorderColor = GreenAccent ,
240+ unfocusedBorderColor = Surface ,
241+ focusedContainerColor = Surface , // Darker inset look
242+ unfocusedContainerColor = Surface ,
243+ focusedTextColor = TextPrimary
244+ ),
245+ modifier = Modifier .weight(1f ).height(50 .dp),
246+ shape = RoundedCornerShape (12 .dp),
247+ trailingIcon = {
248+ IconButton (
249+ onClick = {
250+ if (searchQuery.isNotEmpty()) {
251+ searchQuery = " " // Clear input
252+ } else {
253+ isSearchActive = false // Close search
254+ }
255+ }
256+ ) {
257+ Icon (Icons .Rounded .Close , contentDescription = " Close" , tint = TextMuted )
258+ }
259+ }
260+ )
261+ } else {
262+ Row (modifier = Modifier .padding(horizontal = 16 .dp, vertical = 16 .dp), verticalAlignment = Alignment .CenterVertically ) {
263+ DeviceIcon (activeDeviceOS, GreenAccent , Modifier .size(20 .dp))
264+ Spacer (modifier = Modifier .width(8 .dp))
265+ Text (activeDeviceName, color = TextPrimary , fontWeight = FontWeight .Black , fontSize = 18 .sp, modifier = Modifier .weight(1f ))
266+ }
267+
268+ // ── Search Trigger Button ──
269+ IconButton (onClick = { isSearchActive = true }) {
270+ Icon (Icons .Rounded .Search , contentDescription = " Search" , tint = TextPrimary )
271+ }
218272 }
219273 }
220274
@@ -279,7 +333,7 @@ fun BrowseScreen(
279333 Box (modifier = Modifier .fillMaxSize(), contentAlignment = Alignment .Center ) { CircularProgressIndicator (color = Accent ) }
280334 } else {
281335 LazyColumn (contentPadding = PaddingValues (bottom = 80 .dp)) {
282- items(files ) { file ->
336+ items(displayFiles ) { file ->
283337 val isSelected = selectedFiles.contains(file)
284338 FileRowItem (
285339 file = file, isSelected = isSelected,
@@ -297,8 +351,15 @@ fun BrowseScreen(
297351 Column (modifier = Modifier .align(Alignment .BottomEnd ).padding(16 .dp), horizontalAlignment = Alignment .End ) {
298352 SmallFloatingActionButton (
299353 onClick = onShareClipboardClick,
300- containerColor = Color (0xFFa78bfa ).copy(alpha = 0.15f ), contentColor = Color (0xFFa78bfa ),
301- modifier = Modifier .padding(bottom = 12 .dp), shape = RoundedCornerShape (12 .dp)
354+ containerColor = Color (0xFFa78bfa ).copy(alpha = 0.15f ), // High transparency
355+ contentColor = Color (0xFFa78bfa ),
356+ elevation = FloatingActionButtonDefaults .elevation(0 .dp, 0 .dp, 0 .dp, 0 .dp), // Remove shadow for true glass look
357+ modifier = Modifier
358+ .padding(bottom = 12 .dp)
359+ // Optional: If running strictly on Android 12+, you can add actual blur here
360+ // .graphicsLayer { renderEffect = android.graphics.RenderEffect.createBlurEffect(20f, 20f, android.graphics.Shader.TileMode.CLAMP).asComposeRenderEffect() }
361+ ,
362+ shape = RoundedCornerShape (12 .dp)
302363 ) {
303364 Icon (Icons .Filled .ContentPaste , contentDescription = " Share Clipboard" )
304365 }
0 commit comments