diff --git a/app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppScaffold.kt b/app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppScaffold.kt index c42e58d..560591e 100644 --- a/app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppScaffold.kt +++ b/app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppScaffold.kt @@ -483,6 +483,7 @@ fun AppScaffold( serverUrl = currentSession.serverUrl, userId = userId, config = bottomBarConfig, + activeTabKey = activeTab.name, menuOpen = menuOpen, chatsHighlighted = activeTab == AppTab.Talk && !talkInRoom, navBackHighlighted = (activeTab == AppTab.Mail && mailSidebarOpen) || @@ -499,36 +500,22 @@ fun AppScaffold( else -> Unit } }, - onCreateClick = { - when (activeTab) { - AppTab.Files -> { - if (F7AppPermissions.missing(context).isNotEmpty()) { - onRequestRuntimePermissions { filesUploadRequest++ } - } else { - filesUploadRequest++ - } - } - AppTab.Contacts -> contactsCreateRequest++ - AppTab.Tasks -> tasksCreateRequest++ - AppTab.Support -> supportCreateRequest++ - else -> Unit + onMailClick = { + if (activeTab != AppTab.Mail) { + pushTabHistory(activeTab) + activeTab = AppTab.Mail } }, - onProfileClick = { - menuOpen = false - profileOpen = true + onCardsClick = { + if (activeTab != AppTab.Deck) { + pushTabHistory(activeTab) + activeTab = AppTab.Deck + } }, - onNotificationsClick = { - menuOpen = false - hasNotificationBadge = false - notificationsOpen = true - }, - onSettingsClick = { - when (activeTab) { - AppTab.Mail -> mailSettingsOpen = true - AppTab.Calendar -> calendarSettingsRequest++ - AppTab.Files -> filesSettingsOpen = true - else -> Unit + onConferencesClick = { + if (activeTab != AppTab.Talk) { + pushTabHistory(activeTab) + activeTab = AppTab.Talk } }, onMenuClick = { menuOpen = !menuOpen }, @@ -647,6 +634,7 @@ fun AppScaffold( // Нативные пункты по дизайну меню label.equals("Уведомления", ignoreCase = true) -> { menuOpen = false + hasNotificationBadge = false notificationsOpen = true } label.equals("Настройки", ignoreCase = true) -> { diff --git a/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7BottomBarConfig.kt b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7BottomBarConfig.kt index 70f8d7f..015b068 100644 --- a/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7BottomBarConfig.kt +++ b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7BottomBarConfig.kt @@ -3,10 +3,9 @@ package ru.forbion.f7cloud.core.designsystem enum class F7BottomBarSlot { Chats, NavBack, - Create, - Profile, - Notifications, - Settings, + SectionMail, + SectionCards, + SectionConferences, Menu, } @@ -16,69 +15,21 @@ data class F7BottomBarConfig( val buttonCount: Int get() = slots.size companion object { + // Единая навигационная панель по дизайну «Новое меню»: + // слева «назад» (в Конференциях — «чаты»), затем ярлыки-разделы + // Почта · Карточки · Конференции, справа — выдвижное меню. + // Профиль/Уведомления/Настройки/Создать вынесены (меню и шапки экранов). fun forContext( tabKey: String, talkInRoom: Boolean, - ): F7BottomBarConfig = when (tabKey) { - "Talk" -> if (talkInRoom) { - F7BottomBarConfig(listOf(F7BottomBarSlot.Profile, F7BottomBarSlot.Notifications, F7BottomBarSlot.Menu)) - } else { - F7BottomBarConfig( - listOf( - F7BottomBarSlot.Chats, - F7BottomBarSlot.Profile, - F7BottomBarSlot.Notifications, - F7BottomBarSlot.Menu, - ), - ) - } - "Files" -> F7BottomBarConfig( + ): F7BottomBarConfig { + val left = if (tabKey == "Talk") F7BottomBarSlot.Chats else F7BottomBarSlot.NavBack + return F7BottomBarConfig( listOf( - F7BottomBarSlot.NavBack, - F7BottomBarSlot.Profile, - F7BottomBarSlot.Notifications, - F7BottomBarSlot.Create, - F7BottomBarSlot.Settings, - F7BottomBarSlot.Menu, - ), - ) - "Contacts" -> F7BottomBarConfig( - listOf( - F7BottomBarSlot.Create, - F7BottomBarSlot.Profile, - F7BottomBarSlot.Notifications, - F7BottomBarSlot.Menu, - ), - ) - "Tasks" -> F7BottomBarConfig( - listOf( - F7BottomBarSlot.Create, - F7BottomBarSlot.Profile, - F7BottomBarSlot.Notifications, - F7BottomBarSlot.Menu, - ), - ) - "Support" -> F7BottomBarConfig( - listOf( - F7BottomBarSlot.Create, - F7BottomBarSlot.Profile, - F7BottomBarSlot.Notifications, - F7BottomBarSlot.Menu, - ), - ) - "Mail", "Calendar" -> F7BottomBarConfig( - listOf( - F7BottomBarSlot.NavBack, - F7BottomBarSlot.Profile, - F7BottomBarSlot.Notifications, - F7BottomBarSlot.Settings, - F7BottomBarSlot.Menu, - ), - ) - else -> F7BottomBarConfig( - listOf( - F7BottomBarSlot.Profile, - F7BottomBarSlot.Notifications, + left, + F7BottomBarSlot.SectionMail, + F7BottomBarSlot.SectionCards, + F7BottomBarSlot.SectionConferences, F7BottomBarSlot.Menu, ), ) diff --git a/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7CreateButton.kt b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7CreateButton.kt new file mode 100644 index 0000000..63bd3fa --- /dev/null +++ b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7CreateButton.kt @@ -0,0 +1,53 @@ +package ru.forbion.f7cloud.core.designsystem + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.size +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.draw.shadow +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp + +/** + * Зелёная круглая кнопка «+» — единый элемент создания в шапках экранов + * (Почта/Файлы/Контакты/…). Градиент Primary, как у других зелёных кнопок. + */ +@Composable +fun F7CreateButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + size: Dp = 44.dp, +) { + Box( + modifier = modifier + .size(size) + .shadow(3.dp, CircleShape, spotColor = F7Colors.Primary.copy(alpha = 0.25f)) + .clip(CircleShape) + .background( + Brush.linearGradient( + listOf(F7Colors.PrimaryGradientStart, F7Colors.PrimaryGradientEnd), + ), + ) + .border(1.dp, F7Colors.Primary.copy(alpha = 0.22f), CircleShape) + .clickable(onClick = onClick), + contentAlignment = Alignment.Center, + ) { + Text( + text = "+", + color = Color.White, + fontSize = 26.sp, + fontWeight = FontWeight.Light, + ) + } +} diff --git a/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7MobileBottomBar.kt b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7MobileBottomBar.kt index 3779b3e..0438be0 100644 --- a/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7MobileBottomBar.kt +++ b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7MobileBottomBar.kt @@ -27,10 +27,9 @@ import coil.compose.AsyncImage data class F7BottomBarActions( val onChatsClick: () -> Unit = {}, val onNavBackClick: () -> Unit = {}, - val onCreateClick: () -> Unit = {}, - val onProfileClick: () -> Unit = {}, - val onNotificationsClick: () -> Unit = {}, - val onSettingsClick: () -> Unit = {}, + val onMailClick: () -> Unit = {}, + val onCardsClick: () -> Unit = {}, + val onConferencesClick: () -> Unit = {}, val onMenuClick: () -> Unit = {}, ) @@ -53,6 +52,7 @@ fun F7MobileBottomBar( userId: String, config: F7BottomBarConfig, actions: F7BottomBarActions, + activeTabKey: String = "", menuOpen: Boolean = false, chatsHighlighted: Boolean = false, navBackHighlighted: Boolean = false, @@ -97,26 +97,23 @@ fun F7MobileBottomBar( iconRotation = if (navBackHighlighted) 180f else 0f, onClick = actions.onNavBackClick, ) - F7BottomBarSlot.Create -> F7BottomBarIconSlot( - iconUrl = "$base/themes/forbion/images/header/green-plus.svg", - contentDescription = "Создать", - onClick = actions.onCreateClick, + F7BottomBarSlot.SectionMail -> F7BottomBarIconSlot( + iconUrl = "$base/themes/forbion/images/header/mail-header-icon.svg", + contentDescription = "Почта", + highlighted = activeTabKey == "Mail", + onClick = actions.onMailClick, ) - F7BottomBarSlot.Profile -> F7BottomBarIconSlot( - iconUrl = "$base/themes/forbion/images/header/profile-menu-icon-big.svg", - contentDescription = "Профиль", - onClick = actions.onProfileClick, + F7BottomBarSlot.SectionCards -> F7BottomBarIconSlot( + iconUrl = "$base/themes/forbion/images/header/deck-header-icon.svg", + contentDescription = "Карточки", + highlighted = activeTabKey == "Deck", + onClick = actions.onCardsClick, ) - F7BottomBarSlot.Notifications -> F7BottomBarIconSlot( - iconUrl = "$base/themes/forbion/images/header/not-menu-icon-big.svg", - contentDescription = "Уведомления", - showBadge = showNotificationBadge, - onClick = actions.onNotificationsClick, - ) - F7BottomBarSlot.Settings -> F7BottomBarIconSlot( - iconUrl = "$base/themes/forbion/images/header/setting-menu-icon.svg", - contentDescription = "Настройки", - onClick = actions.onSettingsClick, + F7BottomBarSlot.SectionConferences -> F7BottomBarIconSlot( + iconUrl = "$base/themes/forbion/images/header/spreed-header-icon.svg", + contentDescription = "Конференции", + highlighted = activeTabKey == "Talk", + onClick = actions.onConferencesClick, ) F7BottomBarSlot.Menu -> F7BottomBarIconSlot( iconUrl = if (menuOpen) { @@ -126,6 +123,7 @@ fun F7MobileBottomBar( }, contentDescription = "Меню", highlighted = menuOpen, + showBadge = showNotificationBadge, onClick = actions.onMenuClick, ) } diff --git a/feature/contacts/src/main/java/ru/forbion/f7cloud/feature/contacts/ContactsScreen.kt b/feature/contacts/src/main/java/ru/forbion/f7cloud/feature/contacts/ContactsScreen.kt index c4b64fa..d553ee9 100644 --- a/feature/contacts/src/main/java/ru/forbion/f7cloud/feature/contacts/ContactsScreen.kt +++ b/feature/contacts/src/main/java/ru/forbion/f7cloud/feature/contacts/ContactsScreen.kt @@ -48,6 +48,7 @@ import coil.compose.AsyncImage import coil.request.ImageRequest import ru.forbion.f7cloud.core.auth.AuthSession import ru.forbion.f7cloud.core.designsystem.F7Colors +import ru.forbion.f7cloud.core.designsystem.F7CreateButton import ru.forbion.f7cloud.core.designsystem.F7ModuleScreen @Composable @@ -76,11 +77,23 @@ fun ContactsScreen( loading = state.loading && state.contacts.isEmpty(), error = state.error, ) { - ContactsSearchBar( - serverUrl = session.serverUrl, - query = state.searchQuery, - onQueryChange = vm::setSearchQuery, - ) + // Поиск + кнопка создания контакта (создание раньше вызывалось из нижней + // панели, теперь — из шапки, панель стала навигационной) + Row( + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 8.dp), + horizontalArrangement = Arrangement.spacedBy(8.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + ContactsSearchBar( + serverUrl = session.serverUrl, + query = state.searchQuery, + onQueryChange = vm::setSearchQuery, + modifier = Modifier.weight(1f), + ) + F7CreateButton(onClick = vm::openAddSheet, size = 40.dp) + } if (state.syncing && state.contacts.isNotEmpty()) { Text( "Обновление…", @@ -297,12 +310,11 @@ private fun ContactsSearchBar( serverUrl: String, query: String, onQueryChange: (String) -> Unit, + modifier: Modifier = Modifier, ) { val base = serverUrl.trimEnd('/') Box( - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 8.dp) + modifier = modifier .height(40.dp) .shadow(2.dp, RoundedCornerShape(100.dp), spotColor = Color(0xFFCBCBCB)) .clip(RoundedCornerShape(100.dp)) diff --git a/feature/files/src/main/java/ru/forbion/f7cloud/feature/files/FilesScreen.kt b/feature/files/src/main/java/ru/forbion/f7cloud/feature/files/FilesScreen.kt index 79f5cfe..6e88dda 100644 --- a/feature/files/src/main/java/ru/forbion/f7cloud/feature/files/FilesScreen.kt +++ b/feature/files/src/main/java/ru/forbion/f7cloud/feature/files/FilesScreen.kt @@ -41,6 +41,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel import ru.forbion.f7cloud.core.auth.AuthSession import ru.forbion.f7cloud.core.designsystem.F7AlertDialog import ru.forbion.f7cloud.core.designsystem.F7Colors +import ru.forbion.f7cloud.core.designsystem.F7CreateButton import ru.forbion.f7cloud.core.designsystem.F7ModuleScreen import ru.forbion.f7cloud.core.designsystem.F7OverlayDismissHandler import ru.forbion.f7cloud.core.designsystem.F7OutlinedField @@ -189,6 +190,9 @@ fun FilesScreen( FilesViewToggleButton(viewMode) { viewMode = if (viewMode == FilesViewMode.List) FilesViewMode.Grid else FilesViewMode.List } + // Создание (загрузка/новая папка) — раньше вызывалось из нижней панели, + // теперь кнопка в шапке (нижняя панель стала навигационной) + F7CreateButton(onClick = { showCreateMenu = true }, size = 40.dp) } // Хлебные крошки val crumbSegments = state.currentPath.split("/").filter { it.isNotBlank() }