menu: лончер приложений → bottom-sheet на пол-экрана (v0.5.116/124)
F7AppMenuSheet был fillMaxSize с непрозрачным фоном (закрывал весь экран). Теперь выезжает снизу и занимает ~пол-экрана: якорь BottomCenter, fillMaxHeight(0.6f), скруглённый верх 20dp + тень, ручка-хендл, лёгкий скрим над листом (тап закрывает), зазор под нижнюю панель, сетка иконок скроллится. Экран под меню виден сверху. Бамп версии 0.5.115→0.5.116.
This commit is contained in:
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
Формат: `ГГГГ-ММ-ДД | версия | изменение | контракты | риск`
|
Формат: `ГГГГ-ММ-ДД | версия | изменение | контракты | риск`
|
||||||
|
|
||||||
|
- 2026-07-08 | v0.5.116 (124) | Меню-лончер (сетка приложений) → bottom-sheet на пол-экрана (требование владельца «выходить снизу вверх только на пол экрана»). `F7AppMenuSheet` был `fillMaxSize` с непрозрачным фоном → закрывал весь экран. Теперь: якорь снизу (`Alignment.BottomCenter`), высота `fillMaxHeight(0.6f)`, скруглённый верх (20dp) + тень, ручка-хендл, лёгкий скрим (0.18) над листом с тапом-для-закрытия, зазор `BottomBarReserve` под нижнюю панель, сетка иконок скроллится (`weight(1f)`). Экран под меню теперь виден сверху. Компилируется | контракты не менялись | низкий: только оверлей меню
|
||||||
|
|
||||||
- 2026-07-08 | v0.5.115 (123) | Бамп версии под дизайн-веху (0.5.114→0.5.115, code 122→123, стиль проекта: патч +1 / code +1). До этого Этапы 0/1 + весь дизайн ошибочно шли одной WIP-линией 0.5.114 (122) — теперь ревью-сборки дизайна помечены отдельной версией. Дальше — бампить на каждую заметную веху/ревью-сборку | версионирование | нет: только versionCode/Name
|
- 2026-07-08 | v0.5.115 (123) | Бамп версии под дизайн-веху (0.5.114→0.5.115, code 122→123, стиль проекта: патч +1 / code +1). До этого Этапы 0/1 + весь дизайн ошибочно шли одной WIP-линией 0.5.114 (122) — теперь ревью-сборки дизайна помечены отдельной версией. Дальше — бампить на каждую заметную веху/ревью-сборку | версионирование | нет: только versionCode/Name
|
||||||
|
|
||||||
- 2026-07-08 | v0.5.114 (122) | Дизайн Календаря (месячная сетка): по «Календарь · Месяц» — дни недели вынесены в серые пилюли; сетка стала безрамочной с тонкими гридлайнами (0.5dp Grey3) вместо скруглённых боксов; номер дня сверху-слева; сегодня — белое число в зелёном круге; событие — зелёная пилюля PrimaryLight (до 2 шт + «+N») вместо одного превью/точки. Компактная мобильная модель (месяц сверху + список событий выбранного дня снизу) сохранена — не десктопная таблица. `CalendarMonthGrid`/`CalendarDayCell`, убран неиспользуемый параметр daysWithEvents. Проверено сборкой | контракты не менялись | низкий: только вид месяца
|
- 2026-07-08 | v0.5.114 (122) | Дизайн Календаря (месячная сетка): по «Календарь · Месяц» — дни недели вынесены в серые пилюли; сетка стала безрамочной с тонкими гридлайнами (0.5dp Grey3) вместо скруглённых боксов; номер дня сверху-слева; сегодня — белое число в зелёном круге; событие — зелёная пилюля PrimaryLight (до 2 шт + «+N») вместо одного превью/точки. Компактная мобильная модель (месяц сверху + список событий выбранного дня снизу) сохранена — не десктопная таблица. `CalendarMonthGrid`/`CalendarDayCell`, убран неиспользуемый параметр daysWithEvents. Проверено сборкой | контракты не менялись | низкий: только вид месяца
|
||||||
|
|||||||
+2
-2
@@ -39,8 +39,8 @@ android {
|
|||||||
applicationId 'ru.forbion.f7cloud.mobile'
|
applicationId 'ru.forbion.f7cloud.mobile'
|
||||||
minSdk 26
|
minSdk 26
|
||||||
targetSdk 36
|
targetSdk 36
|
||||||
versionCode 123
|
versionCode 124
|
||||||
versionName '0.5.115'
|
versionName '0.5.116'
|
||||||
missingDimensionStrategy 'default', 'f7'
|
missingDimensionStrategy 'default', 'f7'
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
|
|
||||||
|
|||||||
+74
-31
@@ -9,10 +9,12 @@ import androidx.compose.animation.slideOutVertically
|
|||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.border
|
import androidx.compose.foundation.border
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
@@ -35,6 +37,7 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.draw.shadow
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.SolidColor
|
import androidx.compose.ui.graphics.SolidColor
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
@@ -51,6 +54,10 @@ private val BottomBarReserve: Dp = 90.dp
|
|||||||
private val MenuIconSize = 62.dp
|
private val MenuIconSize = 62.dp
|
||||||
private val MenuGridGap = 20.dp
|
private val MenuGridGap = 20.dp
|
||||||
|
|
||||||
|
// Меню-лист выезжает снизу и занимает ~пол-экрана (не весь), по требованию владельца
|
||||||
|
private const val MenuSheetHeightFraction = 0.6f
|
||||||
|
private val MenuSheetShape = RoundedCornerShape(topStart = 20.dp, topEnd = 20.dp)
|
||||||
|
|
||||||
data class F7AppMenuItem(
|
data class F7AppMenuItem(
|
||||||
val label: String,
|
val label: String,
|
||||||
val iconUrl: String,
|
val iconUrl: String,
|
||||||
@@ -78,41 +85,76 @@ fun F7AppMenuSheet(
|
|||||||
}
|
}
|
||||||
val base = serverUrl.trimEnd('/')
|
val base = serverUrl.trimEnd('/')
|
||||||
|
|
||||||
AnimatedVisibility(
|
Box(modifier = modifier.fillMaxSize()) {
|
||||||
visible = visible,
|
// Затемнение над листом — тап закрывает меню (лист занимает только низ экрана)
|
||||||
enter = fadeIn(tween(250)) + slideInVertically(
|
AnimatedVisibility(
|
||||||
animationSpec = tween(350),
|
visible = visible,
|
||||||
initialOffsetY = { it },
|
enter = fadeIn(tween(200)),
|
||||||
),
|
exit = fadeOut(tween(200)),
|
||||||
exit = fadeOut(tween(200)) + slideOutVertically(
|
modifier = Modifier.fillMaxSize(),
|
||||||
animationSpec = tween(300),
|
|
||||||
targetOffsetY = { it },
|
|
||||||
),
|
|
||||||
modifier = modifier,
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.padding(bottom = BottomBarReserve)
|
|
||||||
.navigationBarsPadding()
|
|
||||||
.background(F7Colors.Background)
|
|
||||||
.padding(start = 16.dp, end = 16.dp, top = 16.dp, bottom = 8.dp),
|
|
||||||
) {
|
) {
|
||||||
F7AppMenuSearchField(
|
Box(
|
||||||
serverUrl = base,
|
modifier = Modifier
|
||||||
value = searchQuery,
|
.fillMaxSize()
|
||||||
onValueChange = { searchQuery = it },
|
.background(Color.Black.copy(alpha = 0.18f))
|
||||||
|
.clickable(
|
||||||
|
interactionSource = remember { MutableInteractionSource() },
|
||||||
|
indication = null,
|
||||||
|
onClick = onDismiss,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
// Сам лист — выезжает снизу вверх на ~пол-экрана, скруглённый верх + тень
|
||||||
|
AnimatedVisibility(
|
||||||
|
visible = visible,
|
||||||
|
enter = fadeIn(tween(250)) + slideInVertically(
|
||||||
|
animationSpec = tween(350),
|
||||||
|
initialOffsetY = { it },
|
||||||
|
),
|
||||||
|
exit = fadeOut(tween(200)) + slideOutVertically(
|
||||||
|
animationSpec = tween(300),
|
||||||
|
targetOffsetY = { it },
|
||||||
|
),
|
||||||
|
modifier = Modifier.align(Alignment.BottomCenter),
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(bottom = 24.dp),
|
.fillMaxHeight(MenuSheetHeightFraction)
|
||||||
)
|
.padding(bottom = BottomBarReserve)
|
||||||
LazyVerticalGrid(
|
.navigationBarsPadding()
|
||||||
columns = GridCells.Fixed(4),
|
.shadow(16.dp, MenuSheetShape, clip = false)
|
||||||
horizontalArrangement = Arrangement.spacedBy(MenuGridGap),
|
.clip(MenuSheetShape)
|
||||||
verticalArrangement = Arrangement.spacedBy(MenuGridGap),
|
.background(F7Colors.Background)
|
||||||
contentPadding = PaddingValues(horizontal = 2.dp),
|
.padding(start = 16.dp, end = 16.dp, top = 8.dp, bottom = 8.dp),
|
||||||
modifier = Modifier.fillMaxSize(),
|
|
||||||
) {
|
) {
|
||||||
|
// Ручка-хендл
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.CenterHorizontally)
|
||||||
|
.padding(top = 2.dp, bottom = 10.dp)
|
||||||
|
.width(40.dp)
|
||||||
|
.height(4.dp)
|
||||||
|
.clip(RoundedCornerShape(2.dp))
|
||||||
|
.background(F7Colors.Border),
|
||||||
|
)
|
||||||
|
F7AppMenuSearchField(
|
||||||
|
serverUrl = base,
|
||||||
|
value = searchQuery,
|
||||||
|
onValueChange = { searchQuery = it },
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(bottom = 20.dp),
|
||||||
|
)
|
||||||
|
LazyVerticalGrid(
|
||||||
|
columns = GridCells.Fixed(4),
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(MenuGridGap),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(MenuGridGap),
|
||||||
|
contentPadding = PaddingValues(horizontal = 2.dp),
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.weight(1f),
|
||||||
|
) {
|
||||||
itemsIndexed(
|
itemsIndexed(
|
||||||
items = filteredItems,
|
items = filteredItems,
|
||||||
key = { index, item -> "${item.label}-$index" },
|
key = { index, item -> "${item.label}-$index" },
|
||||||
@@ -132,6 +174,7 @@ fun F7AppMenuSheet(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user