From 2df027cc76016d2f52d948d9e6478f997b790d7c Mon Sep 17 00:00:00 2001 From: demn Date: Mon, 4 Nov 2024 18:01:32 +0300 Subject: [PATCH 01/28] feat(app, chats): implement navigation to usersearch --- app/src/main/java/me/floow/app/navigation/FlowNavHost.kt | 8 ++++++-- .../chats/src/main/java/me/floow/chats/ui/ChatsRoute.kt | 8 +++++--- .../chats/src/main/java/me/floow/chats/ui/ChatsScreen.kt | 4 +++- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/me/floow/app/navigation/FlowNavHost.kt b/app/src/main/java/me/floow/app/navigation/FlowNavHost.kt index 1e42165..9c01aae 100644 --- a/app/src/main/java/me/floow/app/navigation/FlowNavHost.kt +++ b/app/src/main/java/me/floow/app/navigation/FlowNavHost.kt @@ -3,7 +3,6 @@ package me.floow.app.navigation import android.content.Intent import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.SideEffect import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.navigation.NavHostController @@ -125,7 +124,12 @@ fun FlowNavHost( } composable { - ChatsRoute(modifier) + ChatsRoute( + onSearchClick = { + navController.navigate(SearchUsersScreen) + }, + modifier = modifier + ) } composable { diff --git a/feature/chats/src/main/java/me/floow/chats/ui/ChatsRoute.kt b/feature/chats/src/main/java/me/floow/chats/ui/ChatsRoute.kt index ebaa2f1..6252aa3 100644 --- a/feature/chats/src/main/java/me/floow/chats/ui/ChatsRoute.kt +++ b/feature/chats/src/main/java/me/floow/chats/ui/ChatsRoute.kt @@ -1,17 +1,19 @@ package me.floow.chats.ui -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.NavigationBarDefaults -import androidx.compose.material3.surfaceColorAtElevation import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import me.floow.uikit.util.SetNavigationBarColor @Composable fun ChatsRoute( + onSearchClick: () -> Unit, modifier: Modifier = Modifier ) { - ChatsScreen(modifier) + ChatsScreen( + onSearchClick = onSearchClick, + modifier = modifier + ) SetNavigationBarColor( NavigationBarDefaults.containerColor diff --git a/feature/chats/src/main/java/me/floow/chats/ui/ChatsScreen.kt b/feature/chats/src/main/java/me/floow/chats/ui/ChatsScreen.kt index 7e7c191..97ec6e2 100644 --- a/feature/chats/src/main/java/me/floow/chats/ui/ChatsScreen.kt +++ b/feature/chats/src/main/java/me/floow/chats/ui/ChatsScreen.kt @@ -12,13 +12,14 @@ import me.floow.uikit.components.topbar.TitleTopBarWithActionButton @Composable internal fun ChatsScreen( + onSearchClick: () -> Unit, modifier: Modifier = Modifier ) { Scaffold( topBar = { TitleTopBarWithActionButton( titleText = "Чаты", - onActionButtonClick = { TODO() }, + onActionButtonClick = onSearchClick, icon = { Icon( painterResource(R.drawable.search_icon), @@ -54,6 +55,7 @@ internal fun ChatsScreen( @Composable private fun ChatsScreenPreview() { ChatsScreen( + onSearchClick = {}, modifier = Modifier.fillMaxSize() ) } \ No newline at end of file From 95c58fcec0d4a7af41936caa36d8a2c7aeccde65 Mon Sep 17 00:00:00 2001 From: demn Date: Thu, 7 Nov 2024 00:16:20 +0300 Subject: [PATCH 02/28] feat(app, usersearch, uikit, profile, login): toast instead of crush on TODOs, small fixes and make simple mock user search --- .../me/floow/app/navigation/FlowNavHost.kt | 27 ++- .../ic_launcher_monochrome_foreground.xml | 2 +- .../uikit/components/topbar/SearchTopBar.kt | 174 ++++++++++++------ core/uikit/src/main/res/values-ru/strings.xml | 2 + core/uikit/src/main/res/values/strings.xml | 2 + .../ui/createprofile/CreateProfileRoute.kt | 4 +- .../floow/profile/ui/edit/EditProfileRoute.kt | 4 +- .../demn/usersearch/ui/SearchUsersRoute.kt | 8 + .../demn/usersearch/ui/SearchUsersScreen.kt | 38 +++- .../ui/components/GlobalSearchUsersList.kt | 77 ++++++++ .../ui/components/RecentUsersList.kt | 74 ++++++++ .../ui/components/SearchUsersScreenTopBar.kt | 13 +- .../ui/components/UserGlobalSearchResult.kt | 96 ++++++++++ .../ui/states/EmptySearchResultsState.kt | 9 - .../demn/usersearch/ui/states/LoadingState.kt | 16 +- .../ui/states/NoSearchInputState.kt | 37 ++++ .../ui/states/SearchResultsState.kt | 32 +++- .../uilogic/SearchUsersScreenUiState.kt | 23 ++- .../uilogic/SearchUsersScreenViewModel.kt | 139 +++++++++++++- .../src/main/res/values-ru/strings.xml | 7 + .../src/main/res/values/strings.xml | 7 + 21 files changed, 704 insertions(+), 87 deletions(-) create mode 100644 feature/usersearch/src/main/java/com/demn/usersearch/ui/components/GlobalSearchUsersList.kt create mode 100644 feature/usersearch/src/main/java/com/demn/usersearch/ui/components/RecentUsersList.kt create mode 100644 feature/usersearch/src/main/java/com/demn/usersearch/ui/components/UserGlobalSearchResult.kt delete mode 100644 feature/usersearch/src/main/java/com/demn/usersearch/ui/states/EmptySearchResultsState.kt create mode 100644 feature/usersearch/src/main/java/com/demn/usersearch/ui/states/NoSearchInputState.kt create mode 100644 feature/usersearch/src/main/res/values-ru/strings.xml create mode 100644 feature/usersearch/src/main/res/values/strings.xml diff --git a/app/src/main/java/me/floow/app/navigation/FlowNavHost.kt b/app/src/main/java/me/floow/app/navigation/FlowNavHost.kt index 9c01aae..01548ed 100644 --- a/app/src/main/java/me/floow/app/navigation/FlowNavHost.kt +++ b/app/src/main/java/me/floow/app/navigation/FlowNavHost.kt @@ -1,6 +1,8 @@ package me.floow.app.navigation +import android.content.Context import android.content.Intent +import android.widget.Toast import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier @@ -70,12 +72,18 @@ fun FlowNavHost( startDestination = FeedScreen ) { composable { - FeedRoute(onPostCreateClick = { TODO() }, modifier) + FeedRoute( + onPostCreateClick = { + showNotImplementedToast(context) + }, + modifier + ) } composable { val backStackEntry = navController.currentBackStackEntry - val editProfileScreen: EditProfileScreen? = backStackEntry?.toRoute() + val editProfileScreen: EditProfileScreen? = + backStackEntry?.toRoute() EditProfileRoute( initialData = EditProfileRouteInitialData( @@ -105,7 +113,9 @@ fun FlowNavHost( ) ) }, - goToAddPostScreen = { TODO() }, + goToAddPostScreen = { + showNotImplementedToast(context) + }, shareProfile = { url -> // TODO @@ -134,11 +144,20 @@ fun FlowNavHost( composable { SearchUsersRoute( - onUserPick = { TODO() }, + onBackClick = { + navController.popBackStack() + }, + onUserPick = { + showNotImplementedToast(context) + }, vm = koinViewModel(), modifier = modifier ) } } } +} + +private fun showNotImplementedToast(context: Context) { + Toast.makeText(context, "Фича ещё разрабатывается…", Toast.LENGTH_SHORT).show() } \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_launcher_monochrome_foreground.xml b/app/src/main/res/drawable/ic_launcher_monochrome_foreground.xml index 1cb2479..c35f21b 100644 --- a/app/src/main/res/drawable/ic_launcher_monochrome_foreground.xml +++ b/app/src/main/res/drawable/ic_launcher_monochrome_foreground.xml @@ -18,4 +18,4 @@ android:fillColor="#00000000" android:strokeColor="#35332F" android:strokeLineCap="round"/> - + \ No newline at end of file diff --git a/core/uikit/src/main/java/me/floow/uikit/components/topbar/SearchTopBar.kt b/core/uikit/src/main/java/me/floow/uikit/components/topbar/SearchTopBar.kt index 6a83e53..423b18f 100644 --- a/core/uikit/src/main/java/me/floow/uikit/components/topbar/SearchTopBar.kt +++ b/core/uikit/src/main/java/me/floow/uikit/components/topbar/SearchTopBar.kt @@ -1,77 +1,133 @@ package me.floow.uikit.components.topbar -import androidx.compose.material3.ColorScheme -import androidx.compose.material3.DockedSearchBar +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.text.BasicTextField import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.SearchBar -import androidx.compose.material3.SearchBarColors -import androidx.compose.material3.SearchBarDefaults -import androidx.compose.material3.Surface -import androidx.compose.material3.TextField +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.Constraints +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.graphics.StrokeCap +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import me.floow.uikit.R +import me.floow.uikit.theme.LocalTypography -/** - * Material Design search. - * - * A search bar represents a floating search field that allows users to enter a keyword or phrase - * and get relevant information. It can be used as a way to navigate through an app via search - * queries. - * - * A search bar expands into a search "view" and can be used to display dynamic suggestions or - * search results. - * - * @see - * - * A [SearchBar] tries to occupy the entirety of its allowed size in the expanded state. For - * full-screen behavior as specified by Material guidelines, parent layouts of the [SearchBar] must - * not pass any [Constraints] that limit its size, and the host activity should set - * `WindowCompat.setDecorFitsSystemWindows(window, false)`. - * - * If this expansion behavior is undesirable, for example on large tablet screens, [DockedSearchBar] - * can be used instead. - * - * An example looks like: - * - * @sample androidx.compose.material3.samples.SearchBarSample - * - * @param inputField the input field of this search bar that allows entering a query, typically a - * [SearchBarDefaults.InputField]. - * @param expanded whether this search bar is expanded and showing search results. - * @param onExpandedChange the callback to be invoked when this search bar's expanded state is - * changed. - * @param modifier the [Modifier] to be applied to this search bar. - * @param shape the shape of this search bar when it is not [expanded]. When [expanded], the shape - * will always be [SearchBarDefaults.fullScreenShape]. - * @param colors [SearchBarColors] that will be used to resolve the colors used for this search bar - * in different states. See [SearchBarDefaults.colors]. - * @param tonalElevation when [SearchBarColors.containerColor] is [ColorScheme.surface], a - * translucent primary color overlay is applied on top of the container. A higher tonal elevation - * value will result in a darker color in light theme and lighter color in dark theme. See also: - * [Surface]. - * @param shadowElevation the elevation for the shadow below this search bar - * @param windowInsets the window insets that this search bar will respect - * @param content the content of this search bar to display search results below the [inputField]. - */ -@OptIn(ExperimentalMaterial3Api::class) @Composable fun SearchTopBar( + onBackClick: () -> Unit, + placeholder: String, searchFieldValue: String, onSearchFieldUpdate: (String) -> Unit, modifier: Modifier = Modifier ) { - SearchBar( - inputField = { - TextField( + Column( + modifier = modifier + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .height(80.dp) + .padding(horizontal = 24.dp), + ) { + IconButton( + onClick = onBackClick, + modifier = Modifier.size(24.dp) + ) { + Icon( + painter = painterResource(R.drawable.nav_back_icon), + contentDescription = null, + modifier = Modifier.size(16.dp) + ) + } + + Spacer(Modifier.width(10.dp)) + + BasicTextField( value = searchFieldValue, onValueChange = onSearchFieldUpdate, + singleLine = true, + cursorBrush = SolidColor(MaterialTheme.colorScheme.onBackground), + textStyle = LocalTypography.current.bodyMedium.copy( + color = MaterialTheme.colorScheme.onBackground + ), + decorationBox = { innerTextField -> + Row( + modifier = Modifier + .padding( + horizontal = 14.dp, + vertical = 20.dp + ) + .fillMaxWidth() + ) { + Box(Modifier.fillMaxWidth()) { + innerTextField() + + if (searchFieldValue.isEmpty()) { + Text( + text = placeholder, + style = LocalTypography.current.bodyMedium, + color = MaterialTheme.colorScheme.secondary, + modifier = Modifier + ) + } + } + } + }, + modifier = Modifier + .weight(1f) + .height(58.dp) ) - }, - expanded = false, - onExpandedChange = {}, - ) { + } + HorizontalDivider() + } +} + +@Preview +@Composable +private fun SearchTopBarPreview() { + var searchBarValue by remember { mutableStateOf("") } + + Scaffold( + topBar = { + SearchTopBar( + onBackClick = {}, + searchFieldValue = searchBarValue, + placeholder = "Search…", + onSearchFieldUpdate = { searchBarValue = it } + ) + }, + modifier = Modifier.fillMaxSize() + ) { innerPadding -> + Box( + Modifier + .padding(innerPadding) + .fillMaxSize() + .background(Color.LightGray) + ) } } \ No newline at end of file diff --git a/core/uikit/src/main/res/values-ru/strings.xml b/core/uikit/src/main/res/values-ru/strings.xml index 981299f..3061a91 100644 --- a/core/uikit/src/main/res/values-ru/strings.xml +++ b/core/uikit/src/main/res/values-ru/strings.xml @@ -13,4 +13,6 @@ подписчиков Нет подписчиков Вы можете использовать символы a–z, 0–9 и нижние подчеркивания + Онлайн + Оффлайн \ No newline at end of file diff --git a/core/uikit/src/main/res/values/strings.xml b/core/uikit/src/main/res/values/strings.xml index 0745eae..2be1319 100644 --- a/core/uikit/src/main/res/values/strings.xml +++ b/core/uikit/src/main/res/values/strings.xml @@ -13,4 +13,6 @@ subscribers No subscribers You can use the characters a-z, 0-9, and underscores + Online + Offline \ No newline at end of file diff --git a/feature/login/src/main/java/me/floow/login/ui/createprofile/CreateProfileRoute.kt b/feature/login/src/main/java/me/floow/login/ui/createprofile/CreateProfileRoute.kt index 79cfd32..7035a97 100644 --- a/feature/login/src/main/java/me/floow/login/ui/createprofile/CreateProfileRoute.kt +++ b/feature/login/src/main/java/me/floow/login/ui/createprofile/CreateProfileRoute.kt @@ -39,7 +39,9 @@ fun CreateProfileRoute( CreateProfileScreen( state = state, - onAvatarPickerClick = { TODO() }, + onAvatarPickerClick = { + Toast.makeText(context, "Фича ещё разрабатывается…", Toast.LENGTH_SHORT).show() + }, onNameChange = vm::updateName, onUsernameChange = vm::updateUsername, onBiographyChange = vm::updateBio, diff --git a/feature/profile/src/main/java/me/floow/profile/ui/edit/EditProfileRoute.kt b/feature/profile/src/main/java/me/floow/profile/ui/edit/EditProfileRoute.kt index 35e33fd..1eee7bd 100644 --- a/feature/profile/src/main/java/me/floow/profile/ui/edit/EditProfileRoute.kt +++ b/feature/profile/src/main/java/me/floow/profile/ui/edit/EditProfileRoute.kt @@ -62,7 +62,9 @@ fun EditProfileRoute( } ) }, - onAvatarPickerClick = { TODO() }, + onAvatarPickerClick = { + Toast.makeText(context, "Фича ещё разрабатывается…", Toast.LENGTH_SHORT).show() + }, onNameChange = vm::updateName, onUsernameChange = vm::updateUsername, onBiographyChange = vm::updateBiography, diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/ui/SearchUsersRoute.kt b/feature/usersearch/src/main/java/com/demn/usersearch/ui/SearchUsersRoute.kt index 6dc41b9..7a7bc4f 100644 --- a/feature/usersearch/src/main/java/com/demn/usersearch/ui/SearchUsersRoute.kt +++ b/feature/usersearch/src/main/java/com/demn/usersearch/ui/SearchUsersRoute.kt @@ -1,6 +1,7 @@ package com.demn.usersearch.ui import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier @@ -8,13 +9,20 @@ import com.demn.usersearch.uilogic.SearchUsersScreenViewModel @Composable fun SearchUsersRoute( + onBackClick: () -> Unit, onUserPick: () -> Unit, vm: SearchUsersScreenViewModel, modifier: Modifier = Modifier ) { val state by vm.state.collectAsState() + LaunchedEffect(Unit) { + vm.loadInitialData() + } + SearchUsersScreen( + onBackClick = onBackClick, + onSearchFieldUpdate = vm::updateSearchField, state = state, modifier = modifier ) diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/ui/SearchUsersScreen.kt b/feature/usersearch/src/main/java/com/demn/usersearch/ui/SearchUsersScreen.kt index a814f54..9214235 100644 --- a/feature/usersearch/src/main/java/com/demn/usersearch/ui/SearchUsersScreen.kt +++ b/feature/usersearch/src/main/java/com/demn/usersearch/ui/SearchUsersScreen.kt @@ -1,25 +1,57 @@ package com.demn.usersearch.ui -import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import com.demn.usersearch.ui.components.SearchUsersScreenTopBar +import com.demn.usersearch.ui.states.NoSearchInputState +import com.demn.usersearch.ui.states.LoadingState +import com.demn.usersearch.ui.states.SearchResultsState import com.demn.usersearch.uilogic.SearchUsersScreenUiState @Composable internal fun SearchUsersScreen( + onBackClick: () -> Unit, + onSearchFieldUpdate: (String) -> Unit, state: SearchUsersScreenUiState, modifier: Modifier = Modifier ) { Scaffold( topBar = { - + SearchUsersScreenTopBar( + onBackClick = onBackClick, + searchFieldValue = state.searchField, + onSearchFieldUpdate = onSearchFieldUpdate, + ) }, modifier = modifier, ) { innerPadding -> - Box(modifier = Modifier.padding(innerPadding)) { + val contentModifier = Modifier + .fillMaxSize() + .padding(innerPadding) + + when (state) { + is SearchUsersScreenUiState.Loading -> { + LoadingState( + modifier = contentModifier + ) + } + + is SearchUsersScreenUiState.NoSearchInput -> { + NoSearchInputState( + state = state, + modifier = contentModifier + ) + } + is SearchUsersScreenUiState.HasResults -> { + SearchResultsState( + state = state, + modifier = contentModifier + ) + } } } } \ No newline at end of file diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/GlobalSearchUsersList.kt b/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/GlobalSearchUsersList.kt new file mode 100644 index 0000000..88bba2c --- /dev/null +++ b/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/GlobalSearchUsersList.kt @@ -0,0 +1,77 @@ +package com.demn.usersearch.ui.components + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import com.demn.usersearch.uilogic.UserSearchResult +import me.floow.uikit.theme.LocalTypography +import me.floow.usersearch.R + +@Composable +fun GlobalSearchUsersList( + results: List, + onClick: (UserSearchResult) -> Unit, + modifier: Modifier = Modifier +) { + var isExpanded by remember { mutableStateOf(false) } + + Column(modifier) { + Row( + horizontalArrangement = Arrangement.SpaceBetween, + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 14.dp), + ) { + Text( + text = stringResource(R.string.global_search), + style = LocalTypography.current.bodyMedium, + fontWeight = FontWeight.Bold + ) + + if (results.size > 3) { + Text( + text = stringResource(if (isExpanded) R.string.show_less else R.string.show_more), + style = LocalTypography.current.bodyMedium, + modifier = Modifier + .clickable { + isExpanded = !isExpanded + } + ) + } + } + + Spacer(Modifier.height(12.dp)) + + LazyColumn( + verticalArrangement = Arrangement.spacedBy(8.dp), + modifier = Modifier, + ) { + val croppedResults = if (!isExpanded) results.take(3) else results + + items(croppedResults) { result -> + UserGlobalSearchResult( + result, + onClick = onClick, + modifier = Modifier.fillMaxWidth() + ) + } + } + } +} \ No newline at end of file diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/RecentUsersList.kt b/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/RecentUsersList.kt new file mode 100644 index 0000000..017a64e --- /dev/null +++ b/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/RecentUsersList.kt @@ -0,0 +1,74 @@ +package com.demn.usersearch.ui.components + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import com.demn.usersearch.uilogic.RecentUser +import me.floow.uikit.theme.LocalTypography + +@Composable +fun RecentUsersList( + recentUsers: List, + modifier: Modifier = Modifier +) { + LazyRow( + modifier = modifier, + horizontalArrangement = Arrangement.spacedBy(12.dp) + ) { + item { + Spacer(Modifier.width(2.dp)) + } + + items(recentUsers) { recentUser -> + RecentUsersListItem( + recentUser, + Modifier.fillMaxWidth() + ) + } + + item { + Spacer(Modifier.width(2.dp)) + } + } +} + +@Composable +fun RecentUsersListItem( + recentUser: RecentUser, + modifier: Modifier = Modifier +) { + Column( + modifier = modifier, + horizontalAlignment = Alignment.CenterHorizontally + ) { + Box( + modifier = Modifier + .size(64.dp) + .clip(CircleShape) + .background(Color.LightGray) + ) + + Spacer(Modifier.height(8.dp)) + + Text( + text = recentUser.name.value, + style = LocalTypography.current.bodyMedium + ) + } +} \ No newline at end of file diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/SearchUsersScreenTopBar.kt b/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/SearchUsersScreenTopBar.kt index 23de288..0b97276 100644 --- a/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/SearchUsersScreenTopBar.kt +++ b/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/SearchUsersScreenTopBar.kt @@ -1,14 +1,23 @@ package com.demn.usersearch.ui.components -import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import me.floow.uikit.components.topbar.SearchTopBar +import me.floow.usersearch.R @Composable fun SearchUsersScreenTopBar( + onBackClick: () -> Unit, searchFieldValue: String, onSearchFieldUpdate: (String) -> Unit, modifier: Modifier = Modifier ) { - + SearchTopBar( + onBackClick = onBackClick, + searchFieldValue = searchFieldValue, + placeholder = stringResource(R.string.search_field_placeholder), + onSearchFieldUpdate = onSearchFieldUpdate, + modifier = modifier + ) } \ No newline at end of file diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/UserGlobalSearchResult.kt b/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/UserGlobalSearchResult.kt new file mode 100644 index 0000000..03d1614 --- /dev/null +++ b/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/UserGlobalSearchResult.kt @@ -0,0 +1,96 @@ +package com.demn.usersearch.ui.components + +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.draw.clipToBounds +import androidx.compose.ui.draw.drawBehind +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.demn.usersearch.uilogic.UserSearchResult +import me.floow.domain.values.ProfileName +import me.floow.domain.values.ProfileUsername +import me.floow.uikit.R +import me.floow.uikit.theme.ElevanagonShape +import me.floow.uikit.theme.LocalTypography +import me.floow.uikit.theme.NinehedronShape +import me.floow.uikit.util.ComponentPreviewBox + +@Composable +fun UserGlobalSearchResult( + userSearchResult: UserSearchResult, + onClick: (UserSearchResult) -> Unit, + modifier: Modifier = Modifier +) { + Row( + modifier = modifier + .clickable { onClick(userSearchResult) } + .padding(horizontal = 20.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Box( + Modifier + .size(50.dp) + .clip(CircleShape) + .background(Color.LightGray) + ) + + Spacer(Modifier.width(9.dp)) + + Column( + modifier = Modifier, + verticalArrangement = Arrangement.Center + ) { + Text( + text = userSearchResult.name.value, + style = LocalTypography.current.bodyMedium, + fontWeight = FontWeight.Bold + ) + + Spacer(Modifier.height(2.dp)) + + Text( + text = stringResource(if (userSearchResult.isOnline) R.string.online else R.string.offline), + style = LocalTypography.current.bodyMedium, + color = MaterialTheme.colorScheme.secondary + ) + } + } +} + +@Preview +@Composable +private fun UserGlobalSearchResultPreview() { + ComponentPreviewBox(Modifier.fillMaxWidth()) { + UserGlobalSearchResult( + userSearchResult = UserSearchResult( + ProfileName("Demn"), + ProfileUsername( + "demndevel" + ), + isOnline = false + ), + onClick = {}, + modifier = Modifier.fillMaxWidth() + ) + } +} \ No newline at end of file diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/ui/states/EmptySearchResultsState.kt b/feature/usersearch/src/main/java/com/demn/usersearch/ui/states/EmptySearchResultsState.kt deleted file mode 100644 index 5ab3ceb..0000000 --- a/feature/usersearch/src/main/java/com/demn/usersearch/ui/states/EmptySearchResultsState.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.demn.usersearch.ui.states - -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier - -@Composable -fun EmptySearchResultsState(modifier: Modifier = Modifier) { - -} \ No newline at end of file diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/ui/states/LoadingState.kt b/feature/usersearch/src/main/java/com/demn/usersearch/ui/states/LoadingState.kt index b4799ad..54eebed 100644 --- a/feature/usersearch/src/main/java/com/demn/usersearch/ui/states/LoadingState.kt +++ b/feature/usersearch/src/main/java/com/demn/usersearch/ui/states/LoadingState.kt @@ -1,9 +1,21 @@ package com.demn.usersearch.ui.states +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.size +import androidx.compose.material3.CircularProgressIndicator import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp @Composable -fun LoadingState(modifier: Modifier = Modifier) { - +fun LoadingState( + modifier: Modifier = Modifier +) { + Box( + modifier, + contentAlignment = Alignment.Center + ) { + CircularProgressIndicator(Modifier.size(64.dp)) + } } \ No newline at end of file diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/ui/states/NoSearchInputState.kt b/feature/usersearch/src/main/java/com/demn/usersearch/ui/states/NoSearchInputState.kt new file mode 100644 index 0000000..ff02438 --- /dev/null +++ b/feature/usersearch/src/main/java/com/demn/usersearch/ui/states/NoSearchInputState.kt @@ -0,0 +1,37 @@ +package com.demn.usersearch.ui.states + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import com.demn.usersearch.ui.components.RecentUsersList +import com.demn.usersearch.uilogic.SearchUsersScreenUiState +import me.floow.uikit.theme.LocalTypography + +@Composable +fun NoSearchInputState( + state: SearchUsersScreenUiState.NoSearchInput, + modifier: Modifier = Modifier +) { + Column( + modifier = modifier + ) { + if (state.recentUsers.isNotEmpty()) { + Text( + text = "Recent searches", + style = LocalTypography.current.bodyMedium, + fontWeight = FontWeight.Bold, + modifier = Modifier + .padding(horizontal = 14.dp, vertical = 12.dp) + ) + + RecentUsersList( + recentUsers = state.recentUsers, + modifier = Modifier + ) + } + } +} \ No newline at end of file diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/ui/states/SearchResultsState.kt b/feature/usersearch/src/main/java/com/demn/usersearch/ui/states/SearchResultsState.kt index 191d881..91b9f17 100644 --- a/feature/usersearch/src/main/java/com/demn/usersearch/ui/states/SearchResultsState.kt +++ b/feature/usersearch/src/main/java/com/demn/usersearch/ui/states/SearchResultsState.kt @@ -1,9 +1,39 @@ package com.demn.usersearch.ui.states +import android.widget.Toast +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.unit.dp +import com.demn.usersearch.ui.components.GlobalSearchUsersList +import com.demn.usersearch.ui.components.UserGlobalSearchResult +import com.demn.usersearch.uilogic.SearchUsersScreenUiState @Composable -fun SearchResultsState(modifier: Modifier = Modifier) { +fun SearchResultsState( + state: SearchUsersScreenUiState.HasResults, + modifier: Modifier = Modifier +) { + val context = LocalContext.current + Column( + modifier = modifier + ) { + Spacer(Modifier.height(12.dp)) + + GlobalSearchUsersList( + results = state.results, + onClick = { result -> + Toast.makeText(context, result.toString(), Toast.LENGTH_SHORT).show() + } + ) + } } \ No newline at end of file diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/uilogic/SearchUsersScreenUiState.kt b/feature/usersearch/src/main/java/com/demn/usersearch/uilogic/SearchUsersScreenUiState.kt index d6142d1..960d32b 100644 --- a/feature/usersearch/src/main/java/com/demn/usersearch/uilogic/SearchUsersScreenUiState.kt +++ b/feature/usersearch/src/main/java/com/demn/usersearch/uilogic/SearchUsersScreenUiState.kt @@ -1,9 +1,30 @@ package com.demn.usersearch.uilogic +import me.floow.domain.values.ProfileName +import me.floow.domain.values.ProfileUsername + +data class UserSearchResult( + val name: ProfileName, + val username: ProfileUsername, + val isOnline: Boolean +) + +data class RecentUser( + val name: ProfileName, +) + interface SearchUsersScreenUiState { val searchField: String data class Loading(override val searchField: String) : SearchUsersScreenUiState - data class EmptyResults(override val searchField: String) : SearchUsersScreenUiState + data class NoSearchInput( + override val searchField: String, + val recentUsers: List + ) : SearchUsersScreenUiState + + data class HasResults( + override val searchField: String, + val results: List + ) : SearchUsersScreenUiState } \ No newline at end of file diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/uilogic/SearchUsersScreenViewModel.kt b/feature/usersearch/src/main/java/com/demn/usersearch/uilogic/SearchUsersScreenViewModel.kt index f431a17..a03a4f2 100644 --- a/feature/usersearch/src/main/java/com/demn/usersearch/uilogic/SearchUsersScreenViewModel.kt +++ b/feature/usersearch/src/main/java/com/demn/usersearch/uilogic/SearchUsersScreenViewModel.kt @@ -2,17 +2,40 @@ package com.demn.usersearch.uilogic import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import me.floow.domain.values.ProfileName +import me.floow.domain.values.ProfileUsername +import kotlin.random.Random private data class SearchUsersScreenVmState( - val searchField: String = "" + val searchField: String = "", + val isLoading: Boolean = false, + val globalSearchResults: List? = null, + val recentUsers: List? = null, ) { fun toUiState(): SearchUsersScreenUiState { - return SearchUsersScreenUiState.EmptyResults(searchField = searchField) + if (isLoading) return SearchUsersScreenUiState.Loading(searchField) + + if ((searchField.isBlank() || globalSearchResults == null) && recentUsers != null) return SearchUsersScreenUiState.NoSearchInput( + searchField = searchField, + recentUsers = recentUsers + ) + + if (globalSearchResults != null) { + return SearchUsersScreenUiState.HasResults( + searchField, + globalSearchResults, + ) + } + + return SearchUsersScreenUiState.Loading(searchField) } } @@ -21,5 +44,115 @@ class SearchUsersScreenViewModel : ViewModel() { val state: StateFlow = _state .map(SearchUsersScreenVmState::toUiState) - .stateIn(viewModelScope, SharingStarted.Eagerly, SearchUsersScreenUiState.Loading("")) + .stateIn( + viewModelScope, + SharingStarted.Eagerly, + SearchUsersScreenUiState.NoSearchInput("", emptyList()) + ) + + fun loadInitialData() { + viewModelScope.launch { + _state.update { + it.copy( + isLoading = true + ) + } + + delay(100L) + + _state.update { + it.copy( + recentUsers = generateRandomRecentUsers(), + isLoading = false + ) + } + } + } + + fun updateSearchField(newValue: String) { + _state.update { + it.copy( + searchField = newValue + ) + } + + viewModelScope.launch { + _state.update { + it.copy( + isLoading = true + ) + } + + delay(300L) + + _state.update { + it.copy( + globalSearchResults = generateRandomUserSearchResults(), + isLoading = false + ) + } + } + } + + private fun generateRandomUserSearchResults(): List { + val names = listOf( + "Alice", + "Bob", + "Charlie", + "David", + "Eve", + "Frank", + "Grace", + "Heidi", + "Ivan", + "Judy" + ) + val usernames = listOf( + "user1", + "user2", + "user3", + "user4", + "user5", + "user6", + "user7", + "user8", + "user9", + "user10" + ) + + return List(Random.nextInt(10)) { + val randomName = names[Random.nextInt(names.size)] + val randomUsername = usernames[Random.nextInt(usernames.size)] + val isOnline = Random.nextBoolean() + + UserSearchResult( + name = ProfileName(randomName), + username = ProfileUsername(randomUsername), + isOnline = isOnline + ) + } + } + + private fun generateRandomRecentUsers(): List { + val names = listOf( + "Alice", + "Bob", + "Charlie", + "David", + "Eve", + "Frank", + "Grace", + "Heidi", + "Ivan", + "Judy" + ) + + return List(Random.nextInt(15)) { + val randomName = names[Random.nextInt(names.size)] + + RecentUser( + name = ProfileName(randomName), + ) + } + } } \ No newline at end of file diff --git a/feature/usersearch/src/main/res/values-ru/strings.xml b/feature/usersearch/src/main/res/values-ru/strings.xml new file mode 100644 index 0000000..df9f391 --- /dev/null +++ b/feature/usersearch/src/main/res/values-ru/strings.xml @@ -0,0 +1,7 @@ + + + Поиск + Глобальный поиск + Показать больше + Показать меньше + \ No newline at end of file diff --git a/feature/usersearch/src/main/res/values/strings.xml b/feature/usersearch/src/main/res/values/strings.xml new file mode 100644 index 0000000..4be89dd --- /dev/null +++ b/feature/usersearch/src/main/res/values/strings.xml @@ -0,0 +1,7 @@ + + + Search + Global search + Show more + Show less + \ No newline at end of file From 37fe47f4dd0f795e8661f16e483ba5c94fa365cd Mon Sep 17 00:00:00 2001 From: demn Date: Thu, 7 Nov 2024 01:37:11 +0300 Subject: [PATCH 03/28] fix(app): inverse monochrome app icon colors --- .../ic_launcher_monochrome_foreground.xml | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/app/src/main/res/drawable/ic_launcher_monochrome_foreground.xml b/app/src/main/res/drawable/ic_launcher_monochrome_foreground.xml index c35f21b..e87dc12 100644 --- a/app/src/main/res/drawable/ic_launcher_monochrome_foreground.xml +++ b/app/src/main/res/drawable/ic_launcher_monochrome_foreground.xml @@ -4,18 +4,21 @@ android:viewportWidth="108" android:viewportHeight="108"> + android:pathData="M55.66,71.47L58.17,72.41L59.64,72.94L57.83,67.48L56.41,63.51C56.12,62.7 56.3,61.79 56.87,61.15L60.66,56.93L60.7,56.95L52.62,34.49L46.83,37.48L52.64,55.37C52.99,56.44 52.53,57.61 51.57,58.13C50.61,58.66 49.42,58.38 48.76,57.48L42.81,49.32L40.37,52.54L42.64,54.37L51.86,61.55C52.39,61.96 52.71,62.59 52.74,63.27C52.77,63.95 52.51,64.61 52.03,65.07L48.27,68.68L55.38,71.36" + android:fillColor="#DFC0B2" + android:fillType="evenOdd"/> - - \ No newline at end of file + android:pathData="M61.07,63.27L62.02,65.94L62.04,65.99L63.94,71.71L67.91,65.89L63.26,60.83L61.07,63.27Z" + android:fillColor="#DFC0B2" + android:fillType="evenOdd"/> + + + + + From 77ae8577d364d191b299a3580400ba7ff0b2b474 Mon Sep 17 00:00:00 2001 From: demn Date: Thu, 7 Nov 2024 02:17:21 +0300 Subject: [PATCH 04/28] feat(usersearch): implement mock search by messages --- .../demn/usersearch/ui/SearchUsersRoute.kt | 4 + .../demn/usersearch/ui/SearchUsersScreen.kt | 4 + .../usersearch/ui/components/MessageResult.kt | 88 +++++++++++++++++++ .../ui/components/MessageResultsList.kt | 51 +++++++++++ .../ui/components/UserGlobalSearchResult.kt | 6 +- ...hUsersList.kt => globalSearchUsersList.kt} | 43 ++++----- .../ui/states/SearchResultsState.kt | 46 +++++++--- .../uilogic/SearchUsersScreenUiState.kt | 8 +- .../uilogic/SearchUsersScreenViewModel.kt | 52 ++++++++++- .../src/main/res/values-ru/strings.xml | 1 + .../src/main/res/values/strings.xml | 1 + 11 files changed, 256 insertions(+), 48 deletions(-) create mode 100644 feature/usersearch/src/main/java/com/demn/usersearch/ui/components/MessageResult.kt create mode 100644 feature/usersearch/src/main/java/com/demn/usersearch/ui/components/MessageResultsList.kt rename feature/usersearch/src/main/java/com/demn/usersearch/ui/components/{GlobalSearchUsersList.kt => globalSearchUsersList.kt} (63%) diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/ui/SearchUsersRoute.kt b/feature/usersearch/src/main/java/com/demn/usersearch/ui/SearchUsersRoute.kt index 7a7bc4f..102c9d3 100644 --- a/feature/usersearch/src/main/java/com/demn/usersearch/ui/SearchUsersRoute.kt +++ b/feature/usersearch/src/main/java/com/demn/usersearch/ui/SearchUsersRoute.kt @@ -1,10 +1,14 @@ package com.demn.usersearch.ui +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import com.demn.usersearch.uilogic.SearchUsersScreenViewModel @Composable diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/ui/SearchUsersScreen.kt b/feature/usersearch/src/main/java/com/demn/usersearch/ui/SearchUsersScreen.kt index 9214235..00dc353 100644 --- a/feature/usersearch/src/main/java/com/demn/usersearch/ui/SearchUsersScreen.kt +++ b/feature/usersearch/src/main/java/com/demn/usersearch/ui/SearchUsersScreen.kt @@ -1,10 +1,14 @@ package com.demn.usersearch.ui +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp import com.demn.usersearch.ui.components.SearchUsersScreenTopBar import com.demn.usersearch.ui.states.NoSearchInputState import com.demn.usersearch.ui.states.LoadingState diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/MessageResult.kt b/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/MessageResult.kt new file mode 100644 index 0000000..b369955 --- /dev/null +++ b/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/MessageResult.kt @@ -0,0 +1,88 @@ +package com.demn.usersearch.ui.components + +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.demn.usersearch.uilogic.MessageResult +import me.floow.domain.values.ProfileName +import me.floow.uikit.theme.LocalTypography +import me.floow.uikit.util.ComponentPreviewBox + +@Composable +fun MessageResult( + result: MessageResult, + onClick: (MessageResult) -> Unit, + modifier: Modifier = Modifier +) { + Row( + modifier = modifier + .clickable { onClick(result) } + .padding(horizontal = 20.dp, vertical = 4.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Box( + Modifier + .size(56.dp) + .clip(CircleShape) + .background(Color.LightGray) + ) + + Spacer(Modifier.width(9.dp)) + + Column( + modifier = Modifier, + verticalArrangement = Arrangement.Center + ) { + Text( + text = result.name.value, + style = LocalTypography.current.bodyMedium, + fontWeight = FontWeight.Bold + ) + + Spacer(Modifier.height(2.dp)) + + Text( + text = result.messageText, + style = LocalTypography.current.bodyMedium, + color = MaterialTheme.colorScheme.secondary, + maxLines = 2, + overflow = TextOverflow.Ellipsis, + ) + } + } +} + +@Preview +@Composable +fun MessageResultPreview() { + ComponentPreviewBox(Modifier.fillMaxSize()) { + MessageResult( + result = MessageResult( + name = ProfileName("Богдан"), + messageText = "Привет, дружище. Как у тебя дела? У меня всё отлично. Сегодня сделал огромный пласт задач по дизайну, сейчас тебе скину пару примеров." + ), + onClick = {} + ) + } +} \ No newline at end of file diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/MessageResultsList.kt b/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/MessageResultsList.kt new file mode 100644 index 0000000..1249de1 --- /dev/null +++ b/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/MessageResultsList.kt @@ -0,0 +1,51 @@ +package com.demn.usersearch.ui.components + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyListScope +import androidx.compose.foundation.lazy.items +import androidx.compose.material3.Text +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import com.demn.usersearch.uilogic.MessageResult +import me.floow.uikit.theme.LocalTypography +import me.floow.usersearch.R + +fun LazyListScope.messageResultsList( + results: List, + onClick: (MessageResult) -> Unit, +) { + item { + Spacer(Modifier.height(12.dp)) + + Row( + horizontalArrangement = Arrangement.SpaceBetween, + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 14.dp), + ) { + Text( + text = stringResource(R.string.message_search), + style = LocalTypography.current.bodyMedium, + fontWeight = FontWeight.Bold + ) + } + + Spacer(Modifier.height(12.dp)) + } + + items(results) { result -> + MessageResult( + result = result, + onClick = onClick, + modifier = Modifier + .fillMaxWidth() + ) + } +} \ No newline at end of file diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/UserGlobalSearchResult.kt b/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/UserGlobalSearchResult.kt index 03d1614..7f44545 100644 --- a/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/UserGlobalSearchResult.kt +++ b/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/UserGlobalSearchResult.kt @@ -19,8 +19,6 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip -import androidx.compose.ui.draw.clipToBounds -import androidx.compose.ui.draw.drawBehind import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight @@ -30,9 +28,7 @@ import com.demn.usersearch.uilogic.UserSearchResult import me.floow.domain.values.ProfileName import me.floow.domain.values.ProfileUsername import me.floow.uikit.R -import me.floow.uikit.theme.ElevanagonShape import me.floow.uikit.theme.LocalTypography -import me.floow.uikit.theme.NinehedronShape import me.floow.uikit.util.ComponentPreviewBox @Composable @@ -44,7 +40,7 @@ fun UserGlobalSearchResult( Row( modifier = modifier .clickable { onClick(userSearchResult) } - .padding(horizontal = 20.dp), + .padding(horizontal = 20.dp, vertical = 4.dp), verticalAlignment = Alignment.CenterVertically ) { Box( diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/GlobalSearchUsersList.kt b/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/globalSearchUsersList.kt similarity index 63% rename from feature/usersearch/src/main/java/com/demn/usersearch/ui/components/GlobalSearchUsersList.kt rename to feature/usersearch/src/main/java/com/demn/usersearch/ui/components/globalSearchUsersList.kt index 88bba2c..7d35aff 100644 --- a/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/GlobalSearchUsersList.kt +++ b/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/globalSearchUsersList.kt @@ -2,20 +2,14 @@ package com.demn.usersearch.ui.components import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.foundation.lazy.items import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight @@ -24,15 +18,15 @@ import com.demn.usersearch.uilogic.UserSearchResult import me.floow.uikit.theme.LocalTypography import me.floow.usersearch.R -@Composable -fun GlobalSearchUsersList( +fun LazyListScope.globalSearchUsersList( + isExpanded: Boolean, + onExpandedToggle: () -> Unit, results: List, onClick: (UserSearchResult) -> Unit, - modifier: Modifier = Modifier ) { - var isExpanded by remember { mutableStateOf(false) } + item { + Spacer(Modifier.height(12.dp)) - Column(modifier) { Row( horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier @@ -51,27 +45,22 @@ fun GlobalSearchUsersList( style = LocalTypography.current.bodyMedium, modifier = Modifier .clickable { - isExpanded = !isExpanded + onExpandedToggle() } ) } } - + Spacer(Modifier.height(12.dp)) + } - LazyColumn( - verticalArrangement = Arrangement.spacedBy(8.dp), - modifier = Modifier, - ) { - val croppedResults = if (!isExpanded) results.take(3) else results + val croppedResults = if (!isExpanded) results.take(3) else results - items(croppedResults) { result -> - UserGlobalSearchResult( - result, - onClick = onClick, - modifier = Modifier.fillMaxWidth() - ) - } - } + items(croppedResults) { result -> + UserGlobalSearchResult( + result, + onClick = onClick, + modifier = Modifier.fillMaxWidth() + ) } } \ No newline at end of file diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/ui/states/SearchResultsState.kt b/feature/usersearch/src/main/java/com/demn/usersearch/ui/states/SearchResultsState.kt index 91b9f17..6eac13e 100644 --- a/feature/usersearch/src/main/java/com/demn/usersearch/ui/states/SearchResultsState.kt +++ b/feature/usersearch/src/main/java/com/demn/usersearch/ui/states/SearchResultsState.kt @@ -1,20 +1,22 @@ package com.demn.usersearch.ui.states import android.widget.Toast -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items +import androidx.compose.material3.HorizontalDivider import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp -import com.demn.usersearch.ui.components.GlobalSearchUsersList -import com.demn.usersearch.ui.components.UserGlobalSearchResult +import com.demn.usersearch.ui.components.globalSearchUsersList +import com.demn.usersearch.ui.components.messageResultsList import com.demn.usersearch.uilogic.SearchUsersScreenUiState @Composable @@ -23,17 +25,33 @@ fun SearchResultsState( modifier: Modifier = Modifier ) { val context = LocalContext.current + var isGlobalUsersSearchExpanded by remember { mutableStateOf(false) } - Column( - modifier = modifier - ) { - Spacer(Modifier.height(12.dp)) + Column(modifier = modifier) { + LazyColumn( + modifier = Modifier.fillMaxSize(), + ) { + globalSearchUsersList( + isExpanded = isGlobalUsersSearchExpanded, + onExpandedToggle = { isGlobalUsersSearchExpanded = !isGlobalUsersSearchExpanded }, + results = state.userResults, + onClick = { result -> + Toast.makeText(context, result.toString(), Toast.LENGTH_SHORT).show() + } + ) - GlobalSearchUsersList( - results = state.results, - onClick = { result -> - Toast.makeText(context, result.toString(), Toast.LENGTH_SHORT).show() + item { + Spacer(Modifier.height(12.dp)) + + HorizontalDivider() } - ) + + messageResultsList( + results = state.messageResults, + onClick = { result -> + Toast.makeText(context, result.toString(), Toast.LENGTH_SHORT).show() + } + ) + } } } \ No newline at end of file diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/uilogic/SearchUsersScreenUiState.kt b/feature/usersearch/src/main/java/com/demn/usersearch/uilogic/SearchUsersScreenUiState.kt index 960d32b..5e118b7 100644 --- a/feature/usersearch/src/main/java/com/demn/usersearch/uilogic/SearchUsersScreenUiState.kt +++ b/feature/usersearch/src/main/java/com/demn/usersearch/uilogic/SearchUsersScreenUiState.kt @@ -13,6 +13,11 @@ data class RecentUser( val name: ProfileName, ) +data class MessageResult( + val name: ProfileName, + val messageText: String, +) + interface SearchUsersScreenUiState { val searchField: String @@ -25,6 +30,7 @@ interface SearchUsersScreenUiState { data class HasResults( override val searchField: String, - val results: List + val userResults: List, + val messageResults: List ) : SearchUsersScreenUiState } \ No newline at end of file diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/uilogic/SearchUsersScreenViewModel.kt b/feature/usersearch/src/main/java/com/demn/usersearch/uilogic/SearchUsersScreenViewModel.kt index a03a4f2..e4af577 100644 --- a/feature/usersearch/src/main/java/com/demn/usersearch/uilogic/SearchUsersScreenViewModel.kt +++ b/feature/usersearch/src/main/java/com/demn/usersearch/uilogic/SearchUsersScreenViewModel.kt @@ -18,6 +18,7 @@ private data class SearchUsersScreenVmState( val searchField: String = "", val isLoading: Boolean = false, val globalSearchResults: List? = null, + val messageSearchResults: List? = null, val recentUsers: List? = null, ) { fun toUiState(): SearchUsersScreenUiState { @@ -28,10 +29,11 @@ private data class SearchUsersScreenVmState( recentUsers = recentUsers ) - if (globalSearchResults != null) { + if (globalSearchResults != null && messageSearchResults != null) { return SearchUsersScreenUiState.HasResults( searchField, globalSearchResults, + messageSearchResults ) } @@ -88,12 +90,60 @@ class SearchUsersScreenViewModel : ViewModel() { _state.update { it.copy( globalSearchResults = generateRandomUserSearchResults(), + messageSearchResults = generateRandomMessageSearchResults(), isLoading = false ) } } } + private fun generateRandomMessageSearchResults(): List { + val names = listOf( + "Alice", + "Bob", + "Charlie", + "David", + "Eve", + "Frank", + "Grace", + "Heidi", + "Ivan", + "Judy" + ) + val messages = listOf( + "Привет, как дела?", + "Что нового?", + "Можем встретиться завтра?", + "Извините, я опаздываю!", + "Видел новый фильм?", + "Давай перекусим вместе.", + "Мне нужна твоя помощь.", + "Как прошли выходные?", + "Есть планы на вечер?", + "Нашел отличный новый ресторан.", + "Можешь прислать отчет?", + "Следующую неделю уезжаю в отпуск.", + "Хочешь присоединиться к нам на ужин?", + "Застрял в пробке, скоро буду.", + "Пробовал новую кофейню?", + "Нужно перенести нашу встречу.", + "Получил мое письмо?", + "Давай встретимся как-нибудь.", + "С нетерпением жду поездки!", + "Есть рекомендации по книгам?" + ) + + return List(Random.nextInt(200)) { + val randomName = names[Random.nextInt(names.size)] + val randomMessage = messages[Random.nextInt(messages.size)] + + MessageResult( + name = ProfileName(randomName), + messageText = randomMessage + ) + } + } + private fun generateRandomUserSearchResults(): List { val names = listOf( "Alice", diff --git a/feature/usersearch/src/main/res/values-ru/strings.xml b/feature/usersearch/src/main/res/values-ru/strings.xml index df9f391..8b0d487 100644 --- a/feature/usersearch/src/main/res/values-ru/strings.xml +++ b/feature/usersearch/src/main/res/values-ru/strings.xml @@ -4,4 +4,5 @@ Глобальный поиск Показать больше Показать меньше + Сообщения \ No newline at end of file diff --git a/feature/usersearch/src/main/res/values/strings.xml b/feature/usersearch/src/main/res/values/strings.xml index 4be89dd..c94ff75 100644 --- a/feature/usersearch/src/main/res/values/strings.xml +++ b/feature/usersearch/src/main/res/values/strings.xml @@ -4,4 +4,5 @@ Global search Show more Show less + Message search \ No newline at end of file From 4722248a75108d07e873d0d68cec19b8764616ac Mon Sep 17 00:00:00 2001 From: demn Date: Thu, 7 Nov 2024 02:24:07 +0300 Subject: [PATCH 05/28] refactor(chatssearch): rename module from usersearch to chatssearch --- app/build.gradle.kts | 2 +- app/src/main/java/me/floow/app/MainActivity.kt | 2 +- .../java/me/floow/app/navigation/FlowNavHost.kt | 2 +- feature/{usersearch => chatssearch}/.gitignore | 0 .../{usersearch => chatssearch}/build.gradle.kts | 2 +- .../consumer-rules.pro | 0 .../proguard-rules.pro | 0 .../floow}/usersearch/ExampleInstrumentedTest.kt | 2 +- .../src/main/AndroidManifest.xml | 0 .../me/floow/chatssearch}/di/usersearchModule.kt | 4 ++-- .../me/floow/chatssearch}/ui/SearchUsersRoute.kt | 8 ++------ .../floow/chatssearch}/ui/SearchUsersScreen.kt | 16 ++++++---------- .../chatssearch}/ui/components/MessageResult.kt | 4 ++-- .../ui/components/MessageResultsList.kt | 6 +++--- .../ui/components/RecentUsersList.kt | 4 ++-- .../ui/components/SearchUsersScreenTopBar.kt | 4 ++-- .../ui/components/UserGlobalSearchResult.kt | 4 ++-- .../ui/components/globalSearchUsersList.kt | 6 +++--- .../floow/chatssearch}/ui/states/LoadingState.kt | 2 +- .../chatssearch}/ui/states/NoSearchInputState.kt | 6 +++--- .../chatssearch}/ui/states/SearchResultsState.kt | 8 ++++---- .../uilogic/SearchUsersScreenUiState.kt | 2 +- .../uilogic/SearchUsersScreenViewModel.kt | 2 +- .../src/main/res/values-ru/strings.xml | 0 .../src/main/res/values/strings.xml | 0 .../java/me/floow}/usersearch/ExampleUnitTest.kt | 2 +- settings.gradle.kts | 2 +- 27 files changed, 41 insertions(+), 49 deletions(-) rename feature/{usersearch => chatssearch}/.gitignore (100%) rename feature/{usersearch => chatssearch}/build.gradle.kts (96%) rename feature/{usersearch => chatssearch}/consumer-rules.pro (100%) rename feature/{usersearch => chatssearch}/proguard-rules.pro (100%) rename feature/{usersearch/src/androidTest/java/com/demn => chatssearch/src/androidTest/java/me/floow}/usersearch/ExampleInstrumentedTest.kt (95%) rename feature/{usersearch => chatssearch}/src/main/AndroidManifest.xml (100%) rename feature/{usersearch/src/main/java/com/demn/usersearch => chatssearch/src/main/java/me/floow/chatssearch}/di/usersearchModule.kt (61%) rename feature/{usersearch/src/main/java/com/demn/usersearch => chatssearch/src/main/java/me/floow/chatssearch}/ui/SearchUsersRoute.kt (68%) rename feature/{usersearch/src/main/java/com/demn/usersearch => chatssearch/src/main/java/me/floow/chatssearch}/ui/SearchUsersScreen.kt (69%) rename feature/{usersearch/src/main/java/com/demn/usersearch => chatssearch/src/main/java/me/floow/chatssearch}/ui/components/MessageResult.kt (96%) rename feature/{usersearch/src/main/java/com/demn/usersearch => chatssearch/src/main/java/me/floow/chatssearch}/ui/components/MessageResultsList.kt (91%) rename feature/{usersearch/src/main/java/com/demn/usersearch => chatssearch/src/main/java/me/floow/chatssearch}/ui/components/RecentUsersList.kt (95%) rename feature/{usersearch/src/main/java/com/demn/usersearch => chatssearch/src/main/java/me/floow/chatssearch}/ui/components/SearchUsersScreenTopBar.kt (88%) rename feature/{usersearch/src/main/java/com/demn/usersearch => chatssearch/src/main/java/me/floow/chatssearch}/ui/components/UserGlobalSearchResult.kt (96%) rename feature/{usersearch/src/main/java/com/demn/usersearch => chatssearch/src/main/java/me/floow/chatssearch}/ui/components/globalSearchUsersList.kt (93%) rename feature/{usersearch/src/main/java/com/demn/usersearch => chatssearch/src/main/java/me/floow/chatssearch}/ui/states/LoadingState.kt (92%) rename feature/{usersearch/src/main/java/com/demn/usersearch => chatssearch/src/main/java/me/floow/chatssearch}/ui/states/NoSearchInputState.kt (84%) rename feature/{usersearch/src/main/java/com/demn/usersearch => chatssearch/src/main/java/me/floow/chatssearch}/ui/states/SearchResultsState.kt (87%) rename feature/{usersearch/src/main/java/com/demn/usersearch => chatssearch/src/main/java/me/floow/chatssearch}/uilogic/SearchUsersScreenUiState.kt (95%) rename feature/{usersearch/src/main/java/com/demn/usersearch => chatssearch/src/main/java/me/floow/chatssearch}/uilogic/SearchUsersScreenViewModel.kt (99%) rename feature/{usersearch => chatssearch}/src/main/res/values-ru/strings.xml (100%) rename feature/{usersearch => chatssearch}/src/main/res/values/strings.xml (100%) rename feature/{usersearch/src/test/java/com/demn => chatssearch/src/test/java/me/floow}/usersearch/ExampleUnitTest.kt (91%) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 0afd926..5deeb0c 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -77,7 +77,7 @@ dependencies { implementation(project(":feature:feed")) implementation(project(":feature:explore")) implementation(project(":feature:profile")) - implementation(project(":feature:usersearch")) + implementation(project(":feature:chatssearch")) implementation(libs.androidx.core.splashscreen) diff --git a/app/src/main/java/me/floow/app/MainActivity.kt b/app/src/main/java/me/floow/app/MainActivity.kt index eeb2e84..38dfff8 100644 --- a/app/src/main/java/me/floow/app/MainActivity.kt +++ b/app/src/main/java/me/floow/app/MainActivity.kt @@ -10,7 +10,7 @@ import androidx.activity.enableEdgeToEdge import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.ui.Modifier import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen -import com.demn.usersearch.di.usersearchModule +import me.floow.chatssearch.di.usersearchModule import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch diff --git a/app/src/main/java/me/floow/app/navigation/FlowNavHost.kt b/app/src/main/java/me/floow/app/navigation/FlowNavHost.kt index 01548ed..ef8a74d 100644 --- a/app/src/main/java/me/floow/app/navigation/FlowNavHost.kt +++ b/app/src/main/java/me/floow/app/navigation/FlowNavHost.kt @@ -12,7 +12,7 @@ import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.navigation import androidx.navigation.toRoute -import com.demn.usersearch.ui.SearchUsersRoute +import me.floow.chatssearch.ui.SearchUsersRoute import me.floow.chats.ui.ChatsRoute import me.floow.feed.ui.FeedRoute import me.floow.login.ui.createprofile.CreateProfileRoute diff --git a/feature/usersearch/.gitignore b/feature/chatssearch/.gitignore similarity index 100% rename from feature/usersearch/.gitignore rename to feature/chatssearch/.gitignore diff --git a/feature/usersearch/build.gradle.kts b/feature/chatssearch/build.gradle.kts similarity index 96% rename from feature/usersearch/build.gradle.kts rename to feature/chatssearch/build.gradle.kts index 7903a82..e56757f 100644 --- a/feature/usersearch/build.gradle.kts +++ b/feature/chatssearch/build.gradle.kts @@ -5,7 +5,7 @@ plugins { } android { - namespace = "me.floow.usersearch" + namespace = "me.floow.chatssearch" compileSdk = 34 defaultConfig { diff --git a/feature/usersearch/consumer-rules.pro b/feature/chatssearch/consumer-rules.pro similarity index 100% rename from feature/usersearch/consumer-rules.pro rename to feature/chatssearch/consumer-rules.pro diff --git a/feature/usersearch/proguard-rules.pro b/feature/chatssearch/proguard-rules.pro similarity index 100% rename from feature/usersearch/proguard-rules.pro rename to feature/chatssearch/proguard-rules.pro diff --git a/feature/usersearch/src/androidTest/java/com/demn/usersearch/ExampleInstrumentedTest.kt b/feature/chatssearch/src/androidTest/java/me/floow/usersearch/ExampleInstrumentedTest.kt similarity index 95% rename from feature/usersearch/src/androidTest/java/com/demn/usersearch/ExampleInstrumentedTest.kt rename to feature/chatssearch/src/androidTest/java/me/floow/usersearch/ExampleInstrumentedTest.kt index 7df2a9d..059aacb 100644 --- a/feature/usersearch/src/androidTest/java/com/demn/usersearch/ExampleInstrumentedTest.kt +++ b/feature/chatssearch/src/androidTest/java/me/floow/usersearch/ExampleInstrumentedTest.kt @@ -1,4 +1,4 @@ -package com.demn.usersearch +package me.floow.usersearch import androidx.test.platform.app.InstrumentationRegistry import androidx.test.ext.junit.runners.AndroidJUnit4 diff --git a/feature/usersearch/src/main/AndroidManifest.xml b/feature/chatssearch/src/main/AndroidManifest.xml similarity index 100% rename from feature/usersearch/src/main/AndroidManifest.xml rename to feature/chatssearch/src/main/AndroidManifest.xml diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/di/usersearchModule.kt b/feature/chatssearch/src/main/java/me/floow/chatssearch/di/usersearchModule.kt similarity index 61% rename from feature/usersearch/src/main/java/com/demn/usersearch/di/usersearchModule.kt rename to feature/chatssearch/src/main/java/me/floow/chatssearch/di/usersearchModule.kt index 0978c3f..1166681 100644 --- a/feature/usersearch/src/main/java/com/demn/usersearch/di/usersearchModule.kt +++ b/feature/chatssearch/src/main/java/me/floow/chatssearch/di/usersearchModule.kt @@ -1,8 +1,8 @@ -package com.demn.usersearch.di +package me.floow.chatssearch.di import org.koin.dsl.module import org.koin.core.module.dsl.viewModelOf -import com.demn.usersearch.uilogic.SearchUsersScreenViewModel +import me.floow.chatssearch.uilogic.SearchUsersScreenViewModel val usersearchModule = module { viewModelOf(::SearchUsersScreenViewModel) diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/ui/SearchUsersRoute.kt b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/SearchUsersRoute.kt similarity index 68% rename from feature/usersearch/src/main/java/com/demn/usersearch/ui/SearchUsersRoute.kt rename to feature/chatssearch/src/main/java/me/floow/chatssearch/ui/SearchUsersRoute.kt index 102c9d3..a8da2c4 100644 --- a/feature/usersearch/src/main/java/com/demn/usersearch/ui/SearchUsersRoute.kt +++ b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/SearchUsersRoute.kt @@ -1,15 +1,11 @@ -package com.demn.usersearch.ui +package me.floow.chatssearch.ui -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import com.demn.usersearch.uilogic.SearchUsersScreenViewModel +import me.floow.chatssearch.uilogic.SearchUsersScreenViewModel @Composable fun SearchUsersRoute( diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/ui/SearchUsersScreen.kt b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/SearchUsersScreen.kt similarity index 69% rename from feature/usersearch/src/main/java/com/demn/usersearch/ui/SearchUsersScreen.kt rename to feature/chatssearch/src/main/java/me/floow/chatssearch/ui/SearchUsersScreen.kt index 00dc353..0be969c 100644 --- a/feature/usersearch/src/main/java/com/demn/usersearch/ui/SearchUsersScreen.kt +++ b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/SearchUsersScreen.kt @@ -1,19 +1,15 @@ -package com.demn.usersearch.ui +package me.floow.chatssearch.ui -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.unit.dp -import com.demn.usersearch.ui.components.SearchUsersScreenTopBar -import com.demn.usersearch.ui.states.NoSearchInputState -import com.demn.usersearch.ui.states.LoadingState -import com.demn.usersearch.ui.states.SearchResultsState -import com.demn.usersearch.uilogic.SearchUsersScreenUiState +import me.floow.chatssearch.ui.components.SearchUsersScreenTopBar +import me.floow.chatssearch.ui.states.NoSearchInputState +import me.floow.chatssearch.ui.states.LoadingState +import me.floow.chatssearch.ui.states.SearchResultsState +import me.floow.chatssearch.uilogic.SearchUsersScreenUiState @Composable internal fun SearchUsersScreen( diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/MessageResult.kt b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/MessageResult.kt similarity index 96% rename from feature/usersearch/src/main/java/com/demn/usersearch/ui/components/MessageResult.kt rename to feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/MessageResult.kt index b369955..e5bc14a 100644 --- a/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/MessageResult.kt +++ b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/MessageResult.kt @@ -1,4 +1,4 @@ -package com.demn.usersearch.ui.components +package me.floow.chatssearch.ui.components import androidx.compose.foundation.background import androidx.compose.foundation.clickable @@ -24,7 +24,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.demn.usersearch.uilogic.MessageResult +import me.floow.chatssearch.uilogic.MessageResult import me.floow.domain.values.ProfileName import me.floow.uikit.theme.LocalTypography import me.floow.uikit.util.ComponentPreviewBox diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/MessageResultsList.kt b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/MessageResultsList.kt similarity index 91% rename from feature/usersearch/src/main/java/com/demn/usersearch/ui/components/MessageResultsList.kt rename to feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/MessageResultsList.kt index 1249de1..3a70a31 100644 --- a/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/MessageResultsList.kt +++ b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/MessageResultsList.kt @@ -1,4 +1,4 @@ -package com.demn.usersearch.ui.components +package me.floow.chatssearch.ui.components import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row @@ -13,9 +13,9 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp -import com.demn.usersearch.uilogic.MessageResult +import me.floow.chatssearch.uilogic.MessageResult import me.floow.uikit.theme.LocalTypography -import me.floow.usersearch.R +import me.floow.chatssearch.R fun LazyListScope.messageResultsList( results: List, diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/RecentUsersList.kt b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/RecentUsersList.kt similarity index 95% rename from feature/usersearch/src/main/java/com/demn/usersearch/ui/components/RecentUsersList.kt rename to feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/RecentUsersList.kt index 017a64e..5b77e55 100644 --- a/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/RecentUsersList.kt +++ b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/RecentUsersList.kt @@ -1,4 +1,4 @@ -package com.demn.usersearch.ui.components +package me.floow.chatssearch.ui.components import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement @@ -19,7 +19,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp -import com.demn.usersearch.uilogic.RecentUser +import me.floow.chatssearch.uilogic.RecentUser import me.floow.uikit.theme.LocalTypography @Composable diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/SearchUsersScreenTopBar.kt b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/SearchUsersScreenTopBar.kt similarity index 88% rename from feature/usersearch/src/main/java/com/demn/usersearch/ui/components/SearchUsersScreenTopBar.kt rename to feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/SearchUsersScreenTopBar.kt index 0b97276..b09ee39 100644 --- a/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/SearchUsersScreenTopBar.kt +++ b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/SearchUsersScreenTopBar.kt @@ -1,10 +1,10 @@ -package com.demn.usersearch.ui.components +package me.floow.chatssearch.ui.components import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import me.floow.uikit.components.topbar.SearchTopBar -import me.floow.usersearch.R +import me.floow.chatssearch.R @Composable fun SearchUsersScreenTopBar( diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/UserGlobalSearchResult.kt b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/UserGlobalSearchResult.kt similarity index 96% rename from feature/usersearch/src/main/java/com/demn/usersearch/ui/components/UserGlobalSearchResult.kt rename to feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/UserGlobalSearchResult.kt index 7f44545..5ee6b50 100644 --- a/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/UserGlobalSearchResult.kt +++ b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/UserGlobalSearchResult.kt @@ -1,4 +1,4 @@ -package com.demn.usersearch.ui.components +package me.floow.chatssearch.ui.components import androidx.compose.foundation.background import androidx.compose.foundation.clickable @@ -24,7 +24,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.demn.usersearch.uilogic.UserSearchResult +import me.floow.chatssearch.uilogic.UserSearchResult import me.floow.domain.values.ProfileName import me.floow.domain.values.ProfileUsername import me.floow.uikit.R diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/globalSearchUsersList.kt b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/globalSearchUsersList.kt similarity index 93% rename from feature/usersearch/src/main/java/com/demn/usersearch/ui/components/globalSearchUsersList.kt rename to feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/globalSearchUsersList.kt index 7d35aff..209f5ca 100644 --- a/feature/usersearch/src/main/java/com/demn/usersearch/ui/components/globalSearchUsersList.kt +++ b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/globalSearchUsersList.kt @@ -1,4 +1,4 @@ -package com.demn.usersearch.ui.components +package me.floow.chatssearch.ui.components import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement @@ -14,9 +14,9 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp -import com.demn.usersearch.uilogic.UserSearchResult +import me.floow.chatssearch.uilogic.UserSearchResult import me.floow.uikit.theme.LocalTypography -import me.floow.usersearch.R +import me.floow.chatssearch.R fun LazyListScope.globalSearchUsersList( isExpanded: Boolean, diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/ui/states/LoadingState.kt b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/states/LoadingState.kt similarity index 92% rename from feature/usersearch/src/main/java/com/demn/usersearch/ui/states/LoadingState.kt rename to feature/chatssearch/src/main/java/me/floow/chatssearch/ui/states/LoadingState.kt index 54eebed..52e9bf3 100644 --- a/feature/usersearch/src/main/java/com/demn/usersearch/ui/states/LoadingState.kt +++ b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/states/LoadingState.kt @@ -1,4 +1,4 @@ -package com.demn.usersearch.ui.states +package me.floow.chatssearch.ui.states import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.size diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/ui/states/NoSearchInputState.kt b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/states/NoSearchInputState.kt similarity index 84% rename from feature/usersearch/src/main/java/com/demn/usersearch/ui/states/NoSearchInputState.kt rename to feature/chatssearch/src/main/java/me/floow/chatssearch/ui/states/NoSearchInputState.kt index ff02438..895dfa4 100644 --- a/feature/usersearch/src/main/java/com/demn/usersearch/ui/states/NoSearchInputState.kt +++ b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/states/NoSearchInputState.kt @@ -1,4 +1,4 @@ -package com.demn.usersearch.ui.states +package me.floow.chatssearch.ui.states import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding @@ -7,8 +7,8 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp -import com.demn.usersearch.ui.components.RecentUsersList -import com.demn.usersearch.uilogic.SearchUsersScreenUiState +import me.floow.chatssearch.ui.components.RecentUsersList +import me.floow.chatssearch.uilogic.SearchUsersScreenUiState import me.floow.uikit.theme.LocalTypography @Composable diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/ui/states/SearchResultsState.kt b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/states/SearchResultsState.kt similarity index 87% rename from feature/usersearch/src/main/java/com/demn/usersearch/ui/states/SearchResultsState.kt rename to feature/chatssearch/src/main/java/me/floow/chatssearch/ui/states/SearchResultsState.kt index 6eac13e..6d934a1 100644 --- a/feature/usersearch/src/main/java/com/demn/usersearch/ui/states/SearchResultsState.kt +++ b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/states/SearchResultsState.kt @@ -1,4 +1,4 @@ -package com.demn.usersearch.ui.states +package me.floow.chatssearch.ui.states import android.widget.Toast import androidx.compose.foundation.layout.Column @@ -15,9 +15,9 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp -import com.demn.usersearch.ui.components.globalSearchUsersList -import com.demn.usersearch.ui.components.messageResultsList -import com.demn.usersearch.uilogic.SearchUsersScreenUiState +import me.floow.chatssearch.ui.components.globalSearchUsersList +import me.floow.chatssearch.ui.components.messageResultsList +import me.floow.chatssearch.uilogic.SearchUsersScreenUiState @Composable fun SearchResultsState( diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/uilogic/SearchUsersScreenUiState.kt b/feature/chatssearch/src/main/java/me/floow/chatssearch/uilogic/SearchUsersScreenUiState.kt similarity index 95% rename from feature/usersearch/src/main/java/com/demn/usersearch/uilogic/SearchUsersScreenUiState.kt rename to feature/chatssearch/src/main/java/me/floow/chatssearch/uilogic/SearchUsersScreenUiState.kt index 5e118b7..8bd8d2a 100644 --- a/feature/usersearch/src/main/java/com/demn/usersearch/uilogic/SearchUsersScreenUiState.kt +++ b/feature/chatssearch/src/main/java/me/floow/chatssearch/uilogic/SearchUsersScreenUiState.kt @@ -1,4 +1,4 @@ -package com.demn.usersearch.uilogic +package me.floow.chatssearch.uilogic import me.floow.domain.values.ProfileName import me.floow.domain.values.ProfileUsername diff --git a/feature/usersearch/src/main/java/com/demn/usersearch/uilogic/SearchUsersScreenViewModel.kt b/feature/chatssearch/src/main/java/me/floow/chatssearch/uilogic/SearchUsersScreenViewModel.kt similarity index 99% rename from feature/usersearch/src/main/java/com/demn/usersearch/uilogic/SearchUsersScreenViewModel.kt rename to feature/chatssearch/src/main/java/me/floow/chatssearch/uilogic/SearchUsersScreenViewModel.kt index e4af577..580b31e 100644 --- a/feature/usersearch/src/main/java/com/demn/usersearch/uilogic/SearchUsersScreenViewModel.kt +++ b/feature/chatssearch/src/main/java/me/floow/chatssearch/uilogic/SearchUsersScreenViewModel.kt @@ -1,4 +1,4 @@ -package com.demn.usersearch.uilogic +package me.floow.chatssearch.uilogic import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope diff --git a/feature/usersearch/src/main/res/values-ru/strings.xml b/feature/chatssearch/src/main/res/values-ru/strings.xml similarity index 100% rename from feature/usersearch/src/main/res/values-ru/strings.xml rename to feature/chatssearch/src/main/res/values-ru/strings.xml diff --git a/feature/usersearch/src/main/res/values/strings.xml b/feature/chatssearch/src/main/res/values/strings.xml similarity index 100% rename from feature/usersearch/src/main/res/values/strings.xml rename to feature/chatssearch/src/main/res/values/strings.xml diff --git a/feature/usersearch/src/test/java/com/demn/usersearch/ExampleUnitTest.kt b/feature/chatssearch/src/test/java/me/floow/usersearch/ExampleUnitTest.kt similarity index 91% rename from feature/usersearch/src/test/java/com/demn/usersearch/ExampleUnitTest.kt rename to feature/chatssearch/src/test/java/me/floow/usersearch/ExampleUnitTest.kt index f368351..0eac092 100644 --- a/feature/usersearch/src/test/java/com/demn/usersearch/ExampleUnitTest.kt +++ b/feature/chatssearch/src/test/java/me/floow/usersearch/ExampleUnitTest.kt @@ -1,4 +1,4 @@ -package com.demn.usersearch +package me.floow.usersearch import org.junit.Test diff --git a/settings.gradle.kts b/settings.gradle.kts index 87f01d1..28afb90 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -34,4 +34,4 @@ include(":feature:chats") include(":feature:explore") include(":feature:login") include(":feature:profile") -include(":feature:usersearch") +include(":feature:chatssearch") From 09a065390b1215d29473efade77780492c46c499 Mon Sep 17 00:00:00 2001 From: demn Date: Sun, 10 Nov 2024 06:02:00 +0300 Subject: [PATCH 06/28] feat(app): add bare implementation of deeplinks --- app/src/main/AndroidManifest.xml | 26 ++++++++++++++----- .../me/floow/app/navigation/FlowNavHost.kt | 20 +++++++++++++- .../floow/app/navigation/NavigationGraph.kt | 9 ++++--- .../app/navigation/profileDeeplinkuri.kt | 3 +++ 4 files changed, 48 insertions(+), 10 deletions(-) create mode 100644 app/src/main/java/me/floow/app/navigation/profileDeeplinkuri.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index fc439f0..ceb0452 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,7 @@ + xmlns:tools="http://schemas.android.com/tools"> + + android:launchMode="singleTask" + android:theme="@style/Theme.Flow.Starting"> + + + + + + + + + - + - + + - + + diff --git a/app/src/main/java/me/floow/app/navigation/FlowNavHost.kt b/app/src/main/java/me/floow/app/navigation/FlowNavHost.kt index ef8a74d..4d31224 100644 --- a/app/src/main/java/me/floow/app/navigation/FlowNavHost.kt +++ b/app/src/main/java/me/floow/app/navigation/FlowNavHost.kt @@ -3,6 +3,8 @@ package me.floow.app.navigation import android.content.Context import android.content.Intent import android.widget.Toast +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier @@ -11,6 +13,7 @@ import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.navigation +import androidx.navigation.navDeepLink import androidx.navigation.toRoute import me.floow.chatssearch.ui.SearchUsersRoute import me.floow.chats.ui.ChatsRoute @@ -102,7 +105,22 @@ fun FlowNavHost( ) } - composable { + composable( + deepLinks = listOf( + navDeepLink( + basePath = profileDeeplinkUri + ) + ) + ) { + val username = navController.currentBackStackEntry + ?.toRoute()?.username + + Box(Modifier.fillMaxSize()) { + Text(text = username ?: "no username, invalid input") + } + } + + composable { ProfileRoute( goToProfileEditScreen = { name, username, description -> navController.navigate( diff --git a/app/src/main/java/me/floow/app/navigation/NavigationGraph.kt b/app/src/main/java/me/floow/app/navigation/NavigationGraph.kt index 9d14b67..0669120 100644 --- a/app/src/main/java/me/floow/app/navigation/NavigationGraph.kt +++ b/app/src/main/java/me/floow/app/navigation/NavigationGraph.kt @@ -30,7 +30,10 @@ data object ChatsScreen : NavigationRoute data object SearchUsersScreen : NavigationRoute @Serializable -data object ProfileScreen : NavigationRoute +data class ProfileScreen(val username: String) : NavigationRoute + +@Serializable +data object SelfProfileScreen : NavigationRoute @Serializable data class EditProfileScreen( @@ -51,7 +54,7 @@ val bottomNavigationItems = listOf( drawableIconId = me.floow.uikit.R.drawable.chats_icon, ), BottomNavigationItem( - route = ProfileScreen, + route = SelfProfileScreen, titleId = R.string.profile_bottom_nav_label, drawableIconId = me.floow.uikit.R.drawable.profile_icon, ), @@ -60,5 +63,5 @@ val bottomNavigationItems = listOf( val mainBottomBarNavigationDestinations = listOf( FeedScreen, ChatsScreen, - ProfileScreen + SelfProfileScreen ) \ No newline at end of file diff --git a/app/src/main/java/me/floow/app/navigation/profileDeeplinkuri.kt b/app/src/main/java/me/floow/app/navigation/profileDeeplinkuri.kt new file mode 100644 index 0000000..b081627 --- /dev/null +++ b/app/src/main/java/me/floow/app/navigation/profileDeeplinkuri.kt @@ -0,0 +1,3 @@ +package me.floow.app.navigation + +const val profileDeeplinkUri = "https://floow.me/" \ No newline at end of file From d71fa74c99287d14e271ee4565baa7a7d5294597 Mon Sep 17 00:00:00 2001 From: demn Date: Sun, 10 Nov 2024 06:20:17 +0300 Subject: [PATCH 07/28] fix, feat(chatssearch): add preview for search state, remove magical bottom padding by settings window insets to 0 --- .../floow/chatssearch/ui/SearchUsersScreen.kt | 54 +++++++++++++++++++ .../ui/states/SearchResultsState.kt | 45 ++++++++++++++++ 2 files changed, 99 insertions(+) diff --git a/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/SearchUsersScreen.kt b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/SearchUsersScreen.kt index 0be969c..e3fb532 100644 --- a/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/SearchUsersScreen.kt +++ b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/SearchUsersScreen.kt @@ -1,15 +1,22 @@ package me.floow.chatssearch.ui +import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp import me.floow.chatssearch.ui.components.SearchUsersScreenTopBar import me.floow.chatssearch.ui.states.NoSearchInputState import me.floow.chatssearch.ui.states.LoadingState import me.floow.chatssearch.ui.states.SearchResultsState +import me.floow.chatssearch.uilogic.MessageResult import me.floow.chatssearch.uilogic.SearchUsersScreenUiState +import me.floow.chatssearch.uilogic.UserSearchResult +import me.floow.domain.values.ProfileName +import me.floow.domain.values.ProfileUsername @Composable internal fun SearchUsersScreen( @@ -26,6 +33,7 @@ internal fun SearchUsersScreen( onSearchFieldUpdate = onSearchFieldUpdate, ) }, + contentWindowInsets = WindowInsets(0.dp), modifier = modifier, ) { innerPadding -> val contentModifier = Modifier @@ -54,4 +62,50 @@ internal fun SearchUsersScreen( } } } +} + +@Preview +@Composable +private fun SearchUsersScreenPreview() { + SearchUsersScreen( + onBackClick = { }, + onSearchFieldUpdate = { }, + state = SearchUsersScreenUiState.HasResults( + searchField = "test", + userResults = listOf( + UserSearchResult( + name = ProfileName("Demn"), + username = ProfileUsername("demndevel"), + isOnline = false + ) + ), + messageResults = listOf( + MessageResult( + name = ProfileName("Finsi"), + messageText = "Some example text. Some example text. Some example text. Some example text. Some example text. Some example text. Some example text. " + ), + MessageResult( + name = ProfileName("Demn"), + messageText = "Some example text" + ), + MessageResult( + name = ProfileName("Finsi"), + messageText = "Some example text. Some example text. Some example text. Some example text. Some example text. Some example text. Some example text. " + ), + MessageResult( + name = ProfileName("Demn"), + messageText = "Some example text" + ), + MessageResult( + name = ProfileName("Finsi"), + messageText = "Some example text. Some example text. Some example text. Some example text. Some example text. Some example text. Some example text. " + ), + MessageResult( + name = ProfileName("Demn"), + messageText = "Some example text" + ), + ) + ), + modifier = Modifier.fillMaxSize() + ) } \ No newline at end of file diff --git a/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/states/SearchResultsState.kt b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/states/SearchResultsState.kt index 6d934a1..9bacaff 100644 --- a/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/states/SearchResultsState.kt +++ b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/states/SearchResultsState.kt @@ -14,10 +14,15 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import me.floow.chatssearch.ui.components.globalSearchUsersList import me.floow.chatssearch.ui.components.messageResultsList +import me.floow.chatssearch.uilogic.MessageResult import me.floow.chatssearch.uilogic.SearchUsersScreenUiState +import me.floow.chatssearch.uilogic.UserSearchResult +import me.floow.domain.values.ProfileName +import me.floow.domain.values.ProfileUsername @Composable fun SearchResultsState( @@ -54,4 +59,44 @@ fun SearchResultsState( ) } } +} + +@Preview +@Composable +private fun SearchResultsStatePreview() { + SearchResultsState( + state = SearchUsersScreenUiState.HasResults( + searchField = "test", + userResults = listOf( + UserSearchResult( + name = ProfileName("Demn"), + username = ProfileUsername("demndevel"), + isOnline = false + ) + ), + messageResults = listOf( + MessageResult( + name = ProfileName("Finsi"), + messageText = "Some example text. Some example text. Some example text. Some example text. Some example text. Some example text. Some example text. " + ), + MessageResult( + name = ProfileName("Demn"), + messageText = "Some example text" + ), + MessageResult( + name = ProfileName("Finsi"), + messageText = "Some example text. Some example text. Some example text. Some example text. Some example text. Some example text. Some example text. " + ), + MessageResult( + name = ProfileName("Demn"), + messageText = "Some example text" + ), + MessageResult( + name = ProfileName("Finsi"), + messageText = "Some example text. Some example text. Some example text. Some example text. Some example text. Some example text. Some example text. " + ) + ) + ), + Modifier.fillMaxSize() + ) } \ No newline at end of file From ee3b6480a25259c43b1a0e82947c995be28a3e1c Mon Sep 17 00:00:00 2001 From: demn Date: Sun, 10 Nov 2024 06:24:20 +0300 Subject: [PATCH 08/28] fix(chatssearch): remove global search block when there is no results --- .../ui/states/SearchResultsState.kt | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/states/SearchResultsState.kt b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/states/SearchResultsState.kt index 9bacaff..f1abc3c 100644 --- a/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/states/SearchResultsState.kt +++ b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/states/SearchResultsState.kt @@ -36,19 +36,23 @@ fun SearchResultsState( LazyColumn( modifier = Modifier.fillMaxSize(), ) { - globalSearchUsersList( - isExpanded = isGlobalUsersSearchExpanded, - onExpandedToggle = { isGlobalUsersSearchExpanded = !isGlobalUsersSearchExpanded }, - results = state.userResults, - onClick = { result -> - Toast.makeText(context, result.toString(), Toast.LENGTH_SHORT).show() - } - ) + if (state.userResults.isNotEmpty()) { + globalSearchUsersList( + isExpanded = isGlobalUsersSearchExpanded, + onExpandedToggle = { + isGlobalUsersSearchExpanded = !isGlobalUsersSearchExpanded + }, + results = state.userResults, + onClick = { result -> + Toast.makeText(context, result.toString(), Toast.LENGTH_SHORT).show() + } + ) - item { - Spacer(Modifier.height(12.dp)) + item { + Spacer(Modifier.height(12.dp)) - HorizontalDivider() + HorizontalDivider() + } } messageResultsList( From 4110becfa9b2225111a588eeb510a6b49d9aba60 Mon Sep 17 00:00:00 2001 From: demn Date: Sun, 10 Nov 2024 06:27:42 +0300 Subject: [PATCH 09/28] fix(login, profile): use consistent horizontal padding: 14 instead of 24 --- .../me/floow/login/ui/createprofile/components/EditState.kt | 2 +- .../profile/src/main/java/me/floow/profile/ui/edit/EditState.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/feature/login/src/main/java/me/floow/login/ui/createprofile/components/EditState.kt b/feature/login/src/main/java/me/floow/login/ui/createprofile/components/EditState.kt index 31dd5b8..8291357 100644 --- a/feature/login/src/main/java/me/floow/login/ui/createprofile/components/EditState.kt +++ b/feature/login/src/main/java/me/floow/login/ui/createprofile/components/EditState.kt @@ -40,7 +40,7 @@ fun EditState( ) { Column( modifier = modifier - .padding(24.dp) + .padding(14.dp) ) { Box( contentAlignment = Alignment.Center, diff --git a/feature/profile/src/main/java/me/floow/profile/ui/edit/EditState.kt b/feature/profile/src/main/java/me/floow/profile/ui/edit/EditState.kt index afea00b..0b6982e 100644 --- a/feature/profile/src/main/java/me/floow/profile/ui/edit/EditState.kt +++ b/feature/profile/src/main/java/me/floow/profile/ui/edit/EditState.kt @@ -41,7 +41,7 @@ internal fun EditState( Column( modifier = Modifier .fillMaxSize() - .padding(24.dp) + .padding(14.dp) ) { Box( contentAlignment = Alignment.Center, From 561da225eb1e2e61345a208380ad09daf43aad48 Mon Sep 17 00:00:00 2001 From: demn Date: Sun, 10 Nov 2024 11:07:27 +0300 Subject: [PATCH 10/28] refactor(uikit), feat(uikit): add new font, feat(chats): implement mock chats ui + vm --- .../main/java/me/floow/app/MainActivity.kt | 7 +- .../me/floow/app/navigation/FlowNavHost.kt | 5 +- .../uikit/components/topbar/ProfileTopBar.kt | 2 +- .../topbar/TitleTopBarWithActionButton.kt | 2 +- .../TitleTopBarWithActionButtonWithNavBack.kt | 2 +- .../main/java/me/floow/uikit/theme/Theme.kt | 9 +- feature/chats/build.gradle.kts | 74 +++---- .../main/java/me/floow/chats/ChatsRoute.kt | 41 ++++ .../java/me/floow/chats/di/chatsModule.kt | 9 + .../main/java/me/floow/chats/ui/ChatsRoute.kt | 21 -- .../java/me/floow/chats/ui/ChatsScreen.kt | 61 ------ .../me/floow/chats/ui/chats/ChatsScreen.kt | 105 ++++++++++ .../chats/ui/chats/components/ChatListItem.kt | 192 ++++++++++++++++++ .../chats/ui/chats/components/ChatsList.kt | 36 ++++ .../chats/ui/chats/states/HasDataState.kt | 27 +++ .../java/me/floow/chats/uilogic/chats/Chat.kt | 22 ++ .../chats/uilogic/chats/ChatsScreenUiState.kt | 13 ++ .../uilogic/chats/ChatsScreenViewModel.kt | 58 ++++++ .../uilogic/chats/generateRandomChats.kt | 73 +++++++ .../main/res/drawable/chat_mention_icon.xml | 15 ++ .../src/main/res/drawable/chat_muted_icon.xml | 13 ++ .../src/main/res/drawable/chat_read_icon.xml | 13 ++ .../ui/components/MessageResult.kt | 3 +- .../ui/components/UserGlobalSearchResult.kt | 3 +- .../summary/AboutMeProfileSummaryPage.kt | 2 +- .../AvatarUsernameProfileSummaryPage.kt | 2 +- 26 files changed, 681 insertions(+), 129 deletions(-) create mode 100644 feature/chats/src/main/java/me/floow/chats/ChatsRoute.kt create mode 100644 feature/chats/src/main/java/me/floow/chats/di/chatsModule.kt delete mode 100644 feature/chats/src/main/java/me/floow/chats/ui/ChatsRoute.kt delete mode 100644 feature/chats/src/main/java/me/floow/chats/ui/ChatsScreen.kt create mode 100644 feature/chats/src/main/java/me/floow/chats/ui/chats/ChatsScreen.kt create mode 100644 feature/chats/src/main/java/me/floow/chats/ui/chats/components/ChatListItem.kt create mode 100644 feature/chats/src/main/java/me/floow/chats/ui/chats/components/ChatsList.kt create mode 100644 feature/chats/src/main/java/me/floow/chats/ui/chats/states/HasDataState.kt create mode 100644 feature/chats/src/main/java/me/floow/chats/uilogic/chats/Chat.kt create mode 100644 feature/chats/src/main/java/me/floow/chats/uilogic/chats/ChatsScreenUiState.kt create mode 100644 feature/chats/src/main/java/me/floow/chats/uilogic/chats/ChatsScreenViewModel.kt create mode 100644 feature/chats/src/main/java/me/floow/chats/uilogic/chats/generateRandomChats.kt create mode 100644 feature/chats/src/main/res/drawable/chat_mention_icon.xml create mode 100644 feature/chats/src/main/res/drawable/chat_muted_icon.xml create mode 100644 feature/chats/src/main/res/drawable/chat_read_icon.xml diff --git a/app/src/main/java/me/floow/app/MainActivity.kt b/app/src/main/java/me/floow/app/MainActivity.kt index 38dfff8..c05c322 100644 --- a/app/src/main/java/me/floow/app/MainActivity.kt +++ b/app/src/main/java/me/floow/app/MainActivity.kt @@ -26,6 +26,7 @@ import me.floow.app.di.mockModule import me.floow.app.navigation.AuthDestinationsCluster import me.floow.app.navigation.MainDestinationsCluster import me.floow.app.ui.App +import me.floow.chats.di.chatsModule import me.floow.domain.auth.AuthenticationManager import me.floow.login.di.loginModule import me.floow.profile.di.profileModule @@ -61,7 +62,8 @@ class MainActivity : ComponentActivity() { mockModule, loginModule, profileModule, - usersearchModule + usersearchModule, + chatsModule ) } else { modules( @@ -74,7 +76,8 @@ class MainActivity : ComponentActivity() { mockModule, loginModule, profileModule, - usersearchModule + usersearchModule, + chatsModule ) } } diff --git a/app/src/main/java/me/floow/app/navigation/FlowNavHost.kt b/app/src/main/java/me/floow/app/navigation/FlowNavHost.kt index 4d31224..b64affb 100644 --- a/app/src/main/java/me/floow/app/navigation/FlowNavHost.kt +++ b/app/src/main/java/me/floow/app/navigation/FlowNavHost.kt @@ -16,7 +16,8 @@ import androidx.navigation.compose.navigation import androidx.navigation.navDeepLink import androidx.navigation.toRoute import me.floow.chatssearch.ui.SearchUsersRoute -import me.floow.chats.ui.ChatsRoute +import me.floow.chats.ChatsRoute +import me.floow.chats.uilogic.chats.ChatsScreenViewModel import me.floow.feed.ui.FeedRoute import me.floow.login.ui.createprofile.CreateProfileRoute import me.floow.login.ui.login.LoginRoute @@ -24,6 +25,7 @@ import me.floow.profile.ui.edit.EditProfileRoute import me.floow.profile.ui.edit.EditProfileRouteInitialData import me.floow.profile.ui.profile.ProfileRoute import org.koin.androidx.compose.koinViewModel +import org.koin.compose.koinInject @Composable fun FlowNavHost( @@ -156,6 +158,7 @@ fun FlowNavHost( onSearchClick = { navController.navigate(SearchUsersScreen) }, + vm = koinInject(), modifier = modifier ) } diff --git a/core/uikit/src/main/java/me/floow/uikit/components/topbar/ProfileTopBar.kt b/core/uikit/src/main/java/me/floow/uikit/components/topbar/ProfileTopBar.kt index 20d94da..3840e66 100644 --- a/core/uikit/src/main/java/me/floow/uikit/components/topbar/ProfileTopBar.kt +++ b/core/uikit/src/main/java/me/floow/uikit/components/topbar/ProfileTopBar.kt @@ -42,7 +42,7 @@ fun ProfileTopBar( Column { Text( text = profileUsername, - style = LocalTypography.current.titleMedium + style = LocalTypography.current.titleLarge ) Text( diff --git a/core/uikit/src/main/java/me/floow/uikit/components/topbar/TitleTopBarWithActionButton.kt b/core/uikit/src/main/java/me/floow/uikit/components/topbar/TitleTopBarWithActionButton.kt index 6b26bb6..6e8fc5a 100644 --- a/core/uikit/src/main/java/me/floow/uikit/components/topbar/TitleTopBarWithActionButton.kt +++ b/core/uikit/src/main/java/me/floow/uikit/components/topbar/TitleTopBarWithActionButton.kt @@ -34,7 +34,7 @@ fun TitleTopBarWithActionButton( Text( text = titleText, overflow = TextOverflow.Ellipsis, - style = LocalTypography.current.titleMedium, + style = LocalTypography.current.titleLarge, maxLines = 1, modifier = Modifier.weight(1f) ) diff --git a/core/uikit/src/main/java/me/floow/uikit/components/topbar/TitleTopBarWithActionButtonWithNavBack.kt b/core/uikit/src/main/java/me/floow/uikit/components/topbar/TitleTopBarWithActionButtonWithNavBack.kt index cc2e6c4..99bfb7f 100644 --- a/core/uikit/src/main/java/me/floow/uikit/components/topbar/TitleTopBarWithActionButtonWithNavBack.kt +++ b/core/uikit/src/main/java/me/floow/uikit/components/topbar/TitleTopBarWithActionButtonWithNavBack.kt @@ -55,7 +55,7 @@ fun TitleTopBarWithActionButtonWithNavBack( Text( text = titleText, - style = LocalTypography.current.titleMedium + style = LocalTypography.current.titleLarge ) Spacer(Modifier.weight(1f)) diff --git a/core/uikit/src/main/java/me/floow/uikit/theme/Theme.kt b/core/uikit/src/main/java/me/floow/uikit/theme/Theme.kt index 229e5cc..d7aec7e 100644 --- a/core/uikit/src/main/java/me/floow/uikit/theme/Theme.kt +++ b/core/uikit/src/main/java/me/floow/uikit/theme/Theme.kt @@ -17,13 +17,20 @@ import androidx.core.view.WindowCompat @Immutable data class FlowTypography( - val titleMedium: TextStyle = TextStyle( + val titleLarge: TextStyle = TextStyle( fontFamily = roboto, fontWeight = FontWeight.Black, fontSize = 20.sp, lineHeight = 24.sp, letterSpacing = 0.38.sp ), + val titleMedium: TextStyle = TextStyle( + fontFamily = roboto, + fontWeight = FontWeight.Medium, + fontSize = 16.sp, + lineHeight = 20.sp, + letterSpacing = (-0.32).sp + ), val bodyMedium: TextStyle = TextStyle( fontFamily = roboto, fontWeight = FontWeight.Normal, diff --git a/feature/chats/build.gradle.kts b/feature/chats/build.gradle.kts index 272efdc..39e89a0 100644 --- a/feature/chats/build.gradle.kts +++ b/feature/chats/build.gradle.kts @@ -1,46 +1,52 @@ @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed plugins { - alias(libs.plugins.androidLibrary) - alias(libs.plugins.kotlinAndroid) - alias(libs.plugins.composeCompiler) + alias(libs.plugins.androidLibrary) + alias(libs.plugins.kotlinAndroid) + alias(libs.plugins.composeCompiler) } android { - namespace = "me.flowme.chats" - compileSdk = 34 - - defaultConfig { - minSdk = 28 - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") - } - } - buildFeatures { compose = true } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = "1.8" - } + namespace = "me.flowme.chats" + compileSdk = 34 + + defaultConfig { + minSdk = 28 + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles("consumer-rules.pro") + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + buildFeatures { compose = true } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = "1.8" + } } dependencies { - implementation(project(":core:uikit")) + implementation(project(":core:uikit")) + implementation(project(":core:domain")) - implementation(libs.appcompat) - implementation(libs.ui.tooling) - implementation(libs.ui.tooling.preview) + implementation(libs.appcompat) - testImplementation(libs.junit) + api(platform(libs.koin.bom)) + api(libs.koin.core) + api(libs.koin.android) - androidTestImplementation(libs.androidx.test.ext.junit) - androidTestImplementation(libs.espresso.core) + testImplementation(libs.junit) + + androidTestImplementation(libs.androidx.test.ext.junit) + androidTestImplementation(libs.espresso.core) } \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/ChatsRoute.kt b/feature/chats/src/main/java/me/floow/chats/ChatsRoute.kt new file mode 100644 index 0000000..faeb1cb --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/ChatsRoute.kt @@ -0,0 +1,41 @@ +package me.floow.chats + +import android.widget.Toast +import androidx.compose.material3.NavigationBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import me.floow.chats.ui.chats.ChatsScreen +import me.floow.chats.uilogic.chats.ChatsScreenViewModel +import me.floow.uikit.util.SetNavigationBarColor + +@Composable +fun ChatsRoute( + onSearchClick: () -> Unit, + vm: ChatsScreenViewModel, + modifier: Modifier = Modifier +) { + val state by vm.state.collectAsState() + val context = LocalContext.current + + LaunchedEffect(Unit) { + vm.load() + } + + ChatsScreen( + onSearchClick = onSearchClick, + state = state, + onChatClick = { + // TODO + Toast.makeText(context, it.toString(), Toast.LENGTH_SHORT).show() + }, + modifier = modifier + ) + + SetNavigationBarColor( + NavigationBarDefaults.containerColor + ) +} \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/di/chatsModule.kt b/feature/chats/src/main/java/me/floow/chats/di/chatsModule.kt new file mode 100644 index 0000000..0a4189e --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/di/chatsModule.kt @@ -0,0 +1,9 @@ +package me.floow.chats.di + +import me.floow.chats.uilogic.chats.ChatsScreenViewModel +import org.koin.core.module.dsl.viewModelOf +import org.koin.dsl.module + +val chatsModule = module { + viewModelOf(::ChatsScreenViewModel) +} \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/ui/ChatsRoute.kt b/feature/chats/src/main/java/me/floow/chats/ui/ChatsRoute.kt deleted file mode 100644 index 6252aa3..0000000 --- a/feature/chats/src/main/java/me/floow/chats/ui/ChatsRoute.kt +++ /dev/null @@ -1,21 +0,0 @@ -package me.floow.chats.ui - -import androidx.compose.material3.NavigationBarDefaults -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import me.floow.uikit.util.SetNavigationBarColor - -@Composable -fun ChatsRoute( - onSearchClick: () -> Unit, - modifier: Modifier = Modifier -) { - ChatsScreen( - onSearchClick = onSearchClick, - modifier = modifier - ) - - SetNavigationBarColor( - NavigationBarDefaults.containerColor - ) -} \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/ui/ChatsScreen.kt b/feature/chats/src/main/java/me/floow/chats/ui/ChatsScreen.kt deleted file mode 100644 index 97ec6e2..0000000 --- a/feature/chats/src/main/java/me/floow/chats/ui/ChatsScreen.kt +++ /dev/null @@ -1,61 +0,0 @@ -package me.floow.chats.ui - -import androidx.compose.foundation.layout.* -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import me.floow.uikit.R -import me.floow.uikit.components.topbar.TitleTopBarWithActionButton - -@Composable -internal fun ChatsScreen( - onSearchClick: () -> Unit, - modifier: Modifier = Modifier -) { - Scaffold( - topBar = { - TitleTopBarWithActionButton( - titleText = "Чаты", - onActionButtonClick = onSearchClick, - icon = { - Icon( - painterResource(R.drawable.search_icon), - null - ) - } - ) - }, - modifier = modifier - ) { innerPadding -> - Column( - Modifier - .padding(innerPadding) - .padding(8.dp) - ) { - Spacer(Modifier.height(24.dp)) - - Text( - text = "Flow!", - style = MaterialTheme.typography.titleLarge, - ) - - Spacer(Modifier.height(4.dp)) - - Text( - text = "Chats" - ) - } - } -} - -@Preview -@Composable -private fun ChatsScreenPreview() { - ChatsScreen( - onSearchClick = {}, - modifier = Modifier.fillMaxSize() - ) -} \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chats/ChatsScreen.kt b/feature/chats/src/main/java/me/floow/chats/ui/chats/ChatsScreen.kt new file mode 100644 index 0000000..8066ae1 --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/ui/chats/ChatsScreen.kt @@ -0,0 +1,105 @@ +package me.floow.chats.ui.chats + +import androidx.compose.foundation.layout.* +import androidx.compose.material3.* +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import me.floow.chats.ui.chats.states.HasDataState +import me.floow.chats.uilogic.chats.Chat +import me.floow.chats.uilogic.chats.ChatsScreenUiState +import me.floow.uikit.R +import me.floow.uikit.components.topbar.TitleTopBarWithActionButton + +@Composable +internal fun ChatsScreen( + onSearchClick: () -> Unit, + state: ChatsScreenUiState, + onChatClick: (Chat) -> Unit, + modifier: Modifier = Modifier +) { + Scaffold( + topBar = { + TitleTopBarWithActionButton( + titleText = "Чаты", + onActionButtonClick = onSearchClick, + icon = { + Icon( + painterResource(R.drawable.search_icon), + null + ) + } + ) + }, + contentWindowInsets = WindowInsets(0.dp), + modifier = modifier + ) { innerPadding -> + val commonModifier = Modifier + .fillMaxSize() + .padding(innerPadding) + + when (state) { + is ChatsScreenUiState.Loading -> { + Box(commonModifier, Alignment.Center) { + CircularProgressIndicator() + } + } + + is ChatsScreenUiState.Error -> { + Box(commonModifier, Alignment.Center) { + Text(text = "error") + } + } + + is ChatsScreenUiState.NoChats -> { + Box(commonModifier, Alignment.Center) { + Text(text = "no chats sorry") + } + } + + is ChatsScreenUiState.HasData -> { + HasDataState( + state = state, + onChatClick = onChatClick, + modifier = commonModifier + ) + } + } + } +} + +@Preview +@Composable +private fun ChatsScreenPreview_Loading() { + ChatsScreen( + onSearchClick = {}, + state = ChatsScreenUiState.Loading, + onChatClick = {}, + modifier = Modifier.fillMaxSize() + ) +} + +@Preview +@Composable +private fun ChatsScreenPreview_Error() { + ChatsScreen( + onSearchClick = {}, + state = ChatsScreenUiState.Error, + onChatClick = {}, + modifier = Modifier.fillMaxSize() + ) +} + +@Preview +@Composable +private fun ChatsScreenPreview_HasData() { + ChatsScreen( + onSearchClick = {}, + state = ChatsScreenUiState.Loading, + onChatClick = {}, + modifier = Modifier.fillMaxSize() + ) +} \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chats/components/ChatListItem.kt b/feature/chats/src/main/java/me/floow/chats/ui/chats/components/ChatListItem.kt new file mode 100644 index 0000000..0ca87a6 --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/ui/chats/components/ChatListItem.kt @@ -0,0 +1,192 @@ +package me.floow.chats.ui.chats.components + +import android.net.Uri +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import me.floow.chats.uilogic.chats.Chat +import me.floow.chats.uilogic.chats.LastSentMessageState +import me.floow.domain.values.ProfileName +import me.floow.uikit.theme.LocalTypography +import me.floow.uikit.util.ComponentPreviewBox +import me.flowme.chats.R +import java.time.LocalDateTime +import java.time.format.DateTimeFormatter + +@Composable +internal fun ChatListItem( + chat: Chat, + onClick: (Chat) -> Unit, + modifier: Modifier = Modifier +) { + Row( + modifier = modifier + .clickable { onClick(chat) } + .padding(horizontal = 14.dp, vertical = 8.dp) + .height(62.dp), + verticalAlignment = Alignment.CenterVertically + ) { + AvatarBox( + avatarUrl = chat.avatarUrl, + isOnline = chat.isOnline, + modifier = Modifier + ) + + Spacer(Modifier.width(12.dp)) + + Column( + modifier = Modifier + ) { + Row( + modifier = Modifier, + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = chat.name.value, + style = LocalTypography.current.titleMedium + ) + + if (chat.chatMuted) { + Spacer(Modifier.width(4.dp)) + + Icon( + painter = painterResource(R.drawable.chat_muted_icon), + contentDescription = null, + tint = Color.Unspecified + ) + } + + Spacer(Modifier.weight(1f)) + + if (chat.lastSentMessageState != null) { + when (chat.lastSentMessageState) { + LastSentMessageState.Sent -> { + // TODO + } + + LastSentMessageState.Read -> { + Icon( + painter = painterResource(R.drawable.chat_read_icon), + contentDescription = null, + tint = Color.Unspecified + ) + } + } + } + + Text( + text = chat.lastMessageDateTime.format(DateTimeFormatter.ofPattern("HH:mm")), + style = LocalTypography.current.labelMedium + ) + } + + Spacer(Modifier.height(4.dp)) + + Row( + modifier = Modifier, + verticalAlignment = Alignment.CenterVertically + ) { + if (chat.attachedMediaUrl != null) { + Box( + Modifier + .clip(RoundedCornerShape(4.dp)) + .background(Color.LightGray) + .size(18.dp) + ) + + Spacer(Modifier.width(6.dp)) + } + + Text( + text = chat.lastMessageText, + style = LocalTypography.current.bodyMedium, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + color = MaterialTheme.colorScheme.secondary + ) + + Spacer(Modifier.weight(1f)) + + if (chat.hasMention) { + Icon( + painter = painterResource(R.drawable.chat_mention_icon), + contentDescription = null, + tint = Color.Unspecified + ) + } + } + } + } +} + +@Composable +private fun AvatarBox(avatarUrl: Uri?, isOnline: Boolean, modifier: Modifier.Companion) { + // todo isOnline handling + + Box(modifier = modifier) { + Box( + Modifier + .size(54.dp) + .clip(CircleShape) + .background(Color.LightGray) + ) + + if (isOnline) { + Box( + Modifier + .clip(CircleShape) + .background(MaterialTheme.colorScheme.background) + .padding(3.dp) + .clip(CircleShape) + .size(12.dp) + .background(Color(0xFF5ACD30)) + .align(Alignment.BottomEnd) + ) + } + } +} + +@Preview +@Composable +private fun ChatListItemPreview() { + ComponentPreviewBox(Modifier.fillMaxSize()) { + ChatListItem( + chat = Chat( + name = ProfileName("Demn"), + lastMessageText = "Some message text idk", + isOnline = true, + lastMessageDateTime = LocalDateTime.now().minusHours(3), + avatarUrl = null, + attachedMediaUrl = null, + chatMuted = true, + hasMention = false, + lastSentMessageState = LastSentMessageState.Read + ), + onClick = {}, + modifier = Modifier.fillMaxWidth() + ) + } +} \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chats/components/ChatsList.kt b/feature/chats/src/main/java/me/floow/chats/ui/chats/components/ChatsList.kt new file mode 100644 index 0000000..920aaf5 --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/ui/chats/components/ChatsList.kt @@ -0,0 +1,36 @@ +package me.floow.chats.ui.chats.components + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import me.floow.chats.uilogic.chats.Chat + +@Composable +internal fun ChatsList( + chats: List, + onChatClick: (Chat) -> Unit, + modifier: Modifier = Modifier +) { + LazyColumn( + modifier = modifier, + ) { + item { + Spacer(Modifier.height(8.dp)) + } + + items(chats) { chat -> + ChatListItem( + chat = chat, + onClick = onChatClick, + modifier = Modifier + .fillMaxWidth() + ) + } + } +} \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chats/states/HasDataState.kt b/feature/chats/src/main/java/me/floow/chats/ui/chats/states/HasDataState.kt new file mode 100644 index 0000000..fe6dc4d --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/ui/chats/states/HasDataState.kt @@ -0,0 +1,27 @@ +package me.floow.chats.ui.chats.states + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import me.floow.chats.ui.chats.components.ChatsList +import me.floow.chats.uilogic.chats.Chat +import me.floow.chats.uilogic.chats.ChatsScreenUiState + +@Composable +fun HasDataState( + state: ChatsScreenUiState.HasData, + onChatClick: (Chat) -> Unit, + modifier: Modifier = Modifier +) { + Column(modifier) { + ChatsList( + chats = state.chats, + onChatClick = onChatClick, + modifier = Modifier.fillMaxWidth() + ) + } +} \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/uilogic/chats/Chat.kt b/feature/chats/src/main/java/me/floow/chats/uilogic/chats/Chat.kt new file mode 100644 index 0000000..e2080d2 --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/uilogic/chats/Chat.kt @@ -0,0 +1,22 @@ +package me.floow.chats.uilogic.chats + +import android.net.Uri +import me.floow.domain.values.ProfileName +import java.time.LocalDateTime + +enum class LastSentMessageState { + Sent, + Read, +} + +data class Chat( + val name: ProfileName, + val lastMessageText: String, + val lastMessageDateTime: LocalDateTime, + val isOnline: Boolean, + val hasMention: Boolean, + val chatMuted: Boolean, + val avatarUrl: Uri?, + val attachedMediaUrl: Uri?, + val lastSentMessageState: LastSentMessageState? +) \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/uilogic/chats/ChatsScreenUiState.kt b/feature/chats/src/main/java/me/floow/chats/uilogic/chats/ChatsScreenUiState.kt new file mode 100644 index 0000000..a71b218 --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/uilogic/chats/ChatsScreenUiState.kt @@ -0,0 +1,13 @@ +package me.floow.chats.uilogic.chats + +interface ChatsScreenUiState { + data object Loading : ChatsScreenUiState + + data object NoChats : ChatsScreenUiState + + data object Error : ChatsScreenUiState + + data class HasData( + val chats: List + ) : ChatsScreenUiState +} \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/uilogic/chats/ChatsScreenViewModel.kt b/feature/chats/src/main/java/me/floow/chats/uilogic/chats/ChatsScreenViewModel.kt new file mode 100644 index 0000000..49acb69 --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/uilogic/chats/ChatsScreenViewModel.kt @@ -0,0 +1,58 @@ +package me.floow.chats.uilogic.chats + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch + +private data class ChatsScreenVmState( + val isLoading: Boolean = false, + val isError: Boolean = false, + val chats: List? = null +) { + fun toUiState(): ChatsScreenUiState { + if (isLoading) return ChatsScreenUiState.Loading + + return if (chats != null && !isError) { + ChatsScreenUiState.HasData(chats) + } else { + ChatsScreenUiState.Error + } + } +} + +class ChatsScreenViewModel : ViewModel() { + private val _state = MutableStateFlow(ChatsScreenVmState()) + + val state: StateFlow = _state + .map(ChatsScreenVmState::toUiState) + .stateIn(viewModelScope, SharingStarted.Eagerly, ChatsScreenUiState.Loading) + + fun load() { + viewModelScope.launch { + _state.update { + it.copy( + isLoading = true, + isError = false, + ) + } + + delay(600L) + + + _state.update { + it.copy( + isLoading = false, + isError = false, + chats = generateRandomChats(50) + ) + } + } + } +} \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/uilogic/chats/generateRandomChats.kt b/feature/chats/src/main/java/me/floow/chats/uilogic/chats/generateRandomChats.kt new file mode 100644 index 0000000..a26cf93 --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/uilogic/chats/generateRandomChats.kt @@ -0,0 +1,73 @@ +package me.floow.chats.uilogic.chats + +import android.net.Uri +import me.floow.domain.values.ProfileName +import java.time.LocalDateTime +import kotlin.random.Random + +fun generateRandomChats(n: Int): List { + val firstNames = listOf( + "John", + "Jane", + "Alice", + "Bob", + "Charlie", + "Demn", + "Finsi", + "Mixno", + "Max", + "Vlad", + "Andrew", + "Саша", + "котик" + ) + val messages = listOf( + "Hello!", + "How are you?", + "See you later!", + "Good morning!", + "Have a nice day!", + "Смотри какие пельмени!", + "ИМБИЩЕЕЕЕ!!!", + "На видео Threads, написанный на Compose, а не приложение фейсбука", + "Try out the fastest crypto-to-crypto \uD83D\uDD01 Swaps in Telegram and share the \$10,000 prize fund in our contest for all users! Learn more ›" + ) + + val chats = mutableListOf() + + for (i in 1..n) { + val profileName = ProfileName( + value = firstNames.random(), + ) + val lastMessageText = messages.random() + val lastMessageDateTime = LocalDateTime.now() + .minusDays(Random.nextLong(0, 30)) + .minusHours(Random.nextLong(0, 24)) + .minusMinutes(Random.nextLong(0, 60)) + .minusSeconds(Random.nextLong(0, 60)) + val isOnline = Random.nextBoolean() + val hasMention = Random.nextBoolean() + val chatMuted = Random.nextBoolean() + val avatarUrl = if (Random.nextBoolean()) Uri.parse("https://example.com/avatar") else null + val attachedMediaUrl = + if (Random.nextBoolean()) Uri.parse("https://example.com/media") else null + val lastSentMessageState = + if (Random.nextBoolean()) LastSentMessageState.entries.toTypedArray().random() else null + + val chat = Chat( + name = profileName, + lastMessageText = lastMessageText, + lastMessageDateTime = lastMessageDateTime, + isOnline = isOnline, + hasMention = hasMention, + chatMuted = chatMuted, + avatarUrl = avatarUrl, + attachedMediaUrl = attachedMediaUrl, + lastSentMessageState = lastSentMessageState + ) + + chats.add(chat) + } + + return chats +} \ No newline at end of file diff --git a/feature/chats/src/main/res/drawable/chat_mention_icon.xml b/feature/chats/src/main/res/drawable/chat_mention_icon.xml new file mode 100644 index 0000000..21e0fbd --- /dev/null +++ b/feature/chats/src/main/res/drawable/chat_mention_icon.xml @@ -0,0 +1,15 @@ + + + + diff --git a/feature/chats/src/main/res/drawable/chat_muted_icon.xml b/feature/chats/src/main/res/drawable/chat_muted_icon.xml new file mode 100644 index 0000000..b6f5443 --- /dev/null +++ b/feature/chats/src/main/res/drawable/chat_muted_icon.xml @@ -0,0 +1,13 @@ + + + + diff --git a/feature/chats/src/main/res/drawable/chat_read_icon.xml b/feature/chats/src/main/res/drawable/chat_read_icon.xml new file mode 100644 index 0000000..866a71b --- /dev/null +++ b/feature/chats/src/main/res/drawable/chat_read_icon.xml @@ -0,0 +1,13 @@ + + + diff --git a/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/MessageResult.kt b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/MessageResult.kt index e5bc14a..ca111e1 100644 --- a/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/MessageResult.kt +++ b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/MessageResult.kt @@ -56,8 +56,7 @@ fun MessageResult( ) { Text( text = result.name.value, - style = LocalTypography.current.bodyMedium, - fontWeight = FontWeight.Bold + style = LocalTypography.current.titleMedium, ) Spacer(Modifier.height(2.dp)) diff --git a/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/UserGlobalSearchResult.kt b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/UserGlobalSearchResult.kt index 5ee6b50..54767b2 100644 --- a/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/UserGlobalSearchResult.kt +++ b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/UserGlobalSearchResult.kt @@ -58,8 +58,7 @@ fun UserGlobalSearchResult( ) { Text( text = userSearchResult.name.value, - style = LocalTypography.current.bodyMedium, - fontWeight = FontWeight.Bold + style = LocalTypography.current.titleMedium, ) Spacer(Modifier.height(2.dp)) diff --git a/feature/profile/src/main/java/me/floow/profile/ui/profile/segments/summary/AboutMeProfileSummaryPage.kt b/feature/profile/src/main/java/me/floow/profile/ui/profile/segments/summary/AboutMeProfileSummaryPage.kt index 7c2e505..f7e7db6 100644 --- a/feature/profile/src/main/java/me/floow/profile/ui/profile/segments/summary/AboutMeProfileSummaryPage.kt +++ b/feature/profile/src/main/java/me/floow/profile/ui/profile/segments/summary/AboutMeProfileSummaryPage.kt @@ -22,7 +22,7 @@ internal fun AboutMeProfileSummaryPage(description: String?, modifier: Modifier ) { Text( text = "обо мне", - style = LocalTypography.current.titleMedium, + style = LocalTypography.current.titleLarge, color = Color.White, ) diff --git a/feature/profile/src/main/java/me/floow/profile/ui/profile/segments/summary/AvatarUsernameProfileSummaryPage.kt b/feature/profile/src/main/java/me/floow/profile/ui/profile/segments/summary/AvatarUsernameProfileSummaryPage.kt index fe7f145..938bbf2 100644 --- a/feature/profile/src/main/java/me/floow/profile/ui/profile/segments/summary/AvatarUsernameProfileSummaryPage.kt +++ b/feature/profile/src/main/java/me/floow/profile/ui/profile/segments/summary/AvatarUsernameProfileSummaryPage.kt @@ -45,7 +45,7 @@ internal fun AvatarUsernameProfileSummaryPage( Text( text = displayName ?: stringResource(R.string.no_display_name), - style = LocalTypography.current.titleMedium, + style = LocalTypography.current.titleLarge, color = Color.White, ) From ab1dde797fbd3327cdbad71a98addef1c402a055 Mon Sep 17 00:00:00 2001 From: demn Date: Mon, 11 Nov 2024 17:18:18 +0300 Subject: [PATCH 11/28] fix(chats): change avatar box size --- .../java/me/floow/chats/ui/chats/components/ChatListItem.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chats/components/ChatListItem.kt b/feature/chats/src/main/java/me/floow/chats/ui/chats/components/ChatListItem.kt index 0ca87a6..601c3b5 100644 --- a/feature/chats/src/main/java/me/floow/chats/ui/chats/components/ChatListItem.kt +++ b/feature/chats/src/main/java/me/floow/chats/ui/chats/components/ChatListItem.kt @@ -149,7 +149,7 @@ private fun AvatarBox(avatarUrl: Uri?, isOnline: Boolean, modifier: Modifier.Com Box(modifier = modifier) { Box( Modifier - .size(54.dp) + .size(56.dp) .clip(CircleShape) .background(Color.LightGray) ) From 691a6e9746db3587d16a9cb70622e5ffab2a825d Mon Sep 17 00:00:00 2001 From: demn Date: Mon, 11 Nov 2024 17:18:54 +0300 Subject: [PATCH 12/28] fix(chats): remove outdated TODO from ChatListItem --- .../java/me/floow/chats/ui/chats/components/ChatListItem.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chats/components/ChatListItem.kt b/feature/chats/src/main/java/me/floow/chats/ui/chats/components/ChatListItem.kt index 601c3b5..8d4bfff 100644 --- a/feature/chats/src/main/java/me/floow/chats/ui/chats/components/ChatListItem.kt +++ b/feature/chats/src/main/java/me/floow/chats/ui/chats/components/ChatListItem.kt @@ -144,8 +144,6 @@ internal fun ChatListItem( @Composable private fun AvatarBox(avatarUrl: Uri?, isOnline: Boolean, modifier: Modifier.Companion) { - // todo isOnline handling - Box(modifier = modifier) { Box( Modifier From b7a61dfb68f83cd6dae4c3dde13d8b8d8a59ede0 Mon Sep 17 00:00:00 2001 From: demn Date: Sat, 16 Nov 2024 19:39:35 +0300 Subject: [PATCH 13/28] feat(chats): implement basic Chat screen implementation with navigation --- .../me/floow/app/navigation/FlowNavHost.kt | 29 ++- .../floow/app/navigation/NavigationGraph.kt | 9 +- core/uikit/build.gradle.kts | 2 + .../main/java/me/floow/uikit/theme/Theme.kt | 14 + .../src/main/res/drawable/dropdown_icon.xml | 10 + .../src/main/res/drawable/reply_icon.xml | 20 ++ .../src/main/res/drawable/reply_out_icon.xml | 24 ++ .../src/main/java/me/floow/chats/ChatRoute.kt | 50 ++++ .../main/java/me/floow/chats/ChatsRoute.kt | 10 +- .../java/me/floow/chats/di/chatsModule.kt | 2 + .../java/me/floow/chats/ui/chat/ChatScreen.kt | 83 ++++++ .../chats/ui/chat/components/ChatBubble.kt | 244 ++++++++++++++++++ .../ui/chat/components/ChatMessageField.kt | 9 + .../ui/chat/components/ChatScreenTopBar.kt | 113 ++++++++ .../chats/ui/chat/components/CurrentReply.kt | 83 ++++++ .../chats/ui/chat/components/DateSeparator.kt | 43 +++ .../floow/chats/ui/chat/states/ErrorState.kt | 19 ++ .../chats/ui/chat/states/HasDataState.kt | 75 ++++++ .../chats/ui/chat/states/LoadingState.kt | 19 ++ .../chats/ui/chat/states/NoMessagesState.kt | 19 ++ .../chats/ui/chats/components/ChatListItem.kt | 1 + .../floow/chats/uilogic/chat/ChatMessage.kt | 42 +++ .../chats/uilogic/chat/ChatScreenUiState.kt | 49 ++++ .../chats/uilogic/chat/ChatScreenViewModel.kt | 118 +++++++++ .../uilogic/chat/generateChatMessages.kt | 55 ++++ .../java/me/floow/chats/uilogic/chats/Chat.kt | 1 + .../uilogic/chats/generateRandomChats.kt | 1 + .../res/drawable/current_reply_close_icon.xml | 14 + .../chats/src/main/res/values-ru/strings.xml | 4 + feature/chats/src/main/res/values/strings.xml | 4 + gradle/libs.versions.toml | 3 + 31 files changed, 1160 insertions(+), 9 deletions(-) create mode 100644 core/uikit/src/main/res/drawable/dropdown_icon.xml create mode 100644 core/uikit/src/main/res/drawable/reply_icon.xml create mode 100644 core/uikit/src/main/res/drawable/reply_out_icon.xml create mode 100644 feature/chats/src/main/java/me/floow/chats/ChatRoute.kt create mode 100644 feature/chats/src/main/java/me/floow/chats/ui/chat/ChatScreen.kt create mode 100644 feature/chats/src/main/java/me/floow/chats/ui/chat/components/ChatBubble.kt create mode 100644 feature/chats/src/main/java/me/floow/chats/ui/chat/components/ChatMessageField.kt create mode 100644 feature/chats/src/main/java/me/floow/chats/ui/chat/components/ChatScreenTopBar.kt create mode 100644 feature/chats/src/main/java/me/floow/chats/ui/chat/components/CurrentReply.kt create mode 100644 feature/chats/src/main/java/me/floow/chats/ui/chat/components/DateSeparator.kt create mode 100644 feature/chats/src/main/java/me/floow/chats/ui/chat/states/ErrorState.kt create mode 100644 feature/chats/src/main/java/me/floow/chats/ui/chat/states/HasDataState.kt create mode 100644 feature/chats/src/main/java/me/floow/chats/ui/chat/states/LoadingState.kt create mode 100644 feature/chats/src/main/java/me/floow/chats/ui/chat/states/NoMessagesState.kt create mode 100644 feature/chats/src/main/java/me/floow/chats/uilogic/chat/ChatMessage.kt create mode 100644 feature/chats/src/main/java/me/floow/chats/uilogic/chat/ChatScreenUiState.kt create mode 100644 feature/chats/src/main/java/me/floow/chats/uilogic/chat/ChatScreenViewModel.kt create mode 100644 feature/chats/src/main/java/me/floow/chats/uilogic/chat/generateChatMessages.kt create mode 100644 feature/chats/src/main/res/drawable/current_reply_close_icon.xml create mode 100644 feature/chats/src/main/res/values-ru/strings.xml create mode 100644 feature/chats/src/main/res/values/strings.xml diff --git a/app/src/main/java/me/floow/app/navigation/FlowNavHost.kt b/app/src/main/java/me/floow/app/navigation/FlowNavHost.kt index b64affb..4f51971 100644 --- a/app/src/main/java/me/floow/app/navigation/FlowNavHost.kt +++ b/app/src/main/java/me/floow/app/navigation/FlowNavHost.kt @@ -2,6 +2,7 @@ package me.floow.app.navigation import android.content.Context import android.content.Intent +import android.net.Uri import android.widget.Toast import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize @@ -15,9 +16,10 @@ import androidx.navigation.compose.composable import androidx.navigation.compose.navigation import androidx.navigation.navDeepLink import androidx.navigation.toRoute +import me.floow.chats.ChatRoute +import me.floow.chats.ChatRouteInitialData import me.floow.chatssearch.ui.SearchUsersRoute import me.floow.chats.ChatsRoute -import me.floow.chats.uilogic.chats.ChatsScreenViewModel import me.floow.feed.ui.FeedRoute import me.floow.login.ui.createprofile.CreateProfileRoute import me.floow.login.ui.login.LoginRoute @@ -155,6 +157,15 @@ fun FlowNavHost( composable { ChatsRoute( + onChatClick = { chatToNavigate -> + navController.navigate( + ChatScreen( + interlocutorId = chatToNavigate.id, + interlocutorName = chatToNavigate.name.value, + interlocutorAvatarUri = chatToNavigate.avatarUrl.toString() + ) + ) + }, onSearchClick = { navController.navigate(SearchUsersScreen) }, @@ -163,6 +174,22 @@ fun FlowNavHost( ) } + composable { + val backStackEntry = navController.currentBackStackEntry + val chatScreen: ChatScreen? = + backStackEntry?.toRoute() + + ChatRoute( + initialData = ChatRouteInitialData( + chatInterlocutorId = chatScreen?.interlocutorId ?: -1L, + chatInterlocutorName = chatScreen?.interlocutorName ?: "", + chatInterlocutorAvatarUrl = chatScreen?.interlocutorAvatarUri?.let { Uri.parse(it) } + ), + vm = koinViewModel(), + modifier = modifier + ) + } + composable { SearchUsersRoute( onBackClick = { diff --git a/app/src/main/java/me/floow/app/navigation/NavigationGraph.kt b/app/src/main/java/me/floow/app/navigation/NavigationGraph.kt index 0669120..8690009 100644 --- a/app/src/main/java/me/floow/app/navigation/NavigationGraph.kt +++ b/app/src/main/java/me/floow/app/navigation/NavigationGraph.kt @@ -23,6 +23,13 @@ data object LoginScreen : NavigationRoute @Serializable data object FeedScreen : NavigationRoute +@Serializable +data class ChatScreen( + val interlocutorId: Long = 0L, + val interlocutorName: String = "", + val interlocutorAvatarUri: String? = null, +) : NavigationRoute + @Serializable data object ChatsScreen : NavigationRoute @@ -44,7 +51,7 @@ data class EditProfileScreen( val bottomNavigationItems = listOf( BottomNavigationItem( - route = FeedScreen,//NavigationItem.Main.Feed.route, + route = FeedScreen, titleId = R.string.feed_bottom_nav_label, drawableIconId = me.floow.uikit.R.drawable.feed_icon, ), diff --git a/core/uikit/build.gradle.kts b/core/uikit/build.gradle.kts index 7d47440..c75b475 100644 --- a/core/uikit/build.gradle.kts +++ b/core/uikit/build.gradle.kts @@ -49,6 +49,8 @@ dependencies { api(libs.coil) api(libs.coil.compose) + api(libs.textflow.material3) + testImplementation(libs.junit) androidTestImplementation(libs.androidx.test.ext.junit) diff --git a/core/uikit/src/main/java/me/floow/uikit/theme/Theme.kt b/core/uikit/src/main/java/me/floow/uikit/theme/Theme.kt index d7aec7e..6df0f95 100644 --- a/core/uikit/src/main/java/me/floow/uikit/theme/Theme.kt +++ b/core/uikit/src/main/java/me/floow/uikit/theme/Theme.kt @@ -38,6 +38,20 @@ data class FlowTypography( lineHeight = 20.sp, letterSpacing = (-0.24).sp ), + val captionSmall: TextStyle = TextStyle( + fontFamily = roboto, + fontWeight = FontWeight.Normal, + fontSize = 9.sp, + lineHeight = 14.sp, + letterSpacing = 0.2.sp + ), + val captionMedium: TextStyle = TextStyle( + fontFamily = roboto, + fontWeight = FontWeight.Normal, + fontSize = 13.sp, + lineHeight = 14.sp, + letterSpacing = 0.sp + ), val labelMedium: TextStyle = TextStyle( fontFamily = roboto, fontWeight = FontWeight.Normal, diff --git a/core/uikit/src/main/res/drawable/dropdown_icon.xml b/core/uikit/src/main/res/drawable/dropdown_icon.xml new file mode 100644 index 0000000..450a6e0 --- /dev/null +++ b/core/uikit/src/main/res/drawable/dropdown_icon.xml @@ -0,0 +1,10 @@ + + + diff --git a/core/uikit/src/main/res/drawable/reply_icon.xml b/core/uikit/src/main/res/drawable/reply_icon.xml new file mode 100644 index 0000000..60bb971 --- /dev/null +++ b/core/uikit/src/main/res/drawable/reply_icon.xml @@ -0,0 +1,20 @@ + + + + diff --git a/core/uikit/src/main/res/drawable/reply_out_icon.xml b/core/uikit/src/main/res/drawable/reply_out_icon.xml new file mode 100644 index 0000000..0f19f3b --- /dev/null +++ b/core/uikit/src/main/res/drawable/reply_out_icon.xml @@ -0,0 +1,24 @@ + + + + + + + diff --git a/feature/chats/src/main/java/me/floow/chats/ChatRoute.kt b/feature/chats/src/main/java/me/floow/chats/ChatRoute.kt new file mode 100644 index 0000000..5eed151 --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/ChatRoute.kt @@ -0,0 +1,50 @@ +package me.floow.chats + +import android.net.Uri +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import me.floow.chats.ui.chat.ChatScreen +import me.floow.chats.uilogic.chat.ChatScreenViewModel +import me.floow.uikit.util.SetNavigationBarColor + +data class ChatRouteInitialData( + val chatInterlocutorId: Long, + val chatInterlocutorName: String, + val chatInterlocutorAvatarUrl: Uri? +) + +@Composable +fun ChatRoute( + initialData: ChatRouteInitialData, + vm: ChatScreenViewModel, + modifier: Modifier = Modifier +) { + LaunchedEffect(Unit) { + vm.setInitialData( + initialData.chatInterlocutorId, + initialData.chatInterlocutorName, + initialData.chatInterlocutorAvatarUrl, + ) + + vm.loadData() + } + + val state by vm.state.collectAsState() + + ChatScreen( + onProfileClick = {}, + onTopBarDropdownClick = {}, + onReplyClick = {}, + onChatBubbleClick = {}, + state = state, + modifier = modifier + ) + + SetNavigationBarColor( + MaterialTheme.colorScheme.background + ) +} \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/ChatsRoute.kt b/feature/chats/src/main/java/me/floow/chats/ChatsRoute.kt index faeb1cb..651c60f 100644 --- a/feature/chats/src/main/java/me/floow/chats/ChatsRoute.kt +++ b/feature/chats/src/main/java/me/floow/chats/ChatsRoute.kt @@ -1,25 +1,24 @@ package me.floow.chats -import android.widget.Toast import androidx.compose.material3.NavigationBarDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext import me.floow.chats.ui.chats.ChatsScreen +import me.floow.chats.uilogic.chats.Chat import me.floow.chats.uilogic.chats.ChatsScreenViewModel import me.floow.uikit.util.SetNavigationBarColor @Composable fun ChatsRoute( onSearchClick: () -> Unit, + onChatClick: (Chat) -> Unit, vm: ChatsScreenViewModel, modifier: Modifier = Modifier ) { val state by vm.state.collectAsState() - val context = LocalContext.current LaunchedEffect(Unit) { vm.load() @@ -28,10 +27,7 @@ fun ChatsRoute( ChatsScreen( onSearchClick = onSearchClick, state = state, - onChatClick = { - // TODO - Toast.makeText(context, it.toString(), Toast.LENGTH_SHORT).show() - }, + onChatClick = onChatClick, modifier = modifier ) diff --git a/feature/chats/src/main/java/me/floow/chats/di/chatsModule.kt b/feature/chats/src/main/java/me/floow/chats/di/chatsModule.kt index 0a4189e..420e247 100644 --- a/feature/chats/src/main/java/me/floow/chats/di/chatsModule.kt +++ b/feature/chats/src/main/java/me/floow/chats/di/chatsModule.kt @@ -1,9 +1,11 @@ package me.floow.chats.di import me.floow.chats.uilogic.chats.ChatsScreenViewModel +import me.floow.chats.uilogic.chat.ChatScreenViewModel import org.koin.core.module.dsl.viewModelOf import org.koin.dsl.module val chatsModule = module { viewModelOf(::ChatsScreenViewModel) + viewModelOf(::ChatScreenViewModel) } \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chat/ChatScreen.kt b/feature/chats/src/main/java/me/floow/chats/ui/chat/ChatScreen.kt new file mode 100644 index 0000000..789c5f8 --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/ui/chat/ChatScreen.kt @@ -0,0 +1,83 @@ +package me.floow.chats.ui.chat + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.SideEffect +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import me.floow.chats.ui.chat.components.ChatScreenTopBar +import me.floow.chats.ui.chat.states.ErrorState +import me.floow.chats.ui.chat.states.HasDataState +import me.floow.chats.ui.chat.states.LoadingState +import me.floow.chats.ui.chat.states.NoMessagesState +import me.floow.chats.uilogic.chat.ChatMessage +import me.floow.chats.uilogic.chat.ChatScreenUiState +import me.floow.uikit.R +import me.floow.uikit.theme.ElevanagonShape + +@Composable +fun ChatScreen( + onProfileClick: () -> Unit, + onTopBarDropdownClick: () -> Unit, + onChatBubbleClick: (ChatMessage) -> Unit, + onReplyClick: (ChatMessage) -> Unit, + state: ChatScreenUiState, + modifier: Modifier = Modifier +) { + Scaffold( + topBar = { + ChatScreenTopBar( + profileName = state.chatInterlocutorName, + isOnline = false, + profileAvatar = { modifier -> + Image( + painterResource(R.drawable.cute_girl), + null, + modifier + .clip(ElevanagonShape), + ) + }, + onDropdownClick = onTopBarDropdownClick, + onProfileClick = onProfileClick, + modifier = Modifier + ) + }, + contentWindowInsets = WindowInsets(0.dp), + modifier = modifier + ) { innerPadding -> + val commonModifier = Modifier + .padding(innerPadding) + .fillMaxSize() + + when (state) { + is ChatScreenUiState.Loading -> { + LoadingState(commonModifier) + } + + is ChatScreenUiState.Error -> { + ErrorState(commonModifier) + } + + is ChatScreenUiState.NoMessages -> { + NoMessagesState(commonModifier) + } + + is ChatScreenUiState.HasData -> { + HasDataState( + state = state, + onChatBubbleClick = onChatBubbleClick, + onReplyClick = onReplyClick, + modifier = commonModifier + ) + } + } + } +} diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chat/components/ChatBubble.kt b/feature/chats/src/main/java/me/floow/chats/ui/chat/components/ChatBubble.kt new file mode 100644 index 0000000..dd352ee --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/ui/chat/components/ChatBubble.kt @@ -0,0 +1,244 @@ +package me.floow.chats.ui.chat.components + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.IntrinsicSize +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.widthIn +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +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.unit.dp +import me.floow.chats.uilogic.chat.ChatMessage +import me.floow.chats.uilogic.chat.ChatReplyMessage +import me.floow.chats.uilogic.chat.PrimaryInMessage +import me.floow.chats.uilogic.chat.PrimaryOutMessage +import me.floow.chats.uilogic.chat.ReplyInMessage +import me.floow.chats.uilogic.chat.ReplyOutMessage +import me.floow.uikit.R +import me.floow.uikit.theme.LocalTypography +import me.floow.uikit.util.ComponentPreviewBox +import java.time.LocalDateTime +import java.time.format.DateTimeFormatter + +data class ChatBubbleColors( + val backgroundColor: Color, + val borderColor: Color, + val textColor: Color, + val timeColor: Color, + val replyColor: Color, +) { + companion object { + val Default: ChatBubbleColors + @Composable get() = ChatBubbleColors( + backgroundColor = MaterialTheme.colorScheme.inversePrimary, + borderColor = Color(0xFFBEBEBE), + textColor = MaterialTheme.colorScheme.onBackground, + timeColor = MaterialTheme.colorScheme.onBackground, + replyColor = Color(0xFFBEBEBE), + ) + + val Outlined: ChatBubbleColors + @Composable get() = ChatBubbleColors( + backgroundColor = MaterialTheme.colorScheme.background, + borderColor = Color(0xFFBEBEBE), + textColor = MaterialTheme.colorScheme.onBackground, + timeColor = Color(0xFFBEBEBE), + replyColor = Color(0xFFBEBEBE), + ) + } +} + +@Composable +fun ChatBubble( + chatMessage: ChatMessage, + onClick: (ChatMessage) -> Unit, + onReplyClick: (ChatMessage) -> Unit, + modifier: Modifier = Modifier +) { + val isReply: Boolean = chatMessage is ChatReplyMessage + val isOut: Boolean = chatMessage is PrimaryOutMessage || chatMessage is ReplyOutMessage + + val colors = if (!isOut) ChatBubbleColors.Outlined else ChatBubbleColors.Default + + Column( + horizontalAlignment = if (isOut) Alignment.End else Alignment.Start, + modifier = modifier, + ) { + Column( + modifier = Modifier + .clip(RoundedCornerShape(20.dp)) + .clickable { onClick(chatMessage) } + .background(colors.backgroundColor) + .addBorderIfIn(isOut, colors) + .padding(vertical = 8.dp, horizontal = 10.dp) + .widthIn(74.dp, 324.dp) + .width(IntrinsicSize.Max) + ) { + Text( + text = chatMessage.messageText, + color = colors.textColor, + style = LocalTypography.current.bodyMedium, + modifier = Modifier + ) + + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.End, + ) { + Text( + text = chatMessage.dateTime.format(DateTimeFormatter.ofPattern("hh:mm")), + color = colors.timeColor, + style = LocalTypography.current.labelMedium, + textAlign = TextAlign.End, + ) + } + } + + if (chatMessage is ChatReplyMessage) { + Spacer(Modifier.height(3.dp)) + + Row( + horizontalArrangement = if (isOut) Arrangement.End else Arrangement.Start, + modifier = Modifier + .width(324.dp) + ) { + ReplyContent( + replyMessageText = chatMessage.replyMessageText, + color = colors.replyColor, + modifier = Modifier + .height(25.dp) + .clickable { onReplyClick(chatMessage) } + ) + } + } + } +} + +private fun Modifier.addBorderIfIn(out: Boolean, colors: ChatBubbleColors): Modifier { + return if (out) this + else this.then(Modifier.border(1.dp, colors.borderColor, RoundedCornerShape(20.dp))) +} + +@Composable +private fun ReplyContent( + replyMessageText: String, + color: Color, + modifier: Modifier = Modifier +) { + Row( + modifier = modifier, + verticalAlignment = Alignment.CenterVertically + ) { + Icon( + painter = painterResource(R.drawable.reply_out_icon), + contentDescription = null, + tint = color, + ) + + Spacer(Modifier.width(6.dp)) + + Text( + text = replyMessageText, + color = color, + style = LocalTypography.current.bodyMedium, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + modifier = Modifier + ) + } +} + +@Preview +@Composable +fun ChatBubblePreview_OutReply() { + val mockMessage = ReplyOutMessage( + id = 1L, + messageText = "This is a reply out message", + dateTime = LocalDateTime.now(), + replyMessageId = 2L, + replyMessageText = "This is the message being replied to" + ) + + ComponentPreviewBox(Modifier.fillMaxWidth()) { + ChatBubble( + chatMessage = mockMessage, + onClick = {}, + onReplyClick = {} + ) + } +} + +@Preview +@Composable +fun ChatBubblePreview_InReply() { + val mockMessage = ReplyInMessage( + id = 1L, + replyMessageId = 2L, + replyMessageText = "This is the message being replied to", + messageText = "This is a reply in message", + dateTime = LocalDateTime.now() + ) + + ComponentPreviewBox(Modifier.fillMaxWidth()) { + ChatBubble( + chatMessage = mockMessage, + onClick = {}, + onReplyClick = {} + ) + } +} + +@Preview +@Composable +fun ChatBubblePreview_OutPrimary() { + val mockMessage = PrimaryOutMessage( + id = 1L, + messageText = "This is a primary out message", + dateTime = LocalDateTime.now() + ) + + ComponentPreviewBox(Modifier.fillMaxWidth()) { + ChatBubble( + chatMessage = mockMessage, + onClick = {}, + onReplyClick = {} + ) + } +} + +@Preview +@Composable +fun ChatBubblePreview_InPrimary() { + val mockMessage = PrimaryInMessage( + id = 1L, + messageText = "This is a primary in message. By the way, This is a primary in message. Lorem ipsum dolor sit amet.. Yeahhh", + dateTime = LocalDateTime.now() + ) + + ComponentPreviewBox(Modifier.fillMaxWidth()) { + ChatBubble( + chatMessage = mockMessage, + onClick = {}, + onReplyClick = {} + ) + } +} \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chat/components/ChatMessageField.kt b/feature/chats/src/main/java/me/floow/chats/ui/chat/components/ChatMessageField.kt new file mode 100644 index 0000000..fc5bc98 --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/ui/chat/components/ChatMessageField.kt @@ -0,0 +1,9 @@ +package me.floow.chats.ui.chat.components + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier + +@Composable +fun ChatMessageField(modifier: Modifier = Modifier) { + // TODO +} \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chat/components/ChatScreenTopBar.kt b/feature/chats/src/main/java/me/floow/chats/ui/chat/components/ChatScreenTopBar.kt new file mode 100644 index 0000000..70d3e01 --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/ui/chat/components/ChatScreenTopBar.kt @@ -0,0 +1,113 @@ +package me.floow.chats.ui.chat.components + +import android.net.Uri +import androidx.compose.foundation.Image +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import me.floow.uikit.R +import me.floow.uikit.components.buttons.WideOutlinedIconButton +import me.floow.uikit.theme.ElevanagonShape +import me.floow.uikit.theme.LocalTypography +import me.floow.uikit.util.ComponentPreviewBox + +@Composable +fun ChatScreenTopBar( + profileName: String, + isOnline: Boolean, + profileAvatar: @Composable (Modifier) -> Unit, + onProfileClick: () -> Unit, + onDropdownClick: () -> Unit, + modifier: Modifier = Modifier +) { + Column(modifier) { + Row( + Modifier + .fillMaxWidth() + .height(80.dp) + .padding(horizontal = 24.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .clickable { onProfileClick() } + .weight(1f), + ) { + profileAvatar(Modifier.size(50.dp)) + + Spacer(Modifier.width(8.dp)) + + Column() { + Text( + text = profileName, + style = LocalTypography.current.titleLarge + ) + + Text( + text = stringResource(if (isOnline) R.string.online else R.string.offline), + color = MaterialTheme.colorScheme.onSurfaceVariant, + style = LocalTypography.current.bodyMedium + ) + } + + Spacer(Modifier.width(16.dp)) + } + + WideOutlinedIconButton( + onClick = onDropdownClick, + modifier = Modifier + ) { + Icon( + painterResource(R.drawable.dropdown_icon), + null + ) + } + } + + HorizontalDivider() + } +} + +@Preview +@Composable +private fun ChatScreenTopBarPreview() { + ComponentPreviewBox(Modifier.fillMaxSize()) { + ChatScreenTopBar( + profileName = "Alina", + isOnline = false, + profileAvatar = { modifier -> + Image( + painterResource(R.drawable.cute_girl), + null, + modifier + .clip(ElevanagonShape), + ) + }, + onDropdownClick = {}, + onProfileClick = {}, + modifier = Modifier + .fillMaxSize() + ) + } +} \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chat/components/CurrentReply.kt b/feature/chats/src/main/java/me/floow/chats/ui/chat/components/CurrentReply.kt new file mode 100644 index 0000000..f54cfe4 --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/ui/chat/components/CurrentReply.kt @@ -0,0 +1,83 @@ +package me.floow.chats.ui.chat.components + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import me.floow.uikit.theme.LocalTypography +import me.flowme.chats.R + +@Composable +fun CurrentReply( + userNameToReply: String, + replyMessageText: String, + onClose: () -> Unit, + onClick: () -> Unit, + modifier: Modifier = Modifier +) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = modifier + .clickable { onClick() } + .padding( + horizontal = 16.dp, + vertical = 8.dp + ) + ) { + Column( + modifier = Modifier + .weight(1f) + ) { + Text( + text = "${stringResource(R.string.in_reply_to)} $userNameToReply", + style = LocalTypography.current.bodyMedium, + overflow = TextOverflow.Ellipsis, + fontWeight = FontWeight.Bold, + ) + + Text( + text = replyMessageText, + overflow = TextOverflow.Ellipsis, + style = LocalTypography.current.captionMedium, + color = Color.Gray + ) + } + + IconButton( + onClick = onClose + ) { + Icon( + painter = painterResource(R.drawable.current_reply_close_icon), + contentDescription = null + ) + } + } +} + +@Preview +@Composable +fun CurrentReplyPreview() { + CurrentReply( + userNameToReply = "Bogdan", + replyMessageText = "Компот не квасят, а культивируют. даун", + onClose = {}, + onClick = {}, + modifier = Modifier + .fillMaxWidth() + ) +} \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chat/components/DateSeparator.kt b/feature/chats/src/main/java/me/floow/chats/ui/chat/components/DateSeparator.kt new file mode 100644 index 0000000..fe88d81 --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/ui/chat/components/DateSeparator.kt @@ -0,0 +1,43 @@ +package me.floow.chats.ui.chat.components + +import android.view.RoundedCorner +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import me.floow.uikit.theme.LocalTypography +import me.floow.uikit.util.ComponentPreviewBox + +@Composable +fun DateSeparator( + text: String, + modifier: Modifier = Modifier +) { + Text( + text = text, + style = LocalTypography.current.labelMedium, + color = MaterialTheme.colorScheme.outline, + modifier = modifier + .border(1.dp, MaterialTheme.colorScheme.outline, RoundedCornerShape(20.dp)) + .padding( + horizontal = 10.dp, + vertical = 8.dp + ) + ) +} + +@Preview +@Composable +fun DateSeparatorPreview() { + ComponentPreviewBox { + DateSeparator( + text = "Today", + modifier = Modifier + ) + } +} \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chat/states/ErrorState.kt b/feature/chats/src/main/java/me/floow/chats/ui/chat/states/ErrorState.kt new file mode 100644 index 0000000..f0564fa --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/ui/chat/states/ErrorState.kt @@ -0,0 +1,19 @@ +package me.floow.chats.ui.chat.states + +import androidx.compose.foundation.layout.Box +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier + +@Composable +fun ErrorState(modifier: Modifier = Modifier) { + Box( + modifier = modifier, + contentAlignment = Alignment.Center + ) { + Text( + text = "error occured" + ) + } +} \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chat/states/HasDataState.kt b/feature/chats/src/main/java/me/floow/chats/ui/chat/states/HasDataState.kt new file mode 100644 index 0000000..8b8aaef --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/ui/chat/states/HasDataState.kt @@ -0,0 +1,75 @@ +package me.floow.chats.ui.chat.states + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import me.floow.chats.ui.chat.components.ChatBubble +import me.floow.chats.ui.chat.components.DateSeparator +import me.floow.chats.uilogic.chat.ChatMessage +import me.floow.chats.uilogic.chat.ChatScreenUiState +import me.floow.chats.uilogic.chat.PrimaryOutMessage +import me.floow.chats.uilogic.chat.ReplyOutMessage + +@Composable +fun HasDataState( + state: ChatScreenUiState.HasData, + onChatBubbleClick: (ChatMessage) -> Unit, + onReplyClick: (ChatMessage) -> Unit, + modifier: Modifier = Modifier +) { + Column( + modifier = modifier, + horizontalAlignment = Alignment.CenterHorizontally + ) { + LazyColumn( + modifier = Modifier + .fillMaxWidth() + .weight(1f) + ) { + item { + Spacer(Modifier.height(8.dp)) + + Row( + horizontalArrangement = Arrangement.Center, + modifier = Modifier.fillMaxWidth(), + ) { + DateSeparator( + text = "Today" // todo + ) + } + + Spacer(Modifier.height(8.dp)) + } + + items(state.messages) { message -> + val isOut: Boolean = message is PrimaryOutMessage || message is ReplyOutMessage + + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 14.dp), + horizontalArrangement = if (isOut) Arrangement.End else Arrangement.Start + ) { + ChatBubble( + chatMessage = message, + onClick = onChatBubbleClick, + onReplyClick = onReplyClick, + modifier = Modifier + ) + } + + Spacer(Modifier.height(8.dp)) + } + } + } +} \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chat/states/LoadingState.kt b/feature/chats/src/main/java/me/floow/chats/ui/chat/states/LoadingState.kt new file mode 100644 index 0000000..079827f --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/ui/chat/states/LoadingState.kt @@ -0,0 +1,19 @@ +package me.floow.chats.ui.chat.states + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.size +import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp + +@Composable +fun LoadingState(modifier: Modifier = Modifier) { + Box( + modifier = modifier, + contentAlignment = Alignment.Center + ) { + CircularProgressIndicator(Modifier.size(48.dp)) + } +} \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chat/states/NoMessagesState.kt b/feature/chats/src/main/java/me/floow/chats/ui/chat/states/NoMessagesState.kt new file mode 100644 index 0000000..3f39fc9 --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/ui/chat/states/NoMessagesState.kt @@ -0,0 +1,19 @@ +package me.floow.chats.ui.chat.states + +import androidx.compose.foundation.layout.Box +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier + +@Composable +fun NoMessagesState(modifier: Modifier = Modifier) { + Box( + modifier = modifier, + contentAlignment = Alignment.Center + ) { + Text( + text = "no messages im so sorry" + ) + } +} \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chats/components/ChatListItem.kt b/feature/chats/src/main/java/me/floow/chats/ui/chats/components/ChatListItem.kt index 8d4bfff..b29ffe4 100644 --- a/feature/chats/src/main/java/me/floow/chats/ui/chats/components/ChatListItem.kt +++ b/feature/chats/src/main/java/me/floow/chats/ui/chats/components/ChatListItem.kt @@ -173,6 +173,7 @@ private fun ChatListItemPreview() { ComponentPreviewBox(Modifier.fillMaxSize()) { ChatListItem( chat = Chat( + id = 2L, name = ProfileName("Demn"), lastMessageText = "Some message text idk", isOnline = true, diff --git a/feature/chats/src/main/java/me/floow/chats/uilogic/chat/ChatMessage.kt b/feature/chats/src/main/java/me/floow/chats/uilogic/chat/ChatMessage.kt new file mode 100644 index 0000000..afb501e --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/uilogic/chat/ChatMessage.kt @@ -0,0 +1,42 @@ +package me.floow.chats.uilogic.chat + +import java.time.LocalDateTime + +sealed interface ChatMessage { + val id: Long + val messageText: String + val dateTime: LocalDateTime +} + +interface ChatReplyMessage : ChatMessage { + val replyMessageId: Long + val replyMessageText: String +} + +data class PrimaryOutMessage( + override val id: Long, + override val messageText: String, + override val dateTime: LocalDateTime +) : ChatMessage + +data class ReplyOutMessage( + override val id: Long, + override val messageText: String, + override val dateTime: LocalDateTime, + override val replyMessageId: Long, + override val replyMessageText: String, +) : ChatReplyMessage + +data class PrimaryInMessage( + override val id: Long, + override val messageText: String, + override val dateTime: LocalDateTime +) : ChatMessage + +data class ReplyInMessage( + override val id: Long, + override val replyMessageId: Long, + override val replyMessageText: String, + override val messageText: String, + override val dateTime: LocalDateTime +) : ChatReplyMessage \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/uilogic/chat/ChatScreenUiState.kt b/feature/chats/src/main/java/me/floow/chats/uilogic/chat/ChatScreenUiState.kt new file mode 100644 index 0000000..7a1324d --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/uilogic/chat/ChatScreenUiState.kt @@ -0,0 +1,49 @@ +package me.floow.chats.uilogic.chat + +import android.net.Uri + +data class MessageFieldReply( + val replyId: Long, + val replyMessageText: String, +) + +interface ChatScreenUiState { + val chatInterlocutorId: Long + val chatInterlocutorName: String + val chatInterlocutorAvatarUrl: Uri? + val messageFieldValue: String + val messageFieldReply: MessageFieldReply? + + data class Loading( + override val chatInterlocutorId: Long, + override val chatInterlocutorAvatarUrl: Uri?, + override val messageFieldValue: String, + override val chatInterlocutorName: String, + override val messageFieldReply: MessageFieldReply?, + ) : ChatScreenUiState + + data class Error( + override val chatInterlocutorId: Long, + override val chatInterlocutorAvatarUrl: Uri?, + override val messageFieldValue: String, + override val chatInterlocutorName: String, + override val messageFieldReply: MessageFieldReply?, + ) : ChatScreenUiState + + data class NoMessages( + override val chatInterlocutorId: Long, + override val chatInterlocutorAvatarUrl: Uri?, + override val messageFieldValue: String, + override val chatInterlocutorName: String, + override val messageFieldReply: MessageFieldReply?, + ) : ChatScreenUiState + + data class HasData( + val messages: List, + override val chatInterlocutorId: Long, + override val chatInterlocutorAvatarUrl: Uri?, + override val messageFieldValue: String, + override val chatInterlocutorName: String, + override val messageFieldReply: MessageFieldReply?, + ) : ChatScreenUiState +} \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/uilogic/chat/ChatScreenViewModel.kt b/feature/chats/src/main/java/me/floow/chats/uilogic/chat/ChatScreenViewModel.kt new file mode 100644 index 0000000..da58db9 --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/uilogic/chat/ChatScreenViewModel.kt @@ -0,0 +1,118 @@ +package me.floow.chats.uilogic.chat + +import android.net.Uri +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch + +data class ChatScreenVmState( + val messageFieldValue: String = "", + val chatInterlocutorId: Long = -1L, + val chatInterlocutorName: String = "", + val chatInterlocutorAvatarUrl: Uri? = null, + val isLoading: Boolean = false, + val isError: Boolean = false, + val messages: List? = null, + val messageFieldReply: MessageFieldReply? = null +) { + fun toUiState(): ChatScreenUiState { + return when { + isLoading -> { + ChatScreenUiState.Loading( + chatInterlocutorId = chatInterlocutorId, + chatInterlocutorName = chatInterlocutorName, + chatInterlocutorAvatarUrl = chatInterlocutorAvatarUrl, + messageFieldValue = messageFieldValue, + messageFieldReply = messageFieldReply, + ) + } + + isError || messages == null -> { + ChatScreenUiState.Error( + chatInterlocutorId = chatInterlocutorId, + chatInterlocutorName = chatInterlocutorName, + chatInterlocutorAvatarUrl = chatInterlocutorAvatarUrl, + messageFieldValue = messageFieldValue, + messageFieldReply = messageFieldReply, + ) + } + + messages.isEmpty() -> { + ChatScreenUiState.NoMessages( + chatInterlocutorId = chatInterlocutorId, + chatInterlocutorName = chatInterlocutorName, + chatInterlocutorAvatarUrl = chatInterlocutorAvatarUrl, + messageFieldValue = messageFieldValue, + messageFieldReply = messageFieldReply, + ) + } + + else -> { + ChatScreenUiState.HasData( + chatInterlocutorId = chatInterlocutorId, + chatInterlocutorName = chatInterlocutorName, + chatInterlocutorAvatarUrl = chatInterlocutorAvatarUrl, + messageFieldValue = messageFieldValue, + messages = messages, + messageFieldReply = messageFieldReply, + ) + } + } + } +} + +class ChatScreenViewModel() : ViewModel() { + private val _state: MutableStateFlow = MutableStateFlow( + ChatScreenVmState() + ) + + val state: StateFlow = _state + .map(ChatScreenVmState::toUiState) + .stateIn( + viewModelScope, + SharingStarted.Eagerly, + ChatScreenUiState.Loading( + chatInterlocutorId = 0L, + chatInterlocutorAvatarUrl = null, + messageFieldValue = "", + chatInterlocutorName = "null", + messageFieldReply = null + ) + ) + + fun setInitialData(chatInterlocutorId: Long, chatInterlocutorName: String, chatInterlocutorAvatarUrl: Uri?) { + _state.update { + it.copy( + chatInterlocutorId = chatInterlocutorId, + chatInterlocutorName = chatInterlocutorName, + chatInterlocutorAvatarUrl = chatInterlocutorAvatarUrl + ) + } + } + + fun loadData() { + viewModelScope.launch { + _state.update { + it.copy( + isLoading = true + ) + } + + delay(300L) + + _state.update { + it.copy( + isLoading = false, + messages = generateChatMessages() + ) + } + } + } +} \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/uilogic/chat/generateChatMessages.kt b/feature/chats/src/main/java/me/floow/chats/uilogic/chat/generateChatMessages.kt new file mode 100644 index 0000000..406a015 --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/uilogic/chat/generateChatMessages.kt @@ -0,0 +1,55 @@ +package me.floow.chats.uilogic.chat + +import java.time.LocalDateTime +import kotlin.random.Random + +fun generateChatMessages(): List { + val messageTexts = listOf( + "Hello!", "How are you?", "ну молодец что", "Good morning!", "Good evening!", + "See you later!", "Thank you!", "You're welcome!", "Have a nice day!", + "Если нам снятся люди, предметы. Значит наши мозг знает как все это выглядит, значит он может это нарисовать не только в мозгу, но и на бумаге. Способный, просто не хочешь", + "Наш взгляд - человечен, а вот мир - бесчеловечен. Поэтому нужно нашим человеческим взглядом, обратить бесчеловечный мир в человечный", + "КАПЕЦ ТАМ СЕРГЕЙ ВОЛКОВ\nНИЦШЕ ЧИТАЛ", + "ИМБИЩЕЕЕЕ!!!", + "эээ", + "не", + "потом", + "да", + "ок", + "У меня и в тг видно бывает, но пропадает)) это скорей всего от фронталки съехало, но зачем там такое хз", + "Это в Яндекс музыке видно", + "Утечка слайдов из Google раскрыла некоторые из будущих планов компании в отношении чипсетов Tensor, в частности Tensor G6, и Google явно сосредоточилась на решении проблем с нагревом и эффективностью.", + "Для этого Tensor G6 будет физически меньше G5 (121 мм² против 105 мм²), а также будут удалены различные компоненты. Например, GPU откажется от поддержки трассировки лучей после того, как она появилась на поколение раньше. Среди других примеров - удаление ядер и уменьшение кэша по всему чипу. Разумеется, ничего из этого пока не утверждено.", + "Хз, кто-то из вас вообще предлагал медиа в s3 хранить" + ) + + val random = Random + val chatMessages = mutableListOf() + + for (i in 0..100) { + val id = i.toLong() + val messageText = messageTexts[random.nextInt(messageTexts.size)] + val dateTime = LocalDateTime.now().minusDays(random.nextLong(30)).withNano(0) + + when (i % 4) { + 0 -> { + val replyMessageId = (i - 1).toLong() + val replyMessageText = messageTexts[random.nextInt(messageTexts.size)] + chatMessages.add(ReplyInMessage(id, replyMessageId, replyMessageText, messageText, dateTime)) + } + 1 -> { + val replyMessageId = (i - 1).toLong() + val replyMessageText = messageTexts[random.nextInt(messageTexts.size)] + chatMessages.add(ReplyOutMessage(id, messageText, dateTime, replyMessageId, replyMessageText)) + } + 2 -> { + chatMessages.add(PrimaryInMessage(id, messageText, dateTime)) + } + 3 -> { + chatMessages.add(PrimaryOutMessage(id, messageText, dateTime)) + } + } + } + + return chatMessages +} \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/uilogic/chats/Chat.kt b/feature/chats/src/main/java/me/floow/chats/uilogic/chats/Chat.kt index e2080d2..75a01ba 100644 --- a/feature/chats/src/main/java/me/floow/chats/uilogic/chats/Chat.kt +++ b/feature/chats/src/main/java/me/floow/chats/uilogic/chats/Chat.kt @@ -10,6 +10,7 @@ enum class LastSentMessageState { } data class Chat( + val id: Long, val name: ProfileName, val lastMessageText: String, val lastMessageDateTime: LocalDateTime, diff --git a/feature/chats/src/main/java/me/floow/chats/uilogic/chats/generateRandomChats.kt b/feature/chats/src/main/java/me/floow/chats/uilogic/chats/generateRandomChats.kt index a26cf93..a86023f 100644 --- a/feature/chats/src/main/java/me/floow/chats/uilogic/chats/generateRandomChats.kt +++ b/feature/chats/src/main/java/me/floow/chats/uilogic/chats/generateRandomChats.kt @@ -55,6 +55,7 @@ fun generateRandomChats(n: Int): List { if (Random.nextBoolean()) LastSentMessageState.entries.toTypedArray().random() else null val chat = Chat( + id = Random.nextLong(1L, 100L), name = profileName, lastMessageText = lastMessageText, lastMessageDateTime = lastMessageDateTime, diff --git a/feature/chats/src/main/res/drawable/current_reply_close_icon.xml b/feature/chats/src/main/res/drawable/current_reply_close_icon.xml new file mode 100644 index 0000000..5aa9399 --- /dev/null +++ b/feature/chats/src/main/res/drawable/current_reply_close_icon.xml @@ -0,0 +1,14 @@ + + + + + + diff --git a/feature/chats/src/main/res/values-ru/strings.xml b/feature/chats/src/main/res/values-ru/strings.xml new file mode 100644 index 0000000..56307cb --- /dev/null +++ b/feature/chats/src/main/res/values-ru/strings.xml @@ -0,0 +1,4 @@ + + + В ответ + \ No newline at end of file diff --git a/feature/chats/src/main/res/values/strings.xml b/feature/chats/src/main/res/values/strings.xml new file mode 100644 index 0000000..e49e882 --- /dev/null +++ b/feature/chats/src/main/res/values/strings.xml @@ -0,0 +1,4 @@ + + + In reply to + \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 407fd14..8a0fcbe 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -29,6 +29,7 @@ room = "2.6.1" ksp = "2.0.20-1.0.24" coil = "2.7.0" materialVersion = "1.10.0" +textflow = "1.2.1" [libraries] androidx-browser = { group = "androidx.browser", name = "browser", version.ref = "androidx-browser" } @@ -79,6 +80,8 @@ coil = { group = "io.coil-kt", name = "coil", version.ref = "coil" } coil-compose = { group = "io.coil-kt", name = "coil-compose", version.ref = "coil" } material = { group = "com.google.android.material", name = "material", version.ref = "materialVersion" } +textflow-material3 = { group = "io.github.oleksandrbalan", name = "textflow-material3", version.ref = "textflow" } + [plugins] androidApplication = { id = "com.android.application", version.ref = "agp" } kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } From d9349031fd41b650911e8d8e87c1fa9f2a59b449 Mon Sep 17 00:00:00 2001 From: demn Date: Sat, 16 Nov 2024 19:59:21 +0300 Subject: [PATCH 14/28] feat&refactor(uikit, profile, login): implement common AvatarAndBackgroundPicker --- .../pickers/AvatarAndBackgroundPicker.kt | 91 ++++++++++++ .../profile_background_image_icon.xml | 17 +++ .../ui/createprofile/components/EditState.kt | 139 ++++++++---------- .../me/floow/profile/ui/edit/EditState.kt | 31 +--- 4 files changed, 174 insertions(+), 104 deletions(-) create mode 100644 core/uikit/src/main/java/me/floow/uikit/components/pickers/AvatarAndBackgroundPicker.kt create mode 100644 core/uikit/src/main/res/drawable/profile_background_image_icon.xml diff --git a/core/uikit/src/main/java/me/floow/uikit/components/pickers/AvatarAndBackgroundPicker.kt b/core/uikit/src/main/java/me/floow/uikit/components/pickers/AvatarAndBackgroundPicker.kt new file mode 100644 index 0000000..0d9e745 --- /dev/null +++ b/core/uikit/src/main/java/me/floow/uikit/components/pickers/AvatarAndBackgroundPicker.kt @@ -0,0 +1,91 @@ +package me.floow.uikit.components.pickers + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import me.floow.uikit.R +import me.floow.uikit.theme.ElevanagonShape +import me.floow.uikit.theme.LocalTypography + +@Composable +fun AvatarAndBackgroundPicker( + onAvatarPickerClick: () -> Unit, + onBackgroundPickerClick: () -> Unit, + modifier: Modifier = Modifier +) { + Box( + contentAlignment = Alignment.Center, + modifier = modifier + .fillMaxWidth() + .height(160.dp) + .clip(RoundedCornerShape(16.dp)) + .background(MaterialTheme.colorScheme.secondaryContainer) + .clickable { + onBackgroundPickerClick() + }, + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .align(Alignment.TopEnd) + .padding(14.dp) + ) { + Text( + text = "изменить фон", + style = LocalTypography.current.labelMedium, + color = Color.White + ) + + Spacer(Modifier.width(8.dp)) + + Icon( + painter = painterResource(R.drawable.profile_background_image_icon), + tint = Color.White, + contentDescription = null + ) + } + + Image( + painter = painterResource(me.floow.uikit.R.drawable.cute_girl), + contentDescription = null, + modifier = Modifier + .size(120.dp) + .clip(ElevanagonShape) + .clickable { + onAvatarPickerClick() + } + ) + + Icon( + painter = painterResource(me.floow.uikit.R.drawable.photo_icon), + contentDescription = null, + tint = Color.White, + ) + } +} + +@Preview +@Composable +fun AvatarAndBackgroundPickerPreview() { + AvatarAndBackgroundPicker({}, {}, Modifier.fillMaxWidth()) +} \ No newline at end of file diff --git a/core/uikit/src/main/res/drawable/profile_background_image_icon.xml b/core/uikit/src/main/res/drawable/profile_background_image_icon.xml new file mode 100644 index 0000000..64db391 --- /dev/null +++ b/core/uikit/src/main/res/drawable/profile_background_image_icon.xml @@ -0,0 +1,17 @@ + + + + + + diff --git a/feature/login/src/main/java/me/floow/login/ui/createprofile/components/EditState.kt b/feature/login/src/main/java/me/floow/login/ui/createprofile/components/EditState.kt index 8291357..77aac67 100644 --- a/feature/login/src/main/java/me/floow/login/ui/createprofile/components/EditState.kt +++ b/feature/login/src/main/java/me/floow/login/ui/createprofile/components/EditState.kt @@ -24,6 +24,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import me.floow.login.uilogic.CreateProfileState import me.floow.uikit.components.input.TextFieldWithAdditionalText +import me.floow.uikit.components.pickers.AvatarAndBackgroundPicker import me.floow.uikit.theme.ElevanagonShape import me.floow.uikit.theme.LocalTypography import me.floow.uikit.util.state.ValidatedField @@ -31,92 +32,72 @@ import me.flowme.login.R @Composable fun EditState( - state: CreateProfileState.Edit, - onAvatarPickerClick: () -> Unit = {}, - onNameChange: (String) -> Unit = {}, - onUsernameChange: (String) -> Unit = {}, - onBiographyChange: (String) -> Unit = {}, - modifier: Modifier = Modifier + state: CreateProfileState.Edit, + onAvatarPickerClick: () -> Unit = {}, + onNameChange: (String) -> Unit = {}, + onUsernameChange: (String) -> Unit = {}, + onBiographyChange: (String) -> Unit = {}, + modifier: Modifier = Modifier ) { - Column( - modifier = modifier - .padding(14.dp) - ) { - Box( - contentAlignment = Alignment.Center, - modifier = Modifier - .fillMaxWidth() - .height(160.dp) - .clip(RoundedCornerShape(16.dp)) - .background(MaterialTheme.colorScheme.secondaryContainer) - .clickable { - onAvatarPickerClick() - }, - ) { - Image( - painter = painterResource(me.floow.uikit.R.drawable.cute_girl), - contentDescription = null, - modifier = Modifier - .size(120.dp) - .clip(ElevanagonShape) - ) + Column( + modifier = modifier + .padding(14.dp) + ) { + AvatarAndBackgroundPicker( + onAvatarPickerClick = onAvatarPickerClick, + onBackgroundPickerClick = {}, + modifier = Modifier.fillMaxWidth() + ) - Icon( - painter = painterResource(me.floow.uikit.R.drawable.photo_icon), - contentDescription = null, - tint = Color.White, - ) - } + Spacer(Modifier.height(24.dp)) - Spacer(Modifier.height(24.dp)) + Text( + text = stringResource(R.string.information).uppercase(), + style = LocalTypography.current.labelMedium, + color = MaterialTheme.colorScheme.secondary, + ) - Text( - text = stringResource(R.string.information).uppercase(), - style = LocalTypography.current.labelMedium, - color = MaterialTheme.colorScheme.secondary, - ) + Spacer(Modifier.height(8.dp)) - Spacer(Modifier.height(8.dp)) + TextFieldWithAdditionalText( + additionalText = "", + title = stringResource(R.string.name), + value = state.name.value, + isError = state.name is ValidatedField.Invalid, + placeholder = stringResource(R.string.your_name), + onValueChange = onNameChange, + modifier = Modifier + .fillMaxWidth() + ) - TextFieldWithAdditionalText( - additionalText = "", - title = stringResource(R.string.name), - value = state.name.value, - isError = state.name is ValidatedField.Invalid, - placeholder = stringResource(R.string.your_name), - onValueChange = onNameChange, - modifier = Modifier - .fillMaxWidth() - ) + Spacer(Modifier.height(8.dp)) - Spacer(Modifier.height(8.dp)) + TextFieldWithAdditionalText( + additionalText = stringResource(R.string.username_additional_text), + title = stringResource(R.string.user_id), + value = state.username.value, + isError = state.username is ValidatedField.Invalid, + placeholder = stringResource(R.string.username), + onValueChange = onUsernameChange, + supportingText = stringResource(me.floow.uikit.R.string.username_field_supporting_text), + modifier = Modifier + .fillMaxWidth() + ) - TextFieldWithAdditionalText( - additionalText = stringResource(R.string.username_additional_text), - title = stringResource(R.string.user_id), - value = state.username.value, - isError = state.username is ValidatedField.Invalid, - placeholder = stringResource(R.string.username), - onValueChange = onUsernameChange, - supportingText = stringResource(me.floow.uikit.R.string.username_field_supporting_text), - modifier = Modifier - .fillMaxWidth() - ) + Spacer(Modifier.height(8.dp)) - Spacer(Modifier.height(8.dp)) - - TextFieldWithAdditionalText( - additionalText = "", - title = stringResource(R.string.about), - value = state.bio.value, - isError = state.bio is ValidatedField.Invalid, - placeholder = stringResource(R.string.write_something_about_you), - minLines = 3, - maxLines = 10, - singleLine = false, - onValueChange = onBiographyChange, - modifier = Modifier - .fillMaxWidth() - ) - } + TextFieldWithAdditionalText( + additionalText = "", + title = stringResource(R.string.about), + value = state.bio.value, + isError = state.bio is ValidatedField.Invalid, + placeholder = stringResource(R.string.write_something_about_you), + minLines = 3, + maxLines = 10, + singleLine = false, + onValueChange = onBiographyChange, + modifier = Modifier + .fillMaxWidth() + ) + } } \ No newline at end of file diff --git a/feature/profile/src/main/java/me/floow/profile/ui/edit/EditState.kt b/feature/profile/src/main/java/me/floow/profile/ui/edit/EditState.kt index 0b6982e..fecbb3a 100644 --- a/feature/profile/src/main/java/me/floow/profile/ui/edit/EditState.kt +++ b/feature/profile/src/main/java/me/floow/profile/ui/edit/EditState.kt @@ -26,6 +26,7 @@ import androidx.compose.ui.unit.dp import me.floow.profile.R import me.floow.profile.uilogic.edit.EditProfileState import me.floow.uikit.components.input.TextFieldWithAdditionalText +import me.floow.uikit.components.pickers.AvatarAndBackgroundPicker import me.floow.uikit.theme.ElevanagonShape import me.floow.uikit.theme.LocalTypography import me.floow.uikit.util.state.ValidatedField @@ -43,31 +44,11 @@ internal fun EditState( .fillMaxSize() .padding(14.dp) ) { - Box( - contentAlignment = Alignment.Center, - modifier = Modifier - .fillMaxWidth() - .height(160.dp) - .clip(RoundedCornerShape(16.dp)) - .background(MaterialTheme.colorScheme.secondaryContainer) - .clickable { - onAvatarPickerClick() - }, - ) { - Image( - painter = painterResource(me.floow.uikit.R.drawable.cute_girl), - contentDescription = null, - modifier = Modifier - .size(120.dp) - .clip(ElevanagonShape) - ) - - Icon( - painter = painterResource(me.floow.uikit.R.drawable.photo_icon), - contentDescription = null, - tint = Color.White, - ) - } + AvatarAndBackgroundPicker( + onAvatarPickerClick, + {}, + modifier = Modifier.fillMaxWidth() + ) Spacer(Modifier.height(24.dp)) From d628f8dbf74ea0d35187f013a1f2774cd237b30d Mon Sep 17 00:00:00 2001 From: demn Date: Sat, 16 Nov 2024 20:00:54 +0300 Subject: [PATCH 15/28] refactor(login): remove unused imports --- .../login/ui/createprofile/components/EditState.kt | 12 ------------ .../main/java/me/floow/profile/ui/edit/EditState.kt | 12 ------------ 2 files changed, 24 deletions(-) diff --git a/feature/login/src/main/java/me/floow/login/ui/createprofile/components/EditState.kt b/feature/login/src/main/java/me/floow/login/ui/createprofile/components/EditState.kt index 77aac67..07d025b 100644 --- a/feature/login/src/main/java/me/floow/login/ui/createprofile/components/EditState.kt +++ b/feature/login/src/main/java/me/floow/login/ui/createprofile/components/EditState.kt @@ -1,31 +1,19 @@ package me.floow.login.ui.createprofile.components -import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import me.floow.login.uilogic.CreateProfileState import me.floow.uikit.components.input.TextFieldWithAdditionalText import me.floow.uikit.components.pickers.AvatarAndBackgroundPicker -import me.floow.uikit.theme.ElevanagonShape import me.floow.uikit.theme.LocalTypography import me.floow.uikit.util.state.ValidatedField import me.flowme.login.R diff --git a/feature/profile/src/main/java/me/floow/profile/ui/edit/EditState.kt b/feature/profile/src/main/java/me/floow/profile/ui/edit/EditState.kt index fecbb3a..3965822 100644 --- a/feature/profile/src/main/java/me/floow/profile/ui/edit/EditState.kt +++ b/feature/profile/src/main/java/me/floow/profile/ui/edit/EditState.kt @@ -1,33 +1,21 @@ package me.floow.profile.ui.edit -import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import me.floow.profile.R import me.floow.profile.uilogic.edit.EditProfileState import me.floow.uikit.components.input.TextFieldWithAdditionalText import me.floow.uikit.components.pickers.AvatarAndBackgroundPicker -import me.floow.uikit.theme.ElevanagonShape import me.floow.uikit.theme.LocalTypography import me.floow.uikit.util.state.ValidatedField From f965423e5919af409626d82f08ceea2452c1fbbc Mon Sep 17 00:00:00 2001 From: demn Date: Sat, 16 Nov 2024 20:35:58 +0300 Subject: [PATCH 16/28] =?UTF-8?q?refactor(domain):=20value=20objects=20ref?= =?UTF-8?q?actoring=20=E2=80=93=20add=20createRaw=20with=20OptIn=20annotat?= =?UTF-8?q?ion=20and=20create=20functions=20to=20each,=20make=20primary=20?= =?UTF-8?q?constructors=20private?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floow/data/repos/ProfileRepositoryImpl.kt | 8 ++++--- .../sharedpref/ProfileCacheProviderImpl.kt | 8 ++++--- .../floow/domain/values/ProfileDescription.kt | 20 +++++++++++----- .../me/floow/domain/values/ProfileName.kt | 24 ++++++++++++------- .../me/floow/domain/values/ProfileUsername.kt | 24 ++++++++++++------- .../values/util/RawValueObjectCreate.kt | 6 +++++ .../floow/mock/data/MockProfileRepository.kt | 8 ++++--- .../chats/ui/chats/components/ChatListItem.kt | 2 +- .../uilogic/chats/generateRandomChats.kt | 2 +- .../floow/chatssearch/ui/SearchUsersScreen.kt | 16 ++++++------- .../ui/components/MessageResult.kt | 2 +- .../ui/components/UserGlobalSearchResult.kt | 4 ++-- .../ui/states/SearchResultsState.kt | 14 +++++------ .../uilogic/SearchUsersScreenViewModel.kt | 8 +++---- .../login/uilogic/CreateProfileViewModel.kt | 13 +++++----- .../uilogic/edit/EditProfileViewModel.kt | 14 +++++------ 16 files changed, 103 insertions(+), 70 deletions(-) create mode 100644 core/domain/src/main/java/me/floow/domain/values/util/RawValueObjectCreate.kt diff --git a/core/data/src/main/java/me/floow/data/repos/ProfileRepositoryImpl.kt b/core/data/src/main/java/me/floow/data/repos/ProfileRepositoryImpl.kt index 9f4fd17..7281ffd 100644 --- a/core/data/src/main/java/me/floow/data/repos/ProfileRepositoryImpl.kt +++ b/core/data/src/main/java/me/floow/data/repos/ProfileRepositoryImpl.kt @@ -13,11 +13,13 @@ import me.floow.domain.utils.Logger import me.floow.domain.values.ProfileDescription import me.floow.domain.values.ProfileName import me.floow.domain.values.ProfileUsername +import me.floow.domain.values.util.RawValueObjectCreate class ProfileRepositoryImpl( private val logger: Logger, private val profileApi: ProfileApi, ) : ProfileRepository { + @OptIn(RawValueObjectCreate::class) override suspend fun getSelfData(): GetDataResponse { return when (val selfData = profileApi.getSelf()) { is GetSelfResponse.Success -> { @@ -25,9 +27,9 @@ class ProfileRepositoryImpl( GetDataResponse.Success( SelfProfile( - name = selfData.name?.let { ProfileName(it) }, - username = selfData.username?.let { ProfileUsername(it) }, - description = selfData.biography?.let { ProfileDescription(it) }, + name = selfData.name?.let { ProfileName.createRaw(it) }, + username = selfData.username?.let { ProfileUsername.createRaw(it) }, + description = selfData.biography?.let { ProfileDescription.createRaw(it) }, avatarUrl = selfData.avatarUrl, ) ) diff --git a/core/database/src/main/java/me/floow/database/sharedpref/ProfileCacheProviderImpl.kt b/core/database/src/main/java/me/floow/database/sharedpref/ProfileCacheProviderImpl.kt index 029cae4..6516f3f 100644 --- a/core/database/src/main/java/me/floow/database/sharedpref/ProfileCacheProviderImpl.kt +++ b/core/database/src/main/java/me/floow/database/sharedpref/ProfileCacheProviderImpl.kt @@ -6,6 +6,7 @@ import me.floow.domain.models.SelfProfile import me.floow.domain.values.ProfileDescription import me.floow.domain.values.ProfileName import me.floow.domain.values.ProfileUsername +import me.floow.domain.values.util.RawValueObjectCreate class ProfileCacheProviderImpl( context: Context @@ -22,6 +23,7 @@ class ProfileCacheProviderImpl( private val sharedPreferences = context.getSharedPreferences(PROFILE_CACHE_NAME, Context.MODE_PRIVATE) + @OptIn(RawValueObjectCreate::class) override fun getSelfProfile(): SelfProfile { val name = sharedPreferences.getString(PROFILE_NAME, null) val username = sharedPreferences.getString(PROFILE_NAME, null) @@ -29,10 +31,10 @@ class ProfileCacheProviderImpl( val avatarUrl = sharedPreferences.getString(PROFILE_AVATAR_URL, null) return SelfProfile( - name = name?.let { ProfileName(it) }, + name = name?.let { ProfileName.createRaw(it) }, avatarUrl = avatarUrl, - username = username?.let { ProfileUsername(it) }, - description = bio?.let { ProfileDescription(it) } + username = username?.let { ProfileUsername.createRaw(it) }, + description = bio?.let { ProfileDescription.createRaw(it) } ) } diff --git a/core/domain/src/main/java/me/floow/domain/values/ProfileDescription.kt b/core/domain/src/main/java/me/floow/domain/values/ProfileDescription.kt index 1bb7f55..6d48795 100644 --- a/core/domain/src/main/java/me/floow/domain/values/ProfileDescription.kt +++ b/core/domain/src/main/java/me/floow/domain/values/ProfileDescription.kt @@ -1,23 +1,31 @@ package me.floow.domain.values +import me.floow.domain.values.util.RawValueObjectCreate import me.floow.domain.values.util.ValidationError import me.floow.domain.values.util.ValueValidationResult @JvmInline -value class ProfileDescription( +value class ProfileDescription private constructor( val value: String ) { - init { - check(value.length <= 140) - } - companion object { - fun create(value: String): ValueValidationResult { + fun create(value: String): ProfileDescription { + check(value.length <= 140) + + return ProfileDescription(value) + } + + fun createWithValidation(value: String): ValueValidationResult { return if (value.length > 140) { ValueValidationResult.Invalid(ValidationError.TooLarge) } else { ValueValidationResult.Valid(ProfileDescription(value)) } } + + @RawValueObjectCreate + fun createRaw(value: String): ProfileDescription { + return ProfileDescription(value) + } } } diff --git a/core/domain/src/main/java/me/floow/domain/values/ProfileName.kt b/core/domain/src/main/java/me/floow/domain/values/ProfileName.kt index 320d93e..52f7fa9 100644 --- a/core/domain/src/main/java/me/floow/domain/values/ProfileName.kt +++ b/core/domain/src/main/java/me/floow/domain/values/ProfileName.kt @@ -1,22 +1,25 @@ package me.floow.domain.values +import me.floow.domain.values.util.RawValueObjectCreate import me.floow.domain.values.util.ValidationError import me.floow.domain.values.util.ValueValidationResult @JvmInline -value class ProfileName( +value class ProfileName private constructor( val value: String ) { - init { - check(value.isNotBlank()) { "Should not be blank" } + companion object { + fun create(value: String): ProfileName { + check(value.isNotBlank()) { "Should not be blank" } - check(!value.contains(Regex("[<>&\"']"))) { "Should not contain '<', '>', '&', '\"' and '''" } + check(!value.contains(Regex("[<>&\"']"))) { "Should not contain '<', '>', '&', '\"' and '''" } - check(value.length in 1..32) { "Length should be between 1 and 32 symbols" } - } + check(value.length in 1..32) { "Length should be between 1 and 32 symbols" } - companion object { - fun create(value: String): ValueValidationResult { + return ProfileName(value) + } + + fun createWithValidation(value: String): ValueValidationResult { return when (value.length) { 0 -> { ValueValidationResult.Invalid(ValidationError.ShouldNotBeBlank) @@ -35,5 +38,10 @@ value class ProfileName( } } } + + @RawValueObjectCreate + fun createRaw(value: String): ProfileName { + return ProfileName(value) + } } } diff --git a/core/domain/src/main/java/me/floow/domain/values/ProfileUsername.kt b/core/domain/src/main/java/me/floow/domain/values/ProfileUsername.kt index 331840b..236f772 100644 --- a/core/domain/src/main/java/me/floow/domain/values/ProfileUsername.kt +++ b/core/domain/src/main/java/me/floow/domain/values/ProfileUsername.kt @@ -1,22 +1,25 @@ package me.floow.domain.values +import me.floow.domain.values.util.RawValueObjectCreate import me.floow.domain.values.util.ValidationError import me.floow.domain.values.util.ValueValidationResult @JvmInline -value class ProfileUsername( +value class ProfileUsername private constructor( val value: String ) { - init { - check(value.isNotBlank()) { "Should not be blank" } + companion object { + fun create(value: String): ProfileUsername { + check(value.isNotBlank()) { "Should not be blank" } - check(value.contains(Regex("^[a-zA-Z0-9_]+$"))) { "Should contain only a-z, A-Z, 0-9 and underscores" } + check(value.contains(Regex("^[a-zA-Z0-9_]+$"))) { "Should contain only a-z, A-Z, 0-9 and underscores" } - check(value.length in 3..32) { "Length should be between 3 and 32 symbols" } - } + check(value.length in 3..32) { "Length should be between 3 and 32 symbols" } - companion object { - fun create(value: String): ValueValidationResult { + return ProfileUsername(value) + } + + fun createWithValidation(value: String): ValueValidationResult { return when (value.length) { 0 -> { ValueValidationResult.Invalid(ValidationError.ShouldNotBeBlank) @@ -39,5 +42,10 @@ value class ProfileUsername( } } } + + @RawValueObjectCreate + fun createRaw(value: String): ProfileUsername { + return ProfileUsername(value) + } } } diff --git a/core/domain/src/main/java/me/floow/domain/values/util/RawValueObjectCreate.kt b/core/domain/src/main/java/me/floow/domain/values/util/RawValueObjectCreate.kt new file mode 100644 index 0000000..748b526 --- /dev/null +++ b/core/domain/src/main/java/me/floow/domain/values/util/RawValueObjectCreate.kt @@ -0,0 +1,6 @@ +package me.floow.domain.values.util + +@RequiresOptIn(message = "Raw object creation can prove unsatisfying of business behaviours") +@Retention(AnnotationRetention.BINARY) +@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CONSTRUCTOR) +annotation class RawValueObjectCreate \ No newline at end of file diff --git a/core/mock/src/main/java/me/floow/mock/data/MockProfileRepository.kt b/core/mock/src/main/java/me/floow/mock/data/MockProfileRepository.kt index 87ca2ea..f4ca243 100644 --- a/core/mock/src/main/java/me/floow/mock/data/MockProfileRepository.kt +++ b/core/mock/src/main/java/me/floow/mock/data/MockProfileRepository.kt @@ -8,13 +8,15 @@ import me.floow.domain.models.SelfProfile import me.floow.domain.values.ProfileDescription import me.floow.domain.values.ProfileName import me.floow.domain.values.ProfileUsername +import me.floow.domain.values.util.RawValueObjectCreate class MockProfileRepository : ProfileRepository { + @OptIn(RawValueObjectCreate::class) private var userProfile = SelfProfile( - name = ProfileName("Demn"), + name = ProfileName.createRaw("Demn"), avatarUrl = "https://http.cat/images/200.jpg", - username = ProfileUsername("demndevel"), - description = ProfileDescription("Hi. My name is demn. I like coding: Kotlin, F#, Jetpack Compose, SwiftUI and etc. Welcome to my profile screen!") + username = ProfileUsername.createRaw("demndevel"), + description = ProfileDescription.createRaw("Hi. My name is demn. I like coding: Kotlin, F#, Jetpack Compose, SwiftUI and etc. Welcome to my profile screen!") ) override suspend fun getSelfData(): GetDataResponse { diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chats/components/ChatListItem.kt b/feature/chats/src/main/java/me/floow/chats/ui/chats/components/ChatListItem.kt index b29ffe4..4b547a7 100644 --- a/feature/chats/src/main/java/me/floow/chats/ui/chats/components/ChatListItem.kt +++ b/feature/chats/src/main/java/me/floow/chats/ui/chats/components/ChatListItem.kt @@ -174,7 +174,7 @@ private fun ChatListItemPreview() { ChatListItem( chat = Chat( id = 2L, - name = ProfileName("Demn"), + name = ProfileName.create("Demn"), lastMessageText = "Some message text idk", isOnline = true, lastMessageDateTime = LocalDateTime.now().minusHours(3), diff --git a/feature/chats/src/main/java/me/floow/chats/uilogic/chats/generateRandomChats.kt b/feature/chats/src/main/java/me/floow/chats/uilogic/chats/generateRandomChats.kt index a86023f..d3ffc6b 100644 --- a/feature/chats/src/main/java/me/floow/chats/uilogic/chats/generateRandomChats.kt +++ b/feature/chats/src/main/java/me/floow/chats/uilogic/chats/generateRandomChats.kt @@ -36,7 +36,7 @@ fun generateRandomChats(n: Int): List { val chats = mutableListOf() for (i in 1..n) { - val profileName = ProfileName( + val profileName = ProfileName.create( value = firstNames.random(), ) val lastMessageText = messages.random() diff --git a/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/SearchUsersScreen.kt b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/SearchUsersScreen.kt index e3fb532..11fdb52 100644 --- a/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/SearchUsersScreen.kt +++ b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/SearchUsersScreen.kt @@ -74,34 +74,34 @@ private fun SearchUsersScreenPreview() { searchField = "test", userResults = listOf( UserSearchResult( - name = ProfileName("Demn"), - username = ProfileUsername("demndevel"), + name = ProfileName.create("Demn"), + username = ProfileUsername.create("demndevel"), isOnline = false ) ), messageResults = listOf( MessageResult( - name = ProfileName("Finsi"), + name = ProfileName.create("Finsi"), messageText = "Some example text. Some example text. Some example text. Some example text. Some example text. Some example text. Some example text. " ), MessageResult( - name = ProfileName("Demn"), + name = ProfileName.create("Demn"), messageText = "Some example text" ), MessageResult( - name = ProfileName("Finsi"), + name = ProfileName.create("Finsi"), messageText = "Some example text. Some example text. Some example text. Some example text. Some example text. Some example text. Some example text. " ), MessageResult( - name = ProfileName("Demn"), + name = ProfileName.create("Demn"), messageText = "Some example text" ), MessageResult( - name = ProfileName("Finsi"), + name = ProfileName.create("Finsi"), messageText = "Some example text. Some example text. Some example text. Some example text. Some example text. Some example text. Some example text. " ), MessageResult( - name = ProfileName("Demn"), + name = ProfileName.create("Demn"), messageText = "Some example text" ), ) diff --git a/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/MessageResult.kt b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/MessageResult.kt index ca111e1..4ab9210 100644 --- a/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/MessageResult.kt +++ b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/MessageResult.kt @@ -78,7 +78,7 @@ fun MessageResultPreview() { ComponentPreviewBox(Modifier.fillMaxSize()) { MessageResult( result = MessageResult( - name = ProfileName("Богдан"), + name = ProfileName.create("Богдан"), messageText = "Привет, дружище. Как у тебя дела? У меня всё отлично. Сегодня сделал огромный пласт задач по дизайну, сейчас тебе скину пару примеров." ), onClick = {} diff --git a/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/UserGlobalSearchResult.kt b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/UserGlobalSearchResult.kt index 54767b2..7fe2326 100644 --- a/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/UserGlobalSearchResult.kt +++ b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/components/UserGlobalSearchResult.kt @@ -78,8 +78,8 @@ private fun UserGlobalSearchResultPreview() { ComponentPreviewBox(Modifier.fillMaxWidth()) { UserGlobalSearchResult( userSearchResult = UserSearchResult( - ProfileName("Demn"), - ProfileUsername( + ProfileName.create("Demn"), + ProfileUsername.create( "demndevel" ), isOnline = false diff --git a/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/states/SearchResultsState.kt b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/states/SearchResultsState.kt index f1abc3c..1d0dcef 100644 --- a/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/states/SearchResultsState.kt +++ b/feature/chatssearch/src/main/java/me/floow/chatssearch/ui/states/SearchResultsState.kt @@ -73,30 +73,30 @@ private fun SearchResultsStatePreview() { searchField = "test", userResults = listOf( UserSearchResult( - name = ProfileName("Demn"), - username = ProfileUsername("demndevel"), + name = ProfileName.create("Demn"), + username = ProfileUsername.create("demndevel"), isOnline = false ) ), messageResults = listOf( MessageResult( - name = ProfileName("Finsi"), + name = ProfileName.create("Finsi"), messageText = "Some example text. Some example text. Some example text. Some example text. Some example text. Some example text. Some example text. " ), MessageResult( - name = ProfileName("Demn"), + name = ProfileName.create("Demn"), messageText = "Some example text" ), MessageResult( - name = ProfileName("Finsi"), + name = ProfileName.create("Finsi"), messageText = "Some example text. Some example text. Some example text. Some example text. Some example text. Some example text. Some example text. " ), MessageResult( - name = ProfileName("Demn"), + name = ProfileName.create("Demn"), messageText = "Some example text" ), MessageResult( - name = ProfileName("Finsi"), + name = ProfileName.create("Finsi"), messageText = "Some example text. Some example text. Some example text. Some example text. Some example text. Some example text. Some example text. " ) ) diff --git a/feature/chatssearch/src/main/java/me/floow/chatssearch/uilogic/SearchUsersScreenViewModel.kt b/feature/chatssearch/src/main/java/me/floow/chatssearch/uilogic/SearchUsersScreenViewModel.kt index 580b31e..511d4a3 100644 --- a/feature/chatssearch/src/main/java/me/floow/chatssearch/uilogic/SearchUsersScreenViewModel.kt +++ b/feature/chatssearch/src/main/java/me/floow/chatssearch/uilogic/SearchUsersScreenViewModel.kt @@ -138,7 +138,7 @@ class SearchUsersScreenViewModel : ViewModel() { val randomMessage = messages[Random.nextInt(messages.size)] MessageResult( - name = ProfileName(randomName), + name = ProfileName.create(randomName), messageText = randomMessage ) } @@ -176,8 +176,8 @@ class SearchUsersScreenViewModel : ViewModel() { val isOnline = Random.nextBoolean() UserSearchResult( - name = ProfileName(randomName), - username = ProfileUsername(randomUsername), + name = ProfileName.create(randomName), + username = ProfileUsername.create(randomUsername), isOnline = isOnline ) } @@ -201,7 +201,7 @@ class SearchUsersScreenViewModel : ViewModel() { val randomName = names[Random.nextInt(names.size)] RecentUser( - name = ProfileName(randomName), + name = ProfileName.create(randomName), ) } } diff --git a/feature/login/src/main/java/me/floow/login/uilogic/CreateProfileViewModel.kt b/feature/login/src/main/java/me/floow/login/uilogic/CreateProfileViewModel.kt index 71c0cbc..df02291 100644 --- a/feature/login/src/main/java/me/floow/login/uilogic/CreateProfileViewModel.kt +++ b/feature/login/src/main/java/me/floow/login/uilogic/CreateProfileViewModel.kt @@ -21,7 +21,6 @@ import me.floow.domain.values.util.ValidationError import me.floow.domain.values.util.ValueValidationResult import me.floow.uikit.util.state.ValidatedField import me.floow.uikit.util.state.ValidatedField.Companion.initialField -import java.lang.IllegalStateException data class CreateProfileVmState( val name: ValidatedField = initialField, @@ -59,7 +58,7 @@ class CreateProfileViewModel( val hapticFeedbackFlow: SharedFlow = _hapticFeedbackFlow fun updateName(newValue: String) { - val validationResult = ProfileName.create(newValue) + val validationResult = ProfileName.createWithValidation(newValue) if (validationResult is ValueValidationResult.Invalid) { viewModelScope.launch { @@ -87,7 +86,7 @@ class CreateProfileViewModel( } fun updateUsername(newValue: String) { - val validationResult = ProfileUsername.create(newValue) + val validationResult = ProfileUsername.createWithValidation(newValue) if (validationResult is ValueValidationResult.Invalid) { viewModelScope.launch { @@ -115,7 +114,7 @@ class CreateProfileViewModel( } fun updateBio(newValue: String) { - val validationResult = ProfileDescription.create(newValue) + val validationResult = ProfileDescription.createWithValidation(newValue) if (validationResult is ValueValidationResult.Invalid) { viewModelScope.launch { @@ -163,9 +162,9 @@ class CreateProfileViewModel( val result = _profileRepository.edit( data = EditProfileData( - name = ProfileName(_state.value.name.value), - username = ProfileUsername(_state.value.username.value), - description = ProfileDescription(_state.value.bio.value) + name = ProfileName.create(_state.value.name.value), + username = ProfileUsername.create(_state.value.username.value), + description = ProfileDescription.create(_state.value.bio.value) ) ) diff --git a/feature/profile/src/main/java/me/floow/profile/uilogic/edit/EditProfileViewModel.kt b/feature/profile/src/main/java/me/floow/profile/uilogic/edit/EditProfileViewModel.kt index 8c2f4d8..eab43ca 100644 --- a/feature/profile/src/main/java/me/floow/profile/uilogic/edit/EditProfileViewModel.kt +++ b/feature/profile/src/main/java/me/floow/profile/uilogic/edit/EditProfileViewModel.kt @@ -23,8 +23,6 @@ import me.floow.domain.values.util.ValueValidationResult import me.floow.profile.ui.edit.EditProfileRouteInitialData import me.floow.uikit.util.state.ValidatedField import me.floow.uikit.util.state.ValidatedField.Companion.initialField -import me.floow.uikit.util.state.ValidationErrorType -import java.lang.IllegalStateException data class CreateProfileVmState( val name: ValidatedField = initialField, @@ -78,7 +76,7 @@ class EditProfileViewModel( } fun updateName(newValue: String) { - val validationResult = ProfileName.create(newValue) + val validationResult = ProfileName.createWithValidation(newValue) if (validationResult is ValueValidationResult.Invalid) { viewModelScope.launch { @@ -106,7 +104,7 @@ class EditProfileViewModel( } fun updateUsername(newValue: String) { - val validationResult = ProfileUsername.create(newValue) + val validationResult = ProfileUsername.createWithValidation(newValue) if (validationResult is ValueValidationResult.Invalid) { viewModelScope.launch { @@ -134,7 +132,7 @@ class EditProfileViewModel( } fun updateBiography(newValue: String) { - val validationResult = ProfileDescription.create(newValue) + val validationResult = ProfileDescription.createWithValidation(newValue) if (validationResult is ValueValidationResult.Invalid) { viewModelScope.launch { @@ -182,9 +180,9 @@ class EditProfileViewModel( val result = _profileRepository.edit( data = EditProfileData( - name = ProfileName(_state.value.name.value), - username = ProfileUsername(_state.value.username.value), - description = ProfileDescription(_state.value.bio.value) + name = ProfileName.create(_state.value.name.value), + username = ProfileUsername.create(_state.value.username.value), + description = ProfileDescription.create(_state.value.bio.value) ) ) From dad52b24a0dfb97ddeddce6061610294e0318228 Mon Sep 17 00:00:00 2001 From: demn Date: Sun, 17 Nov 2024 09:56:04 +0300 Subject: [PATCH 17/28] feat(uikit): add placeholders and image painter to avatar&background picker --- .../pickers/AvatarAndBackgroundPicker.kt | 55 +++++++++++++++---- .../ui/createprofile/components/EditState.kt | 2 + .../me/floow/profile/ui/edit/EditState.kt | 6 +- 3 files changed, 51 insertions(+), 12 deletions(-) diff --git a/core/uikit/src/main/java/me/floow/uikit/components/pickers/AvatarAndBackgroundPicker.kt b/core/uikit/src/main/java/me/floow/uikit/components/pickers/AvatarAndBackgroundPicker.kt index 0d9e745..7616be7 100644 --- a/core/uikit/src/main/java/me/floow/uikit/components/pickers/AvatarAndBackgroundPicker.kt +++ b/core/uikit/src/main/java/me/floow/uikit/components/pickers/AvatarAndBackgroundPicker.kt @@ -1,6 +1,5 @@ package me.floow.uikit.components.pickers -import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box @@ -19,7 +18,10 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.draw.paint import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -29,6 +31,8 @@ import me.floow.uikit.theme.LocalTypography @Composable fun AvatarAndBackgroundPicker( + avatarImagePainter: Painter? = null, + backgroundImagePainter: Painter? = null, onAvatarPickerClick: () -> Unit, onBackgroundPickerClick: () -> Unit, modifier: Modifier = Modifier @@ -39,7 +43,7 @@ fun AvatarAndBackgroundPicker( .fillMaxWidth() .height(160.dp) .clip(RoundedCornerShape(16.dp)) - .background(MaterialTheme.colorScheme.secondaryContainer) + .setBackgroundBoxImage(backgroundImagePainter) .clickable { onBackgroundPickerClick() }, @@ -65,27 +69,58 @@ fun AvatarAndBackgroundPicker( ) } - Image( - painter = painterResource(me.floow.uikit.R.drawable.cute_girl), - contentDescription = null, + Box( + contentAlignment = Alignment.Center, modifier = Modifier .size(120.dp) .clip(ElevanagonShape) + .setAvatarBoxImage(avatarImagePainter) .clickable { onAvatarPickerClick() } + ) { + Icon( + painter = painterResource(R.drawable.photo_icon), + contentDescription = null, + tint = Color.White, + ) + } + } +} + +private fun Modifier.setAvatarBoxImage(avatarImagePainter: Painter?): Modifier { + return if (avatarImagePainter == null) { + this.then( + Modifier + .background(Color.LightGray) ) + } else { + Modifier + .paint( + painter = avatarImagePainter, + contentScale = ContentScale.FillBounds + ) + } +} - Icon( - painter = painterResource(me.floow.uikit.R.drawable.photo_icon), - contentDescription = null, - tint = Color.White, +@Composable +private fun Modifier.setBackgroundBoxImage(backgroundImagePainter: Painter?): Modifier { + return if (backgroundImagePainter == null) { + this.then( + Modifier + .background(MaterialTheme.colorScheme.primaryContainer) ) + } else { + Modifier + .paint( + painter = backgroundImagePainter, + contentScale = ContentScale.FillBounds + ) } } @Preview @Composable fun AvatarAndBackgroundPickerPreview() { - AvatarAndBackgroundPicker({}, {}, Modifier.fillMaxWidth()) + AvatarAndBackgroundPicker(null, null, {}, {}, Modifier.fillMaxWidth()) } \ No newline at end of file diff --git a/feature/login/src/main/java/me/floow/login/ui/createprofile/components/EditState.kt b/feature/login/src/main/java/me/floow/login/ui/createprofile/components/EditState.kt index 07d025b..7a6dc52 100644 --- a/feature/login/src/main/java/me/floow/login/ui/createprofile/components/EditState.kt +++ b/feature/login/src/main/java/me/floow/login/ui/createprofile/components/EditState.kt @@ -32,6 +32,8 @@ fun EditState( .padding(14.dp) ) { AvatarAndBackgroundPicker( + avatarImagePainter = null, + backgroundImagePainter = null, onAvatarPickerClick = onAvatarPickerClick, onBackgroundPickerClick = {}, modifier = Modifier.fillMaxWidth() diff --git a/feature/profile/src/main/java/me/floow/profile/ui/edit/EditState.kt b/feature/profile/src/main/java/me/floow/profile/ui/edit/EditState.kt index 3965822..c696fc6 100644 --- a/feature/profile/src/main/java/me/floow/profile/ui/edit/EditState.kt +++ b/feature/profile/src/main/java/me/floow/profile/ui/edit/EditState.kt @@ -33,8 +33,10 @@ internal fun EditState( .padding(14.dp) ) { AvatarAndBackgroundPicker( - onAvatarPickerClick, - {}, + avatarImagePainter = null, + backgroundImagePainter = null, + onAvatarPickerClick = onAvatarPickerClick, + onBackgroundPickerClick = {}, modifier = Modifier.fillMaxWidth() ) From 7f9143b1d1ff20b8f6f03ae083f7ce3ca294ff97 Mon Sep 17 00:00:00 2001 From: demn Date: Wed, 20 Nov 2024 02:15:22 +0300 Subject: [PATCH 18/28] feat(chats): implement MessageInputField --- .../main/res/drawable/emoji_picker_icon.xml | 12 ++ .../uikit/src/main/res/drawable/send_icon.xml | 9 ++ .../ui/chat/components/MessageInputField.kt | 130 ++++++++++++++++++ 3 files changed, 151 insertions(+) create mode 100644 core/uikit/src/main/res/drawable/emoji_picker_icon.xml create mode 100644 core/uikit/src/main/res/drawable/send_icon.xml create mode 100644 feature/chats/src/main/java/me/floow/chats/ui/chat/components/MessageInputField.kt diff --git a/core/uikit/src/main/res/drawable/emoji_picker_icon.xml b/core/uikit/src/main/res/drawable/emoji_picker_icon.xml new file mode 100644 index 0000000..b9047dd --- /dev/null +++ b/core/uikit/src/main/res/drawable/emoji_picker_icon.xml @@ -0,0 +1,12 @@ + + + diff --git a/core/uikit/src/main/res/drawable/send_icon.xml b/core/uikit/src/main/res/drawable/send_icon.xml new file mode 100644 index 0000000..aace891 --- /dev/null +++ b/core/uikit/src/main/res/drawable/send_icon.xml @@ -0,0 +1,9 @@ + + + diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chat/components/MessageInputField.kt b/feature/chats/src/main/java/me/floow/chats/ui/chat/components/MessageInputField.kt new file mode 100644 index 0000000..ab5c6a6 --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/ui/chat/components/MessageInputField.kt @@ -0,0 +1,130 @@ +package me.floow.chats.ui.chat.components + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.text.BasicTextField +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import me.floow.uikit.theme.LocalTypography +import me.flowme.chats.R + +@Composable +fun MessageInputField( + value: String, + onValueChange: (String) -> Unit, + onEmojiPickerClick: () -> Unit, + onSendClick: () -> Unit, + sendButtonActive: Boolean, + modifier: Modifier = Modifier +) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = modifier + .padding( + top = 13.dp, + bottom = 16.dp, + ) + .padding(horizontal = 16.dp) + ) { + Icon( + painter = painterResource( + me.floow.uikit.R.drawable.emoji_picker_icon, + ), + contentDescription = null, + tint = Color(0xFF8E959B), + modifier = Modifier + .clip(CircleShape) + .clickable { onEmojiPickerClick() } + ) + + Spacer( + Modifier + .width(11.dp) + ) + + BasicTextField( + value = value, + onValueChange = onValueChange, + textStyle = LocalTypography.current.titleMedium.copy( + fontWeight = FontWeight.Normal, + color = MaterialTheme.colorScheme.onBackground + ), + maxLines = 4, + cursorBrush = SolidColor(MaterialTheme.colorScheme.onBackground), + modifier = Modifier + .weight(1f) + ) { innerTextField -> + Box { + if (value.isEmpty()) { + Text( + text = stringResource(R.string.message_input_field_placeholder), + color = Color.Gray, + style = LocalTypography.current.titleMedium, + fontWeight = FontWeight.Normal + ) + } + + innerTextField() + } + } + + Spacer( + Modifier + .width(11.dp) + ) + + Icon( + painter = painterResource( + me.floow.uikit.R.drawable.send_icon, + ), + tint = sendButtonColor(sendButtonActive), + contentDescription = null, + modifier = Modifier + .clickable { + if (sendButtonActive) onSendClick() + } + ) + } +} + +@Composable +private fun sendButtonColor(sendButtonActive: Boolean) = + if (sendButtonActive) MaterialTheme.colorScheme.inversePrimary + else Color(0xFF868686) + +@Preview +@Composable +private fun MessageInputFieldPreview() { + var value by remember { mutableStateOf("") } + + MessageInputField( + value = value, + onValueChange = { value = it }, + onSendClick = {}, + onEmojiPickerClick = {}, + sendButtonActive = value.isNotBlank(), + modifier = Modifier.fillMaxWidth() + ) +} \ No newline at end of file From 56238b42e6512737edbf9585a06cd8a8bed0c9bd Mon Sep 17 00:00:00 2001 From: demn Date: Wed, 20 Nov 2024 02:16:45 +0300 Subject: [PATCH 19/28] feat(chats): manifest and ui fixes accordingly to the ime in chats, add replyable bubbles and implement splitting messages by date --- app/build.gradle.kts | 2 +- app/src/main/AndroidManifest.xml | 3 +- app/src/main/java/me/floow/app/ui/App.kt | 2 + feature/chats/build.gradle.kts | 2 +- .../src/main/java/me/floow/chats/ChatRoute.kt | 22 ++- .../java/me/floow/chats/ui/chat/ChatScreen.kt | 83 ++++++++--- .../chats/ui/chat/components/ChatBubble.kt | 7 +- .../chats/ui/chat/components/CurrentReply.kt | 1 + .../CustomReplyAnchoredDraggableState.kt | 36 +++++ .../chat/components/replyable/ReplyMarker.kt | 32 +++++ .../replyable/ReplyableChatBubble.kt | 133 ++++++++++++++++++ .../components/replyable/replyDraggable.kt | 66 +++++++++ .../replyable/touchSlopConfiguration.kt | 12 ++ .../chats/ui/chat/states/HasDataState.kt | 84 +++++++---- .../floow/chats/uilogic/chat/ChatMessage.kt | 2 +- .../chats/uilogic/chat/ChatScreenUiState.kt | 3 +- .../chats/uilogic/chat/ChatScreenViewModel.kt | 58 +++++++- .../chats/uilogic/chat/DatedChatMessages.kt | 8 ++ .../chats/src/main/res/values-ru/strings.xml | 2 + feature/chats/src/main/res/values/strings.xml | 2 + 20 files changed, 496 insertions(+), 64 deletions(-) create mode 100644 feature/chats/src/main/java/me/floow/chats/ui/chat/components/replyable/CustomReplyAnchoredDraggableState.kt create mode 100644 feature/chats/src/main/java/me/floow/chats/ui/chat/components/replyable/ReplyMarker.kt create mode 100644 feature/chats/src/main/java/me/floow/chats/ui/chat/components/replyable/ReplyableChatBubble.kt create mode 100644 feature/chats/src/main/java/me/floow/chats/ui/chat/components/replyable/replyDraggable.kt create mode 100644 feature/chats/src/main/java/me/floow/chats/ui/chat/components/replyable/touchSlopConfiguration.kt create mode 100644 feature/chats/src/main/java/me/floow/chats/uilogic/chat/DatedChatMessages.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 5deeb0c..489b59d 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -12,7 +12,7 @@ plugins { android { namespace = "me.floow.app" - compileSdk = 34 + compileSdk = 35 defaultConfig { applicationId = "me.floow.app" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ceb0452..a31a514 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -20,7 +20,8 @@ android:exported="true" android:label="@string/app_name" android:launchMode="singleTask" - android:theme="@style/Theme.Flow.Starting"> + android:theme="@style/Theme.Flow.Starting" + android:windowSoftInputMode="adjustNothing"> diff --git a/app/src/main/java/me/floow/app/ui/App.kt b/app/src/main/java/me/floow/app/ui/App.kt index 06bb309..091f9ea 100644 --- a/app/src/main/java/me/floow/app/ui/App.kt +++ b/app/src/main/java/me/floow/app/ui/App.kt @@ -3,6 +3,7 @@ package me.floow.app.ui import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut +import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.material3.* @@ -59,6 +60,7 @@ fun App( modifier = Modifier .fillMaxSize() .padding(innerPadding) + .consumeWindowInsets(innerPadding) ) } } diff --git a/feature/chats/build.gradle.kts b/feature/chats/build.gradle.kts index 39e89a0..5f785da 100644 --- a/feature/chats/build.gradle.kts +++ b/feature/chats/build.gradle.kts @@ -7,7 +7,7 @@ plugins { android { namespace = "me.flowme.chats" - compileSdk = 34 + compileSdk = 35 defaultConfig { minSdk = 28 diff --git a/feature/chats/src/main/java/me/floow/chats/ChatRoute.kt b/feature/chats/src/main/java/me/floow/chats/ChatRoute.kt index 5eed151..7c058c4 100644 --- a/feature/chats/src/main/java/me/floow/chats/ChatRoute.kt +++ b/feature/chats/src/main/java/me/floow/chats/ChatRoute.kt @@ -1,12 +1,15 @@ package me.floow.chats +import android.content.Context import android.net.Uri +import android.widget.Toast import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext import me.floow.chats.ui.chat.ChatScreen import me.floow.chats.uilogic.chat.ChatScreenViewModel import me.floow.uikit.util.SetNavigationBarColor @@ -23,6 +26,9 @@ fun ChatRoute( vm: ChatScreenViewModel, modifier: Modifier = Modifier ) { + val state by vm.state.collectAsState() + val context = LocalContext.current + LaunchedEffect(Unit) { vm.setInitialData( initialData.chatInterlocutorId, @@ -33,18 +39,26 @@ fun ChatRoute( vm.loadData() } - val state by vm.state.collectAsState() - ChatScreen( onProfileClick = {}, onTopBarDropdownClick = {}, - onReplyClick = {}, onChatBubbleClick = {}, + onReply = vm::addCurrentReply, + onReplyClick = {}, + onCurrentReplyClose = vm::closeCurrentReply, + onCurrentReplyClick = { showTodoToast(context) }, + onMessageInputFieldValueChange = vm::updateMessageInputField, + onEmojiPickerClick = { showTodoToast(context) }, + onSendClick = vm::sendMessage, state = state, - modifier = modifier + modifier = modifier, ) SetNavigationBarColor( MaterialTheme.colorScheme.background ) +} + +private fun showTodoToast(context: Context) { + Toast.makeText(context, "feature currently unavailable", Toast.LENGTH_SHORT).show() } \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chat/ChatScreen.kt b/feature/chats/src/main/java/me/floow/chats/ui/chat/ChatScreen.kt index 789c5f8..87ac0c9 100644 --- a/feature/chats/src/main/java/me/floow/chats/ui/chat/ChatScreen.kt +++ b/feature/chats/src/main/java/me/floow/chats/ui/chat/ChatScreen.kt @@ -1,19 +1,24 @@ package me.floow.chats.ui.chat import androidx.compose.foundation.Image +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.padding +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold -import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.SideEffect import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import me.floow.chats.ui.chat.components.ChatScreenTopBar +import me.floow.chats.ui.chat.components.CurrentReply +import me.floow.chats.ui.chat.components.MessageInputField import me.floow.chats.ui.chat.states.ErrorState import me.floow.chats.ui.chat.states.HasDataState import me.floow.chats.ui.chat.states.LoadingState @@ -28,7 +33,13 @@ fun ChatScreen( onProfileClick: () -> Unit, onTopBarDropdownClick: () -> Unit, onChatBubbleClick: (ChatMessage) -> Unit, + onReply: (ChatMessage) -> Unit, onReplyClick: (ChatMessage) -> Unit, + onCurrentReplyClose: () -> Unit, + onCurrentReplyClick: () -> Unit, + onMessageInputFieldValueChange: (String) -> Unit, + onEmojiPickerClick: () -> Unit, + onSendClick: () -> Unit, state: ChatScreenUiState, modifier: Modifier = Modifier ) { @@ -53,31 +64,63 @@ fun ChatScreen( contentWindowInsets = WindowInsets(0.dp), modifier = modifier ) { innerPadding -> - val commonModifier = Modifier - .padding(innerPadding) - .fillMaxSize() + Column( + modifier = Modifier + .fillMaxSize() + .imePadding() + ) { + val commonModifier = Modifier + .padding(innerPadding) + .fillMaxWidth() + .weight(1f) + .background(MaterialTheme.colorScheme.surfaceContainer) - when (state) { - is ChatScreenUiState.Loading -> { - LoadingState(commonModifier) - } + when (state) { + is ChatScreenUiState.Loading -> { + LoadingState(commonModifier) + } - is ChatScreenUiState.Error -> { - ErrorState(commonModifier) - } + is ChatScreenUiState.Error -> { + ErrorState(commonModifier) + } - is ChatScreenUiState.NoMessages -> { - NoMessagesState(commonModifier) + is ChatScreenUiState.NoMessages -> { + NoMessagesState(commonModifier) + } + + is ChatScreenUiState.HasData -> { + HasDataState( + state = state, + onChatBubbleClick = onChatBubbleClick, + onReply = onReply, + onReplyClick = onReplyClick, + modifier = commonModifier + ) + } } - is ChatScreenUiState.HasData -> { - HasDataState( - state = state, - onChatBubbleClick = onChatBubbleClick, - onReplyClick = onReplyClick, - modifier = commonModifier + state.messageFieldReply?.let { reply -> + CurrentReply( + userNameToReply = reply.replyAuthorName, + replyMessageText = reply.replyMessageText, + onClose = onCurrentReplyClose, + onClick = onCurrentReplyClick, + modifier = Modifier + .fillMaxWidth() ) } + + HorizontalDivider() + + MessageInputField( + value = state.messageFieldValue, + onValueChange = onMessageInputFieldValueChange, + onEmojiPickerClick = onEmojiPickerClick, + onSendClick = onSendClick, + sendButtonActive = state.messageFieldValue.isNotEmpty(), + modifier = Modifier + .fillMaxWidth() + ) } } } diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chat/components/ChatBubble.kt b/feature/chats/src/main/java/me/floow/chats/ui/chat/components/ChatBubble.kt index dd352ee..02c9c22 100644 --- a/feature/chats/src/main/java/me/floow/chats/ui/chat/components/ChatBubble.kt +++ b/feature/chats/src/main/java/me/floow/chats/ui/chat/components/ChatBubble.kt @@ -58,7 +58,7 @@ data class ChatBubbleColors( val Outlined: ChatBubbleColors @Composable get() = ChatBubbleColors( - backgroundColor = MaterialTheme.colorScheme.background, + backgroundColor = MaterialTheme.colorScheme.surfaceContainer, borderColor = Color(0xFFBEBEBE), textColor = MaterialTheme.colorScheme.onBackground, timeColor = Color(0xFFBEBEBE), @@ -74,7 +74,6 @@ fun ChatBubble( onReplyClick: (ChatMessage) -> Unit, modifier: Modifier = Modifier ) { - val isReply: Boolean = chatMessage is ChatReplyMessage val isOut: Boolean = chatMessage is PrimaryOutMessage || chatMessage is ReplyOutMessage val colors = if (!isOut) ChatBubbleColors.Outlined else ChatBubbleColors.Default @@ -86,7 +85,7 @@ fun ChatBubble( Column( modifier = Modifier .clip(RoundedCornerShape(20.dp)) - .clickable { onClick(chatMessage) } +// .clickable { onClick(chatMessage) } TODO .background(colors.backgroundColor) .addBorderIfIn(isOut, colors) .padding(vertical = 8.dp, horizontal = 10.dp) @@ -119,7 +118,7 @@ fun ChatBubble( Row( horizontalArrangement = if (isOut) Arrangement.End else Arrangement.Start, modifier = Modifier - .width(324.dp) + .widthIn(74.dp, 324.dp) ) { ReplyContent( replyMessageText = chatMessage.replyMessageText, diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chat/components/CurrentReply.kt b/feature/chats/src/main/java/me/floow/chats/ui/chat/components/CurrentReply.kt index f54cfe4..291fa11 100644 --- a/feature/chats/src/main/java/me/floow/chats/ui/chat/components/CurrentReply.kt +++ b/feature/chats/src/main/java/me/floow/chats/ui/chat/components/CurrentReply.kt @@ -52,6 +52,7 @@ fun CurrentReply( Text( text = replyMessageText, + maxLines = 1, overflow = TextOverflow.Ellipsis, style = LocalTypography.current.captionMedium, color = Color.Gray diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chat/components/replyable/CustomReplyAnchoredDraggableState.kt b/feature/chats/src/main/java/me/floow/chats/ui/chat/components/replyable/CustomReplyAnchoredDraggableState.kt new file mode 100644 index 0000000..68c8f41 --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/ui/chat/components/replyable/CustomReplyAnchoredDraggableState.kt @@ -0,0 +1,36 @@ +package me.floow.chats.ui.chat.components.replyable + +import androidx.compose.animation.core.AnimationSpec +import androidx.compose.animation.core.animate +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableFloatStateOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue + +internal class CustomReplyAnchoredDraggableState( + val initialValue: Float, + val replyOffset: Float +) { + var currentValue by mutableFloatStateOf(initialValue) + var isDragged by mutableStateOf(false) + var isAnimated by mutableStateOf(false) + + suspend fun animateTo( + targetOffset: Float, + animationVelocity: Float, + snapAnimationSpec: AnimationSpec + ) { + animate( + initialValue = currentValue, + targetValue = targetOffset, + initialVelocity = animationVelocity, + animationSpec = snapAnimationSpec + ) { value, _ -> + currentValue = value + } + } + + fun requireOffset(): Float { + return currentValue + } +} \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chat/components/replyable/ReplyMarker.kt b/feature/chats/src/main/java/me/floow/chats/ui/chat/components/replyable/ReplyMarker.kt new file mode 100644 index 0000000..c7b3e64 --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/ui/chat/components/replyable/ReplyMarker.kt @@ -0,0 +1,32 @@ +package me.floow.chats.ui.chat.components.replyable + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import me.floow.uikit.R + +@Composable +internal fun ReplyMarker( + modifier: Modifier = Modifier +) { + Icon( + painter = painterResource(R.drawable.reply_icon), + contentDescription = null, + tint = Color.Black, + modifier = modifier + .clip(RoundedCornerShape(8.dp)) + .background(MaterialTheme.colorScheme.secondaryContainer) + .padding( + horizontal = 8.dp, + vertical = 4.dp + ) + ) +} \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chat/components/replyable/ReplyableChatBubble.kt b/feature/chats/src/main/java/me/floow/chats/ui/chat/components/replyable/ReplyableChatBubble.kt new file mode 100644 index 0000000..db3f6bb --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/ui/chat/components/replyable/ReplyableChatBubble.kt @@ -0,0 +1,133 @@ +package me.floow.chats.ui.chat.components.replyable + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.core.tween +import androidx.compose.animation.scaleIn +import androidx.compose.animation.scaleOut +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.IntrinsicSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.offset +import androidx.compose.foundation.layout.width +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.platform.LocalViewConfiguration +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.IntOffset +import androidx.compose.ui.unit.dp +import me.floow.chats.ui.chat.components.ChatBubble +import me.floow.chats.uilogic.chat.ChatMessage +import me.floow.chats.uilogic.chat.PrimaryInMessage +import me.floow.chats.uilogic.chat.PrimaryOutMessage +import me.floow.chats.uilogic.chat.ReplyInMessage +import me.floow.chats.uilogic.chat.ReplyOutMessage +import me.floow.uikit.util.ComponentPreviewBox +import java.time.LocalDateTime +import kotlin.math.roundToInt + +@Composable +internal fun ReplyableChatBubble( + chatMessage: ChatMessage, + onClick: (ChatMessage) -> Unit, + onReplyClick: (ChatMessage) -> Unit, + onReply: (ChatMessage) -> Unit, + modifier: Modifier = Modifier +) { + val currentViewConfiguration = LocalViewConfiguration.current + val density = LocalDensity.current + val state = remember { + CustomReplyAnchoredDraggableState( + initialValue = 0f, + replyOffset = with(density) { -40.dp.toPx() } + ) + } + + val coroutineScope = rememberCoroutineScope() + + CompositionLocalProvider(touchSlopConfiguration(currentViewConfiguration)) { + Box( + modifier = modifier + .replyDraggable( + state = state, + coroutineScope = coroutineScope, + onReply = { onReply(chatMessage) } + ) + ) { + Box( + modifier = Modifier + .widthByBubbleType(chatMessage) + ) { + Box(Modifier.align(Alignment.TopEnd)) { + AnimatedVisibility( + visible = state.currentValue != 0f, + enter = scaleIn(tween(300)), + exit = scaleOut(tween(300)) + ) { + ReplyMarker() + } + } + + Box( + modifier = Modifier + .offset { + IntOffset( + x = state + .requireOffset() + .roundToInt(), + y = 0 + ) + }, + ) { + ChatBubble( + chatMessage = chatMessage, + onClick = onClick, + onReplyClick = onReplyClick, + modifier = modifier + ) + } + } + } + } +} + +private fun Modifier.widthByBubbleType(chatMessage: ChatMessage): Modifier { + return when (chatMessage) { + is PrimaryInMessage, is ReplyInMessage -> { + this.width(IntrinsicSize.Max) + } + + is PrimaryOutMessage, is ReplyOutMessage -> { + this.then( + Modifier.fillMaxWidth() + ) + } + } +} + +@Preview +@Composable +private fun ReplyableChatBubblePreview() { + ComponentPreviewBox(Modifier.fillMaxWidth()) { + ReplyableChatBubble( + chatMessage = PrimaryOutMessage( + id = 100L, + messageText = "Some awesome!!! Message. See you later.. probably", + dateTime = LocalDateTime.now(), + ), + onClick = {}, + onReplyClick = {}, + onReply = { + println("REPLY !!!") + println("REPLY !!!") + println("REPLY !!!") + }, + modifier = Modifier + ) + } +} + diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chat/components/replyable/replyDraggable.kt b/feature/chats/src/main/java/me/floow/chats/ui/chat/components/replyable/replyDraggable.kt new file mode 100644 index 0000000..cf065a8 --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/ui/chat/components/replyable/replyDraggable.kt @@ -0,0 +1,66 @@ +package me.floow.chats.ui.chat.components.replyable + +import androidx.compose.animation.core.tween +import androidx.compose.foundation.gestures.detectHorizontalDragGestures +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.input.pointer.pointerInput +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch + +@Composable +internal fun Modifier.replyDraggable( + state: CustomReplyAnchoredDraggableState, + coroutineScope: CoroutineScope, + onReply: () -> Unit, +): Modifier { + return this.then( + Modifier + .pointerInput(Unit) { + detectHorizontalDragGestures( + onDragStart = { + state.isDragged = true + }, + onDragEnd = { + state.isDragged = false + + coroutineScope.launch { + if (state.currentValue < state.replyOffset * 0.7 && !state.isAnimated) { + state.isAnimated = true + + state.animateTo( + targetOffset = state.replyOffset, + animationVelocity = 3f, + snapAnimationSpec = tween(50), + ) + + onReply() + + state.animateTo( + targetOffset = 0f, + animationVelocity = 3f, + snapAnimationSpec = tween(150), + ) + } else if (!state.isAnimated) { + state.isAnimated = true + + state.animateTo( + targetOffset = 0f, + animationVelocity = 3f, + snapAnimationSpec = tween(200), + ) + } + + state.isAnimated = false + } + }, + onHorizontalDrag = { change, dragAmount -> + change.consume() + val newValue = + (state.currentValue + dragAmount).coerceIn(state.replyOffset, 0f) + state.currentValue = newValue + } + ) + } + ) +} \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chat/components/replyable/touchSlopConfiguration.kt b/feature/chats/src/main/java/me/floow/chats/ui/chat/components/replyable/touchSlopConfiguration.kt new file mode 100644 index 0000000..2a852ff --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/ui/chat/components/replyable/touchSlopConfiguration.kt @@ -0,0 +1,12 @@ +package me.floow.chats.ui.chat.components.replyable + +import androidx.compose.runtime.Composable +import androidx.compose.ui.platform.LocalViewConfiguration +import androidx.compose.ui.platform.ViewConfiguration + +@Composable +internal fun touchSlopConfiguration(current: ViewConfiguration) = + LocalViewConfiguration provides object : ViewConfiguration by current { + override val touchSlop: Float + get() = current.touchSlop * 2f + } \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chat/states/HasDataState.kt b/feature/chats/src/main/java/me/floow/chats/ui/chat/states/HasDataState.kt index 8b8aaef..e225113 100644 --- a/feature/chats/src/main/java/me/floow/chats/ui/chat/states/HasDataState.kt +++ b/feature/chats/src/main/java/me/floow/chats/ui/chat/states/HasDataState.kt @@ -1,5 +1,6 @@ package me.floow.chats.ui.chat.states +import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -12,18 +13,24 @@ import androidx.compose.foundation.lazy.items import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp -import me.floow.chats.ui.chat.components.ChatBubble import me.floow.chats.ui.chat.components.DateSeparator +import me.floow.chats.ui.chat.components.replyable.ReplyableChatBubble import me.floow.chats.uilogic.chat.ChatMessage import me.floow.chats.uilogic.chat.ChatScreenUiState import me.floow.chats.uilogic.chat.PrimaryOutMessage import me.floow.chats.uilogic.chat.ReplyOutMessage +import me.flowme.chats.R +import java.time.LocalDate +import java.time.format.DateTimeFormatter +@OptIn(ExperimentalFoundationApi::class) @Composable fun HasDataState( state: ChatScreenUiState.HasData, onChatBubbleClick: (ChatMessage) -> Unit, + onReply: (ChatMessage) -> Unit, onReplyClick: (ChatMessage) -> Unit, modifier: Modifier = Modifier ) { @@ -36,40 +43,59 @@ fun HasDataState( .fillMaxWidth() .weight(1f) ) { - item { - Spacer(Modifier.height(8.dp)) + state.messages.forEach { (date, messageList) -> + stickyHeader { + Spacer(Modifier.height(8.dp)) - Row( - horizontalArrangement = Arrangement.Center, - modifier = Modifier.fillMaxWidth(), - ) { - DateSeparator( - text = "Today" // todo - ) - } + Row( + horizontalArrangement = Arrangement.Center, + modifier = Modifier.fillMaxWidth(), + ) { + DateSeparator( + text = getDateSeparatorText(date) + ) + } - Spacer(Modifier.height(8.dp)) - } + Spacer(Modifier.height(8.dp)) + } - items(state.messages) { message -> - val isOut: Boolean = message is PrimaryOutMessage || message is ReplyOutMessage + items(messageList) { message -> + val isOut: Boolean = message is PrimaryOutMessage || message is ReplyOutMessage - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 14.dp), - horizontalArrangement = if (isOut) Arrangement.End else Arrangement.Start - ) { - ChatBubble( - chatMessage = message, - onClick = onChatBubbleClick, - onReplyClick = onReplyClick, + Row( modifier = Modifier - ) - } + .fillMaxWidth() + .padding(horizontal = 14.dp), + horizontalArrangement = if (isOut) Arrangement.End else Arrangement.Start + ) { + ReplyableChatBubble( + chatMessage = message, + onClick = onChatBubbleClick, + onReplyClick = onReplyClick, + onReply = onReply, + modifier = Modifier + .fillMaxWidth() + ) +// ChatBubble( +// chatMessage = message, +// onClick = onChatBubbleClick, +// onReplyClick = onReplyClick, +// modifier = Modifier +// ) + } - Spacer(Modifier.height(8.dp)) + Spacer(Modifier.height(8.dp)) + } } } } -} \ No newline at end of file +} + +@Composable +fun getDateSeparatorText(date: LocalDate): String { + return if (date == LocalDate.now()) { + stringResource(R.string.today) + } else { + date.format(DateTimeFormatter.ofPattern("dd.MM.yy")) + } +} diff --git a/feature/chats/src/main/java/me/floow/chats/uilogic/chat/ChatMessage.kt b/feature/chats/src/main/java/me/floow/chats/uilogic/chat/ChatMessage.kt index afb501e..bb36edb 100644 --- a/feature/chats/src/main/java/me/floow/chats/uilogic/chat/ChatMessage.kt +++ b/feature/chats/src/main/java/me/floow/chats/uilogic/chat/ChatMessage.kt @@ -8,7 +8,7 @@ sealed interface ChatMessage { val dateTime: LocalDateTime } -interface ChatReplyMessage : ChatMessage { +sealed interface ChatReplyMessage : ChatMessage { val replyMessageId: Long val replyMessageText: String } diff --git a/feature/chats/src/main/java/me/floow/chats/uilogic/chat/ChatScreenUiState.kt b/feature/chats/src/main/java/me/floow/chats/uilogic/chat/ChatScreenUiState.kt index 7a1324d..9a3ec55 100644 --- a/feature/chats/src/main/java/me/floow/chats/uilogic/chat/ChatScreenUiState.kt +++ b/feature/chats/src/main/java/me/floow/chats/uilogic/chat/ChatScreenUiState.kt @@ -4,6 +4,7 @@ import android.net.Uri data class MessageFieldReply( val replyId: Long, + val replyAuthorName: String, val replyMessageText: String, ) @@ -39,7 +40,7 @@ interface ChatScreenUiState { ) : ChatScreenUiState data class HasData( - val messages: List, + val messages: List, override val chatInterlocutorId: Long, override val chatInterlocutorAvatarUrl: Uri?, override val messageFieldValue: String, diff --git a/feature/chats/src/main/java/me/floow/chats/uilogic/chat/ChatScreenViewModel.kt b/feature/chats/src/main/java/me/floow/chats/uilogic/chat/ChatScreenViewModel.kt index da58db9..bad2088 100644 --- a/feature/chats/src/main/java/me/floow/chats/uilogic/chat/ChatScreenViewModel.kt +++ b/feature/chats/src/main/java/me/floow/chats/uilogic/chat/ChatScreenViewModel.kt @@ -19,7 +19,7 @@ data class ChatScreenVmState( val chatInterlocutorAvatarUrl: Uri? = null, val isLoading: Boolean = false, val isError: Boolean = false, - val messages: List? = null, + val messages: List? = null, val messageFieldReply: MessageFieldReply? = null ) { fun toUiState(): ChatScreenUiState { @@ -87,7 +87,11 @@ class ChatScreenViewModel() : ViewModel() { ) ) - fun setInitialData(chatInterlocutorId: Long, chatInterlocutorName: String, chatInterlocutorAvatarUrl: Uri?) { + fun setInitialData( + chatInterlocutorId: Long, + chatInterlocutorName: String, + chatInterlocutorAvatarUrl: Uri? + ) { _state.update { it.copy( chatInterlocutorId = chatInterlocutorId, @@ -111,8 +115,58 @@ class ChatScreenViewModel() : ViewModel() { it.copy( isLoading = false, messages = generateChatMessages() + .sortedBy { it.dateTime } + .groupBy { it.dateTime.toLocalDate() } + .map { (datetime, messages) -> + DatedChatMessages( + datetime = datetime, + messages = messages + ) + } ) } } } + + fun closeCurrentReply() { + _state.update { + it.copy( + messageFieldReply = null + ) + } + } + + fun updateMessageInputField(newValue: String) { + _state.update { + it.copy( + messageFieldValue = newValue + ) + } + } + + fun sendMessage() { + TODO("Not yet implemented") + } + + fun addCurrentReply(chatMessage: ChatMessage) { + val replyAuthorName = when (chatMessage) { + is PrimaryInMessage, is ReplyInMessage -> { + _state.value.chatInterlocutorName + } + + else -> { + "You" // TODO + } + } + + _state.update { + it.copy( + messageFieldReply = MessageFieldReply( + replyId = chatMessage.id, + replyAuthorName = replyAuthorName, + replyMessageText = chatMessage.messageText + ) + ) + } + } } \ No newline at end of file diff --git a/feature/chats/src/main/java/me/floow/chats/uilogic/chat/DatedChatMessages.kt b/feature/chats/src/main/java/me/floow/chats/uilogic/chat/DatedChatMessages.kt new file mode 100644 index 0000000..622a9af --- /dev/null +++ b/feature/chats/src/main/java/me/floow/chats/uilogic/chat/DatedChatMessages.kt @@ -0,0 +1,8 @@ +package me.floow.chats.uilogic.chat + +import java.time.LocalDate + +data class DatedChatMessages( + val datetime: LocalDate, + val messages: List +) \ No newline at end of file diff --git a/feature/chats/src/main/res/values-ru/strings.xml b/feature/chats/src/main/res/values-ru/strings.xml index 56307cb..c427453 100644 --- a/feature/chats/src/main/res/values-ru/strings.xml +++ b/feature/chats/src/main/res/values-ru/strings.xml @@ -1,4 +1,6 @@ В ответ + Сообщение + Сегодня \ No newline at end of file diff --git a/feature/chats/src/main/res/values/strings.xml b/feature/chats/src/main/res/values/strings.xml index e49e882..488971f 100644 --- a/feature/chats/src/main/res/values/strings.xml +++ b/feature/chats/src/main/res/values/strings.xml @@ -1,4 +1,6 @@ In reply to + Message + Today \ No newline at end of file From fd85f5556d260192cf630d679ff2b9c01af9b57a Mon Sep 17 00:00:00 2001 From: demn Date: Wed, 20 Nov 2024 02:18:06 +0300 Subject: [PATCH 20/28] chore: upgrade libs versions --- gradle/libs.versions.toml | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8a0fcbe..fd51843 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,34 +1,32 @@ [versions] -agp = "8.2.0" +agp = "8.2.2" androidxCoreSplashscreen = "1.0.1" credentials = "1.2.2" graphics-shapes = "1.0.1" kotlin = "2.0.20" -core-ktx = "1.13.1" +core-ktx = "1.15.0" junit = "4.13.2" androidx-test-ext-junit = "1.2.1" espresso-core = "3.6.1" -lifecycle-runtime-ktx = "2.8.6" -activity-compose = "1.9.2" -compose-bom = "2024.09.02" -org-jetbrains-kotlin-jvm = "2.0.10" +lifecycle-runtime-ktx = "2.8.7" +activity-compose = "1.9.3" +compose-bom = "2024.11.00" +org-jetbrains-kotlin-jvm = "2.0.20" appcompat = "1.7.0" -androidx-navigation-compose = "2.8.3" +androidx-navigation-compose = "2.8.4" serialization = "1.7.1" serialization-json = "1.7.1" -ui-tooling = "1.7.2" +ui-tooling = "1.7.5" ktor = "2.3.12" coroutines = "1.9.0-RC.2" gmsGoogleServices = "4.4.2" firebaseCrashlytics = "3.0.2" -firebaseBom = "33.3.0" +firebaseBom = "33.6.0" androidx-browser = "1.8.0" koin = "4.0.0-RC1" -material = "1.12.0" room = "2.6.1" ksp = "2.0.20-1.0.24" coil = "2.7.0" -materialVersion = "1.10.0" textflow = "1.2.1" [libraries] @@ -78,7 +76,6 @@ room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "room" } coil = { group = "io.coil-kt", name = "coil", version.ref = "coil" } coil-compose = { group = "io.coil-kt", name = "coil-compose", version.ref = "coil" } -material = { group = "com.google.android.material", name = "material", version.ref = "materialVersion" } textflow-material3 = { group = "io.github.oleksandrbalan", name = "textflow-material3", version.ref = "textflow" } From cdf9df9ed4292d6f6eff39413e8570f6a0a9faf4 Mon Sep 17 00:00:00 2001 From: demn Date: Fri, 9 May 2025 19:54:19 +0300 Subject: [PATCH 21/28] chore: version bump --- gradle/libs.versions.toml | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index fd51843..d19807e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,30 +1,29 @@ [versions] agp = "8.2.2" androidxCoreSplashscreen = "1.0.1" -credentials = "1.2.2" graphics-shapes = "1.0.1" -kotlin = "2.0.20" -core-ktx = "1.15.0" +kotlin = "2.1.20" +core-ktx = "1.16.0" junit = "4.13.2" androidx-test-ext-junit = "1.2.1" espresso-core = "3.6.1" -lifecycle-runtime-ktx = "2.8.7" -activity-compose = "1.9.3" -compose-bom = "2024.11.00" +lifecycle-runtime-ktx = "2.9.0" +activity-compose = "1.10.1" +compose-bom = "2025.05.00" org-jetbrains-kotlin-jvm = "2.0.20" appcompat = "1.7.0" -androidx-navigation-compose = "2.8.4" -serialization = "1.7.1" -serialization-json = "1.7.1" -ui-tooling = "1.7.5" -ktor = "2.3.12" -coroutines = "1.9.0-RC.2" +androidx-navigation-compose = "2.9.0" +serialization = "1.8.1" +serialization-json = "1.8.1" +ui-tooling = "1.8.1" +ktor = "3.1.2" +coroutines = "1.10.2" gmsGoogleServices = "4.4.2" -firebaseCrashlytics = "3.0.2" -firebaseBom = "33.6.0" +firebaseCrashlytics = "3.0.3" +firebaseBom = "33.13.0" androidx-browser = "1.8.0" koin = "4.0.0-RC1" -room = "2.6.1" +room = "2.7.1" ksp = "2.0.20-1.0.24" coil = "2.7.0" textflow = "1.2.1" From 7eefe5bef19033abe3a74dd9ce6fc49fde196402 Mon Sep 17 00:00:00 2001 From: demn Date: Sat, 10 May 2025 19:35:04 +0300 Subject: [PATCH 22/28] chore, fix: agp version bump & fixes accordingly to new versions --- .../java/me/floow/api/util/safeApiCall.kt | 6 +-- feature/shared/build.gradle.kts | 48 +++++++++++++++++++ gradle/libs.versions.toml | 4 +- settings.gradle.kts | 1 + 4 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 feature/shared/build.gradle.kts diff --git a/core/api/src/main/java/me/floow/api/util/safeApiCall.kt b/core/api/src/main/java/me/floow/api/util/safeApiCall.kt index 314bb90..1460c7b 100644 --- a/core/api/src/main/java/me/floow/api/util/safeApiCall.kt +++ b/core/api/src/main/java/me/floow/api/util/safeApiCall.kt @@ -1,9 +1,9 @@ package me.floow.api.util import io.ktor.util.network.* -import io.ktor.utils.io.core.EOFException -import io.ktor.utils.io.errors.IOException import kotlinx.coroutines.TimeoutCancellationException +import kotlinx.io.EOFException +import kotlinx.io.IOException suspend fun safeApiCall(errorResponse: T, apiCall: suspend () -> T): T { return try { @@ -17,4 +17,4 @@ suspend fun safeApiCall(errorResponse: T, apiCall: suspend () -> T): T { } catch (ex: IOException) { errorResponse } -} \ No newline at end of file +} diff --git a/feature/shared/build.gradle.kts b/feature/shared/build.gradle.kts new file mode 100644 index 0000000..4d3230c --- /dev/null +++ b/feature/shared/build.gradle.kts @@ -0,0 +1,48 @@ +plugins { + alias(libs.plugins.androidLibrary) + alias(libs.plugins.kotlinAndroid) + alias(libs.plugins.composeCompiler) +} + +android { + namespace = "me.floow.shared" + compileSdk = 34 + + defaultConfig { + minSdk = 28 + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles("consumer-rules.pro") + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + } + } + buildFeatures { compose = true } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = "1.8" + } +} + +dependencies { + implementation(project(":core:uikit")) + implementation(project(":core:domain")) + + implementation(libs.appcompat) + + api(platform(libs.koin.bom)) + api(libs.koin.core) + api(libs.koin.android) + + testImplementation(libs.junit) + + androidTestImplementation(libs.androidx.test.ext.junit) + androidTestImplementation(libs.espresso.core) +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d19807e..3776266 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -agp = "8.2.2" +agp = "8.6.1" androidxCoreSplashscreen = "1.0.1" graphics-shapes = "1.0.1" kotlin = "2.1.20" @@ -24,7 +24,7 @@ firebaseBom = "33.13.0" androidx-browser = "1.8.0" koin = "4.0.0-RC1" room = "2.7.1" -ksp = "2.0.20-1.0.24" +ksp = "2.1.20-1.0.31" coil = "2.7.0" textflow = "1.2.1" diff --git a/settings.gradle.kts b/settings.gradle.kts index 28afb90..ba950ed 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -35,3 +35,4 @@ include(":feature:explore") include(":feature:login") include(":feature:profile") include(":feature:chatssearch") +include(":feature:shared") From 897906f50707a35a43a4eb16a46af7cf61113fe3 Mon Sep 17 00:00:00 2001 From: demn Date: Sat, 10 May 2025 19:35:27 +0300 Subject: [PATCH 23/28] fix(chats): small color fixes --- .../chats/ui/chat/components/DateSeparator.kt | 2 + .../chats/ui/chat/states/HasDataState.kt | 152 ++++++++++++++---- 2 files changed, 119 insertions(+), 35 deletions(-) diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chat/components/DateSeparator.kt b/feature/chats/src/main/java/me/floow/chats/ui/chat/components/DateSeparator.kt index fe88d81..e19898f 100644 --- a/feature/chats/src/main/java/me/floow/chats/ui/chat/components/DateSeparator.kt +++ b/feature/chats/src/main/java/me/floow/chats/ui/chat/components/DateSeparator.kt @@ -1,6 +1,7 @@ package me.floow.chats.ui.chat.components import android.view.RoundedCorner +import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape @@ -23,6 +24,7 @@ fun DateSeparator( style = LocalTypography.current.labelMedium, color = MaterialTheme.colorScheme.outline, modifier = modifier + .background(MaterialTheme.colorScheme.surfaceContainer, RoundedCornerShape(20.dp)) .border(1.dp, MaterialTheme.colorScheme.outline, RoundedCornerShape(20.dp)) .padding( horizontal = 10.dp, diff --git a/feature/chats/src/main/java/me/floow/chats/ui/chat/states/HasDataState.kt b/feature/chats/src/main/java/me/floow/chats/ui/chat/states/HasDataState.kt index e225113..89fe7e2 100644 --- a/feature/chats/src/main/java/me/floow/chats/ui/chat/states/HasDataState.kt +++ b/feature/chats/src/main/java/me/floow/chats/ui/chat/states/HasDataState.kt @@ -1,20 +1,37 @@ package me.floow.chats.ui.chat.states +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.derivedStateOf +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp +import kotlinx.coroutines.Job +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch import me.floow.chats.ui.chat.components.DateSeparator import me.floow.chats.ui.chat.components.replyable.ReplyableChatBubble import me.floow.chats.uilogic.chat.ChatMessage @@ -34,58 +51,123 @@ fun HasDataState( onReplyClick: (ChatMessage) -> Unit, modifier: Modifier = Modifier ) { + val lazyListState = rememberLazyListState() + var dateSeparatorVisible by remember { mutableStateOf(false) } + val coroutineScope = rememberCoroutineScope() + val firstVisibleItemScrollOffset by remember { derivedStateOf { lazyListState.firstVisibleItemScrollOffset } } + var dateSeparatorJob by remember { mutableStateOf(null) } + + LaunchedEffect(firstVisibleItemScrollOffset) { + if (dateSeparatorJob != null) { + dateSeparatorJob?.cancel() + } + + dateSeparatorJob = coroutineScope.launch { + dateSeparatorVisible = true + + delay(300L) + + dateSeparatorVisible = false + } + } + + val dateSeparatorModifier = Modifier + .fillMaxWidth() + .height(32.dp) + Column( modifier = modifier, horizontalAlignment = Alignment.CenterHorizontally ) { - LazyColumn( - modifier = Modifier + Box( + Modifier .fillMaxWidth() .weight(1f) ) { - state.messages.forEach { (date, messageList) -> - stickyHeader { - Spacer(Modifier.height(8.dp)) + LazyColumn( + state = lazyListState, + modifier = Modifier + .fillMaxWidth() + .fillMaxHeight() + ) { + state.messages.forEach { (date, messageList) -> +// stickyHeader { +// Spacer(Modifier.height(8.dp)) +// +// Row( +// horizontalArrangement = Arrangement.Center, +// modifier = dateSeparatorModifier, +// ) { +// if (dateSeparatorVisible) { +// DateSeparator( +// text = getDateSeparatorText(date) +// ) +// } +// } +// +// Spacer11 + // (Modifier.height(8.dp)) +// } - Row( - horizontalArrangement = Arrangement.Center, - modifier = Modifier.fillMaxWidth(), - ) { - DateSeparator( - text = getDateSeparatorText(date) - ) + item { + Spacer(Modifier.height(8.dp)) + + Row( + horizontalArrangement = Arrangement.Center, + modifier = dateSeparatorModifier, + ) { + DateSeparator( + text = getDateSeparatorText(date) + ) + } + + Spacer(Modifier.height(8.dp)) } - Spacer(Modifier.height(8.dp)) + items(messageList) { message -> + val isOut: Boolean = + message is PrimaryOutMessage || message is ReplyOutMessage + + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 14.dp), + horizontalArrangement = if (isOut) Arrangement.End else Arrangement.Start + ) { + ReplyableChatBubble( + chatMessage = message, + onClick = onChatBubbleClick, + onReplyClick = onReplyClick, + onReply = onReply, + modifier = Modifier + .fillMaxWidth() + ) + } + + Spacer(Modifier.height(8.dp)) + } } + } - items(messageList) { message -> - val isOut: Boolean = message is PrimaryOutMessage || message is ReplyOutMessage + Column { + Spacer(Modifier.height(8.dp)) - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 14.dp), - horizontalArrangement = if (isOut) Arrangement.End else Arrangement.Start + Row( + horizontalArrangement = Arrangement.Center, + modifier = dateSeparatorModifier, + ) { + AnimatedVisibility ( + visible = dateSeparatorVisible, + enter = fadeIn(), + exit = fadeOut() ) { - ReplyableChatBubble( - chatMessage = message, - onClick = onChatBubbleClick, - onReplyClick = onReplyClick, - onReply = onReply, - modifier = Modifier - .fillMaxWidth() + DateSeparator( + text = "Today" ) -// ChatBubble( -// chatMessage = message, -// onClick = onChatBubbleClick, -// onReplyClick = onReplyClick, -// modifier = Modifier -// ) } - - Spacer(Modifier.height(8.dp)) } + + Spacer(Modifier.height(8.dp)) } } } From 378bb1a5d7ef05ee353679cd0a3406b2462399c8 Mon Sep 17 00:00:00 2001 From: demn Date: Sat, 10 May 2025 19:57:15 +0300 Subject: [PATCH 24/28] feat(uikit): implement BlankContentBox --- .../uikit/components/misc/BlankContentBox.kt | 61 ++++ .../src/main/res/drawable/blank_girl.xml | 270 ++++++++++++++++++ 2 files changed, 331 insertions(+) create mode 100644 core/uikit/src/main/java/me/floow/uikit/components/misc/BlankContentBox.kt create mode 100644 core/uikit/src/main/res/drawable/blank_girl.xml diff --git a/core/uikit/src/main/java/me/floow/uikit/components/misc/BlankContentBox.kt b/core/uikit/src/main/java/me/floow/uikit/components/misc/BlankContentBox.kt new file mode 100644 index 0000000..7008dd7 --- /dev/null +++ b/core/uikit/src/main/java/me/floow/uikit/components/misc/BlankContentBox.kt @@ -0,0 +1,61 @@ +package me.floow.uikit.components.misc + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import me.floow.uikit.R +import me.floow.uikit.theme.LocalTypography + +@Composable +fun BlankContentBox(modifier: Modifier = Modifier) { + Box( + contentAlignment = Alignment.Center, + modifier = modifier + ) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier + ) { + Image( + painter = painterResource(R.drawable.blank_girl), + contentDescription = null, + ) + + Spacer(Modifier.height(24.dp)) + + Text( + text = "Ничего нет.", + style = LocalTypography.current.titleLarge.copy( + fontSize = 24.sp, + ), + ) + + Spacer(Modifier.height(10.dp)) + + Text( + text = "Но скоро будет, обещаем!", + style = LocalTypography.current.bodyMedium, + ) + } + } +} + +@Preview +@Composable +private fun BlankContentBoxPreview() { + BlankContentBox( + modifier = Modifier + .fillMaxSize() + ) +} diff --git a/core/uikit/src/main/res/drawable/blank_girl.xml b/core/uikit/src/main/res/drawable/blank_girl.xml new file mode 100644 index 0000000..48a1b49 --- /dev/null +++ b/core/uikit/src/main/res/drawable/blank_girl.xml @@ -0,0 +1,270 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 3cb7a90730015b0f99e5939667860963a891dfe7 Mon Sep 17 00:00:00 2001 From: demn Date: Sat, 10 May 2025 19:57:25 +0300 Subject: [PATCH 25/28] feat(feed): use BlankContentBox --- .../src/main/java/me/floow/feed/ui/FeedScreen.kt | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/feature/feed/src/main/java/me/floow/feed/ui/FeedScreen.kt b/feature/feed/src/main/java/me/floow/feed/ui/FeedScreen.kt index 9f116c2..ffeb196 100644 --- a/feature/feed/src/main/java/me/floow/feed/ui/FeedScreen.kt +++ b/feature/feed/src/main/java/me/floow/feed/ui/FeedScreen.kt @@ -12,6 +12,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import me.floow.uikit.R +import me.floow.uikit.components.misc.BlankContentBox import me.floow.uikit.components.topbar.TitleTopBarWithActionButton @Composable @@ -39,16 +40,7 @@ internal fun FeedScreen( .padding(8.dp) .padding(innerPadding) ) { - Text( - "Flow!", - style = MaterialTheme.typography.titleLarge, - ) - - Spacer(Modifier.height(4.dp)) - - Text( - text = "Feed" - ) + BlankContentBox(Modifier.fillMaxSize()) } } } @@ -60,4 +52,4 @@ private fun FeedScreenPreview() { onPostCreateClick = {}, modifier = Modifier.fillMaxSize() ) -} \ No newline at end of file +} From 25eb2100156336e4e2191bb7a121e3dde6eebafd Mon Sep 17 00:00:00 2001 From: demn Date: Sat, 10 May 2025 19:57:37 +0300 Subject: [PATCH 26/28] feat(shared): add sharedModule --- .../src/main/kotlin/me/floow/shared/di/sharedModule.kt | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 feature/shared/src/main/kotlin/me/floow/shared/di/sharedModule.kt diff --git a/feature/shared/src/main/kotlin/me/floow/shared/di/sharedModule.kt b/feature/shared/src/main/kotlin/me/floow/shared/di/sharedModule.kt new file mode 100644 index 0000000..54707f2 --- /dev/null +++ b/feature/shared/src/main/kotlin/me/floow/shared/di/sharedModule.kt @@ -0,0 +1,9 @@ +package me.floow.shared.di + +import org.koin.dsl.module +import org.koin.dsl.module +import org.koin.core.module.dsl.viewModelOf + +val sharedModule = module { + +} From 32f20cd1cc3f52a530ab94fb781e504a928c39bc Mon Sep 17 00:00:00 2001 From: demn Date: Sat, 10 May 2025 20:02:45 +0300 Subject: [PATCH 27/28] fix(uikit): use string resources --- .../java/me/floow/uikit/components/misc/BlankContentBox.kt | 5 +++-- core/uikit/src/main/res/values-ru/strings.xml | 4 +++- core/uikit/src/main/res/values/strings.xml | 4 +++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/core/uikit/src/main/java/me/floow/uikit/components/misc/BlankContentBox.kt b/core/uikit/src/main/java/me/floow/uikit/components/misc/BlankContentBox.kt index 7008dd7..555c6e4 100644 --- a/core/uikit/src/main/java/me/floow/uikit/components/misc/BlankContentBox.kt +++ b/core/uikit/src/main/java/me/floow/uikit/components/misc/BlankContentBox.kt @@ -11,6 +11,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @@ -35,7 +36,7 @@ fun BlankContentBox(modifier: Modifier = Modifier) { Spacer(Modifier.height(24.dp)) Text( - text = "Ничего нет.", + text = stringResource(R.string.there_is_nothing), style = LocalTypography.current.titleLarge.copy( fontSize = 24.sp, ), @@ -44,7 +45,7 @@ fun BlankContentBox(modifier: Modifier = Modifier) { Spacer(Modifier.height(10.dp)) Text( - text = "Но скоро будет, обещаем!", + text = stringResource(R.string.but_it_will_be_soon_we_promise), style = LocalTypography.current.bodyMedium, ) } diff --git a/core/uikit/src/main/res/values-ru/strings.xml b/core/uikit/src/main/res/values-ru/strings.xml index 3061a91..04bb993 100644 --- a/core/uikit/src/main/res/values-ru/strings.xml +++ b/core/uikit/src/main/res/values-ru/strings.xml @@ -15,4 +15,6 @@ Вы можете использовать символы a–z, 0–9 и нижние подчеркивания Онлайн Оффлайн - \ No newline at end of file + Ничего нет. + Но скоро будет, обещаем! + diff --git a/core/uikit/src/main/res/values/strings.xml b/core/uikit/src/main/res/values/strings.xml index 2be1319..0ef3409 100644 --- a/core/uikit/src/main/res/values/strings.xml +++ b/core/uikit/src/main/res/values/strings.xml @@ -15,4 +15,6 @@ You can use the characters a-z, 0-9, and underscores Online Offline - \ No newline at end of file + There is nothing. + But it will be soon, we promise! + From c03013269f051f485ac3630ecfd414865af9cddf Mon Sep 17 00:00:00 2001 From: demn Date: Sat, 10 May 2025 22:52:41 +0300 Subject: [PATCH 28/28] fix(uikit): impl ErrorWithButtonContentBox + curious picture set --- .../misc/ErrorWithButtonContentBox.kt | 105 ++++++++++++++++++ .../src/main/res/drawable/curious_pic_a.png | Bin 0 -> 11731 bytes .../src/main/res/drawable/curious_pic_b.png | Bin 0 -> 162973 bytes .../src/main/res/drawable/curious_pic_c.png | Bin 0 -> 110562 bytes .../src/main/res/drawable/curious_pic_d.png | Bin 0 -> 133762 bytes 5 files changed, 105 insertions(+) create mode 100644 core/uikit/src/main/java/me/floow/uikit/components/misc/ErrorWithButtonContentBox.kt create mode 100644 core/uikit/src/main/res/drawable/curious_pic_a.png create mode 100644 core/uikit/src/main/res/drawable/curious_pic_b.png create mode 100644 core/uikit/src/main/res/drawable/curious_pic_c.png create mode 100644 core/uikit/src/main/res/drawable/curious_pic_d.png diff --git a/core/uikit/src/main/java/me/floow/uikit/components/misc/ErrorWithButtonContentBox.kt b/core/uikit/src/main/java/me/floow/uikit/components/misc/ErrorWithButtonContentBox.kt new file mode 100644 index 0000000..0cba51b --- /dev/null +++ b/core/uikit/src/main/java/me/floow/uikit/components/misc/ErrorWithButtonContentBox.kt @@ -0,0 +1,105 @@ +package me.floow.uikit.components.misc + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.size +import androidx.compose.material3.Button +import androidx.compose.material3.FilledTonalButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import me.floow.uikit.R +import me.floow.uikit.theme.LocalTypography + +private val curiousPicsList = listOf( + R.drawable.curious_pic_a, + R.drawable.curious_pic_b, + R.drawable.curious_pic_c, + R.drawable.curious_pic_d, +) + +@Composable +fun ErrorWithButtonContentBox( + title: String, + description: String, + onButtonClick: () -> Unit, + buttonContent: @Composable () -> Unit, + modifier: Modifier = Modifier +) { + val curiousPicResource = remember { curiousPicsList.random() } + + Box( + contentAlignment = Alignment.Center, + modifier = modifier + ) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier.fillMaxWidth() + ) { + Image( + painter = painterResource(curiousPicResource), + contentDescription = null, + modifier = Modifier + .size(164.dp) + ) + + Spacer(Modifier.height(10.dp)) + + Text( + text = title, + style = LocalTypography.current.titleLarge.copy( + fontSize = 24.sp, + ), + ) + + Spacer(Modifier.height(10.dp)) + + Text( + text = description, + style = LocalTypography.current.bodyMedium, + ) + + Spacer(Modifier.height(20.dp)) + + FilledTonalButton( + onClick = onButtonClick, + modifier = Modifier, + ) { + buttonContent() + } + } + } +} + +@Preview +@Composable +private fun NotFoundScreenPreview() { + Surface( + modifier = Modifier + .fillMaxSize() + ) { + ErrorWithButtonContentBox( + title = "Страница не найдена :(", + description = "Страницы не существует или она была удалена.", + onButtonClick = {}, + buttonContent = { + Text("Назад", color = MaterialTheme.colorScheme.primary) + }, + modifier = Modifier + .fillMaxSize() + ) + } +} diff --git a/core/uikit/src/main/res/drawable/curious_pic_a.png b/core/uikit/src/main/res/drawable/curious_pic_a.png new file mode 100644 index 0000000000000000000000000000000000000000..636b81a0734c3ea8de560c10723612ae0bf73d60 GIT binary patch literal 11731 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


Y&hr@~ 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%0D1tzMwl3celsMdBoWeR6) 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 =KB+ZL+xlrv1uhHlg;8@?I^d&c^nnqX!* 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 literal 0 HcmV?d00001 diff --git a/core/uikit/src/main/res/drawable/curious_pic_d.png b/core/uikit/src/main/res/drawable/curious_pic_d.png new file mode 100644 index 0000000000000000000000000000000000000000..11f96780d15b95dbe9f88219d473531c2e678306 GIT binary patch literal 133762 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 U6Q%|Cr-Z*`C6y#