Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 62 additions & 25 deletions app/src/main/kotlin/com/wire/android/ui/home/HomeScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusProperties
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.layout.ContentScale
Expand Down Expand Up @@ -265,6 +268,8 @@ fun HomeContent(
modifier: Modifier = Modifier,
) {
val context = LocalContext.current
val searchFocusRequester = remember { FocusRequester() }
val fabFocusRequester = remember { FocusRequester() }

with(homeStateHolder) {
fun openWireHomeDestination(item: HomeDestination) {
Expand Down Expand Up @@ -329,6 +334,8 @@ fun HomeContent(
onOpenConversationFilter = {
homeStateHolder.conversationsFilterBottomSheetState.show(Unit)
},
searchFocusRequester = searchFocusRequester,
fabFocusRequester = if (currentNavigationItem.fab != null) fabFocusRequester else null,
)
}
},
Expand All @@ -343,7 +350,13 @@ fun HomeContent(
isSearchActive = searchBarState.isSearchActive,
searchBarHint = stringResource(searchBar.hint),
searchQueryTextState = searchBarState.searchQueryTextState,
onActiveChanged = searchBarState::searchActiveChanged,
onCloseSearchClicked = searchBarState::closeSearch,
onActiveChanged = { isFocused ->
if (isFocused) {
searchBarState.openSearch()
}
},
externalFocusRequester = searchFocusRequester,
)
}
}
Expand Down Expand Up @@ -388,30 +401,12 @@ fun HomeContent(
enter = scaleIn(),
exit = scaleOut(),
) {
var currentFab by remember { mutableStateOf(currentNavigationItem.fab ?: FabOptions.NewConversation) }
// to keep the fab during the exit animation, we need to keep last known (non-null) fab data
if (currentNavigationItem.fab != null) currentFab = currentNavigationItem.fab!!

FloatingActionButton(
text = stringResource(currentFab.text),
icon = {
Image(
painter = painterResource(currentFab.icon),
contentDescription = stringResource(currentFab.contentDescription),
contentScale = ContentScale.FillBounds,
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onPrimary),
modifier = Modifier
.padding(start = dimensions().spacing4x, top = dimensions().spacing2x)
.size(dimensions().fabIconSize)
)
},
onClick = {
when (currentNavigationItem.fab) {
FabOptions.NewConversation -> onNewConversationClick()
FabOptions.NewMeeting -> homeStateHolder.newMeetingBottomSheetState.show(Unit)
else -> { /* no-op */ }
}
}
HomeFloatingActionButton(
currentNavigationItem = currentNavigationItem,
fabFocusRequester = fabFocusRequester,
searchFocusRequester = searchFocusRequester,
onNewConversationClick = onNewConversationClick,
onNewMeetingClick = { homeStateHolder.newMeetingBottomSheetState.show(Unit) }
)
}
}
Expand All @@ -420,3 +415,45 @@ fun HomeContent(
)
}
}

@Composable
private fun HomeFloatingActionButton(
currentNavigationItem: HomeDestination,
fabFocusRequester: FocusRequester,
searchFocusRequester: FocusRequester,
onNewConversationClick: () -> Unit,
onNewMeetingClick: () -> Unit,
) {
var currentFab by remember { mutableStateOf(currentNavigationItem.fab ?: FabOptions.NewConversation) }
// to keep the fab during the exit animation, we need to keep last known (non-null) fab data
currentNavigationItem.fab?.let { currentFab = it }

FloatingActionButton(
text = stringResource(currentFab.text),
modifier = Modifier
.focusRequester(fabFocusRequester)
.focusProperties {
if (currentNavigationItem.searchBar != null) {
next = searchFocusRequester
}
},
icon = {
Image(
painter = painterResource(currentFab.icon),
contentDescription = stringResource(currentFab.contentDescription),
contentScale = ContentScale.FillBounds,
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onPrimary),
modifier = Modifier
.padding(start = dimensions().spacing4x, top = dimensions().spacing2x)
.size(dimensions().fabIconSize)
)
},
onClick = {
when (currentNavigationItem.fab) {
FabOptions.NewConversation -> onNewConversationClick()
FabOptions.NewMeeting -> onNewMeetingClick()
else -> { /* no-op */ }
}
}
)
}
21 changes: 18 additions & 3 deletions app/src/main/kotlin/com/wire/android/ui/home/HomeTopBar.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@

import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusProperties
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
Expand All @@ -41,7 +44,7 @@
import com.wire.kalium.logic.data.user.UserAvailabilityStatus

