knock requests : start knock requests list view
This commit is contained in:
parent
19e2f5964b
commit
62dc795023
9 changed files with 388 additions and 13 deletions
|
|
@ -24,6 +24,7 @@ dependencies {
|
||||||
implementation(projects.libraries.architecture)
|
implementation(projects.libraries.architecture)
|
||||||
implementation(projects.libraries.matrix.api)
|
implementation(projects.libraries.matrix.api)
|
||||||
implementation(projects.libraries.matrixui)
|
implementation(projects.libraries.matrixui)
|
||||||
|
implementation(projects.libraries.uiStrings)
|
||||||
implementation(projects.libraries.designsystem)
|
implementation(projects.libraries.designsystem)
|
||||||
|
|
||||||
testImplementation(libs.test.junit)
|
testImplementation(libs.test.junit)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 New Vector Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
* Please see LICENSE in the repository root for full details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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,
|
||||||
|
val displayName: String?,
|
||||||
|
val avatarUrl: String?,
|
||||||
|
val reason: String?,
|
||||||
|
)
|
||||||
|
|
||||||
|
fun KnockRequest.getAvatarData(size: AvatarSize) = AvatarData(
|
||||||
|
id = userId.value,
|
||||||
|
name = displayName,
|
||||||
|
url = avatarUrl,
|
||||||
|
size = size,
|
||||||
|
)
|
||||||
|
|
||||||
|
fun KnockRequest.getBestName(): String {
|
||||||
|
return displayName?.takeIf { it.isNotEmpty() } ?: userId.value
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -7,6 +7,11 @@
|
||||||
|
|
||||||
package io.element.android.features.knockrequests.impl.list
|
package io.element.android.features.knockrequests.impl.list
|
||||||
|
|
||||||
|
import io.element.android.features.knockrequests.impl.KnockRequest
|
||||||
|
|
||||||
sealed interface KnockRequestsListEvents {
|
sealed interface KnockRequestsListEvents {
|
||||||
|
data class Accept(val knockRequest: KnockRequest) : KnockRequestsListEvents
|
||||||
|
data class Decline(val knockRequest: KnockRequest) : KnockRequestsListEvents
|
||||||
data object AcceptAll : KnockRequestsListEvents
|
data object AcceptAll : KnockRequestsListEvents
|
||||||
|
data object DismissCurrentAction : KnockRequestsListEvents
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ class KnockRequestsListNode @AssistedInject constructor(
|
||||||
val state = presenter.present()
|
val state = presenter.present()
|
||||||
KnockRequestsListView(
|
KnockRequestsListView(
|
||||||
state = state,
|
state = state,
|
||||||
|
onBackClick = ::navigateUp,
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,21 +8,35 @@
|
||||||
package io.element.android.features.knockrequests.impl.list
|
package io.element.android.features.knockrequests.impl.list
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import io.element.android.libraries.architecture.AsyncData
|
||||||
import io.element.android.libraries.architecture.Presenter
|
import io.element.android.libraries.architecture.Presenter
|
||||||
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class KnockRequestsListPresenter @Inject constructor() : Presenter<KnockRequestsListState> {
|
class KnockRequestsListPresenter @Inject constructor() : Presenter<KnockRequestsListState> {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun present(): KnockRequestsListState {
|
override fun present(): KnockRequestsListState {
|
||||||
|
val actions = remember {
|
||||||
|
mutableStateOf<KnockRequestsCurrentAction>(KnockRequestsCurrentAction.None)
|
||||||
|
}
|
||||||
|
|
||||||
fun handleEvents(event: KnockRequestsListEvents) {
|
fun handleEvents(event: KnockRequestsListEvents) {
|
||||||
when (event) {
|
when (event) {
|
||||||
KnockRequestsListEvents.AcceptAll -> Unit
|
KnockRequestsListEvents.AcceptAll -> Unit
|
||||||
|
is KnockRequestsListEvents.Accept -> Unit
|
||||||
|
is KnockRequestsListEvents.Decline -> Unit
|
||||||
|
KnockRequestsListEvents.DismissCurrentAction -> {
|
||||||
|
actions.value = KnockRequestsCurrentAction.None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return KnockRequestsListState(
|
return KnockRequestsListState(
|
||||||
|
knockRequests = AsyncData.Success(persistentListOf()),
|
||||||
|
currentAction = actions.value,
|
||||||
eventSink = ::handleEvents
|
eventSink = ::handleEvents
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,20 @@
|
||||||
|
|
||||||
package io.element.android.features.knockrequests.impl.list
|
package io.element.android.features.knockrequests.impl.list
|
||||||
|
|
||||||
// TODO add your ui models. Remove the eventSink if you don't have events.
|
import io.element.android.features.knockrequests.impl.KnockRequest
|
||||||
// Do not use default value, so no member get forgotten in the presenters.
|
import io.element.android.libraries.architecture.AsyncAction
|
||||||
|
import io.element.android.libraries.architecture.AsyncData
|
||||||
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
|
|
||||||
data class KnockRequestsListState(
|
data class KnockRequestsListState(
|
||||||
val eventSink: (KnockRequestsListEvents) -> Unit
|
val knockRequests: AsyncData<ImmutableList<KnockRequest>>,
|
||||||
|
val currentAction: KnockRequestsCurrentAction,
|
||||||
|
val eventSink: (KnockRequestsListEvents) -> Unit,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
sealed interface KnockRequestsCurrentAction {
|
||||||
|
data object None : KnockRequestsCurrentAction
|
||||||
|
data class Accept(val async: AsyncAction<Unit>) : KnockRequestsCurrentAction
|
||||||
|
data class Decline(val async: AsyncAction<Unit>) : KnockRequestsCurrentAction
|
||||||
|
data class AcceptAll(val async: AsyncAction<Unit>) : KnockRequestsCurrentAction
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,73 @@
|
||||||
package io.element.android.features.knockrequests.impl.list
|
package io.element.android.features.knockrequests.impl.list
|
||||||
|
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||||
|
import io.element.android.features.knockrequests.impl.KnockRequest
|
||||||
|
import io.element.android.libraries.architecture.AsyncAction
|
||||||
|
import io.element.android.libraries.architecture.AsyncData
|
||||||
|
import io.element.android.libraries.matrix.api.core.UserId
|
||||||
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
|
|
||||||
open class KnockRequestsListStateProvider : PreviewParameterProvider<KnockRequestsListState> {
|
open class KnockRequestsListStateProvider : PreviewParameterProvider<KnockRequestsListState> {
|
||||||
override val values: Sequence<KnockRequestsListState>
|
override val values: Sequence<KnockRequestsListState>
|
||||||
get() = sequenceOf(
|
get() = sequenceOf(
|
||||||
aKnockRequestsListState(),
|
aKnockRequestsListState(
|
||||||
// Add other states here
|
knockRequests = AsyncData.Loading(),
|
||||||
|
),
|
||||||
|
aKnockRequestsListState(
|
||||||
|
knockRequests = AsyncData.Success(
|
||||||
|
persistentListOf()
|
||||||
|
),
|
||||||
|
),
|
||||||
|
aKnockRequestsListState(
|
||||||
|
knockRequests = AsyncData.Success(
|
||||||
|
persistentListOf(
|
||||||
|
aKnockRequest()
|
||||||
|
)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
aKnockRequestsListState(
|
||||||
|
knockRequests = AsyncData.Success(
|
||||||
|
persistentListOf(
|
||||||
|
aKnockRequest(),
|
||||||
|
aKnockRequest(
|
||||||
|
userId = UserId("@user:example.com"),
|
||||||
|
displayName = null,
|
||||||
|
avatarUrl = null,
|
||||||
|
reason = null,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
aKnockRequestsListState(
|
||||||
|
knockRequests = AsyncData.Success(
|
||||||
|
persistentListOf(
|
||||||
|
aKnockRequest()
|
||||||
|
)
|
||||||
|
),
|
||||||
|
actions = KnockRequestsCurrentAction.AcceptAll(AsyncAction.Loading),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun aKnockRequestsListState() = KnockRequestsListState(
|
fun aKnockRequest(
|
||||||
eventSink = {}
|
userId: UserId = UserId("@jacob_ross:example.com"),
|
||||||
|
displayName: String? = "Jacob Ross",
|
||||||
|
avatarUrl: String? = null,
|
||||||
|
reason: String? = "Hi, I would like to get access to this room please.",
|
||||||
|
) = KnockRequest(
|
||||||
|
userId = userId,
|
||||||
|
displayName = displayName,
|
||||||
|
avatarUrl = avatarUrl,
|
||||||
|
reason = reason,
|
||||||
|
)
|
||||||
|
|
||||||
|
fun aKnockRequestsListState(
|
||||||
|
knockRequests: AsyncData<ImmutableList<KnockRequest>> = AsyncData.Success(persistentListOf()),
|
||||||
|
actions: KnockRequestsCurrentAction = KnockRequestsCurrentAction.None,
|
||||||
|
eventSink: (KnockRequestsListEvents) -> Unit = {},
|
||||||
|
) = KnockRequestsListState(
|
||||||
|
knockRequests = knockRequests,
|
||||||
|
currentAction = actions,
|
||||||
|
eventSink = eventSink,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -7,31 +7,278 @@
|
||||||
|
|
||||||
package io.element.android.features.knockrequests.impl.list
|
package io.element.android.features.knockrequests.impl.list
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.consumeWindowInsets
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.draw.clipToBounds
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
|
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.getAvatarData
|
||||||
|
import io.element.android.features.knockrequests.impl.getBestName
|
||||||
|
import io.element.android.libraries.architecture.AsyncData
|
||||||
|
import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule
|
||||||
|
import io.element.android.libraries.designsystem.components.BigIcon
|
||||||
|
import io.element.android.libraries.designsystem.components.async.AsyncActionView
|
||||||
|
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.button.BackButton
|
||||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||||
|
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
|
||||||
|
import io.element.android.libraries.designsystem.theme.components.HorizontalDivider
|
||||||
|
import io.element.android.libraries.designsystem.theme.components.OutlinedButton
|
||||||
|
import io.element.android.libraries.designsystem.theme.components.Scaffold
|
||||||
import io.element.android.libraries.designsystem.theme.components.Text
|
import io.element.android.libraries.designsystem.theme.components.Text
|
||||||
|
import io.element.android.libraries.designsystem.theme.components.TextButton
|
||||||
|
import io.element.android.libraries.designsystem.theme.components.TopAppBar
|
||||||
|
import io.element.android.libraries.ui.strings.CommonStrings
|
||||||
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun KnockRequestsListView(
|
fun KnockRequestsListView(
|
||||||
state: KnockRequestsListState,
|
state: KnockRequestsListState,
|
||||||
|
onBackClick: () -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
Box(modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
Scaffold(
|
||||||
Text(
|
modifier = modifier,
|
||||||
"KnockRequestsList feature view",
|
topBar = {
|
||||||
color = MaterialTheme.colorScheme.primary,
|
KnockRequestsListTopBar(onBackClick = onBackClick)
|
||||||
|
},
|
||||||
|
content = { padding ->
|
||||||
|
KnockRequestsListContent(
|
||||||
|
state = state,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(padding)
|
||||||
|
.consumeWindowInsets(padding),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun KnockRequestsListContent(state: KnockRequestsListState, modifier: Modifier) {
|
||||||
|
|
||||||
|
fun onAcceptClick(knockRequest: KnockRequest) {
|
||||||
|
state.eventSink(KnockRequestsListEvents.Accept(knockRequest))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onDeclineClick(knockRequest: KnockRequest) {
|
||||||
|
state.eventSink(KnockRequestsListEvents.Decline(knockRequest))
|
||||||
|
}
|
||||||
|
|
||||||
|
Box(modifier, contentAlignment = Alignment.Center) {
|
||||||
|
when (state.knockRequests) {
|
||||||
|
is AsyncData.Success -> {
|
||||||
|
val knockRequests = state.knockRequests.data
|
||||||
|
if (knockRequests.isEmpty()) {
|
||||||
|
KnockRequestsListEmpty()
|
||||||
|
} else {
|
||||||
|
KnockRequestsList(
|
||||||
|
knockRequests = knockRequests,
|
||||||
|
onAcceptClick = ::onAcceptClick,
|
||||||
|
onDeclineClick = ::onDeclineClick,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> Unit
|
||||||
|
}
|
||||||
|
KnockRequestsActionsView(
|
||||||
|
actions = state.currentAction,
|
||||||
|
onDismiss = {
|
||||||
|
state.eventSink(KnockRequestsListEvents.AcceptAll)
|
||||||
|
},
|
||||||
|
modifier = Modifier.align(Alignment.BottomCenter),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun KnockRequestsActionsView(
|
||||||
|
actions: KnockRequestsCurrentAction,
|
||||||
|
onDismiss: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
) {
|
||||||
|
Box(modifier) {
|
||||||
|
when (actions) {
|
||||||
|
is KnockRequestsCurrentAction.AcceptAll -> {
|
||||||
|
AsyncActionView(
|
||||||
|
async = actions.async,
|
||||||
|
onSuccess = {},
|
||||||
|
onErrorDismiss = onDismiss,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is KnockRequestsCurrentAction.Accept -> {
|
||||||
|
AsyncActionView(
|
||||||
|
async = actions.async,
|
||||||
|
onSuccess = {},
|
||||||
|
onErrorDismiss = onDismiss,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is KnockRequestsCurrentAction.Decline -> {
|
||||||
|
AsyncActionView(
|
||||||
|
async = actions.async,
|
||||||
|
onSuccess = {},
|
||||||
|
onErrorDismiss = onDismiss,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
KnockRequestsCurrentAction.None -> Unit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun KnockRequestsList(
|
||||||
|
knockRequests: ImmutableList<KnockRequest>,
|
||||||
|
onAcceptClick: (KnockRequest) -> Unit,
|
||||||
|
onDeclineClick: (KnockRequest) -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
) {
|
||||||
|
LazyColumn(modifier = modifier) {
|
||||||
|
itemsIndexed(knockRequests) { index, knockRequest ->
|
||||||
|
KnockRequestItem(
|
||||||
|
knockRequest = knockRequest,
|
||||||
|
onAcceptClick = onAcceptClick,
|
||||||
|
onDeclineClick = onDeclineClick,
|
||||||
|
)
|
||||||
|
if (index != knockRequests.size - 1) {
|
||||||
|
HorizontalDivider()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun KnockRequestItem(
|
||||||
|
knockRequest: KnockRequest,
|
||||||
|
onAcceptClick: (KnockRequest) -> Unit,
|
||||||
|
onDeclineClick: (KnockRequest) -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
modifier = modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(horizontal = 16.dp, vertical = 12.dp)
|
||||||
|
) {
|
||||||
|
Avatar(knockRequest.getAvatarData(AvatarSize.KnockRequestItem))
|
||||||
|
Spacer(modifier = Modifier.width(16.dp))
|
||||||
|
Column(modifier = Modifier) {
|
||||||
|
// Name
|
||||||
|
Text(
|
||||||
|
modifier = Modifier.clipToBounds(),
|
||||||
|
text = knockRequest.getBestName(),
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
color = MaterialTheme.colorScheme.primary,
|
||||||
|
style = ElementTheme.typography.fontBodyLgMedium,
|
||||||
|
)
|
||||||
|
// UserId
|
||||||
|
if (!knockRequest.displayName.isNullOrEmpty()) {
|
||||||
|
Text(
|
||||||
|
text = knockRequest.userId.value,
|
||||||
|
color = MaterialTheme.colorScheme.secondary,
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
style = ElementTheme.typography.fontBodyMdRegular,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
// Reason
|
||||||
|
if (!knockRequest.reason.isNullOrBlank()) {
|
||||||
|
Spacer(modifier = Modifier.height(12.dp))
|
||||||
|
Text(
|
||||||
|
text = knockRequest.reason,
|
||||||
|
style = ElementTheme.typography.fontBodyMdRegular,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.height(12.dp))
|
||||||
|
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(16.dp)) {
|
||||||
|
OutlinedButton(
|
||||||
|
text = stringResource(CommonStrings.action_decline),
|
||||||
|
onClick = {
|
||||||
|
onDeclineClick(knockRequest)
|
||||||
|
},
|
||||||
|
size = ButtonSize.MediumLowPadding,
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
)
|
||||||
|
Button(
|
||||||
|
text = stringResource(CommonStrings.action_accept),
|
||||||
|
onClick = {
|
||||||
|
onAcceptClick(knockRequest)
|
||||||
|
},
|
||||||
|
size = ButtonSize.MediumLowPadding,
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(12.dp))
|
||||||
|
TextButton(
|
||||||
|
text = stringResource(CommonStrings.screen_knock_requests_list_decline_and_ban_action_title),
|
||||||
|
onClick = {
|
||||||
|
onAcceptClick(knockRequest)
|
||||||
|
},
|
||||||
|
destructive = true,
|
||||||
|
size = ButtonSize.Small,
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun KnockRequestsListEmpty(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = modifier.padding(
|
||||||
|
horizontal = 32.dp,
|
||||||
|
vertical = 48.dp,
|
||||||
|
),
|
||||||
|
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.",
|
||||||
|
iconStyle = BigIcon.Style.Default(CompoundIcons.Pin()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
private fun KnockRequestsListTopBar(onBackClick: () -> Unit) {
|
||||||
|
TopAppBar(
|
||||||
|
title = {
|
||||||
|
Text(
|
||||||
|
text = "Requests to join",
|
||||||
|
style = ElementTheme.typography.aliasScreenTitle,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
navigationIcon = { BackButton(onClick = onBackClick) },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@PreviewsDayNight
|
@PreviewsDayNight
|
||||||
@Composable
|
@Composable
|
||||||
internal fun KnockRequestsListViewPreview(
|
internal fun KnockRequestsListViewPreview(
|
||||||
|
|
@ -39,5 +286,6 @@ internal fun KnockRequestsListViewPreview(
|
||||||
) = ElementPreview {
|
) = ElementPreview {
|
||||||
KnockRequestsListView(
|
KnockRequestsListView(
|
||||||
state = state,
|
state = state,
|
||||||
|
onBackClick = {},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,4 +54,6 @@ enum class AvatarSize(val dp: Dp) {
|
||||||
EditProfileDetails(96.dp),
|
EditProfileDetails(96.dp),
|
||||||
|
|
||||||
Suggestion(32.dp),
|
Suggestion(32.dp),
|
||||||
|
|
||||||
|
KnockRequestItem(52.dp),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue