From fd341cb22aefa397ef23959f2d665cb5d007726b Mon Sep 17 00:00:00 2001 From: b-dev-mobile Date: Fri, 10 Jul 2026 06:43:56 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20=D0=BD=D0=B8=D0=B6=D0=BD=D1=8F=D1=8F=20?= =?UTF-8?q?=D0=BF=D0=B0=D0=BD=D0=B5=D0=BB=D1=8C=201:1=20=D1=81=20=D1=81?= =?UTF-8?q?=D0=B0=D0=B9=D1=82=D0=BE=D0=BC=20(=D0=97=D0=B0=D0=B4=D0=B0?= =?UTF-8?q?=D1=87=D0=B8=20+=20mobile-=D0=B8=D0=BA=D0=BE=D0=BD=D0=BA=D0=B8)?= =?UTF-8?q?;=20Deck=20=D0=BE=D1=82=D0=BA=D1=80=D1=8B=D0=B2=D0=B0=D0=B5?= =?UTF-8?q?=D1=82=D1=81=D1=8F=20=D1=83=D1=81=D1=82=D0=BE=D0=B9=D1=87=D0=B8?= =?UTF-8?q?=D0=B2=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Нижняя панель (по layout.user.php сайта): средняя кнопка = ЗАДАЧИ (была Карточки) — по решению владельца «как на сайте»; иконки из набора mobile-*-icon (плоский конверт mobile-mail-icon вместо конверта-с-@, mobile-tasks-icon, mobile-spreed-icon вебкамера, mobile-burger-icon), локально/офлайн; размеры 25dp (app-link) как на сайте, стрелка «назад» 18dp. Карточки остаются в шторке-меню. Deck: loadBoardDetail больше не рушится, если GET /boards/{id} (метки/права) не отвечает — стеки грузятся всё равно (вероятная причина «доска не открывается» на устройстве). Заголовок/метки/права подставляются best-effort. Co-Authored-By: Claude Fable 5 --- .../forbion/f7cloud/mobile/ui/AppScaffold.kt | 6 ++-- .../main/assets/menu/mobile-burger-icon.svg | 5 +++ .../src/main/assets/menu/mobile-mail-icon.svg | 5 +++ .../main/assets/menu/mobile-spreed-icon.svg | 14 ++++++++ .../main/assets/menu/mobile-tasks-icon.svg | 12 +++++++ .../main/assets/menu/sidebar-chevron-left.svg | 3 ++ .../core/designsystem/F7BottomBarConfig.kt | 10 +++--- .../core/designsystem/F7MobileBottomBar.kt | 36 ++++++++++--------- .../f7cloud/feature/deck/DeckRepository.kt | 16 ++++++--- 9 files changed, 77 insertions(+), 30 deletions(-) create mode 100644 core/designsystem/src/main/assets/menu/mobile-burger-icon.svg create mode 100644 core/designsystem/src/main/assets/menu/mobile-mail-icon.svg create mode 100644 core/designsystem/src/main/assets/menu/mobile-spreed-icon.svg create mode 100644 core/designsystem/src/main/assets/menu/mobile-tasks-icon.svg create mode 100644 core/designsystem/src/main/assets/menu/sidebar-chevron-left.svg 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 d123553..148b228 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 @@ -469,10 +469,10 @@ fun AppScaffold( activeTab = AppTab.Mail } }, - onCardsClick = { - if (activeTab != AppTab.Deck) { + onTasksClick = { + if (activeTab != AppTab.Tasks) { pushTabHistory(activeTab) - activeTab = AppTab.Deck + activeTab = AppTab.Tasks } }, onConferencesClick = { diff --git a/core/designsystem/src/main/assets/menu/mobile-burger-icon.svg b/core/designsystem/src/main/assets/menu/mobile-burger-icon.svg new file mode 100644 index 0000000..653853e --- /dev/null +++ b/core/designsystem/src/main/assets/menu/mobile-burger-icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/core/designsystem/src/main/assets/menu/mobile-mail-icon.svg b/core/designsystem/src/main/assets/menu/mobile-mail-icon.svg new file mode 100644 index 0000000..c889812 --- /dev/null +++ b/core/designsystem/src/main/assets/menu/mobile-mail-icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/core/designsystem/src/main/assets/menu/mobile-spreed-icon.svg b/core/designsystem/src/main/assets/menu/mobile-spreed-icon.svg new file mode 100644 index 0000000..0429be7 --- /dev/null +++ b/core/designsystem/src/main/assets/menu/mobile-spreed-icon.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/core/designsystem/src/main/assets/menu/mobile-tasks-icon.svg b/core/designsystem/src/main/assets/menu/mobile-tasks-icon.svg new file mode 100644 index 0000000..d9f4849 --- /dev/null +++ b/core/designsystem/src/main/assets/menu/mobile-tasks-icon.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/core/designsystem/src/main/assets/menu/sidebar-chevron-left.svg b/core/designsystem/src/main/assets/menu/sidebar-chevron-left.svg new file mode 100644 index 0000000..61a0ea5 --- /dev/null +++ b/core/designsystem/src/main/assets/menu/sidebar-chevron-left.svg @@ -0,0 +1,3 @@ + + + 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 42e51c3..5f1ed05 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 @@ -4,7 +4,7 @@ enum class F7BottomBarSlot { Chats, NavBack, SectionMail, - SectionCards, + SectionTasks, SectionConferences, Menu, } @@ -15,10 +15,8 @@ data class F7BottomBarConfig( val buttonCount: Int get() = slots.size companion object { - // Единая навигационная панель по дизайну «Новое меню»: - // слева «назад», затем ярлыки-разделы Почта · Карточки · Конференции, - // справа — выдвижное меню. Кнопки «чаты» (по просьбе владельца убрана), - // профиль/уведомления/настройки/создать в панели нет (меню и шапки экранов). + // Нижняя панель 1:1 с мобильным сайтом forbion (layout.user.php): + // «назад», затем ярлыки-разделы Почта · Задачи · Конференции, справа — меню. @Suppress("UNUSED_PARAMETER") fun forContext( tabKey: String, @@ -27,7 +25,7 @@ data class F7BottomBarConfig( listOf( F7BottomBarSlot.NavBack, F7BottomBarSlot.SectionMail, - F7BottomBarSlot.SectionCards, + F7BottomBarSlot.SectionTasks, F7BottomBarSlot.SectionConferences, F7BottomBarSlot.Menu, ), 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 6075a7e..72d869c 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 @@ -30,19 +30,24 @@ data class F7BottomBarActions( val onChatsClick: () -> Unit = {}, val onNavBackClick: () -> Unit = {}, val onMailClick: () -> Unit = {}, - val onCardsClick: () -> Unit = {}, + val onTasksClick: () -> Unit = {}, val onConferencesClick: () -> Unit = {}, val onMenuClick: () -> Unit = {}, ) +// Иконки нижней панели — ЛОКАЛЬНЫЕ mobile-*-icon из живой темы (assets/menu/), 1:1 с сайтом. +private fun barIcon(name: String): String = "file:///android_asset/menu/$name" + // Живой forbion (_header.css .header__mobile-bottom): пилюля 328×61, паддинг 3, // фон #F5F5F5; кнопки 55, фон #FBFBFB, рамка #E6E6E6; активная кнопка-раздел и открытый // бургер — полупрозрачный зелёный градиент 104°. private val BottomBarWidth = 328.dp private val BottomBarHeight = 61.dp private val BottomBarButtonSize = 55.dp -private val BottomBarIconSize = 34.dp -private val BottomBarSectionIconSize = 46.dp +// Живой сайт: app-link/бургер img = 25px; стрелка «назад» мельче. +private val BottomBarIconSize = 25.dp +private val BottomBarSectionIconSize = 25.dp +private val BottomBarBackIconSize = 18.dp private val BottomBarOuterPadding = 3.dp private val BottomBarButtonShape = RoundedCornerShape(100.dp) private val BottomBarButtonBg = Color(0xFFFBFBFB) @@ -94,38 +99,35 @@ fun F7MobileBottomBar( onClick = actions.onChatsClick, ) F7BottomBarSlot.NavBack -> F7BottomBarIconSlot( - iconUrl = "$base/themes/forbion/images/header/sidebar-chevron-left.svg", - contentDescription = "Папки", + iconUrl = barIcon("sidebar-chevron-left.svg"), + contentDescription = "Назад", + iconSize = BottomBarBackIconSize, iconRotation = if (navBackHighlighted) 180f else 0f, onClick = actions.onNavBackClick, ) F7BottomBarSlot.SectionMail -> F7BottomBarIconSlot( - iconUrl = "$base/themes/forbion/images/header/mail-header-icon.svg", + iconUrl = barIcon("mobile-mail-icon.svg"), contentDescription = "Почта", iconSize = BottomBarSectionIconSize, active = activeTabKey.equals("mail", ignoreCase = true), onClick = actions.onMailClick, ) - F7BottomBarSlot.SectionCards -> F7BottomBarIconSlot( - iconUrl = "$base/themes/forbion/images/header/deck-header-icon.svg", - contentDescription = "Карточки", + F7BottomBarSlot.SectionTasks -> F7BottomBarIconSlot( + iconUrl = barIcon("mobile-tasks-icon.svg"), + contentDescription = "Задачи", iconSize = BottomBarSectionIconSize, - active = activeTabKey.equals("deck", ignoreCase = true), - onClick = actions.onCardsClick, + active = activeTabKey.equals("tasks", ignoreCase = true), + onClick = actions.onTasksClick, ) F7BottomBarSlot.SectionConferences -> F7BottomBarIconSlot( - iconUrl = "$base/themes/forbion/images/header/spreed-header-icon.svg", + iconUrl = barIcon("mobile-spreed-icon.svg"), contentDescription = "Конференции", iconSize = BottomBarSectionIconSize, active = activeTabKey.equals("talk", ignoreCase = true), onClick = actions.onConferencesClick, ) F7BottomBarSlot.Menu -> F7BottomBarIconSlot( - iconUrl = if (menuOpen) { - "$base/themes/forbion/images/header/menu-burger-green.svg" - } else { - "$base/themes/forbion/images/header/menu-burger-gray.svg" - }, + iconUrl = barIcon("mobile-burger-icon.svg"), contentDescription = "Меню", active = menuOpen, showBadge = showNotificationBadge, diff --git a/feature/deck/src/main/java/ru/forbion/f7cloud/feature/deck/DeckRepository.kt b/feature/deck/src/main/java/ru/forbion/f7cloud/feature/deck/DeckRepository.kt index 5ef1279..984900e 100644 --- a/feature/deck/src/main/java/ru/forbion/f7cloud/feature/deck/DeckRepository.kt +++ b/feature/deck/src/main/java/ru/forbion/f7cloud/feature/deck/DeckRepository.kt @@ -50,9 +50,17 @@ class DeckRepository { suspend fun loadBoardDetail(session: AuthSession, boardId: Int): DeckBoardDetail { val c = client(session) - val board = getJson(c, "${apiBase(session)}/boards/$boardId") as JSONObject - val labels = parseLabels(board.optJSONArray("labels")) - val canEdit = board.optJSONObject("permissions")?.optBoolean("PERMISSION_EDIT", true) ?: true + // Доска-объект (метки/права) — НЕ критична: если запрос упадёт, доску всё равно + // открываем со стеками (раньше был баг — сбой board#read рушил всю загрузку). + var boardTitle = "" + var labels = emptyList() + var canEdit = true + runCatching { getJson(c, "${apiBase(session)}/boards/$boardId") as JSONObject } + .onSuccess { board -> + boardTitle = board.optString("title") + labels = parseLabels(board.optJSONArray("labels")) + canEdit = board.optJSONObject("permissions")?.optBoolean("PERMISSION_EDIT", true) ?: true + } val stacksJson = getJson(c, "${apiBase(session)}/boards/$boardId/stacks") as? JSONArray ?: JSONArray() val stacks = mutableListOf() for (i in 0 until stacksJson.length()) { @@ -74,7 +82,7 @@ class DeckRepository { } return DeckBoardDetail( boardId = boardId, - title = board.optString("title"), + title = boardTitle, canEdit = canEdit, labels = labels, stacks = stacks.sortedBy { it.order },