From 08e3b738a9816e986a17a2dfe0f54b47a36f0525 Mon Sep 17 00:00:00 2001 From: T8RIN Date: Sat, 19 Mar 2022 16:29:35 +0300 Subject: [PATCH] Search for notes/goals added --- .idea/deploymentTargetDropDown.xml | 17 ++ .idea/inspectionProfiles/Project_Default.xml | 7 + .../java/ru/tech/firenote/MainActivity.kt | 286 +++++++++++++++--- .../ui/composable/navigation/Navigation.kt | 6 +- .../composable/screen/GoalCreationScreen.kt | 8 +- .../composable/screen/base/GoalListScreen.kt | 31 +- .../composable/screen/base/NoteListScreen.kt | 24 +- .../ui/composable/single/AppBarActions.kt | 2 +- .../ui/composable/single/AppBarWithInsets.kt | 19 +- .../composable/single/BottomNavigationBar.kt | 3 +- .../firenote/ui/composable/single/GoalItem.kt | 68 +++-- .../firenote/ui/composable/single/NoteItem.kt | 43 ++- .../tech/firenote/viewModel/MainViewModel.kt | 5 +- app/src/main/res/values/strings.xml | 2 + 14 files changed, 414 insertions(+), 107 deletions(-) create mode 100644 .idea/deploymentTargetDropDown.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml new file mode 100644 index 0000000..4ddd9d7 --- /dev/null +++ b/.idea/deploymentTargetDropDown.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..0803fec --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/java/ru/tech/firenote/MainActivity.kt b/app/src/main/java/ru/tech/firenote/MainActivity.kt index 4b58a99..48c7f8f 100644 --- a/app/src/main/java/ru/tech/firenote/MainActivity.kt +++ b/app/src/main/java/ru/tech/firenote/MainActivity.kt @@ -13,12 +13,17 @@ import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.foundation.layout.* +import androidx.compose.foundation.text.BasicTextField +import androidx.compose.foundation.text.KeyboardActions import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ExitToApp import androidx.compose.material.icons.outlined.AddTask import androidx.compose.material.icons.outlined.Edit import androidx.compose.material.icons.outlined.Image +import androidx.compose.material.icons.rounded.ArrowBack +import androidx.compose.material.icons.rounded.Close import androidx.compose.material.icons.rounded.Edit +import androidx.compose.material.icons.rounded.Search import androidx.compose.material.icons.twotone.FactCheck import androidx.compose.material.icons.twotone.StickyNote2 import androidx.compose.material3.* @@ -27,10 +32,16 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha +import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp import androidx.core.view.WindowCompat import androidx.navigation.compose.rememberNavController import com.google.accompanist.insets.ProvideWindowInsets @@ -85,6 +96,9 @@ class MainActivity : ComponentActivity() { dismissText = R.string.close, dismissAction = { finishAffinity() } ) + if (mainViewModel.searchMode.value) BackHandler { + mainViewModel.searchMode.value = false + } ProvideWindowInsets { val snackbarHostState = remember { SnackbarHostState() } @@ -101,22 +115,119 @@ class MainActivity : ComponentActivity() { Row { Scaffold( topBar = { - when (mainViewModel.selectedItem.value) { - 2 -> { - AppBarWithInsets( - type = APP_BAR_CENTER, - navigationIcon = { + AppBarWithInsets( + type = APP_BAR_CENTER, + navigationIcon = { + when (mainViewModel.selectedItem.value) { + 0 -> { + if (!mainViewModel.searchMode.value) { + IconButton(onClick = { + mainViewModel.searchMode + .value = true + mainViewModel.searchString.value = + "" + }) { + Icon(Icons.Rounded.Search, null) + } + } else { + IconButton(onClick = { + mainViewModel.searchMode + .value = false + mainViewModel.searchString.value = + "" + }) { + Icon( + Icons.Rounded.ArrowBack, + null + ) + } + } + } + 1 -> { + if (!mainViewModel.searchMode.value) { + IconButton(onClick = { + mainViewModel.searchMode + .value = true + mainViewModel.searchString.value = + "" + + }) { + Icon(Icons.Rounded.Search, null) + } + } else { + IconButton(onClick = { + mainViewModel.searchMode + .value = false + mainViewModel.searchString.value = + "" + }) { + Icon( + Icons.Rounded.ArrowBack, + null + ) + } + } + } + 2 -> { IconButton(onClick = { mainViewModel.showUsernameDialog.value = true }) { Icon(Icons.Rounded.Edit, null) } - }, - scrollBehavior = mainViewModel.scrollBehavior.value, - title = mainViewModel.profileTitle.value, - actions = { - ProfileActions { + } + } + }, + scrollBehavior = mainViewModel.scrollBehavior.value, + title = { + if (!mainViewModel.searchMode.value) { + Text( + text = if (mainViewModel.selectedItem.value == 2) mainViewModel.profileTitle.value + else stringResource(mainViewModel.title.value), + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + } else { + val localFocusManager = + LocalFocusManager.current + BasicTextField( + modifier = Modifier.fillMaxWidth(), + value = mainViewModel.searchString.value, + textStyle = TextStyle( + fontSize = 22.sp, + color = MaterialTheme.colorScheme.onBackground, + textAlign = TextAlign.Start, + ), + keyboardActions = KeyboardActions( + onDone = { localFocusManager.clearFocus() } + ), + singleLine = true, + cursorBrush = SolidColor(MaterialTheme.colorScheme.onBackground), + onValueChange = { + mainViewModel.searchString.value = + it + }) + if (mainViewModel.searchString.value.isEmpty()) { + Text( + text = stringResource(R.string.searchHere), + modifier = Modifier + .fillMaxWidth() + .padding(start = 12.dp), + style = TextStyle( + fontSize = 22.sp, + color = MaterialTheme.colorScheme.outline, + textAlign = TextAlign.Start, + ) + ) + } + } + }, + actions = { + if (!mainViewModel.searchMode.value) { + when (mainViewModel.selectedItem.value) { + 0 -> NoteActions(mainViewModel) + 1 -> GoalActions(mainViewModel) + 2 -> ProfileActions { navController.navigate(Screen.NoteListScreen.route) { navController.popBackStack() launchSingleTop = true @@ -130,21 +241,15 @@ class MainActivity : ComponentActivity() { mainViewModel.signOut() } } - ) - } - else -> { - AppBarWithInsets( - scrollBehavior = mainViewModel.scrollBehavior.value, - title = stringResource(mainViewModel.title.value), - actions = { - when (mainViewModel.selectedItem.value) { - 0 -> NoteActions(mainViewModel) - 1 -> GoalActions(mainViewModel) - } + } else { + IconButton(onClick = { + mainViewModel.searchString.value = "" + }) { + Icon(Icons.Rounded.Close, null) } - ) + } } - } + ) }, floatingActionButton = { ExtendedFloatingActionButton(onClick = { @@ -189,7 +294,7 @@ class MainActivity : ComponentActivity() { BottomNavigationBar( title = mainViewModel.title, selectedItem = mainViewModel.selectedItem, - filterType = mainViewModel.filterType, + searchMode = mainViewModel.searchMode, navController = navController, items = listOf( Screen.NoteListScreen, @@ -213,22 +318,113 @@ class MainActivity : ComponentActivity() { } else { Scaffold( topBar = { - when (mainViewModel.selectedItem.value) { - 2 -> { - AppBarWithInsets( - type = APP_BAR_CENTER, - navigationIcon = { + AppBarWithInsets( + type = APP_BAR_CENTER, + navigationIcon = { + when (mainViewModel.selectedItem.value) { + 0 -> { + if (!mainViewModel.searchMode.value) { + IconButton(onClick = { + mainViewModel.searchMode + .value = true + mainViewModel.searchString.value = + "" + + }) { + Icon(Icons.Rounded.Search, null) + } + } else { + IconButton(onClick = { + mainViewModel.searchMode + .value = false + mainViewModel.searchString.value = + "" + }) { + Icon(Icons.Rounded.ArrowBack, null) + } + } + } + 1 -> { + if (!mainViewModel.searchMode.value) { + IconButton(onClick = { + mainViewModel.searchMode + .value = true + mainViewModel.searchString.value = + "" + + }) { + Icon(Icons.Rounded.Search, null) + } + } else { + IconButton(onClick = { + mainViewModel.searchMode + .value = false + mainViewModel.searchString.value = + "" + }) { + Icon(Icons.Rounded.ArrowBack, null) + } + } + } + 2 -> { IconButton(onClick = { mainViewModel.showUsernameDialog.value = true }) { Icon(Icons.Rounded.Edit, null) } - }, - scrollBehavior = mainViewModel.scrollBehavior.value, - title = mainViewModel.profileTitle.value, - actions = { - ProfileActions { + } + } + }, + scrollBehavior = mainViewModel.scrollBehavior.value, + title = { + if (!mainViewModel.searchMode.value) { + Text( + text = if (mainViewModel.selectedItem.value == 2) mainViewModel.profileTitle.value + else stringResource(mainViewModel.title.value), + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + } else { + val localFocusManager = + LocalFocusManager.current + BasicTextField( + modifier = Modifier.fillMaxWidth(), + value = mainViewModel.searchString.value, + textStyle = TextStyle( + fontSize = 22.sp, + color = MaterialTheme.colorScheme.onBackground, + textAlign = TextAlign.Start, + ), + keyboardActions = KeyboardActions( + onDone = { localFocusManager.clearFocus() } + ), + singleLine = true, + cursorBrush = SolidColor(MaterialTheme.colorScheme.onBackground), + onValueChange = { + mainViewModel.searchString.value = it + }) + if (mainViewModel.searchString.value.isEmpty()) { + Text( + text = stringResource(R.string.searchHere), + modifier = Modifier + .fillMaxWidth() + .padding(start = 12.dp), + style = TextStyle( + fontSize = 22.sp, + color = MaterialTheme.colorScheme.outline, + textAlign = TextAlign.Start, + ) + ) + } + } + }, + actions = { + if (!mainViewModel.searchMode.value) { + when (mainViewModel.selectedItem.value) { + 0 -> NoteActions(mainViewModel) + 1 -> GoalActions(mainViewModel) + 2 -> ProfileActions { navController.navigate(Screen.NoteListScreen.route) { navController.popBackStack() launchSingleTop = true @@ -242,21 +438,15 @@ class MainActivity : ComponentActivity() { mainViewModel.signOut() } } - ) - } - else -> { - AppBarWithInsets( - scrollBehavior = mainViewModel.scrollBehavior.value, - title = stringResource(mainViewModel.title.value), - actions = { - when (mainViewModel.selectedItem.value) { - 0 -> NoteActions(mainViewModel) - 1 -> GoalActions(mainViewModel) - } + } else { + IconButton(onClick = { + mainViewModel.searchString.value = "" + }) { + Icon(Icons.Rounded.Close, null) } - ) + } } - } + ) }, floatingActionButton = { ExtendedFloatingActionButton(onClick = { @@ -291,7 +481,7 @@ class MainActivity : ComponentActivity() { BottomNavigationBar( title = mainViewModel.title, selectedItem = mainViewModel.selectedItem, - filterType = mainViewModel.filterType, + searchMode = mainViewModel.searchMode, navController = navController, items = listOf( Screen.NoteListScreen, diff --git a/app/src/main/java/ru/tech/firenote/ui/composable/navigation/Navigation.kt b/app/src/main/java/ru/tech/firenote/ui/composable/navigation/Navigation.kt index c1957fe..a9f7cca 100644 --- a/app/src/main/java/ru/tech/firenote/ui/composable/navigation/Navigation.kt +++ b/app/src/main/java/ru/tech/firenote/ui/composable/navigation/Navigation.kt @@ -29,7 +29,8 @@ fun Navigation( mainViewModel.showNoteCreation, mainViewModel.globalNote, mainViewModel.filterType, - mainViewModel.isDescendingFilter + mainViewModel.isDescendingFilter, + mainViewModel.searchString ) } composable(Screen.GoalsScreen.route) { @@ -37,7 +38,8 @@ fun Navigation( mainViewModel.showGoalCreation, mainViewModel.globalGoal, mainViewModel.filterType, - mainViewModel.isDescendingFilter + mainViewModel.isDescendingFilter, + mainViewModel.searchString ) } composable(Screen.ProfileScreen.route) { diff --git a/app/src/main/java/ru/tech/firenote/ui/composable/screen/GoalCreationScreen.kt b/app/src/main/java/ru/tech/firenote/ui/composable/screen/GoalCreationScreen.kt index 603d7f2..255f389 100644 --- a/app/src/main/java/ru/tech/firenote/ui/composable/screen/GoalCreationScreen.kt +++ b/app/src/main/java/ru/tech/firenote/ui/composable/screen/GoalCreationScreen.kt @@ -16,11 +16,11 @@ import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.text.BasicTextField import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.outlined.Add import androidx.compose.material.icons.outlined.Edit import androidx.compose.material.icons.outlined.Save import androidx.compose.material.icons.rounded.ArrowBack +import androidx.compose.material.icons.rounded.Close import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.runtime.saveable.rememberSaveable @@ -234,7 +234,9 @@ fun GoalCreationScreen( if (text.isEmpty()) { Text( stringResource(R.string.subGoalHere), - modifier = Modifier.align(Alignment.CenterStart), + modifier = Modifier + .align(Alignment.CenterStart) + .padding(start = 12.dp), color = Color.DarkGray ) } @@ -245,7 +247,7 @@ fun GoalCreationScreen( IconButton(onClick = { viewModel.removeFromContent(index) }) { - Icon(Icons.Filled.Close, null, tint = darkColorScheme().onTertiary) + Icon(Icons.Rounded.Close, null, tint = darkColorScheme().onTertiary) } Spacer(Modifier.size(8.dp)) diff --git a/app/src/main/java/ru/tech/firenote/ui/composable/screen/base/GoalListScreen.kt b/app/src/main/java/ru/tech/firenote/ui/composable/screen/base/GoalListScreen.kt index 8120bfc..b60b04a 100644 --- a/app/src/main/java/ru/tech/firenote/ui/composable/screen/base/GoalListScreen.kt +++ b/app/src/main/java/ru/tech/firenote/ui/composable/screen/base/GoalListScreen.kt @@ -11,6 +11,7 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Delete import androidx.compose.material.icons.twotone.Cloud +import androidx.compose.material.icons.twotone.FindInPage import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Icon import androidx.compose.material3.SnackbarResult @@ -39,6 +40,7 @@ fun GoalListScreen( globalGoal: MutableState = mutableStateOf(null), filterType: MutableState, isDescendingFilter: MutableState, + searchString: MutableState, viewModel: GoalListViewModel = hiltViewModel() ) { val paddingValues = PaddingValues(top = 10.dp, start = 10.dp, end = 10.dp, bottom = 140.dp) @@ -63,7 +65,7 @@ fun GoalListScreen( } is UIState.Success<*> -> { val repoList = state.data as List - val data = if (isDescendingFilter.value) { + var data = if (isDescendingFilter.value) { when (filterType.value) { 1 -> repoList.sortedBy { (it.color ?: 0).priorityGoal } 3 -> repoList.sortedBy { it.timestamp } @@ -91,6 +93,32 @@ fun GoalListScreen( } } + if (searchString.value.isNotEmpty()) { + data = repoList.filter { + val statement1 = + it.title?.lowercase()?.contains(searchString.value.lowercase()) ?: false + var statement2 = false + it.content?.forEach { data -> + if (data.content?.lowercase() + ?.contains(searchString.value.lowercase()) == true + ) statement2 = true + } + + statement1 or statement2 + } + if (data.isEmpty()) { + Column( + modifier = Modifier + .fillMaxSize(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + Icon(Icons.TwoTone.FindInPage, null, modifier = Modifier.fillMaxSize(0.3f)) + Text(stringResource(R.string.nothingFound)) + } + } + } + LazyColumn( verticalArrangement = Arrangement.spacedBy(8.dp), contentPadding = paddingValues @@ -98,7 +126,6 @@ fun GoalListScreen( items(data.size) { index -> val locGoal = data[index] GoalItem( - cutCornerSize = 0.dp, goal = locGoal, onDeleteClick = { goal = locGoal diff --git a/app/src/main/java/ru/tech/firenote/ui/composable/screen/base/NoteListScreen.kt b/app/src/main/java/ru/tech/firenote/ui/composable/screen/base/NoteListScreen.kt index 46e6deb..0e6ed05 100644 --- a/app/src/main/java/ru/tech/firenote/ui/composable/screen/base/NoteListScreen.kt +++ b/app/src/main/java/ru/tech/firenote/ui/composable/screen/base/NoteListScreen.kt @@ -12,6 +12,7 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Delete import androidx.compose.material.icons.twotone.Cloud +import androidx.compose.material.icons.twotone.FindInPage import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Icon import androidx.compose.material3.SnackbarResult @@ -41,6 +42,7 @@ fun NoteListScreen( globalNote: MutableState = mutableStateOf(null), filterType: MutableState, isDescendingFilter: MutableState, + searchString: MutableState, viewModel: NoteListViewModel = hiltViewModel() ) { val notePaddingValues = PaddingValues(top = 10.dp, start = 10.dp, end = 10.dp, bottom = 140.dp) @@ -65,7 +67,7 @@ fun NoteListScreen( } is UIState.Success<*> -> { val repoList = state.data as List - val data = if (isDescendingFilter.value) { + var data = if (isDescendingFilter.value) { when (filterType.value) { 1 -> repoList.sortedByDescending { (it.color ?: 0).priority } 2 -> repoList.sortedBy { it.timestamp } @@ -79,6 +81,26 @@ fun NoteListScreen( } } + if (searchString.value.isNotEmpty()) { + data = repoList.filter { + it.content?.lowercase()?.contains(searchString.value.lowercase()) + ?.or( + it.title?.lowercase()?.contains(searchString.value.lowercase()) ?: false + ) ?: false + } + if (data.isEmpty()) { + Column( + modifier = Modifier + .fillMaxSize(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + Icon(Icons.TwoTone.FindInPage, null, modifier = Modifier.fillMaxSize(0.3f)) + Text(stringResource(R.string.nothingFound)) + } + } + } + LazyColumn( verticalArrangement = Arrangement.spacedBy(8.dp), contentPadding = notePaddingValues diff --git a/app/src/main/java/ru/tech/firenote/ui/composable/single/AppBarActions.kt b/app/src/main/java/ru/tech/firenote/ui/composable/single/AppBarActions.kt index 211e969..f8850fd 100644 --- a/app/src/main/java/ru/tech/firenote/ui/composable/single/AppBarActions.kt +++ b/app/src/main/java/ru/tech/firenote/ui/composable/single/AppBarActions.kt @@ -77,7 +77,7 @@ fun NoteActions( ) DropdownMenuItem( onClick = { - viewModel.filterType.value in 2..3 + viewModel.filterType.value = 2 showFilter.value = false }, text = { Text(stringResource(R.string.date)) }, diff --git a/app/src/main/java/ru/tech/firenote/ui/composable/single/AppBarWithInsets.kt b/app/src/main/java/ru/tech/firenote/ui/composable/single/AppBarWithInsets.kt index face622..3487e86 100644 --- a/app/src/main/java/ru/tech/firenote/ui/composable/single/AppBarWithInsets.kt +++ b/app/src/main/java/ru/tech/firenote/ui/composable/single/AppBarWithInsets.kt @@ -6,13 +6,12 @@ import androidx.compose.material3.* import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.text.style.TextOverflow import com.google.accompanist.insets.statusBarsPadding @Composable fun AppBarWithInsets( modifier: Modifier = Modifier, - title: String, + title: @Composable () -> Unit = {}, type: Int = APP_BAR_SIMPLE, scrollBehavior: TopAppBarScrollBehavior? = null, navigationIcon: @Composable () -> Unit = {}, @@ -30,13 +29,7 @@ fun AppBarWithInsets( when (type) { APP_BAR_CENTER -> { CenterAlignedTopAppBar( - title = { - Text( - text = title, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - }, + title = title, navigationIcon = navigationIcon, actions = actions, scrollBehavior = scrollBehavior, @@ -46,13 +39,7 @@ fun AppBarWithInsets( } APP_BAR_SIMPLE -> { SmallTopAppBar( - title = { - Text( - text = title, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - }, + title = title, navigationIcon = navigationIcon, actions = actions, scrollBehavior = scrollBehavior, diff --git a/app/src/main/java/ru/tech/firenote/ui/composable/single/BottomNavigationBar.kt b/app/src/main/java/ru/tech/firenote/ui/composable/single/BottomNavigationBar.kt index 0234351..9b92185 100644 --- a/app/src/main/java/ru/tech/firenote/ui/composable/single/BottomNavigationBar.kt +++ b/app/src/main/java/ru/tech/firenote/ui/composable/single/BottomNavigationBar.kt @@ -13,7 +13,7 @@ import ru.tech.firenote.ui.route.Screen fun BottomNavigationBar( navController: NavHostController, items: List, - filterType: MutableState, + searchMode: MutableState, title: MutableState, selectedItem: MutableState, alwaysShowLabel: Boolean = true @@ -44,6 +44,7 @@ fun BottomNavigationBar( navController.popBackStack() launchSingleTop = true } + searchMode.value = false } } ) diff --git a/app/src/main/java/ru/tech/firenote/ui/composable/single/GoalItem.kt b/app/src/main/java/ru/tech/firenote/ui/composable/single/GoalItem.kt index 9d12cd5..286d2ba 100644 --- a/app/src/main/java/ru/tech/firenote/ui/composable/single/GoalItem.kt +++ b/app/src/main/java/ru/tech/firenote/ui/composable/single/GoalItem.kt @@ -6,29 +6,33 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Delete import androidx.compose.material3.* import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.derivedStateOf +import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.CornerRadius -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.geometry.Size import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Path import androidx.compose.ui.graphics.drawscope.clipPath +import androidx.compose.ui.platform.LocalLayoutDirection +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.dp import ru.tech.firenote.model.Goal import ru.tech.firenote.ui.composable.provider.LocalWindowSize import ru.tech.firenote.ui.composable.utils.WindowSize -import ru.tech.firenote.utils.Utils.blend +import java.text.SimpleDateFormat +import java.util.* @Composable fun GoalItem( goal: Goal, modifier: Modifier = Modifier, cornerRadius: Dp = 10.dp, - cutCornerSize: Dp = 30.dp, onDeleteClick: () -> Unit ) { var doneAll = true @@ -45,8 +49,8 @@ fun GoalItem( ) { Canvas(modifier = Modifier.matchParentSize()) { val clipPath = Path().apply { - lineTo(size.width - cutCornerSize.toPx(), 0f) - lineTo(size.width, cutCornerSize.toPx()) + lineTo(size.width, 0f) + lineTo(size.width, 0f) lineTo(size.width, size.height) lineTo(0f, size.height) close() @@ -58,32 +62,45 @@ fun GoalItem( size = size, cornerRadius = CornerRadius(cornerRadius.toPx()) ) - drawRoundRect( - color = Color( - (goal.color ?: 0).blend() - ), - topLeft = Offset(size.width - cutCornerSize.toPx(), -100f), - size = Size(cutCornerSize.toPx() + 100f, cutCornerSize.toPx() + 100f), - cornerRadius = CornerRadius(cornerRadius.toPx()) - ) } } Column( modifier = Modifier .fillMaxSize() .padding(16.dp) - .padding(end = 32.dp) ) { - Text( - text = goal.title ?: "", - style = MaterialTheme.typography.bodyLarge, - color = if (doneAll) Color.DarkGray else Color.Black, - textDecoration = if (doneAll) TextDecoration.LineThrough else TextDecoration.None, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) + + val convertTime by derivedStateOf { + SimpleDateFormat("dd/MM/yyyy\nHH:mm", Locale.getDefault()).format( + goal.timestamp ?: 0L + ) + } + + Row(modifier = Modifier.fillMaxWidth()) { + Text( + modifier = Modifier.weight(2f), + text = goal.title ?: "", + style = MaterialTheme.typography.bodyLarge, + color = if (doneAll) Color.DarkGray else Color.Black, + textDecoration = if (doneAll) TextDecoration.LineThrough else TextDecoration.None, + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) { + Text( + modifier = Modifier.weight(1f), + text = convertTime, + style = MaterialTheme.typography.bodySmall, + color = Color.DarkGray, + maxLines = 2, + textAlign = TextAlign.Justify, + overflow = TextOverflow.Ellipsis + ) + } + + } Spacer(modifier = Modifier.height(8.dp)) - Column { + Column(Modifier.padding(end = 32.dp)) { mapped?.let { it.forEachIndexed { index, item -> if (index <= when (LocalWindowSize.current) { @@ -97,7 +114,8 @@ fun GoalItem( style = MaterialTheme.typography.bodySmall, color = if (item.done == true) Color.DarkGray else Color.Black, textDecoration = if (item.done == true) TextDecoration.LineThrough else TextDecoration.None, - overflow = TextOverflow.Ellipsis + overflow = TextOverflow.Ellipsis, + maxLines = 5 ) } } diff --git a/app/src/main/java/ru/tech/firenote/ui/composable/single/NoteItem.kt b/app/src/main/java/ru/tech/firenote/ui/composable/single/NoteItem.kt index c7022cb..2b7b580 100644 --- a/app/src/main/java/ru/tech/firenote/ui/composable/single/NoteItem.kt +++ b/app/src/main/java/ru/tech/firenote/ui/composable/single/NoteItem.kt @@ -6,6 +6,9 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Delete import androidx.compose.material3.* import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.derivedStateOf +import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.CornerRadius @@ -14,13 +17,18 @@ import androidx.compose.ui.geometry.Size import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Path import androidx.compose.ui.graphics.drawscope.clipPath +import androidx.compose.ui.platform.LocalLayoutDirection +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.dp import ru.tech.firenote.model.Note import ru.tech.firenote.ui.composable.provider.LocalWindowSize import ru.tech.firenote.ui.composable.utils.WindowSize import ru.tech.firenote.utils.Utils.blend +import java.text.SimpleDateFormat +import java.util.* @Composable fun NoteItem( @@ -64,13 +72,34 @@ fun NoteItem( .padding(16.dp) .padding(end = 32.dp) ) { - Text( - text = note.title ?: "", - style = MaterialTheme.typography.bodyLarge, - color = Color.Black, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) + val convertTime by derivedStateOf { + SimpleDateFormat("dd/MM/yyyy\nHH:mm", Locale.getDefault()).format( + note.timestamp ?: 0L + ) + } + + Row(modifier = Modifier.fillMaxWidth()) { + Text( + modifier = Modifier.weight(2f), + text = note.title ?: "", + style = MaterialTheme.typography.bodyLarge, + color = Color.Black, + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) { + Text( + modifier = Modifier.weight(1f), + text = convertTime, + style = MaterialTheme.typography.bodySmall, + color = Color.DarkGray, + maxLines = 2, + textAlign = TextAlign.Justify, + overflow = TextOverflow.Ellipsis + ) + } + + } Spacer(modifier = Modifier.height(8.dp)) Text( text = note.content ?: "", diff --git a/app/src/main/java/ru/tech/firenote/viewModel/MainViewModel.kt b/app/src/main/java/ru/tech/firenote/viewModel/MainViewModel.kt index e6b9bf0..fec40e1 100644 --- a/app/src/main/java/ru/tech/firenote/viewModel/MainViewModel.kt +++ b/app/src/main/java/ru/tech/firenote/viewModel/MainViewModel.kt @@ -21,7 +21,7 @@ class MainViewModel @Inject constructor( ) : ViewModel() { val title = mutableStateOf(Screen.NoteListScreen.resourceId) - val profileTitle = mutableStateOf("User") + val profileTitle = mutableStateOf("") val selectedItem = mutableStateOf(0) @@ -35,6 +35,9 @@ class MainViewModel @Inject constructor( targetState = false } + val searchMode = mutableStateOf(false) + val searchString = mutableStateOf("") + val resultLauncher = mutableStateOf?>(null) val isAuth = mutableStateOf(repository.auth.currentUser == null) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6a39c9d..d9d72af 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -78,4 +78,6 @@ Add subgoal Enter your subgoal here Completion + Search here + Nothing found, try to change your search query \ No newline at end of file