Merge pull request #5599 from element-hq/feature/fga/home_topbar_2
Design : update Home TopBar and RoomList Filters
This commit is contained in:
commit
0745f308c5
50 changed files with 333 additions and 288 deletions
|
|
@ -32,5 +32,6 @@ data class HomeState(
|
|||
val eventSink: (HomeEvents) -> Unit,
|
||||
) {
|
||||
val displayActions = currentHomeNavigationBarItem == HomeNavigationBarItem.Chats
|
||||
val displayRoomListFilters = currentHomeNavigationBarItem == HomeNavigationBarItem.Chats && roomListState.displayFilters
|
||||
val showNavigationBar = isSpaceFeatureEnabled && homeSpacesState.spaceRooms.isNotEmpty()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import androidx.compose.foundation.layout.calculateStartPadding
|
|||
import androidx.compose.foundation.layout.consumeWindowInsets
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
|
|
@ -39,9 +40,9 @@ import dev.chrisbanes.haze.materials.HazeMaterials
|
|||
import dev.chrisbanes.haze.rememberHazeState
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.compound.tokens.generated.CompoundIcons
|
||||
import io.element.android.features.home.impl.components.HomeTopBar
|
||||
import io.element.android.features.home.impl.components.RoomListContentView
|
||||
import io.element.android.features.home.impl.components.RoomListMenuAction
|
||||
import io.element.android.features.home.impl.components.RoomListTopBar
|
||||
import io.element.android.features.home.impl.model.RoomListRoomSummary
|
||||
import io.element.android.features.home.impl.roomlist.RoomListContextMenu
|
||||
import io.element.android.features.home.impl.roomlist.RoomListDeclineInviteMenu
|
||||
|
|
@ -62,6 +63,7 @@ import io.element.android.libraries.designsystem.theme.components.Scaffold
|
|||
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarHost
|
||||
import io.element.android.libraries.designsystem.utils.snackbar.rememberSnackbarHostState
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
fun HomeView(
|
||||
|
|
@ -143,7 +145,7 @@ private fun HomeScaffold(
|
|||
}
|
||||
|
||||
val appBarState = rememberTopAppBarState()
|
||||
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(appBarState)
|
||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(appBarState)
|
||||
val snackbarHostState = rememberSnackbarHostState(snackbarMessage = state.snackbarMessage)
|
||||
val roomListState: RoomListState = state.roomListState
|
||||
|
||||
|
|
@ -154,11 +156,13 @@ private fun HomeScaffold(
|
|||
}
|
||||
|
||||
val hazeState = rememberHazeState()
|
||||
val roomsLazyListState = rememberLazyListState()
|
||||
val spacesLazyListState = rememberLazyListState()
|
||||
|
||||
Scaffold(
|
||||
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
topBar = {
|
||||
RoomListTopBar(
|
||||
HomeTopBar(
|
||||
title = stringResource(state.currentHomeNavigationBarItem.labelRes),
|
||||
currentUserAndNeighbors = state.currentUserAndNeighbors,
|
||||
showAvatarIndicator = state.showAvatarIndicator,
|
||||
|
|
@ -171,7 +175,7 @@ private fun HomeScaffold(
|
|||
},
|
||||
scrollBehavior = scrollBehavior,
|
||||
displayMenuItems = state.displayActions,
|
||||
displayFilters = roomListState.displayFilters && state.currentHomeNavigationBarItem == HomeNavigationBarItem.Chats,
|
||||
displayFilters = state.displayRoomListFilters,
|
||||
filtersState = roomListState.filtersState,
|
||||
canReportBug = state.canReportBug,
|
||||
modifier = if (state.isSpaceFeatureEnabled) {
|
||||
|
|
@ -180,41 +184,39 @@ private fun HomeScaffold(
|
|||
style = HazeMaterials.thick(),
|
||||
)
|
||||
} else {
|
||||
Modifier
|
||||
.background(ElementTheme.colors.bgCanvasDefault)
|
||||
Modifier.background(ElementTheme.colors.bgCanvasDefault)
|
||||
}
|
||||
)
|
||||
},
|
||||
bottomBar = {
|
||||
if (state.showNavigationBar) {
|
||||
NavigationBar(
|
||||
containerColor = Color.Transparent,
|
||||
modifier = Modifier
|
||||
.hazeEffect(
|
||||
state = hazeState,
|
||||
style = HazeMaterials.thick(),
|
||||
)
|
||||
) {
|
||||
HomeNavigationBarItem.entries.forEach { item ->
|
||||
val isSelected = state.currentHomeNavigationBarItem == item
|
||||
NavigationBarItem(
|
||||
selected = isSelected,
|
||||
onClick = {
|
||||
state.eventSink(HomeEvents.SelectHomeNavigationBarItem(item))
|
||||
},
|
||||
icon = {
|
||||
NavigationBarIcon(
|
||||
imageVector = item.icon(isSelected),
|
||||
)
|
||||
},
|
||||
label = {
|
||||
NavigationBarText(
|
||||
text = stringResource(item.labelRes),
|
||||
)
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
HomeBottomBar(
|
||||
currentHomeNavigationBarItem = state.currentHomeNavigationBarItem,
|
||||
onItemClick = { item ->
|
||||
// scroll to top if selecting the same item
|
||||
if (item == state.currentHomeNavigationBarItem) {
|
||||
val lazyListStateTarget = when (item) {
|
||||
HomeNavigationBarItem.Chats -> roomsLazyListState
|
||||
HomeNavigationBarItem.Spaces -> spacesLazyListState
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
coroutineScope.launch {
|
||||
if (lazyListStateTarget.firstVisibleItemIndex > 10) {
|
||||
lazyListStateTarget.scrollToItem(10)
|
||||
}
|
||||
// Also reset the scrollBehavior height offset as it's not triggered by programmatic scrolls
|
||||
scrollBehavior.state.heightOffset = 0f
|
||||
lazyListStateTarget.animateScrollToItem(0)
|
||||
}
|
||||
} else {
|
||||
state.eventSink(HomeEvents.SelectHomeNavigationBarItem(item))
|
||||
}
|
||||
},
|
||||
modifier = Modifier.hazeEffect(
|
||||
state = hazeState,
|
||||
style = HazeMaterials.thick(),
|
||||
)
|
||||
)
|
||||
}
|
||||
},
|
||||
content = { padding ->
|
||||
|
|
@ -223,6 +225,7 @@ private fun HomeScaffold(
|
|||
RoomListContentView(
|
||||
contentState = roomListState.contentState,
|
||||
filtersState = roomListState.filtersState,
|
||||
lazyListState = roomsLazyListState,
|
||||
hideInvitesAvatars = roomListState.hideInvitesAvatars,
|
||||
eventSink = roomListState.eventSink,
|
||||
onSetUpRecoveryClick = onSetUpRecoveryClick,
|
||||
|
|
@ -260,6 +263,7 @@ private fun HomeScaffold(
|
|||
.consumeWindowInsets(padding)
|
||||
.hazeSource(state = hazeState),
|
||||
state = state.homeSpacesState,
|
||||
lazyListState = spacesLazyListState,
|
||||
onSpaceClick = { spaceId ->
|
||||
onRoomClick(spaceId)
|
||||
}
|
||||
|
|
@ -283,6 +287,38 @@ private fun HomeScaffold(
|
|||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun HomeBottomBar(
|
||||
currentHomeNavigationBarItem: HomeNavigationBarItem,
|
||||
onItemClick: (HomeNavigationBarItem) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
NavigationBar(
|
||||
containerColor = Color.Transparent,
|
||||
modifier = modifier
|
||||
) {
|
||||
HomeNavigationBarItem.entries.forEach { item ->
|
||||
val isSelected = currentHomeNavigationBarItem == item
|
||||
NavigationBarItem(
|
||||
selected = isSelected,
|
||||
onClick = {
|
||||
onItemClick(item)
|
||||
},
|
||||
icon = {
|
||||
NavigationBarIcon(
|
||||
imageVector = item.icon(isSelected),
|
||||
)
|
||||
},
|
||||
label = {
|
||||
NavigationBarText(
|
||||
text = stringResource(item.labelRes),
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun RoomListRoomSummary.contentType() = displayType.ordinal
|
||||
|
||||
@PreviewsDayNight
|
||||
|
|
|
|||
|
|
@ -10,14 +10,12 @@ package io.element.android.features.home.impl.components
|
|||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.statusBarsPadding
|
||||
import androidx.compose.foundation.pager.VerticalPager
|
||||
import androidx.compose.foundation.pager.rememberPagerState
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.TopAppBarScrollBehavior
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
|
|
@ -32,7 +30,6 @@ import androidx.compose.runtime.setValue
|
|||
import androidx.compose.runtime.snapshotFlow
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.semantics.heading
|
||||
|
|
@ -46,22 +43,20 @@ import io.element.android.features.home.impl.filters.RoomListFiltersState
|
|||
import io.element.android.features.home.impl.filters.RoomListFiltersView
|
||||
import io.element.android.features.home.impl.filters.aRoomListFiltersState
|
||||
import io.element.android.libraries.designsystem.atomic.atoms.RedIndicatorAtom
|
||||
import io.element.android.libraries.designsystem.components.TopAppBarScrollBehaviorLayout
|
||||
import io.element.android.libraries.designsystem.components.avatar.Avatar
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarType
|
||||
import io.element.android.libraries.designsystem.modifiers.backgroundVerticalGradient
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.text.applyScaleDown
|
||||
import io.element.android.libraries.designsystem.text.toSp
|
||||
import io.element.android.libraries.designsystem.theme.aliasScreenTitle
|
||||
import io.element.android.libraries.designsystem.theme.components.DropdownMenu
|
||||
import io.element.android.libraries.designsystem.theme.components.DropdownMenuItem
|
||||
import io.element.android.libraries.designsystem.theme.components.HorizontalDivider
|
||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
||||
import io.element.android.libraries.designsystem.theme.components.IconButton
|
||||
import io.element.android.libraries.designsystem.theme.components.MediumTopAppBar
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.designsystem.theme.components.TopAppBar
|
||||
import io.element.android.libraries.matrix.api.core.SessionId
|
||||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
import io.element.android.libraries.matrix.api.user.MatrixUser
|
||||
|
|
@ -76,7 +71,7 @@ import kotlinx.collections.immutable.toImmutableList
|
|||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun RoomListTopBar(
|
||||
fun HomeTopBar(
|
||||
title: String,
|
||||
currentUserAndNeighbors: ImmutableList<MatrixUser>,
|
||||
showAvatarIndicator: Boolean,
|
||||
|
|
@ -87,169 +82,113 @@ fun RoomListTopBar(
|
|||
onAccountSwitch: (SessionId) -> Unit,
|
||||
scrollBehavior: TopAppBarScrollBehavior,
|
||||
displayMenuItems: Boolean,
|
||||
canReportBug: Boolean,
|
||||
displayFilters: Boolean,
|
||||
filtersState: RoomListFiltersState,
|
||||
canReportBug: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
DefaultRoomListTopBar(
|
||||
title = title,
|
||||
currentUserAndNeighbors = currentUserAndNeighbors,
|
||||
showAvatarIndicator = showAvatarIndicator,
|
||||
areSearchResultsDisplayed = areSearchResultsDisplayed,
|
||||
onOpenSettings = onOpenSettings,
|
||||
onAccountSwitch = onAccountSwitch,
|
||||
onSearchClick = onToggleSearch,
|
||||
onMenuActionClick = onMenuActionClick,
|
||||
scrollBehavior = scrollBehavior,
|
||||
displayMenuItems = displayMenuItems,
|
||||
displayFilters = displayFilters,
|
||||
filtersState = filtersState,
|
||||
canReportBug = canReportBug,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
private fun DefaultRoomListTopBar(
|
||||
title: String,
|
||||
currentUserAndNeighbors: ImmutableList<MatrixUser>,
|
||||
showAvatarIndicator: Boolean,
|
||||
areSearchResultsDisplayed: Boolean,
|
||||
scrollBehavior: TopAppBarScrollBehavior,
|
||||
onOpenSettings: () -> Unit,
|
||||
onAccountSwitch: (SessionId) -> Unit,
|
||||
onSearchClick: () -> Unit,
|
||||
onMenuActionClick: (RoomListMenuAction) -> Unit,
|
||||
displayMenuItems: Boolean,
|
||||
displayFilters: Boolean,
|
||||
filtersState: RoomListFiltersState,
|
||||
canReportBug: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val collapsedFraction = scrollBehavior.state.collapsedFraction
|
||||
Box(modifier = modifier) {
|
||||
val collapsedTitleTextStyle = ElementTheme.typography.aliasScreenTitle
|
||||
val expandedTitleTextStyle = ElementTheme.typography.fontHeadingLgBold.copy(
|
||||
// Due to a limitation of MediumTopAppBar, and to avoid the text to be truncated,
|
||||
// ensure that the font size will never be bigger than 28.dp.
|
||||
fontSize = 28.dp.applyScaleDown().toSp()
|
||||
)
|
||||
MaterialTheme(
|
||||
colorScheme = ElementTheme.materialColors,
|
||||
shapes = MaterialTheme.shapes,
|
||||
typography = ElementTheme.materialTypography.copy(
|
||||
headlineSmall = expandedTitleTextStyle,
|
||||
titleLarge = collapsedTitleTextStyle
|
||||
Column(modifier) {
|
||||
TopAppBar(
|
||||
modifier = Modifier
|
||||
.backgroundVerticalGradient(
|
||||
isVisible = !areSearchResultsDisplayed,
|
||||
)
|
||||
.statusBarsPadding(),
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
containerColor = Color.Transparent,
|
||||
scrolledContainerColor = Color.Transparent,
|
||||
),
|
||||
) {
|
||||
Column {
|
||||
MediumTopAppBar(
|
||||
modifier = Modifier
|
||||
.backgroundVerticalGradient(
|
||||
isVisible = !areSearchResultsDisplayed,
|
||||
)
|
||||
.statusBarsPadding(),
|
||||
colors = TopAppBarDefaults.mediumTopAppBarColors(
|
||||
containerColor = Color.Transparent,
|
||||
scrolledContainerColor = Color.Transparent,
|
||||
),
|
||||
title = {
|
||||
Text(
|
||||
modifier = Modifier.semantics {
|
||||
heading()
|
||||
},
|
||||
text = title,
|
||||
)
|
||||
title = {
|
||||
Text(
|
||||
modifier = Modifier.semantics {
|
||||
heading()
|
||||
},
|
||||
navigationIcon = {
|
||||
NavigationIcon(
|
||||
currentUserAndNeighbors = currentUserAndNeighbors,
|
||||
showAvatarIndicator = showAvatarIndicator,
|
||||
onAccountSwitch = onAccountSwitch,
|
||||
onClick = onOpenSettings,
|
||||
style = ElementTheme.typography.aliasScreenTitle,
|
||||
text = title,
|
||||
)
|
||||
},
|
||||
navigationIcon = {
|
||||
NavigationIcon(
|
||||
currentUserAndNeighbors = currentUserAndNeighbors,
|
||||
showAvatarIndicator = showAvatarIndicator,
|
||||
onAccountSwitch = onAccountSwitch,
|
||||
onClick = onOpenSettings,
|
||||
)
|
||||
},
|
||||
actions = {
|
||||
if (displayMenuItems) {
|
||||
IconButton(
|
||||
onClick = onToggleSearch,
|
||||
) {
|
||||
Icon(
|
||||
imageVector = CompoundIcons.Search(),
|
||||
contentDescription = stringResource(CommonStrings.action_search),
|
||||
)
|
||||
},
|
||||
actions = {
|
||||
if (displayMenuItems) {
|
||||
IconButton(
|
||||
onClick = onSearchClick,
|
||||
) {
|
||||
Icon(
|
||||
imageVector = CompoundIcons.Search(),
|
||||
contentDescription = stringResource(CommonStrings.action_search),
|
||||
}
|
||||
if (RoomListConfig.HAS_DROP_DOWN_MENU) {
|
||||
var showMenu by remember { mutableStateOf(false) }
|
||||
IconButton(
|
||||
onClick = { showMenu = !showMenu }
|
||||
) {
|
||||
Icon(
|
||||
imageVector = CompoundIcons.OverflowVertical(),
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
DropdownMenu(
|
||||
expanded = showMenu,
|
||||
onDismissRequest = { showMenu = false }
|
||||
) {
|
||||
if (RoomListConfig.SHOW_INVITE_MENU_ITEM) {
|
||||
DropdownMenuItem(
|
||||
onClick = {
|
||||
showMenu = false
|
||||
onMenuActionClick(RoomListMenuAction.InviteFriends)
|
||||
},
|
||||
text = { Text(stringResource(id = CommonStrings.action_invite)) },
|
||||
leadingIcon = {
|
||||
Icon(
|
||||
imageVector = CompoundIcons.ShareAndroid(),
|
||||
tint = ElementTheme.colors.iconSecondary,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
if (RoomListConfig.HAS_DROP_DOWN_MENU) {
|
||||
var showMenu by remember { mutableStateOf(false) }
|
||||
IconButton(
|
||||
onClick = { showMenu = !showMenu }
|
||||
) {
|
||||
Icon(
|
||||
imageVector = CompoundIcons.OverflowVertical(),
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
DropdownMenu(
|
||||
expanded = showMenu,
|
||||
onDismissRequest = { showMenu = false }
|
||||
) {
|
||||
if (RoomListConfig.SHOW_INVITE_MENU_ITEM) {
|
||||
DropdownMenuItem(
|
||||
onClick = {
|
||||
showMenu = false
|
||||
onMenuActionClick(RoomListMenuAction.InviteFriends)
|
||||
},
|
||||
text = { Text(stringResource(id = CommonStrings.action_invite)) },
|
||||
leadingIcon = {
|
||||
Icon(
|
||||
imageVector = CompoundIcons.ShareAndroid(),
|
||||
tint = ElementTheme.colors.iconSecondary,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
if (RoomListConfig.SHOW_REPORT_PROBLEM_MENU_ITEM && canReportBug) {
|
||||
DropdownMenuItem(
|
||||
onClick = {
|
||||
showMenu = false
|
||||
onMenuActionClick(RoomListMenuAction.ReportBug)
|
||||
},
|
||||
text = { Text(stringResource(id = CommonStrings.common_report_a_problem)) },
|
||||
leadingIcon = {
|
||||
Icon(
|
||||
imageVector = CompoundIcons.ChatProblem(),
|
||||
tint = ElementTheme.colors.iconSecondary,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
if (RoomListConfig.SHOW_REPORT_PROBLEM_MENU_ITEM && canReportBug) {
|
||||
DropdownMenuItem(
|
||||
onClick = {
|
||||
showMenu = false
|
||||
onMenuActionClick(RoomListMenuAction.ReportBug)
|
||||
},
|
||||
text = { Text(stringResource(id = CommonStrings.common_report_a_problem)) },
|
||||
leadingIcon = {
|
||||
Icon(
|
||||
imageVector = CompoundIcons.ChatProblem(),
|
||||
tint = ElementTheme.colors.iconSecondary,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
scrollBehavior = scrollBehavior,
|
||||
windowInsets = WindowInsets(0.dp),
|
||||
)
|
||||
if (displayFilters) {
|
||||
RoomListFiltersView(
|
||||
state = filtersState,
|
||||
modifier = Modifier.padding(bottom = 16.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
// We want a 16dp left padding for the navigationIcon :
|
||||
// 4dp from default TopAppBarHorizontalPadding
|
||||
// 8dp from AccountIcon default padding (because of IconButton)
|
||||
// 4dp extra padding using left insets
|
||||
windowInsets = WindowInsets(left = 4.dp),
|
||||
)
|
||||
if (displayFilters) {
|
||||
TopAppBarScrollBehaviorLayout(scrollBehavior = scrollBehavior) {
|
||||
RoomListFiltersView(
|
||||
state = filtersState,
|
||||
modifier = Modifier.padding(bottom = 16.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
HorizontalDivider(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.alpha(collapsedFraction)
|
||||
.align(Alignment.BottomCenter),
|
||||
color = ElementTheme.materialColors.outlineVariant,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -301,9 +240,11 @@ private fun AccountIcon(
|
|||
isCurrentAccount: Boolean,
|
||||
showAvatarIndicator: Boolean,
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val testTag = if (isCurrentAccount) Modifier.testTag(TestTags.homeScreenSettings) else Modifier
|
||||
IconButton(
|
||||
modifier = if (isCurrentAccount) Modifier.testTag(TestTags.homeScreenSettings) else Modifier,
|
||||
modifier = modifier.then(testTag),
|
||||
onClick = onClick,
|
||||
) {
|
||||
Box {
|
||||
|
|
@ -329,20 +270,20 @@ private fun AccountIcon(
|
|||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun DefaultRoomListTopBarPreview() = ElementPreview {
|
||||
DefaultRoomListTopBar(
|
||||
internal fun HomeTopBarPreview() = ElementPreview {
|
||||
HomeTopBar(
|
||||
title = stringResource(R.string.screen_roomlist_main_space_title),
|
||||
currentUserAndNeighbors = persistentListOf(MatrixUser(UserId("@id:domain"), "Alice")),
|
||||
showAvatarIndicator = false,
|
||||
areSearchResultsDisplayed = false,
|
||||
scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(rememberTopAppBarState()),
|
||||
scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState()),
|
||||
onOpenSettings = {},
|
||||
onAccountSwitch = {},
|
||||
onSearchClick = {},
|
||||
onToggleSearch = {},
|
||||
displayMenuItems = true,
|
||||
canReportBug = true,
|
||||
displayFilters = true,
|
||||
filtersState = aRoomListFiltersState(),
|
||||
canReportBug = true,
|
||||
onMenuActionClick = {},
|
||||
)
|
||||
}
|
||||
|
|
@ -350,20 +291,20 @@ internal fun DefaultRoomListTopBarPreview() = ElementPreview {
|
|||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun DefaultRoomListTopBarWithIndicatorPreview() = ElementPreview {
|
||||
DefaultRoomListTopBar(
|
||||
internal fun HomeTopBarWithIndicatorPreview() = ElementPreview {
|
||||
HomeTopBar(
|
||||
title = stringResource(R.string.screen_roomlist_main_space_title),
|
||||
currentUserAndNeighbors = persistentListOf(MatrixUser(UserId("@id:domain"), "Alice")),
|
||||
showAvatarIndicator = true,
|
||||
areSearchResultsDisplayed = false,
|
||||
scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(rememberTopAppBarState()),
|
||||
scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState()),
|
||||
onOpenSettings = {},
|
||||
onAccountSwitch = {},
|
||||
onSearchClick = {},
|
||||
onToggleSearch = {},
|
||||
displayMenuItems = true,
|
||||
canReportBug = true,
|
||||
displayFilters = true,
|
||||
filtersState = aRoomListFiltersState(),
|
||||
canReportBug = true,
|
||||
onMenuActionClick = {},
|
||||
)
|
||||
}
|
||||
|
|
@ -371,20 +312,20 @@ internal fun DefaultRoomListTopBarWithIndicatorPreview() = ElementPreview {
|
|||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun DefaultRoomListTopBarMultiAccountPreview() = ElementPreview {
|
||||
DefaultRoomListTopBar(
|
||||
internal fun HomeTopBarMultiAccountPreview() = ElementPreview {
|
||||
HomeTopBar(
|
||||
title = stringResource(R.string.screen_roomlist_main_space_title),
|
||||
currentUserAndNeighbors = aMatrixUserList().take(3).toImmutableList(),
|
||||
showAvatarIndicator = false,
|
||||
areSearchResultsDisplayed = false,
|
||||
scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(rememberTopAppBarState()),
|
||||
scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState()),
|
||||
onOpenSettings = {},
|
||||
onAccountSwitch = {},
|
||||
onSearchClick = {},
|
||||
onToggleSearch = {},
|
||||
displayMenuItems = true,
|
||||
canReportBug = true,
|
||||
displayFilters = true,
|
||||
filtersState = aRoomListFiltersState(),
|
||||
canReportBug = true,
|
||||
onMenuActionClick = {},
|
||||
)
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@ import androidx.compose.foundation.layout.fillMaxSize
|
|||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.runtime.Composable
|
||||
|
|
@ -60,6 +61,7 @@ import kotlinx.collections.immutable.ImmutableList
|
|||
fun RoomListContentView(
|
||||
contentState: RoomListContentState,
|
||||
filtersState: RoomListFiltersState,
|
||||
lazyListState: LazyListState,
|
||||
hideInvitesAvatars: Boolean,
|
||||
eventSink: (RoomListEvents) -> Unit,
|
||||
onSetUpRecoveryClick: () -> Unit,
|
||||
|
|
@ -97,6 +99,7 @@ fun RoomListContentView(
|
|||
onSetUpRecoveryClick = onSetUpRecoveryClick,
|
||||
onConfirmRecoveryKeyClick = onConfirmRecoveryKeyClick,
|
||||
onRoomClick = onRoomClick,
|
||||
lazyListState = lazyListState,
|
||||
contentPadding = contentPadding,
|
||||
)
|
||||
}
|
||||
|
|
@ -176,6 +179,7 @@ private fun RoomsView(
|
|||
onConfirmRecoveryKeyClick: () -> Unit,
|
||||
onRoomClick: (RoomListRoomSummary) -> Unit,
|
||||
contentPadding: PaddingValues,
|
||||
lazyListState: LazyListState,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
if (state.summaries.isEmpty() && filtersState.hasAnyFilterSelected) {
|
||||
|
|
@ -192,6 +196,7 @@ private fun RoomsView(
|
|||
onConfirmRecoveryKeyClick = onConfirmRecoveryKeyClick,
|
||||
onRoomClick = onRoomClick,
|
||||
contentPadding = contentPadding,
|
||||
lazyListState = lazyListState,
|
||||
modifier = modifier.fillMaxSize(),
|
||||
)
|
||||
}
|
||||
|
|
@ -206,9 +211,9 @@ private fun RoomsViewList(
|
|||
onConfirmRecoveryKeyClick: () -> Unit,
|
||||
onRoomClick: (RoomListRoomSummary) -> Unit,
|
||||
contentPadding: PaddingValues,
|
||||
lazyListState: LazyListState,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val lazyListState = rememberLazyListState()
|
||||
val visibleRange by remember {
|
||||
derivedStateOf {
|
||||
val layoutInfo = lazyListState.layoutInfo
|
||||
|
|
@ -343,6 +348,7 @@ internal fun RoomListContentViewPreview(@PreviewParameter(RoomListContentStatePr
|
|||
onConfirmRecoveryKeyClick = {},
|
||||
onRoomClick = {},
|
||||
onCreateRoomClick = {},
|
||||
lazyListState = rememberLazyListState(),
|
||||
contentPadding = PaddingValues(0.dp),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
package io.element.android.features.home.impl.spaces
|
||||
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
|
|
@ -26,10 +28,14 @@ import kotlinx.collections.immutable.toImmutableList
|
|||
@Composable
|
||||
fun HomeSpacesView(
|
||||
state: HomeSpacesState,
|
||||
lazyListState: LazyListState,
|
||||
onSpaceClick: (RoomId) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
LazyColumn(modifier) {
|
||||
LazyColumn(
|
||||
modifier = modifier,
|
||||
state = lazyListState
|
||||
) {
|
||||
val space = state.space
|
||||
when (space) {
|
||||
CurrentSpace.Root -> {
|
||||
|
|
@ -77,6 +83,7 @@ internal fun HomeSpacesViewPreview(
|
|||
) = ElementPreview {
|
||||
HomeSpacesView(
|
||||
state = state,
|
||||
lazyListState = rememberLazyListState(),
|
||||
onSpaceClick = {},
|
||||
modifier = Modifier,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.designsystem.components
|
||||
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.TopAppBarScrollBehavior
|
||||
import androidx.compose.material3.contentColorFor
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.UiComposable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.Layout
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
|
||||
/**
|
||||
* A layout that measures its content to set the height offset limit of a [TopAppBarScrollBehavior].
|
||||
* It places the content according to the current height offset of the scroll behavior.
|
||||
*
|
||||
*/
|
||||
@ExperimentalMaterial3Api
|
||||
@Composable
|
||||
fun TopAppBarScrollBehaviorLayout(
|
||||
scrollBehavior: TopAppBarScrollBehavior,
|
||||
modifier: Modifier = Modifier,
|
||||
backgroundColor: Color = ElementTheme.colors.bgCanvasDefault,
|
||||
contentColor: Color = contentColorFor(backgroundColor),
|
||||
content: @Composable @UiComposable () -> Unit,
|
||||
) {
|
||||
Surface(
|
||||
modifier = modifier,
|
||||
color = backgroundColor,
|
||||
contentColor = contentColor
|
||||
) {
|
||||
Layout(
|
||||
content = content,
|
||||
measurePolicy = { measurables, constraints ->
|
||||
val placeable = measurables.first().measure(constraints)
|
||||
val contentHeight = placeable.height.toFloat()
|
||||
scrollBehavior.state.heightOffsetLimit = -contentHeight
|
||||
val heightOffset = scrollBehavior.state.heightOffset
|
||||
val layoutHeight = (contentHeight + heightOffset).toInt()
|
||||
layout(placeable.width, layoutHeight) {
|
||||
placeable.place(0, heightOffset.toInt())
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -81,11 +81,11 @@ class KonsistPreviewTest {
|
|||
"BackgroundVerticalGradientDisabledPreview",
|
||||
"BackgroundVerticalGradientPreview",
|
||||
"ColorAliasesPreview",
|
||||
"DefaultRoomListTopBarMultiAccountPreview",
|
||||
"DefaultRoomListTopBarWithIndicatorPreview",
|
||||
"FocusedEventPreview",
|
||||
"GradientFloatingActionButtonCircleShapePreview",
|
||||
"HeaderFooterPageScrollablePreview",
|
||||
"HomeTopBarMultiAccountPreview",
|
||||
"HomeTopBarWithIndicatorPreview",
|
||||
"IconsOtherPreview",
|
||||
"MarkdownTextComposerEditPreview",
|
||||
"MatrixBadgeAtomInfoPreview",
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b9595d23fae3fb23bf1a893744c3e28f99b163091d374dabd65d24dbde69af6c
|
||||
size 25617
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:fd357c3f6b143b3dcc4f8a23cd0c8e34b801709630a2c31406b4563e928f64ed
|
||||
size 22757
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b9b7f028749ba909fbeb0c8c2a81ccc6337b3f9c7a8af20e5492c938b1ac8d7a
|
||||
size 25962
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:13b6b3cd99a2561e5116c5dd9950fdb1db61cf3a5a83014c67900bc455f0b53c
|
||||
size 23171
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9c8add737c25478dc3be8fc638661fb03be922702136d4ae83bfcfca4287e5c1
|
||||
size 25709
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9b330c24f0a118665aa3f6eb68b2573deed4167cd3ddbbbe08eed8ddc27c639d
|
||||
size 22814
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6992a2fbaebed88e22c58e393d086bbcba50afd822ac869b9e27dc68ed3a493e
|
||||
size 22007
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:67a87f2231268e26e06e62aada18c4c62e8ee53e1eb1ddc538f8c7e98881acbc
|
||||
size 20256
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0fdbe7e7ab22f44cc60a04582d5a5159055d4af3af0d3d2a7cd012f48abd9592
|
||||
size 22443
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:96942af60064898a853268f8aa8103f04a836332fef09fbfa83ad01cccae54d3
|
||||
size 20651
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e38f16c942bcfb31103b5e80d168a5425f181632ea4440a054aa4d0985bd335a
|
||||
size 22106
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:677c21f745e4b9c7984f6c8fe3f84a27fabe6aeaf5f8cac82bb5ac692bd6a797
|
||||
size 20308
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b9d9c029f8aa66d921be752b3bd5c70d00aa80b8dc6fed343a4ab7b9be5a187f
|
||||
size 125045
|
||||
oid sha256:a3530f2d4ba4b189c7e40c19548fe1d44fea844505ed411cd476eb41add5aac5
|
||||
size 122437
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6a249702f230f3dc0c9ee097fc11496df64c11436680e3f790d1fbf9051c4119
|
||||
size 65098
|
||||
oid sha256:60f321d5352e1966b44e13b4b9e56da3f2cfd14e5eb4a468b61b1939799d364a
|
||||
size 61182
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:440881dfdccf466ac78d3486f05a16acf32c65cd9a926e51f9a03c8df153a996
|
||||
size 33572
|
||||
oid sha256:dd257b64d9e91bedebcf4552e8b93d357304954ad844b7f7d52bc76fc1543747
|
||||
size 29901
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:4e7a170db66cbdae26a12cba6d221264097733e09fb868974ce2f29dbf4f942d
|
||||
size 28313
|
||||
oid sha256:4e3e455fbe6e3a10ec1578e01dc3f10c3b2b0688f99a1855319143c8fc7044a8
|
||||
size 25355
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a1e803f9818ffed85454a4d7c02d2b5fa63e9fc6280c521cddfd8253225ed790
|
||||
size 89858
|
||||
oid sha256:bf7d32047c608340c06edfb8ade3cc8b92858eaa763fedafa915c16439657fc2
|
||||
size 88205
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:86eb0a74576e1023a0e79e2c42083efa0ab7e59f57688f431cdb825937106d03
|
||||
size 83133
|
||||
oid sha256:abf95575cbd55470c798accf988bc6a509daea71eded4108857595993873df4e
|
||||
size 81038
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d85ed502c37c8486c9b7e235ebb639bb7a6ddcdfec388b48ec1626ca45d7fd95
|
||||
size 51335
|
||||
oid sha256:c9e019924f41de0c16f1f403944b8fe390afa65d1ad604db3dd0baadbc30db5b
|
||||
size 50953
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6a249702f230f3dc0c9ee097fc11496df64c11436680e3f790d1fbf9051c4119
|
||||
size 65098
|
||||
oid sha256:60f321d5352e1966b44e13b4b9e56da3f2cfd14e5eb4a468b61b1939799d364a
|
||||
size 61182
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6a249702f230f3dc0c9ee097fc11496df64c11436680e3f790d1fbf9051c4119
|
||||
size 65098
|
||||
oid sha256:60f321d5352e1966b44e13b4b9e56da3f2cfd14e5eb4a468b61b1939799d364a
|
||||
size 61182
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3df1fc44ef9b4c71349aefaa06a09583b25b5baa2765c572fde2579d543c7dc8
|
||||
size 62134
|
||||
oid sha256:93b7d7b0d7df69921015ece40ae3ab859c81cd3e78828143f660a481a72b73e2
|
||||
size 62305
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:08f1583ccded2046d10fd19890bcc70b9fedf0efe310318a6a6209bded37b423
|
||||
size 52241
|
||||
oid sha256:ef2b3724cdd28175824554f800019fa663be341f0854751b50321e9b73203b6a
|
||||
size 54275
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6a249702f230f3dc0c9ee097fc11496df64c11436680e3f790d1fbf9051c4119
|
||||
size 65098
|
||||
oid sha256:60f321d5352e1966b44e13b4b9e56da3f2cfd14e5eb4a468b61b1939799d364a
|
||||
size 61182
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e609fcb03b38d2265b91f6cccbd91092b050c34f979116a20e1d2f72c9fb7d9c
|
||||
size 52933
|
||||
oid sha256:6bb7a5a23947cd3a311c8d9526508c121beb4e0ee37f337bf8361845be10d172
|
||||
size 54415
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:58536ac6068bce6399048fb5a082791ce4d2d74dc9e39d96e6483c818067a3b1
|
||||
size 52741
|
||||
oid sha256:11e9f28e6131eae66e268b72daab6d404d1f1f8b0eba78eb11d4376284eb11e3
|
||||
size 54220
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a5eb9e2d9245b31509ecd22351cc11b6d5fe27dcad76ab1eab36d692cf0fed2b
|
||||
size 50942
|
||||
oid sha256:26bfe68b4448aa83e19f196d8633eeb74883064db319aab355a5e755b7cbb56d
|
||||
size 52439
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a6c524b3c587eea43d5d753757fe42434ee751709559851ec9e0ca283c6f2236
|
||||
size 82960
|
||||
oid sha256:196cad6f5c3d01d52c88713526848d7905b59b49866f27f6e420df0b6b8f9e73
|
||||
size 80857
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ea48147772f8fa99aca0345a5a98f8d2ea6fd26793edab55f7d920a7e3f56414
|
||||
size 60213
|
||||
oid sha256:7e9b4b3247cf2f540866286de61760a45956d8179891aeb669b4763bdd29393d
|
||||
size 57993
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c065e34ccdcb98cf347177057029fb052986e680eb3a0ce0d3ba1110f893a6ed
|
||||
size 29213
|
||||
oid sha256:496855b1b3186adcad8b35895ee51776dce00a8d3229b8dccac4d6e4482bdaff
|
||||
size 26577
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:aeecc6082c03bbb7fc3d5d2cff9c145fa6b1b2da253fc5d9d7df4b3b49705f67
|
||||
size 23513
|
||||
oid sha256:8b98678dc90bce52ab2293e5102794b4fc3b51fc667a6c061d771ea90212a0f2
|
||||
size 22034
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3911b9f33b862f1fa47ac80420f1ded92d8c7c304a0b0af8c7132033eca63da1
|
||||
size 84486
|
||||
oid sha256:a7ff4652d94dec6bc98b3f1dea0d182576c7bfc72e39f232d224046e6492b55e
|
||||
size 83764
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:58917137b3500639edcd3308f665cb9111450bf0c34fe07880076f43725ae145
|
||||
size 78202
|
||||
oid sha256:cb1d9b5143703ec9a8035e11374c7e56ce4d3f836005632a109e5556b141c59b
|
||||
size 77098
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:82748aa6dee71f50a9a1eaa1f34e2966126c4b13c4dc2a2a53c5588f8ba83f50
|
||||
size 46455
|
||||
oid sha256:8f0e5430bcd399d5a39c3d92e7551243f0e15bc315f9ec6ded43829d4672308c
|
||||
size 47186
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ea48147772f8fa99aca0345a5a98f8d2ea6fd26793edab55f7d920a7e3f56414
|
||||
size 60213
|
||||
oid sha256:7e9b4b3247cf2f540866286de61760a45956d8179891aeb669b4763bdd29393d
|
||||
size 57993
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ea48147772f8fa99aca0345a5a98f8d2ea6fd26793edab55f7d920a7e3f56414
|
||||
size 60213
|
||||
oid sha256:7e9b4b3247cf2f540866286de61760a45956d8179891aeb669b4763bdd29393d
|
||||
size 57993
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:494864f07f4ca2ef426f611842f580fa6d2c5d04c61385acd649e50ee49e9405
|
||||
size 58119
|
||||
oid sha256:a8db3006e7ea4826022d47a4ae37dab2a7ddd064d4cc2c48b44deca0f158541c
|
||||
size 59301
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e3d89f2829ddb05c63da3f4afcadf55e70a8c70b7df46d0e04eba35932fe947d
|
||||
size 49455
|
||||
oid sha256:1b6fc1c78e05737b3231172b2b72b532b769ae9928ddd6674a864bee56566f6e
|
||||
size 52623
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ea48147772f8fa99aca0345a5a98f8d2ea6fd26793edab55f7d920a7e3f56414
|
||||
size 60213
|
||||
oid sha256:7e9b4b3247cf2f540866286de61760a45956d8179891aeb669b4763bdd29393d
|
||||
size 57993
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0493d1a09ba7d41e0ef0b66ef4068528af281cfaa9f7187d64d17316ca97d2fd
|
||||
size 50038
|
||||
oid sha256:957b8712456f13d83857616e2ffab05c5d60f50e6b39037bb47af0d272c53b02
|
||||
size 51863
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:4215bf2ac9870ec1d6f3832adc8e8bfd2ce4d1ab2c1ef5584a0a934e880969be
|
||||
size 49887
|
||||
oid sha256:beac305c3cc0661633873276a99798b1fa693342bd4ab9424bc44759a1f745ec
|
||||
size 51695
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9977db4bcc333f7fa0f662e8cc73170fe96a90bcb545f5471cb6e107f159f943
|
||||
size 48083
|
||||
oid sha256:aba9a16cabbe67f28512721740e268bebd93b3084efd93e8de7eed251fd1ffe0
|
||||
size 49849
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:21cbfa635df606c3fa17345a1ad1055e47f2265b059cb10580dfc464c694870e
|
||||
size 78085
|
||||
oid sha256:101d0425024c30f2dce8b6d91ed2416fc115c4bf3719fd6c46093705ba4ef772
|
||||
size 76985
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue