diff --git a/features/knockrequests/api/build.gradle.kts b/features/knockrequests/api/build.gradle.kts index e3d563f2e0..90bcb6e568 100644 --- a/features/knockrequests/api/build.gradle.kts +++ b/features/knockrequests/api/build.gradle.kts @@ -5,8 +5,6 @@ * Please see LICENSE in the repository root for full details. */ -import extension.setupAnvil - plugins { id("io.element.android-library") } @@ -19,4 +17,3 @@ dependencies { implementation(projects.libraries.architecture) implementation(projects.libraries.matrix.api) } - diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/KnockRequest.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/KnockRequest.kt index 81ba322abe..d9df9a5bc2 100644 --- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/KnockRequest.kt +++ b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/KnockRequest.kt @@ -10,7 +10,6 @@ package io.element.android.features.knockrequests.impl import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.matrix.api.core.UserId -import io.element.android.libraries.matrix.api.user.MatrixUser data class KnockRequest( val userId: UserId, @@ -30,6 +29,3 @@ fun KnockRequest.getAvatarData(size: AvatarSize) = AvatarData( fun KnockRequest.getBestName(): String { return displayName?.takeIf { it.isNotEmpty() } ?: userId.value } - - - diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListNode.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListNode.kt index 0310f67d2e..ce8d602861 100644 --- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListNode.kt +++ b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListNode.kt @@ -15,7 +15,6 @@ import com.bumble.appyx.core.plugin.Plugin import dagger.assisted.Assisted import dagger.assisted.AssistedInject import io.element.android.anvilannotations.ContributesNode -import io.element.android.libraries.di.AppScope import io.element.android.libraries.di.RoomScope @ContributesNode(RoomScope::class) @@ -24,7 +23,6 @@ class KnockRequestsListNode @AssistedInject constructor( @Assisted plugins: List, private val presenter: KnockRequestsListPresenter, ) : Node(buildContext, plugins = plugins) { - @Composable override fun View(modifier: Modifier) { val state = presenter.present() diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListPresenter.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListPresenter.kt index 8ae993c9ef..fcafc5428b 100644 --- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListPresenter.kt +++ b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListPresenter.kt @@ -26,7 +26,6 @@ import javax.inject.Inject class KnockRequestsListPresenter @Inject constructor( private val room: MatrixRoom, ) : Presenter { - @Composable override fun present(): KnockRequestsListState { val currentAction = remember { mutableStateOf(KnockRequestsCurrentAction.None) } @@ -56,7 +55,7 @@ class KnockRequestsListPresenter @Inject constructor( } LaunchedEffect(currentAction) { - when (val action = currentAction.value) { + when (currentAction.value) { is KnockRequestsCurrentAction.Accept -> { // Accept the knock request } diff --git a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListView.kt b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListView.kt index abc0a09970..ca289eeef4 100644 --- a/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListView.kt +++ b/features/knockrequests/impl/src/main/kotlin/io/element/android/features/knockrequests/impl/list/KnockRequestsListView.kt @@ -13,6 +13,7 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.consumeWindowInsets @@ -28,7 +29,9 @@ import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment @@ -36,6 +39,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clipToBounds import androidx.compose.ui.draw.shadow import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.PreviewParameter @@ -43,6 +47,7 @@ import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.features.knockrequests.impl.KnockRequest +import io.element.android.features.knockrequests.impl.R import io.element.android.features.knockrequests.impl.getAvatarData import io.element.android.features.knockrequests.impl.getBestName import io.element.android.libraries.architecture.AsyncData @@ -54,6 +59,7 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.designsystem.text.toDp import io.element.android.libraries.designsystem.theme.aliasScreenTitle import io.element.android.libraries.designsystem.theme.components.Button import io.element.android.libraries.designsystem.theme.components.ButtonSize @@ -90,8 +96,10 @@ fun KnockRequestsListView( } @Composable -private fun KnockRequestsListContent(state: KnockRequestsListState, modifier: Modifier) { - +private fun KnockRequestsListContent( + state: KnockRequestsListState, + modifier: Modifier = Modifier, +) { fun onAcceptClick(knockRequest: KnockRequest) { state.eventSink(KnockRequestsListEvents.Accept(knockRequest)) } @@ -100,6 +108,8 @@ private fun KnockRequestsListContent(state: KnockRequestsListState, modifier: Mo state.eventSink(KnockRequestsListEvents.Decline(knockRequest)) } + var bottomPaddingInPixels by remember { mutableIntStateOf(0) } + Box(modifier.fillMaxSize()) { when (state.knockRequests) { is AsyncData.Success -> { @@ -114,6 +124,7 @@ private fun KnockRequestsListContent(state: KnockRequestsListState, modifier: Mo canBan = state.canBan, onAcceptClick = ::onAcceptClick, onDeclineClick = ::onDeclineClick, + contentPadding = PaddingValues(bottom = bottomPaddingInPixels.toDp()), ) } } @@ -130,6 +141,9 @@ private fun KnockRequestsListContent(state: KnockRequestsListState, modifier: Mo onClick = { state.eventSink(KnockRequestsListEvents.AcceptAll) }, + onHeightChange = { height -> + bottomPaddingInPixels = height + }, modifier = Modifier.align(Alignment.BottomCenter), ) } @@ -186,8 +200,12 @@ private fun KnockRequestsList( onAcceptClick: (KnockRequest) -> Unit, onDeclineClick: (KnockRequest) -> Unit, modifier: Modifier = Modifier, + contentPadding: PaddingValues = PaddingValues(0.dp), ) { - LazyColumn(modifier = modifier) { + LazyColumn( + modifier = modifier.fillMaxSize(), + contentPadding = contentPadding, + ) { itemsIndexed(knockRequests) { index, knockRequest -> KnockRequestItem( knockRequest = knockRequest, @@ -316,7 +334,7 @@ private fun KnockRequestItem( if (canBan) { Spacer(modifier = Modifier.height(12.dp)) TextButton( - text = stringResource(CommonStrings.screen_knock_requests_list_decline_and_ban_action_title), + text = stringResource(R.string.screen_knock_requests_list_decline_and_ban_action_title), onClick = { onAcceptClick(knockRequest) }, @@ -325,22 +343,25 @@ private fun KnockRequestItem( modifier = Modifier.fillMaxWidth(), ) } - } } } @Composable -private fun KnockRequestsAcceptAll(onClick: () -> Unit, modifier: Modifier) { +private fun KnockRequestsAcceptAll( + onClick: () -> Unit, + onHeightChange: (Int) -> Unit, + modifier: Modifier = Modifier +) { Box( modifier = modifier .shadow(elevation = 24.dp, spotColor = Color.Transparent) .background(color = ElementTheme.colors.bgCanvasDefault) .padding(vertical = 12.dp, horizontal = 16.dp) - ) - { + .onSizeChanged { onHeightChange(it.height) } + ) { OutlinedButton( - text = ("Accept all"), + text = stringResource(R.string.screen_knock_requests_list_accept_all_button_title), onClick = onClick, size = ButtonSize.Medium, modifier = Modifier.fillMaxWidth(), @@ -360,8 +381,8 @@ private fun KnockRequestsEmptyList( contentAlignment = Alignment.Center, ) { IconTitleSubtitleMolecule( - title = "No pending request to join", - subTitle = "When somebody will ask to join the room, you’ll be able to see their request here.", + title = stringResource(R.string.screen_knock_requests_list_empty_state_title), + subTitle = stringResource(R.string.screen_knock_requests_list_empty_state_description), iconStyle = BigIcon.Style.Default(CompoundIcons.Pin()), ) } @@ -373,7 +394,7 @@ private fun KnockRequestsListTopBar(onBackClick: () -> Unit) { TopAppBar( title = { Text( - text = "Requests to join", + text = stringResource(R.string.screen_knock_requests_list_title), style = ElementTheme.typography.aliasScreenTitle, ) }, diff --git a/features/knockrequests/impl/src/main/res/values/localazy.xml b/features/knockrequests/impl/src/main/res/values/localazy.xml new file mode 100644 index 0000000000..df14d665b8 --- /dev/null +++ b/features/knockrequests/impl/src/main/res/values/localazy.xml @@ -0,0 +1,17 @@ + + + "Yes, accept all" + "Are you sure you want to accept all requests to join?" + "Accept all requests" + "Accept all" + "Yes, decline and ban" + "Are you sure you want to decline and ban %1$s? This user won’t be able to request access to join this room again." + "Decline and ban from accessing" + "Yes, decline" + "Are you sure you want to decline %1$s request to join this room?" + "Decline access" + "Decline and ban" + "When somebody will ask to join the room, you’ll be able to see their request here." + "No pending request to join" + "Requests to join" + diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt index dc6568a60f..46588ae5fe 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt @@ -169,10 +169,6 @@ class RoomDetailsPresenter @Inject constructor( ) } - private fun getCanBan(membersState: MatrixRoomMembersState): Any { - TODO("Not yet implemented") - } - @Composable private fun roomMemberDetailsPresenter(dmMemberState: RoomMember?) = remember(dmMemberState) { dmMemberState?.let { roomMember -> diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index 18d580d9f4..f52b53564b 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -296,11 +296,6 @@ Reason: %1$s." "Hey, talk to me on %1$s: %2$s" "%1$s Android" "Rageshake to report bug" - "Accept all" - "Decline and ban" - "When somebody will ask to join the room, you’ll be able to see their request here." - "No pending request to join" - "Requests to join" "Failed selecting media, please try again." "Failed processing media to upload, please try again." "Failed uploading media, please try again." diff --git a/tools/localazy/config.json b/tools/localazy/config.json index f18744bae9..9bf178ac85 100644 --- a/tools/localazy/config.json +++ b/tools/localazy/config.json @@ -286,6 +286,12 @@ "screen_join_room_.*", "screen\\.join_room\\..*" ] + }, + { + "name" : ":features:knockrequests:impl", + "includeRegex" : [ + "screen\\.knock_requests_list\\..*" + ] } ] }