@Composable
fun HomeTopBar(

Check failure on line 47 in app/src/main/kotlin/com/wire/android/ui/home/HomeTopBar.kt

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this method to reduce its Cognitive Complexity from 17 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=wireapp_wire-android&issues=AZ5AheEit7pOQKkRlRQF&open=AZ5AheEit7pOQKkRlRQF&pullRequest=4837
title: String,
currentConversationFilter: ConversationFilter,
navigationItem: HomeDestination,
Expand All @@ -52,9 +55,13 @@
onHamburgerMenuClick: () -> Unit,
onNavigateToSelfUserProfile: () -> Unit,
onOpenConversationFilter: () -> Unit,
modifier: Modifier = Modifier,
searchFocusRequester: FocusRequester? = null,
fabFocusRequester: FocusRequester? = null,
) {
WireCenterAlignedTopAppBar(
title = title,
modifier = modifier,
onNavigationPressed = onHamburgerMenuClick,
navigationIconType = NavigationIconType.Menu,
actions = {
Expand Down Expand Up @@ -82,11 +89,19 @@
}
UserProfileAvatar(
avatarData = userAvatarData,
clickable = remember {
modifier = Modifier
.focusProperties {
when {
fabFocusRequester != null -> next = fabFocusRequester
searchFocusRequester != null -> next = searchFocusRequester
}
},
clickable = remember(openLabel, onNavigateToSelfUserProfile) {
Clickable(
enabled = true,
onClickDescription = openLabel
) { onNavigateToSelfUserProfile() }
onClickDescription = openLabel,
onClick = onNavigateToSelfUserProfile
)
},
type = UserProfileAvatarType.WithIndicators.RegularUser(
legalHoldIndicatorVisible = withLegalHoldIndicator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,12 @@ fun SearchUsersAndAppsScreen(
backIconContentDescription = stringResource(id = R.string.content_description_add_participants_back_btn),
searchBarDescription = stringResource(R.string.content_description_add_participants_search_field),
searchQueryTextState = searchBarState.searchQueryTextState,
onActiveChanged = searchBarState::searchActiveChanged,
onCloseSearchClicked = searchBarState::closeSearch,
onActiveChanged = { isFocused ->
if (isFocused) {
searchBarState.openSearch()
}
},
)
},
topBarFooter = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import com.wire.android.ui.common.colorsScheme
import com.wire.android.ui.common.onEscapeOrBackKey
import com.wire.android.ui.home.conversations.ConversationActionPermissionType
import com.wire.android.ui.home.conversations.model.UriAsset
import com.wire.android.ui.home.messagecomposer.recordaudio.RecordAudioComponent
Expand Down Expand Up @@ -56,10 +58,18 @@ fun AdditionalOptionsMenu(
onRichOptionButtonClicked: (RichTextMarkdown) -> Unit,
onDrawingModeClicked: () -> Unit,
modifier: Modifier = Modifier,
initialKeyboardFocusRequester: FocusRequester? = null,
onOnSelfDeletingOptionClicked: ((SelfDeletionTimer) -> Unit)? = null,
onGifOptionClicked: (() -> Unit)? = null
) {
Box(modifier.background(colorsScheme().surface)) {
Box(
modifier
.onEscapeOrBackKey(
enabled = additionalOptionsState == AdditionalOptionMenuState.RichTextEditing,
onKeyPressed = onCloseRichEditingButtonClicked
)
.background(colorsScheme().surface)
) {
when (additionalOptionsState) {
AdditionalOptionMenuState.AttachmentAndAdditionalOptionsMenu -> {
AttachmentAndAdditionalOptionsMenuItems(
Expand All @@ -75,7 +85,8 @@ fun AdditionalOptionsMenu(
onRichEditingButtonClicked = onRichEditingButtonClicked,
onPingClicked = onPingOptionClicked,
onDrawingModeClicked = onDrawingModeClicked,
isFileSharingEnabled = isFileSharingEnabled
isFileSharingEnabled = isFileSharingEnabled,
initialKeyboardFocusRequester = initialKeyboardFocusRequester
)
}

Expand Down Expand Up @@ -146,7 +157,8 @@ fun AttachmentAndAdditionalOptionsMenuItems(
onPingClicked: () -> Unit = {},
onGifButtonClicked: () -> Unit = {},
onRichEditingButtonClicked: () -> Unit = {},
onDrawingModeClicked: () -> Unit = {}
onDrawingModeClicked: () -> Unit = {},
initialKeyboardFocusRequester: FocusRequester? = null
) {
Column(modifier.wrapContentSize()) {
HorizontalDivider(color = MaterialTheme.wireColorScheme.outline)
Expand All @@ -163,7 +175,8 @@ fun AttachmentAndAdditionalOptionsMenuItems(
onGifButtonClicked = onGifButtonClicked,
onRichEditingButtonClicked = onRichEditingButtonClicked,
onDrawingModeClicked = onDrawingModeClicked,
isFileSharingEnabled = isFileSharingEnabled
isFileSharingEnabled = isFileSharingEnabled,
initialKeyboardFocusRequester = initialKeyboardFocusRequester
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.scale
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.rememberTextMeasurer
Expand Down Expand Up @@ -77,6 +79,7 @@ fun AttachmentOptionsComponent(
) {
val density = LocalDensity.current
val textMeasurer = rememberTextMeasurer()
val firstOptionFocusRequester = remember { FocusRequester() }

val attachmentOptions = buildAttachmentOptionItems(
isFileSharingEnabled = isFileSharingEnabled,
Expand Down Expand Up @@ -123,6 +126,12 @@ fun AttachmentOptionsComponent(
val (columns, contentPadding) = params
val numberOfColumns = (fullWidth / minColumnWidth).toInt()

LaunchedEffect(optionsVisible, visibleAttachmentOptions.size) {
if (optionsVisible && visibleAttachmentOptions.isNotEmpty()) {
firstOptionFocusRequester.requestFocus()
}
}

LazyVerticalGrid(
columns = columns,
modifier = Modifier.fillMaxSize(),
Expand Down Expand Up @@ -162,7 +171,15 @@ fun AttachmentOptionsComponent(
AttachmentButton(
icon = option.icon,
labelStyle = labelStyle,
modifier = Modifier.scale(animatedScale),
modifier = Modifier
.scale(animatedScale)
.then(
if (index == 0) {
Modifier.focusRequester(firstOptionFocusRequester)
} else {
Modifier
}
),
text = stringResource(option.text)
) { option.onClick() }
}
Expand Down
Loading