First Commit

This commit is contained in:
2025-12-18 16:28:50 +07:00
commit 8c3e4f491f
9974 changed files with 396488 additions and 0 deletions

View File

@@ -0,0 +1,30 @@
/*
* Copyright (c) 2025 Element Creations Ltd.
* Copyright 2024, 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.features.joinroom.impl
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.joinroom.api.JoinRoomEntryPoint
import io.element.android.libraries.architecture.createNode
@ContributesBinding(AppScope::class)
class DefaultJoinRoomEntryPoint : JoinRoomEntryPoint {
override fun createNode(
parentNode: Node,
buildContext: BuildContext,
inputs: JoinRoomEntryPoint.Inputs,
): Node {
return parentNode.createNode<JoinRoomFlowNode>(
buildContext = buildContext,
plugins = listOf(inputs)
)
}
}

View File

@@ -0,0 +1,24 @@
/*
* Copyright (c) 2025 Element Creations Ltd.
* Copyright 2024, 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.features.joinroom.impl
import io.element.android.features.invite.api.InviteData
sealed interface JoinRoomEvents {
data object RetryFetchingContent : JoinRoomEvents
data object DismissErrorAndHideContent : JoinRoomEvents
data object JoinRoom : JoinRoomEvents
data object KnockRoom : JoinRoomEvents
data object ForgetRoom : JoinRoomEvents
data class CancelKnock(val requiresConfirmation: Boolean) : JoinRoomEvents
data class UpdateKnockMessage(val message: String) : JoinRoomEvents
data object ClearActionStates : JoinRoomEvents
data class AcceptInvite(val inviteData: InviteData) : JoinRoomEvents
data class DeclineInvite(val inviteData: InviteData, val blockUser: Boolean) : JoinRoomEvents
}

View File

@@ -0,0 +1,107 @@
/*
* Copyright (c) 2025 Element Creations Ltd.
* Copyright 2024, 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.features.joinroom.impl
import android.os.Parcelable
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.node.node
import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.navmodel.backstack.BackStack
import com.bumble.appyx.navmodel.backstack.operation.push
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.AssistedInject
import io.element.android.annotations.ContributesNode
import io.element.android.features.invite.api.InviteData
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteView
import io.element.android.features.invite.api.declineandblock.DeclineInviteAndBlockEntryPoint
import io.element.android.features.joinroom.api.JoinRoomEntryPoint
import io.element.android.libraries.architecture.BackstackView
import io.element.android.libraries.architecture.BaseFlowNode
import io.element.android.libraries.architecture.inputs
import io.element.android.libraries.di.SessionScope
import kotlinx.parcelize.Parcelize
@ContributesNode(SessionScope::class)
@AssistedInject
class JoinRoomFlowNode(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
presenterFactory: JoinRoomPresenter.Factory,
private val acceptDeclineInviteView: AcceptDeclineInviteView,
private val declineAndBlockEntryPoint: DeclineInviteAndBlockEntryPoint
) : BaseFlowNode<JoinRoomFlowNode.NavTarget>(
backstack = BackStack(
initialElement = NavTarget.Root,
savedStateMap = buildContext.savedStateMap,
),
buildContext = buildContext,
plugins = plugins
) {
private val inputs: JoinRoomEntryPoint.Inputs = inputs()
private val presenter = presenterFactory.create(
inputs.roomId,
inputs.roomIdOrAlias,
inputs.roomDescription,
inputs.serverNames,
inputs.trigger,
)
sealed interface NavTarget : Parcelable {
@Parcelize
data object Root : NavTarget
@Parcelize
data class DeclineInviteAndBlockUser(val inviteData: InviteData) : NavTarget
}
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
return when (navTarget) {
is NavTarget.DeclineInviteAndBlockUser -> declineAndBlockEntryPoint.createNode(
parentNode = this,
buildContext = buildContext,
inviteData = navTarget.inviteData,
)
NavTarget.Root -> rootNode(buildContext)
}
}
@Composable
override fun View(modifier: Modifier) {
BackstackView(modifier)
}
private fun rootNode(buildContext: BuildContext): Node {
return node(buildContext) { modifier ->
val state = presenter.present()
JoinRoomView(
state = state,
onBackClick = ::navigateUp,
onJoinSuccess = {},
onForgetSuccess = ::navigateUp,
onCancelKnockSuccess = {},
onKnockSuccess = {},
onDeclineInviteAndBlockUser = {
backstack.push(
NavTarget.DeclineInviteAndBlockUser(it)
)
},
modifier = modifier
)
acceptDeclineInviteView.Render(
state = state.acceptDeclineInviteState,
onAcceptInviteSuccess = {},
onDeclineInviteSuccess = {},
modifier = Modifier
)
}
}
}

View File

@@ -0,0 +1,385 @@
/*
* Copyright (c) 2025 Element Creations Ltd.
* Copyright 2024, 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.features.joinroom.impl
import androidx.annotation.VisibleForTesting
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.AssistedInject
import im.vector.app.features.analytics.plan.JoinedRoom
import io.element.android.features.invite.api.InviteData
import io.element.android.features.invite.api.SeenInvitesStore
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvents
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteState
import io.element.android.features.invite.api.toInviteData
import io.element.android.features.joinroom.impl.di.CancelKnockRoom
import io.element.android.features.joinroom.impl.di.ForgetRoom
import io.element.android.features.joinroom.impl.di.KnockRoom
import io.element.android.features.roomdirectory.api.RoomDescription
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.architecture.runUpdatingState
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.RoomIdOrAlias
import io.element.android.libraries.matrix.api.room.CurrentUserMembership
import io.element.android.libraries.matrix.api.room.RoomInfo
import io.element.android.libraries.matrix.api.room.RoomMembershipDetails
import io.element.android.libraries.matrix.api.room.RoomType
import io.element.android.libraries.matrix.api.room.isDm
import io.element.android.libraries.matrix.api.room.join.JoinRoom
import io.element.android.libraries.matrix.api.room.join.JoinRule
import io.element.android.libraries.matrix.api.room.preview.RoomPreviewInfo
import io.element.android.libraries.matrix.api.spaces.SpaceRoom
import io.element.android.libraries.matrix.ui.model.toInviteSender
import io.element.android.libraries.matrix.ui.safety.rememberHideInvitesAvatar
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import java.util.Optional
import kotlin.jvm.optionals.getOrNull
@AssistedInject
class JoinRoomPresenter(
@Assisted private val roomId: RoomId,
@Assisted private val roomIdOrAlias: RoomIdOrAlias,
@Assisted private val roomDescription: Optional<RoomDescription>,
@Assisted private val serverNames: List<String>,
@Assisted private val trigger: JoinedRoom.Trigger,
private val matrixClient: MatrixClient,
private val joinRoom: JoinRoom,
private val knockRoom: KnockRoom,
private val cancelKnockRoom: CancelKnockRoom,
private val forgetRoom: ForgetRoom,
private val acceptDeclineInvitePresenter: Presenter<AcceptDeclineInviteState>,
private val buildMeta: BuildMeta,
private val seenInvitesStore: SeenInvitesStore,
) : Presenter<JoinRoomState> {
fun interface Factory {
fun create(
roomId: RoomId,
roomIdOrAlias: RoomIdOrAlias,
roomDescription: Optional<RoomDescription>,
serverNames: List<String>,
trigger: JoinedRoom.Trigger,
): JoinRoomPresenter
}
private val spaceList = matrixClient.spaceService.spaceRoomList(roomId)
@Composable
override fun present(): JoinRoomState {
val coroutineScope = rememberCoroutineScope()
var retryCount by remember { mutableIntStateOf(0) }
val roomInfo by remember {
matrixClient.getRoomInfoFlow(roomId)
}.collectAsState(initial = Optional.empty())
val spaceRoom by spaceList.currentSpaceFlow.collectAsState()
val joinAction: MutableState<AsyncAction<Unit>> = remember { mutableStateOf(AsyncAction.Uninitialized) }
val knockAction: MutableState<AsyncAction<Unit>> = remember { mutableStateOf(AsyncAction.Uninitialized) }
val cancelKnockAction: MutableState<AsyncAction<Unit>> = remember { mutableStateOf(AsyncAction.Uninitialized) }
val forgetRoomAction: MutableState<AsyncAction<Unit>> = remember { mutableStateOf(AsyncAction.Uninitialized) }
var knockMessage by rememberSaveable { mutableStateOf("") }
var isDismissingContent by remember { mutableStateOf(false) }
val hideInviteAvatars by matrixClient.rememberHideInvitesAvatar()
val canReportRoom by produceState(false) { value = matrixClient.canReportRoom() }
var contentState by remember {
mutableStateOf<ContentState>(ContentState.Loading)
}
LaunchedEffect(roomInfo, retryCount, isDismissingContent, spaceRoom) {
when {
isDismissingContent -> contentState = ContentState.Dismissing
roomInfo.isPresent -> {
val notJoinedRoom = matrixClient.getRoomPreview(roomIdOrAlias, serverNames).getOrNull()
val membershipDetails = notJoinedRoom?.membershipDetails()?.getOrNull()
val joinedMembersCountOverride = notJoinedRoom?.previewInfo?.numberOfJoinedMembers
contentState = roomInfo.get().toContentState(
joinedMembersCountOverride = joinedMembersCountOverride,
membershipDetails = membershipDetails,
childrenCount = spaceRoom.getOrNull()?.childrenCount,
)
}
spaceRoom.isPresent -> {
val spaceRoom = spaceRoom.get()
// Only use this state when space is not locally known
contentState = if (spaceRoom.state != null) {
ContentState.Loading
} else {
spaceRoom.toContentState()
}
}
roomDescription.isPresent -> {
contentState = roomDescription.get().toContentState()
}
else -> {
contentState = ContentState.Loading
val result = matrixClient.getRoomPreview(roomIdOrAlias, serverNames)
contentState = result.fold(
onSuccess = { preview ->
val membershipDetails = preview.membershipDetails().getOrNull()
preview.previewInfo.toContentState(membershipDetails)
},
onFailure = { throwable ->
ContentState.UnknownRoom
}
)
}
}
}
val acceptDeclineInviteState = acceptDeclineInvitePresenter.present()
LaunchedEffect(contentState) {
contentState.markRoomInviteAsSeen()
}
fun handleEvent(event: JoinRoomEvents) {
when (event) {
JoinRoomEvents.JoinRoom -> coroutineScope.joinRoom(joinAction)
is JoinRoomEvents.KnockRoom -> coroutineScope.knockRoom(knockAction, knockMessage)
is JoinRoomEvents.AcceptInvite -> {
acceptDeclineInviteState.eventSink(
AcceptDeclineInviteEvents.AcceptInvite(event.inviteData)
)
}
is JoinRoomEvents.DeclineInvite -> {
acceptDeclineInviteState.eventSink(
AcceptDeclineInviteEvents.DeclineInvite(invite = event.inviteData, blockUser = event.blockUser, shouldConfirm = true)
)
}
is JoinRoomEvents.CancelKnock -> coroutineScope.cancelKnockRoom(event.requiresConfirmation, cancelKnockAction)
JoinRoomEvents.RetryFetchingContent -> {
retryCount++
}
JoinRoomEvents.ClearActionStates -> {
knockAction.value = AsyncAction.Uninitialized
joinAction.value = AsyncAction.Uninitialized
cancelKnockAction.value = AsyncAction.Uninitialized
forgetRoomAction.value = AsyncAction.Uninitialized
}
is JoinRoomEvents.UpdateKnockMessage -> {
knockMessage = event.message.take(MAX_KNOCK_MESSAGE_LENGTH)
}
JoinRoomEvents.DismissErrorAndHideContent -> {
isDismissingContent = true
}
JoinRoomEvents.ForgetRoom -> coroutineScope.forgetRoom(forgetRoomAction)
}
}
return JoinRoomState(
roomIdOrAlias = roomIdOrAlias,
contentState = contentState,
acceptDeclineInviteState = acceptDeclineInviteState,
joinAction = joinAction.value,
knockAction = knockAction.value,
forgetAction = forgetRoomAction.value,
cancelKnockAction = cancelKnockAction.value,
applicationName = buildMeta.applicationName,
knockMessage = knockMessage,
hideInviteAvatars = hideInviteAvatars,
canReportRoom = canReportRoom,
eventSink = ::handleEvent,
)
}
private fun CoroutineScope.joinRoom(joinAction: MutableState<AsyncAction<Unit>>) = launch {
joinAction.runUpdatingState {
joinRoom.invoke(
roomIdOrAlias = roomIdOrAlias,
serverNames = serverNames,
trigger = trigger
)
}
}
private fun CoroutineScope.knockRoom(knockAction: MutableState<AsyncAction<Unit>>, message: String) = launch {
knockAction.runUpdatingState {
knockRoom(roomIdOrAlias, message, serverNames)
}
}
private fun CoroutineScope.cancelKnockRoom(requiresConfirmation: Boolean, cancelKnockAction: MutableState<AsyncAction<Unit>>) = launch {
if (requiresConfirmation) {
cancelKnockAction.value = AsyncAction.ConfirmingNoParams
} else {
cancelKnockAction.runUpdatingState {
cancelKnockRoom(roomId)
}
}
}
private fun CoroutineScope.forgetRoom(forgetAction: MutableState<AsyncAction<Unit>>) = launch {
forgetAction.runUpdatingState {
forgetRoom.invoke(roomId)
}
}
private suspend fun ContentState.markRoomInviteAsSeen() {
if ((this as? ContentState.Loaded)?.joinAuthorisationStatus as? JoinAuthorisationStatus.IsInvited != null) {
seenInvitesStore.markAsSeen(roomId)
}
}
}
private fun RoomPreviewInfo.toContentState(membershipDetails: RoomMembershipDetails?): ContentState {
return ContentState.Loaded(
roomId = roomId,
name = name,
topic = topic,
alias = canonicalAlias,
numberOfMembers = numberOfJoinedMembers,
roomAvatarUrl = avatarUrl,
joinAuthorisationStatus = computeJoinAuthorisationStatus(
membership,
membershipDetails,
joinRule,
{ toInviteData() }
),
joinRule = joinRule,
details = when (roomType) {
is RoomType.Other,
RoomType.Room -> LoadedDetails.Room(
isDm = false,
)
RoomType.Space -> LoadedDetails.Space(
childrenCount = 0,
heroes = persistentListOf(),
)
}
)
}
private fun SpaceRoom.toContentState(): ContentState {
return ContentState.Loaded(
roomId = roomId,
name = displayName,
topic = topic,
alias = canonicalAlias,
numberOfMembers = numJoinedMembers.toLong(),
roomAvatarUrl = avatarUrl,
joinAuthorisationStatus = computeJoinAuthorisationStatus(
membership = state,
membershipDetails = null,
joinRule = joinRule,
inviteData = { toInviteData() }
),
joinRule = joinRule,
details = LoadedDetails.Space(
childrenCount = childrenCount,
heroes = heroes.toImmutableList(),
)
)
}
@VisibleForTesting
internal fun RoomDescription.toContentState(): ContentState {
return ContentState.Loaded(
roomId = roomId,
name = name,
topic = topic,
alias = alias,
numberOfMembers = numberOfMembers,
roomAvatarUrl = avatarUrl,
joinAuthorisationStatus = when (joinRule) {
RoomDescription.JoinRule.KNOCK -> JoinAuthorisationStatus.CanKnock
RoomDescription.JoinRule.PUBLIC -> JoinAuthorisationStatus.CanJoin
else -> JoinAuthorisationStatus.Unknown
},
joinRule = when (joinRule) {
RoomDescription.JoinRule.KNOCK -> JoinRule.Knock
RoomDescription.JoinRule.PUBLIC -> JoinRule.Public
RoomDescription.JoinRule.RESTRICTED -> JoinRule.Restricted(persistentListOf())
RoomDescription.JoinRule.KNOCK_RESTRICTED -> JoinRule.KnockRestricted(persistentListOf())
RoomDescription.JoinRule.INVITE -> JoinRule.Invite
RoomDescription.JoinRule.UNKNOWN -> null
},
details = LoadedDetails.Room(isDm = false)
)
}
@VisibleForTesting
internal fun RoomInfo.toContentState(
joinedMembersCountOverride: Long?,
membershipDetails: RoomMembershipDetails?,
childrenCount: Int?,
): ContentState {
return ContentState.Loaded(
roomId = id,
name = name,
topic = topic,
alias = canonicalAlias,
numberOfMembers = joinedMembersCountOverride ?: joinedMembersCount,
roomAvatarUrl = avatarUrl,
joinAuthorisationStatus = computeJoinAuthorisationStatus(
membership = currentUserMembership,
membershipDetails = membershipDetails,
joinRule = joinRule,
inviteData = { toInviteData() }
),
joinRule = joinRule,
details = if (isSpace) {
LoadedDetails.Space(
childrenCount = childrenCount ?: 0,
heroes = heroes,
)
} else {
LoadedDetails.Room(
isDm = isDm,
)
},
)
}
private fun computeJoinAuthorisationStatus(
membership: CurrentUserMembership?,
membershipDetails: RoomMembershipDetails?,
joinRule: JoinRule?,
inviteData: () -> InviteData,
): JoinAuthorisationStatus {
return when (membership) {
CurrentUserMembership.INVITED -> {
JoinAuthorisationStatus.IsInvited(
inviteData = inviteData(),
inviteSender = membershipDetails?.senderMember?.toInviteSender()
)
}
CurrentUserMembership.BANNED -> JoinAuthorisationStatus.IsBanned(
membershipDetails?.senderMember?.toInviteSender(),
membershipDetails?.membershipChangeReason
)
CurrentUserMembership.KNOCKED -> JoinAuthorisationStatus.IsKnocked
else -> joinRule.toJoinAuthorisationStatus()
}
}
private fun JoinRule?.toJoinAuthorisationStatus(): JoinAuthorisationStatus {
return when (this) {
JoinRule.Knock,
is JoinRule.KnockRestricted -> JoinAuthorisationStatus.CanKnock
JoinRule.Invite,
JoinRule.Private -> JoinAuthorisationStatus.NeedInvite
is JoinRule.Restricted -> JoinAuthorisationStatus.Restricted
JoinRule.Public -> JoinAuthorisationStatus.CanJoin
else -> JoinAuthorisationStatus.Unknown
}
}

View File

@@ -0,0 +1,121 @@
/*
* Copyright (c) 2025 Element Creations Ltd.
* Copyright 2024, 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.features.joinroom.impl
import androidx.compose.runtime.Immutable
import io.element.android.features.invite.api.InviteData
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteState
import io.element.android.libraries.architecture.AsyncAction
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.RoomAlias
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.RoomIdOrAlias
import io.element.android.libraries.matrix.api.room.join.JoinRoom
import io.element.android.libraries.matrix.api.room.join.JoinRule
import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.ui.model.InviteSender
import kotlinx.collections.immutable.ImmutableList
internal const val MAX_KNOCK_MESSAGE_LENGTH = 500
data class JoinRoomState(
val roomIdOrAlias: RoomIdOrAlias,
val contentState: ContentState,
val acceptDeclineInviteState: AcceptDeclineInviteState,
val joinAction: AsyncAction<Unit>,
val knockAction: AsyncAction<Unit>,
val forgetAction: AsyncAction<Unit>,
val cancelKnockAction: AsyncAction<Unit>,
private val applicationName: String,
val knockMessage: String,
val hideInviteAvatars: Boolean,
val canReportRoom: Boolean,
val eventSink: (JoinRoomEvents) -> Unit
) {
val isJoinActionUnauthorized = joinAction is AsyncAction.Failure && joinAction.error is JoinRoom.Failures.UnauthorizedJoin
val joinAuthorisationStatus = when (contentState) {
is ContentState.Loaded -> {
when {
isJoinActionUnauthorized -> {
JoinAuthorisationStatus.Unauthorized
}
else -> {
contentState.joinAuthorisationStatus
}
}
}
is ContentState.UnknownRoom -> {
if (isJoinActionUnauthorized) {
JoinAuthorisationStatus.Unauthorized
} else {
JoinAuthorisationStatus.Unknown
}
}
else -> JoinAuthorisationStatus.None
}
val hideAvatarsImages = hideInviteAvatars && joinAuthorisationStatus is JoinAuthorisationStatus.IsInvited
}
@Immutable
sealed interface ContentState {
data object Dismissing : ContentState
data object Loading : ContentState
data class Failure(val error: Throwable) : ContentState
data object UnknownRoom : ContentState
data class Loaded(
val roomId: RoomId,
val name: String?,
val topic: String?,
val alias: RoomAlias?,
val numberOfMembers: Long?,
val roomAvatarUrl: String?,
val joinAuthorisationStatus: JoinAuthorisationStatus,
val joinRule: JoinRule?,
val details: LoadedDetails,
) : ContentState {
val showMemberCount = numberOfMembers != null
val isSpace = details is LoadedDetails.Space
fun avatarData(size: AvatarSize): AvatarData {
return AvatarData(
id = roomId.value,
name = name,
url = roomAvatarUrl,
size = size,
)
}
}
}
@Immutable
sealed interface LoadedDetails {
data class Room(
val isDm: Boolean,
) : LoadedDetails
data class Space(
val childrenCount: Int,
val heroes: ImmutableList<MatrixUser>,
) : LoadedDetails
}
sealed interface JoinAuthorisationStatus {
data object None : JoinAuthorisationStatus
data class IsInvited(val inviteData: InviteData, val inviteSender: InviteSender?) : JoinAuthorisationStatus
data class IsBanned(val banSender: InviteSender?, val reason: String?) : JoinAuthorisationStatus
data object IsKnocked : JoinAuthorisationStatus
data object CanKnock : JoinAuthorisationStatus
data object CanJoin : JoinAuthorisationStatus
data object NeedInvite : JoinAuthorisationStatus
data object Restricted : JoinAuthorisationStatus
data object Unknown : JoinAuthorisationStatus
data object Unauthorized : JoinAuthorisationStatus
}

View File

@@ -0,0 +1,246 @@
/*
* Copyright (c) 2025 Element Creations Ltd.
* Copyright 2024, 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.features.joinroom.impl
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.features.invite.api.InviteData
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteState
import io.element.android.features.invite.api.acceptdecline.anAcceptDeclineInviteState
import io.element.android.libraries.architecture.AsyncAction
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.RoomAlias
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.RoomIdOrAlias
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias
import io.element.android.libraries.matrix.api.exception.ClientException
import io.element.android.libraries.matrix.api.room.join.JoinRoom
import io.element.android.libraries.matrix.api.room.join.JoinRule
import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.ui.model.InviteSender
import kotlinx.collections.immutable.toImmutableList
open class JoinRoomStateProvider : PreviewParameterProvider<JoinRoomState> {
override val values: Sequence<JoinRoomState>
get() = sequenceOf(
aJoinRoomState(
contentState = ContentState.Loading
),
aJoinRoomState(
contentState = ContentState.UnknownRoom
),
aJoinRoomState(
contentState = aLoadedContentState(
name = null,
alias = null,
topic = null,
)
),
aJoinRoomState(
contentState = aLoadedContentState(joinAuthorisationStatus = JoinAuthorisationStatus.CanJoin)
),
aJoinRoomState(
contentState = aLoadedContentState(joinAuthorisationStatus = JoinAuthorisationStatus.CanJoin),
joinAction = AsyncAction.Failure(JoinRoom.Failures.UnauthorizedJoin)
),
aJoinRoomState(
contentState = aLoadedContentState(joinAuthorisationStatus = JoinAuthorisationStatus.CanJoin),
joinAction = AsyncAction.Failure(ClientException.Generic("Something went wrong", null))
),
aJoinRoomState(
contentState = aLoadedContentState(
joinAuthorisationStatus = JoinAuthorisationStatus.IsInvited(
inviteData = anInviteData(),
inviteSender = null,
)
)
),
aJoinRoomState(
contentState = aLoadedContentState(
numberOfMembers = 123,
joinAuthorisationStatus = JoinAuthorisationStatus.IsInvited(
inviteData = anInviteData(),
inviteSender = anInviteSender(),
),
)
),
aJoinRoomState(
contentState = aFailureContentState()
),
aJoinRoomState(
contentState = aLoadedContentState(
roomId = RoomId("!aSpaceId:domain"),
name = "A space",
alias = null,
topic = "This is the topic of a space",
details = aLoadedDetailsSpace(
childrenCount = 42,
),
)
),
aJoinRoomState(
contentState = aLoadedContentState(
name = "A DM",
details = aLoadedDetailsRoom(
isDm = true,
),
)
),
aJoinRoomState(
contentState = aLoadedContentState(
joinAuthorisationStatus = JoinAuthorisationStatus.CanKnock,
topic = "lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt" +
" ut labore et dolore magna aliqua ut enim ad minim veniam quis nostrud exercitation ullamco" +
" laboris nisi ut aliquip ex ea commodo consequat duis aute irure dolor in reprehenderit in" +
" voluptate velit esse cillum dolore eu fugiat nulla pariatur excepteur sint occaecat cupidatat" +
" non proident sunt in culpa qui officia deserunt mollit anim id est laborum",
numberOfMembers = 888,
)
),
aJoinRoomState(
knockMessage = "Let me in please!",
contentState = aLoadedContentState(
joinAuthorisationStatus = JoinAuthorisationStatus.CanKnock,
topic = "lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt" +
" ut labore et dolore magna aliqua ut enim ad minim veniam quis nostrud exercitation ullamco" +
" laboris nisi ut aliquip ex ea commodo consequat duis aute irure dolor in reprehenderit in" +
" voluptate velit esse cillum dolore eu fugiat nulla pariatur excepteur sint occaecat cupidatat" +
" non proident sunt in culpa qui officia deserunt mollit anim id est laborum",
numberOfMembers = 888,
)
),
aJoinRoomState(
contentState = aLoadedContentState(
name = "A knocked Room",
joinAuthorisationStatus = JoinAuthorisationStatus.IsKnocked
)
),
aJoinRoomState(
contentState = aLoadedContentState(
name = "A private room",
joinAuthorisationStatus = JoinAuthorisationStatus.NeedInvite
)
),
aJoinRoomState(
contentState = aLoadedContentState(
name = "A banned room",
joinAuthorisationStatus = JoinAuthorisationStatus.IsBanned(
banSender = InviteSender(
userId = UserId("@alice:domain"),
displayName = "Alice",
avatarData = AvatarData("alice", "Alice", size = AvatarSize.InviteSender),
membershipChangeReason = "spamming"
),
reason = "spamming",
),
)
),
aJoinRoomState(
contentState = aLoadedContentState(
name = "A restricted room",
joinAuthorisationStatus = JoinAuthorisationStatus.Restricted,
)
),
)
}
fun aFailureContentState(): ContentState {
return ContentState.Failure(
error = Exception("Error"),
)
}
fun aLoadedContentState(
roomId: RoomId = A_ROOM_ID,
name: String? = "Element X android",
alias: RoomAlias? = RoomAlias("#exa:matrix.org"),
topic: String? = "Element X is a secure, private and decentralized messenger.",
numberOfMembers: Long? = null,
roomAvatarUrl: String? = null,
joinAuthorisationStatus: JoinAuthorisationStatus = JoinAuthorisationStatus.Unknown,
joinRule: JoinRule? = null,
details: LoadedDetails = aLoadedDetailsRoom(isDm = false),
) = ContentState.Loaded(
roomId = roomId,
name = name,
alias = alias,
topic = topic,
numberOfMembers = numberOfMembers,
roomAvatarUrl = roomAvatarUrl,
joinAuthorisationStatus = joinAuthorisationStatus,
joinRule = joinRule,
details = details,
)
fun aLoadedDetailsRoom(
isDm: Boolean = false,
) = LoadedDetails.Room(
isDm = isDm
)
fun aLoadedDetailsSpace(
childrenCount: Int = 0,
heroes: List<MatrixUser> = emptyList(),
) = LoadedDetails.Space(
childrenCount = childrenCount,
heroes = heroes.toImmutableList()
)
fun aJoinRoomState(
roomIdOrAlias: RoomIdOrAlias = A_ROOM_ALIAS.toRoomIdOrAlias(),
contentState: ContentState = aLoadedContentState(),
acceptDeclineInviteState: AcceptDeclineInviteState = anAcceptDeclineInviteState(),
joinAction: AsyncAction<Unit> = AsyncAction.Uninitialized,
knockAction: AsyncAction<Unit> = AsyncAction.Uninitialized,
forgetAction: AsyncAction<Unit> = AsyncAction.Uninitialized,
cancelKnockAction: AsyncAction<Unit> = AsyncAction.Uninitialized,
knockMessage: String = "",
hideInviteAvatars: Boolean = false,
canReportRoom: Boolean = true,
eventSink: (JoinRoomEvents) -> Unit = {}
) = JoinRoomState(
roomIdOrAlias = roomIdOrAlias,
contentState = contentState,
acceptDeclineInviteState = acceptDeclineInviteState,
joinAction = joinAction,
knockAction = knockAction,
cancelKnockAction = cancelKnockAction,
forgetAction = forgetAction,
applicationName = "AppName",
knockMessage = knockMessage,
hideInviteAvatars = hideInviteAvatars,
canReportRoom = canReportRoom,
eventSink = eventSink
)
internal fun anInviteSender(
userId: UserId = UserId("@bob:domain"),
displayName: String = "Bob",
avatarData: AvatarData = AvatarData(userId.value, displayName, size = AvatarSize.InviteSender),
membershipChangeReason: String? = null,
) = InviteSender(
userId = userId,
displayName = displayName,
avatarData = avatarData,
membershipChangeReason = membershipChangeReason,
)
internal fun anInviteData(
roomId: RoomId = A_ROOM_ID,
roomName: String = "Room name",
isDm: Boolean = false,
) = InviteData(
roomId = roomId,
roomName = roomName,
isDm = isDm,
)
private val A_ROOM_ID = RoomId("!exa:matrix.org")
private val A_ROOM_ALIAS = RoomAlias("#exa:matrix.org")

View File

@@ -0,0 +1,658 @@
/*
* Copyright (c) 2025 Element Creations Ltd.
* Copyright 2024, 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.features.joinroom.impl
import androidx.compose.foundation.background
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.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.style.TextOverflow
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.invite.api.InviteData
import io.element.android.libraries.designsystem.atomic.atoms.PlaceholderAtom
import io.element.android.libraries.designsystem.atomic.atoms.RoomPreviewDescriptionAtom
import io.element.android.libraries.designsystem.atomic.atoms.RoomPreviewSubtitleAtom
import io.element.android.libraries.designsystem.atomic.atoms.RoomPreviewTitleAtom
import io.element.android.libraries.designsystem.atomic.molecules.ButtonRowMolecule
import io.element.android.libraries.designsystem.atomic.molecules.IconTitlePlaceholdersRowMolecule
import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule
import io.element.android.libraries.designsystem.atomic.molecules.MembersCountMolecule
import io.element.android.libraries.designsystem.atomic.organisms.RoomPreviewOrganism
import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage
import io.element.android.libraries.designsystem.components.Announcement
import io.element.android.libraries.designsystem.components.AnnouncementType
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.avatar.AvatarType
import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.components.button.SuperButton
import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog
import io.element.android.libraries.designsystem.components.dialogs.RetryDialog
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
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.CircularProgressIndicator
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.IconSource
import io.element.android.libraries.designsystem.theme.components.OutlinedButton
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.TextField
import io.element.android.libraries.designsystem.theme.components.TopAppBar
import io.element.android.libraries.designsystem.theme.placeholderBackground
import io.element.android.libraries.matrix.api.core.RoomIdOrAlias
import io.element.android.libraries.matrix.api.spaces.SpaceRoomVisibility
import io.element.android.libraries.matrix.ui.components.SpaceInfoRow
import io.element.android.libraries.matrix.ui.components.SpaceMembersView
import io.element.android.libraries.matrix.ui.model.InviteSender
import io.element.android.libraries.ui.strings.CommonStrings
import kotlinx.collections.immutable.persistentListOf
@Composable
fun JoinRoomView(
state: JoinRoomState,
onBackClick: () -> Unit,
onJoinSuccess: () -> Unit,
onKnockSuccess: () -> Unit,
onForgetSuccess: () -> Unit,
onCancelKnockSuccess: () -> Unit,
onDeclineInviteAndBlockUser: (InviteData) -> Unit,
modifier: Modifier = Modifier,
) {
Box(
modifier = modifier.fillMaxSize(),
) {
HeaderFooterPage(
containerColor = Color.Transparent,
contentPadding = PaddingValues(
horizontal = 16.dp,
vertical = 24.dp
),
topBar = {
JoinRoomTopBar(
contentState = state.contentState,
hideAvatarImage = state.hideAvatarsImages,
onBackClick = onBackClick,
)
},
content = {
JoinRoomContent(
roomIdOrAlias = state.roomIdOrAlias,
contentState = state.contentState,
knockMessage = state.knockMessage,
hideAvatarsImages = state.hideAvatarsImages,
onKnockMessageUpdate = { state.eventSink(JoinRoomEvents.UpdateKnockMessage(it)) },
)
},
footer = {
JoinRoomFooter(
joinAuthorisationStatus = state.joinAuthorisationStatus,
onAcceptInvite = { inviteData ->
state.eventSink(JoinRoomEvents.AcceptInvite(inviteData))
},
onDeclineInvite = { inviteData, blockUser ->
if (state.canReportRoom && blockUser) {
onDeclineInviteAndBlockUser(inviteData)
} else {
state.eventSink(JoinRoomEvents.DeclineInvite(inviteData, blockUser = blockUser))
}
},
onJoinRoom = {
state.eventSink(JoinRoomEvents.JoinRoom)
},
onKnockRoom = {
state.eventSink(JoinRoomEvents.KnockRoom)
},
onCancelKnock = {
state.eventSink(JoinRoomEvents.CancelKnock(requiresConfirmation = true))
},
onForgetRoom = {
state.eventSink(JoinRoomEvents.ForgetRoom)
},
onGoBack = onBackClick,
)
}
)
}
if (state.contentState is ContentState.Failure) {
RetryDialog(
title = stringResource(R.string.screen_join_room_loading_alert_title),
content = stringResource(CommonStrings.error_network_or_server_issue),
onRetry = { state.eventSink(JoinRoomEvents.RetryFetchingContent) },
onDismiss = {
state.eventSink(JoinRoomEvents.DismissErrorAndHideContent)
onBackClick()
}
)
}
// This particular error is shown directly in the footer
if (!state.isJoinActionUnauthorized) {
AsyncActionView(
async = state.joinAction,
errorTitle = { stringResource(CommonStrings.common_something_went_wrong) },
errorMessage = { stringResource(CommonStrings.error_network_or_server_issue) },
onSuccess = { onJoinSuccess() },
onErrorDismiss = { state.eventSink(JoinRoomEvents.ClearActionStates) },
)
}
AsyncActionView(
async = state.knockAction,
errorTitle = { stringResource(CommonStrings.common_something_went_wrong) },
errorMessage = { stringResource(CommonStrings.error_network_or_server_issue) },
onSuccess = { onKnockSuccess() },
onErrorDismiss = { state.eventSink(JoinRoomEvents.ClearActionStates) },
)
AsyncActionView(
async = state.forgetAction,
errorTitle = { stringResource(CommonStrings.common_something_went_wrong) },
errorMessage = { stringResource(CommonStrings.error_network_or_server_issue) },
onSuccess = { onForgetSuccess() },
onErrorDismiss = { state.eventSink(JoinRoomEvents.ClearActionStates) },
)
AsyncActionView(
async = state.cancelKnockAction,
onSuccess = { onCancelKnockSuccess() },
onErrorDismiss = { state.eventSink(JoinRoomEvents.ClearActionStates) },
errorTitle = { stringResource(CommonStrings.common_something_went_wrong) },
errorMessage = { stringResource(CommonStrings.error_network_or_server_issue) },
confirmationDialog = {
ConfirmationDialog(
content = stringResource(R.string.screen_join_room_cancel_knock_alert_description),
title = stringResource(R.string.screen_join_room_cancel_knock_alert_title),
submitText = stringResource(R.string.screen_join_room_cancel_knock_alert_confirmation),
cancelText = stringResource(CommonStrings.action_no),
onSubmitClick = { state.eventSink(JoinRoomEvents.CancelKnock(requiresConfirmation = false)) },
onDismiss = { state.eventSink(JoinRoomEvents.ClearActionStates) },
)
},
)
}
@Composable
private fun JoinRoomFooter(
joinAuthorisationStatus: JoinAuthorisationStatus,
onAcceptInvite: (InviteData) -> Unit,
onDeclineInvite: (InviteData, Boolean) -> Unit,
onJoinRoom: () -> Unit,
onKnockRoom: () -> Unit,
onCancelKnock: () -> Unit,
onForgetRoom: () -> Unit,
onGoBack: () -> Unit,
modifier: Modifier = Modifier,
) {
Box(
modifier = modifier
.fillMaxWidth()
.padding(top = 8.dp)
) {
when (joinAuthorisationStatus) {
is JoinAuthorisationStatus.IsInvited -> {
Column {
ButtonRowMolecule(horizontalArrangement = Arrangement.spacedBy(20.dp)) {
OutlinedButton(
text = stringResource(CommonStrings.action_decline),
onClick = { onDeclineInvite(joinAuthorisationStatus.inviteData, false) },
modifier = Modifier.weight(1f),
size = ButtonSize.LargeLowPadding,
leadingIcon = IconSource.Vector(CompoundIcons.Close())
)
Button(
text = stringResource(CommonStrings.action_accept),
onClick = { onAcceptInvite(joinAuthorisationStatus.inviteData) },
modifier = Modifier.weight(1f),
size = ButtonSize.LargeLowPadding,
leadingIcon = IconSource.Vector(CompoundIcons.Check())
)
}
Spacer(modifier = Modifier.height(24.dp))
TextButton(
text = stringResource(R.string.screen_join_room_decline_and_block_button_title),
onClick = { onDeclineInvite(joinAuthorisationStatus.inviteData, true) },
modifier = Modifier.fillMaxWidth(),
destructive = true
)
}
}
JoinAuthorisationStatus.CanJoin -> {
SuperButton(
onClick = onJoinRoom,
modifier = Modifier.fillMaxWidth(),
buttonSize = ButtonSize.Large,
) {
Text(
text = stringResource(R.string.screen_join_room_join_action),
)
}
}
JoinAuthorisationStatus.CanKnock -> {
SuperButton(
onClick = onKnockRoom,
modifier = Modifier.fillMaxWidth(),
buttonSize = ButtonSize.Large,
) {
Text(
text = stringResource(R.string.screen_join_room_knock_action),
)
}
}
JoinAuthorisationStatus.IsKnocked -> {
OutlinedButton(
text = stringResource(R.string.screen_join_room_cancel_knock_action),
onClick = onCancelKnock,
modifier = Modifier.fillMaxWidth(),
size = ButtonSize.Large,
)
}
JoinAuthorisationStatus.NeedInvite -> {
Announcement(
title = stringResource(R.string.screen_join_room_invite_required_message),
description = null,
type = AnnouncementType.Informative(isCritical = false),
)
}
is JoinAuthorisationStatus.IsBanned -> JoinBannedFooter(joinAuthorisationStatus, onForgetRoom)
JoinAuthorisationStatus.Unknown -> JoinRestrictedFooter(onJoinRoom)
JoinAuthorisationStatus.Restricted -> JoinRestrictedFooter(onJoinRoom)
JoinAuthorisationStatus.Unauthorized -> JoinUnauthorizedFooter(onGoBack)
JoinAuthorisationStatus.None -> Unit
}
}
}
@Composable
private fun JoinUnauthorizedFooter(
onOkClick: () -> Unit,
modifier: Modifier = Modifier,
) {
Column(modifier = modifier) {
Announcement(
title = stringResource(R.string.screen_join_room_fail_message),
description = stringResource(R.string.screen_join_room_fail_reason),
type = AnnouncementType.Informative(isCritical = true),
)
Spacer(Modifier.height(24.dp))
Button(
text = stringResource(CommonStrings.action_ok),
onClick = onOkClick,
modifier = Modifier.fillMaxWidth(),
)
}
}
@Composable
private fun JoinBannedFooter(
status: JoinAuthorisationStatus.IsBanned,
onForgetRoom: () -> Unit,
modifier: Modifier = Modifier,
) {
Column(modifier = modifier) {
val banReason = status.reason?.let {
stringResource(R.string.screen_join_room_ban_reason, it.removeSuffix("."))
}
val title = if (status.banSender != null) {
stringResource(R.string.screen_join_room_ban_by_message, status.banSender.displayName)
} else {
stringResource(R.string.screen_join_room_ban_message)
}
Announcement(
title = title,
description = banReason,
type = AnnouncementType.Informative(isCritical = true),
)
Spacer(Modifier.height(24.dp))
Button(
text = stringResource(R.string.screen_join_room_forget_action),
onClick = onForgetRoom,
modifier = Modifier.fillMaxWidth(),
size = ButtonSize.Large,
)
}
}
@Composable
private fun JoinRestrictedFooter(
onJoinRoom: () -> Unit,
modifier: Modifier = Modifier,
) {
Column(modifier = modifier) {
Announcement(
title = stringResource(R.string.screen_join_room_join_restricted_message),
description = null,
type = AnnouncementType.Informative(),
)
Spacer(Modifier.height(24.dp))
SuperButton(
onClick = onJoinRoom,
modifier = Modifier.fillMaxWidth(),
buttonSize = ButtonSize.Large,
) {
Text(
text = stringResource(R.string.screen_join_room_join_action),
)
}
}
}
@Composable
private fun JoinRoomContent(
roomIdOrAlias: RoomIdOrAlias,
contentState: ContentState,
knockMessage: String,
hideAvatarsImages: Boolean,
onKnockMessageUpdate: (String) -> Unit,
modifier: Modifier = Modifier,
) {
Box(modifier = modifier) {
when (contentState) {
is ContentState.Loaded -> {
when (contentState.joinAuthorisationStatus) {
is JoinAuthorisationStatus.IsKnocked -> {
IsKnockedLoadedContent()
}
else -> {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.verticalScroll(rememberScrollState())
) {
DefaultLoadedContent(
contentState = contentState,
hideAvatarImage = hideAvatarsImages,
)
when (contentState.joinAuthorisationStatus) {
is JoinAuthorisationStatus.IsInvited -> {
val inviteSender = contentState.joinAuthorisationStatus.inviteSender
if (inviteSender != null) {
Spacer(Modifier.height(16.dp))
InvitedByView(inviteSender, hideAvatarsImages)
}
}
is JoinAuthorisationStatus.CanKnock -> {
Spacer(modifier = Modifier.height(24.dp))
val supportingText = if (knockMessage.isNotEmpty()) {
"${knockMessage.length}/$MAX_KNOCK_MESSAGE_LENGTH"
} else {
stringResource(R.string.screen_join_room_knock_message_description)
}
TextField(
value = knockMessage,
onValueChange = onKnockMessageUpdate,
maxLines = 3,
minLines = 3,
modifier = Modifier.fillMaxWidth(),
supportingText = supportingText
)
}
else -> Unit
}
}
}
}
}
is ContentState.UnknownRoom -> UnknownRoomContent()
is ContentState.Loading -> IncompleteContent(roomIdOrAlias, isLoading = true)
is ContentState.Dismissing -> IncompleteContent(roomIdOrAlias, isLoading = false)
is ContentState.Failure -> IncompleteContent(roomIdOrAlias, isLoading = false)
}
}
}
@Composable
private fun InvitedByView(
sender: InviteSender,
hideAvatarImage: Boolean,
modifier: Modifier = Modifier
) {
Column(
modifier
.fillMaxWidth()
.padding(vertical = 16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = stringResource(R.string.screen_join_room_invited_by),
style = ElementTheme.typography.fontBodyMdRegular,
color = ElementTheme.colors.textSecondary
)
Spacer(Modifier.height(8.dp))
Avatar(
avatarData = sender.avatarData,
avatarType = AvatarType.User,
hideImage = hideAvatarImage,
forcedAvatarSize = AvatarSize.RoomPreviewInviter.dp
)
Spacer(Modifier.height(8.dp))
Text(
text = sender.displayName,
style = ElementTheme.typography.fontBodyLgRegular,
color = ElementTheme.colors.textPrimary
)
Spacer(Modifier.height(4.dp))
Text(
text = sender.userId.value,
style = ElementTheme.typography.fontBodySmRegular,
color = ElementTheme.colors.textSecondary
)
}
}
@Composable
private fun UnknownRoomContent(
modifier: Modifier = Modifier
) {
RoomPreviewOrganism(
modifier = modifier,
avatar = {
Box(
modifier = Modifier
.size(AvatarSize.RoomPreviewHeader.dp)
.background(
color = ElementTheme.colors.placeholderBackground,
shape = CircleShape
)
) {
Icon(
modifier = Modifier.align(Alignment.Center),
tint = ElementTheme.colors.iconPrimary,
imageVector = CompoundIcons.VisibilityOff(),
contentDescription = null,
)
}
},
title = {
RoomPreviewTitleAtom(stringResource(R.string.screen_join_room_title_no_preview))
},
subtitle = {
},
)
}
@Composable
private fun IncompleteContent(
roomIdOrAlias: RoomIdOrAlias,
isLoading: Boolean,
modifier: Modifier = Modifier
) {
RoomPreviewOrganism(
modifier = modifier,
avatar = {
PlaceholderAtom(width = AvatarSize.RoomPreviewHeader.dp, height = AvatarSize.RoomPreviewHeader.dp)
},
title = {
when (roomIdOrAlias) {
is RoomIdOrAlias.Alias -> {
RoomPreviewSubtitleAtom(roomIdOrAlias.identifier)
}
is RoomIdOrAlias.Id -> {
PlaceholderAtom(width = 200.dp, height = 22.dp)
}
}
},
subtitle = {
if (isLoading) {
Spacer(Modifier.height(8.dp))
CircularProgressIndicator()
}
},
)
}
@Composable
private fun IsKnockedLoadedContent(modifier: Modifier = Modifier) {
IconTitleSubtitleMolecule(
modifier = modifier.padding(horizontal = 8.dp),
iconStyle = BigIcon.Style.SuccessSolid,
title = stringResource(R.string.screen_join_room_knock_sent_title),
subTitle = stringResource(R.string.screen_join_room_knock_sent_description),
)
}
@Composable
private fun DefaultLoadedContent(
contentState: ContentState.Loaded,
hideAvatarImage: Boolean,
modifier: Modifier = Modifier,
) {
RoomPreviewOrganism(
modifier = modifier,
avatar = {
Avatar(
contentState.avatarData(AvatarSize.RoomPreviewHeader),
hideImage = hideAvatarImage,
avatarType = if (contentState.isSpace) AvatarType.Space() else AvatarType.Room(),
)
},
title = {
if (contentState.name != null) {
RoomPreviewTitleAtom(title = contentState.name)
} else {
RoomPreviewTitleAtom(
title = stringResource(id = CommonStrings.common_no_room_name),
fontStyle = FontStyle.Italic
)
}
},
subtitle = {
when {
contentState.details is LoadedDetails.Space -> {
SpaceInfoRow(visibility = SpaceRoomVisibility.fromJoinRule(contentState.joinRule))
}
contentState.alias != null -> {
RoomPreviewSubtitleAtom(contentState.alias.value)
}
}
},
description = {
RoomPreviewDescriptionAtom(
contentState.topic ?: "",
maxLines = if (contentState.joinAuthorisationStatus is JoinAuthorisationStatus.CanJoin) Int.MAX_VALUE else 2
)
},
memberCount = {
if (contentState.showMemberCount) {
val membersCount = contentState.numberOfMembers?.toInt() ?: 0
if (contentState.isSpace) {
SpaceMembersView(persistentListOf(), membersCount)
} else {
MembersCountMolecule(memberCount = membersCount)
}
}
}
)
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun JoinRoomTopBar(
contentState: ContentState,
hideAvatarImage: Boolean,
onBackClick: () -> Unit,
) {
TopAppBar(
navigationIcon = {
BackButton(onClick = onBackClick)
},
title = {
if (contentState is ContentState.Loaded && contentState.joinAuthorisationStatus is JoinAuthorisationStatus.IsKnocked) {
val roundedCornerShape = RoundedCornerShape(8.dp)
val titleModifier = Modifier
.clip(roundedCornerShape)
if (contentState.name != null) {
Row(
modifier = titleModifier,
verticalAlignment = Alignment.CenterVertically
) {
Avatar(
avatarData = contentState.avatarData(AvatarSize.TimelineRoom),
hideImage = hideAvatarImage,
avatarType = AvatarType.Room(),
)
Text(
modifier = Modifier
.padding(horizontal = 8.dp)
.semantics {
heading()
},
text = contentState.name,
style = ElementTheme.typography.fontBodyLgMedium,
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
}
} else {
IconTitlePlaceholdersRowMolecule(
iconSize = AvatarSize.TimelineRoom.dp,
modifier = titleModifier
)
}
}
},
)
}
@PreviewsDayNight
@Composable
internal fun JoinRoomViewPreview(@PreviewParameter(JoinRoomStateProvider::class) state: JoinRoomState) = ElementPreview {
JoinRoomView(
state = state,
onBackClick = { },
onJoinSuccess = { },
onKnockSuccess = { },
onForgetSuccess = { },
onCancelKnockSuccess = { },
onDeclineInviteAndBlockUser = { },
)
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright (c) 2025 Element Creations Ltd.
* Copyright 2024, 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.features.joinroom.impl.di
import dev.zacsweers.metro.ContributesBinding
import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomId
interface CancelKnockRoom {
suspend operator fun invoke(roomId: RoomId): Result<Unit>
}
@ContributesBinding(SessionScope::class)
class DefaultCancelKnockRoom(private val client: MatrixClient) : CancelKnockRoom {
override suspend fun invoke(roomId: RoomId): Result<Unit> {
return client
.getRoom(roomId)
?.use { it.leave() }
?: Result.failure(IllegalStateException("No pending room found"))
}
}

View File

@@ -0,0 +1,26 @@
/*
* Copyright (c) 2025 Element Creations Ltd.
* 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.features.joinroom.impl.di
import dev.zacsweers.metro.ContributesBinding
import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomId
interface ForgetRoom {
suspend operator fun invoke(roomId: RoomId): Result<Unit>
}
@ContributesBinding(SessionScope::class)
class DefaultForgetRoom(private val client: MatrixClient) : ForgetRoom {
override suspend fun invoke(roomId: RoomId): Result<Unit> {
return client.getRoom(roomId)?.use { it.forget() }
?: Result.failure(IllegalStateException("Room not found"))
}
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright (c) 2025 Element Creations Ltd.
* Copyright 2024, 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.features.joinroom.impl.di
import dev.zacsweers.metro.BindingContainer
import dev.zacsweers.metro.ContributesTo
import dev.zacsweers.metro.Provides
import im.vector.app.features.analytics.plan.JoinedRoom
import io.element.android.features.invite.api.SeenInvitesStore
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteState
import io.element.android.features.joinroom.impl.JoinRoomPresenter
import io.element.android.features.roomdirectory.api.RoomDescription
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.RoomIdOrAlias
import io.element.android.libraries.matrix.api.room.join.JoinRoom
import java.util.Optional
@BindingContainer
@ContributesTo(SessionScope::class)
object JoinRoomModule {
@Provides
fun providesJoinRoomPresenterFactory(
client: MatrixClient,
joinRoom: JoinRoom,
knockRoom: KnockRoom,
cancelKnockRoom: CancelKnockRoom,
forgetRoom: ForgetRoom,
acceptDeclineInvitePresenter: Presenter<AcceptDeclineInviteState>,
buildMeta: BuildMeta,
seenInvitesStore: SeenInvitesStore,
): JoinRoomPresenter.Factory {
return object : JoinRoomPresenter.Factory {
override fun create(
roomId: RoomId,
roomIdOrAlias: RoomIdOrAlias,
roomDescription: Optional<RoomDescription>,
serverNames: List<String>,
trigger: JoinedRoom.Trigger,
): JoinRoomPresenter {
return JoinRoomPresenter(
roomId = roomId,
roomIdOrAlias = roomIdOrAlias,
roomDescription = roomDescription,
serverNames = serverNames,
trigger = trigger,
matrixClient = client,
joinRoom = joinRoom,
knockRoom = knockRoom,
forgetRoom = forgetRoom,
cancelKnockRoom = cancelKnockRoom,
acceptDeclineInvitePresenter = acceptDeclineInvitePresenter,
buildMeta = buildMeta,
seenInvitesStore = seenInvitesStore,
)
}
}
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (c) 2025 Element Creations Ltd.
* Copyright 2024, 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.features.joinroom.impl.di
import dev.zacsweers.metro.ContributesBinding
import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomIdOrAlias
interface KnockRoom {
suspend operator fun invoke(
roomIdOrAlias: RoomIdOrAlias,
message: String,
serverNames: List<String>,
): Result<Unit>
}
@ContributesBinding(SessionScope::class)
class DefaultKnockRoom(private val client: MatrixClient) : KnockRoom {
override suspend fun invoke(
roomIdOrAlias: RoomIdOrAlias,
message: String,
serverNames: List<String>
): Result<Unit> {
return client
.knockRoom(roomIdOrAlias, message, serverNames)
.map { }
}
}

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_join_action">"Далучыцца"</string>
<string name="screen_join_room_knock_action">"Націсніце, каб далучыцца"</string>
<string name="screen_join_room_space_not_supported_description">"%1$s пакуль не падтрымлівае прасторы. Вы можаце атрымаць доступ да прастор праз вэб-старонку."</string>
<string name="screen_join_room_space_not_supported_title">"Прасторы пакуль не падтрымліваюцца"</string>
<string name="screen_join_room_subtitle_knock">"Націсніце кнопку ніжэй, і адміністратар пакоя атрымае апавяшчэнне. Вы зможаце далучыцца да размовы пасля зацвярджэння."</string>
<string name="screen_join_room_subtitle_no_preview">"Вы павінны быць удзельнікам гэтага пакоя каб прагледзець гісторыю паведамленняў."</string>
<string name="screen_join_room_title_knock">"Вы хочаце далучыцца да гэтага пакоя?"</string>
<string name="screen_join_room_title_no_preview">"Перадпрагляд недаступны"</string>
</resources>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_decline_and_block_button_title">"Отхвърляне и блокиране"</string>
<string name="screen_join_room_join_action">"Присъединяване"</string>
</resources>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_by_message">"Byli jste vykázáni uživatelem %1$s."</string>
<string name="screen_join_room_ban_message">"Byl vám zakázán vstup"</string>
<string name="screen_join_room_ban_reason">"Důvod: %1$s."</string>
<string name="screen_join_room_cancel_knock_action">"Zrušit žádost"</string>
<string name="screen_join_room_cancel_knock_alert_confirmation">"Ano, zrušit"</string>
<string name="screen_join_room_cancel_knock_alert_description">"Opravdu chcete zrušit svou žádost o vstup do této místnosti?"</string>
<string name="screen_join_room_cancel_knock_alert_title">"Zrušit žádost o vstup"</string>
<string name="screen_join_room_decline_and_block_alert_confirmation">"Ano, odmítnout a zablokovat"</string>
<string name="screen_join_room_decline_and_block_alert_message">"Opravdu chcete odmítnout pozvánku do této místnosti? Tím také zabráníte tomu, aby vás %1$s kontaktoval(a) nebo pozval(a) do místností."</string>
<string name="screen_join_room_decline_and_block_alert_title">"Odmítnout pozvání a zablokovat"</string>
<string name="screen_join_room_decline_and_block_button_title">"Odmítnout a zablokovat"</string>
<string name="screen_join_room_fail_message">"Vstup se nezdařil"</string>
<string name="screen_join_room_fail_reason">"Buď musíte být pozváni ke vstupu, nebo mohou existovat omezení přístupu."</string>
<string name="screen_join_room_forget_action">"Zapomenout"</string>
<string name="screen_join_room_invite_required_message">"Pro vstup potřebujete pozvánku"</string>
<string name="screen_join_room_invited_by">"Pozván(a)"</string>
<string name="screen_join_room_join_action">"Vstoupit"</string>
<string name="screen_join_room_join_restricted_message">"Abyste se mohli připojit, musíte být pozváni nebo být členem některého prostoru."</string>
<string name="screen_join_room_knock_action">"Zaklepejte a připojte se"</string>
<string name="screen_join_room_knock_message_characters_count">"Povolené znaky %1$d z %2$d"</string>
<string name="screen_join_room_knock_message_description">"Zpráva (nepovinné)"</string>
<string name="screen_join_room_knock_sent_description">"Pokud bude váš požadavek přijat, obdržíte pozvánku na vstup do místnosti."</string>
<string name="screen_join_room_knock_sent_title">"Žádost o vstup odeslána"</string>
<string name="screen_join_room_loading_alert_message">"Náhled místnosti se nám nepodařilo zobrazit. To může být způsobeno problémy se sítí nebo serverem."</string>
<string name="screen_join_room_loading_alert_title">"Náhled této místnosti jsme nemohli zobrazit"</string>
<string name="screen_join_room_space_not_supported_description">"%1$s zatím nepodporuje prostory. Prostory můžete používat na webu."</string>
<string name="screen_join_room_space_not_supported_title">"Prostory zatím nejsou podporovány"</string>
<string name="screen_join_room_subtitle_knock">"Klikněte na tlačítko níže a správce místnosti bude informován. Po schválení se budete moci připojit ke konverzaci."</string>
<string name="screen_join_room_subtitle_no_preview">"Pro zobrazení historie zpráv musíte být členem této místnosti."</string>
<string name="screen_join_room_title_knock">"Chcete se připojit k této místnosti?"</string>
<string name="screen_join_room_title_no_preview">"Náhled není k dispozici"</string>
</resources>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_by_message">"Cawsoch eich gwahardd o\'r ystafell hon gan %1$s."</string>
<string name="screen_join_room_ban_message">"Cawsoch eich gwahardd o\'r ystafell hon"</string>
<string name="screen_join_room_ban_reason">"Rheswm: %1$s."</string>
<string name="screen_join_room_cancel_knock_action">"Diddymu cais"</string>
<string name="screen_join_room_cancel_knock_alert_confirmation">"Iawn, diddymu"</string>
<string name="screen_join_room_cancel_knock_alert_description">"Ydych chi\'n siŵr eich bod am ddiddymu\'ch cais i ymuno â\'r ystafell hon?"</string>
<string name="screen_join_room_cancel_knock_alert_title">"Diddymu cais i ymuno"</string>
<string name="screen_join_room_decline_and_block_alert_confirmation">"Iawn, gwrthod a rhwystro"</string>
<string name="screen_join_room_decline_and_block_alert_message">"Ydych chi\'n siŵr eich bod am wrthod y gwahoddiad i ymuno â\'r ystafell hon? Bydd hyn hefyd yn atal %1$s rhag cysylltu â chi neu eich gwahodd i ystafelloedd."</string>
<string name="screen_join_room_decline_and_block_alert_title">"Gwrthod gwahoddiad a rhwystro"</string>
<string name="screen_join_room_decline_and_block_button_title">"Gwrthod a rhwystro"</string>
<string name="screen_join_room_fail_message">"Methodd yr ymuno â\'r ystafell."</string>
<string name="screen_join_room_fail_reason">"Mae\'r ystafell hon naill ai drwy wahoddiad yn unig neu efallai y bydd cyfyngiadau ar fynediad ar lefel y gofod."</string>
<string name="screen_join_room_forget_action">"Anghofiwch yr ystafell hon"</string>
<string name="screen_join_room_invite_required_message">"Mae angen gwahoddiad arnoch chi er mwyn ymuno â\'r ystafell hon"</string>
<string name="screen_join_room_invited_by">"Gwahoddwyd gan"</string>
<string name="screen_join_room_join_action">"Ymuno"</string>
<string name="screen_join_room_join_restricted_message">"Efallai y bydd angen i chi gael eich gwahodd neu fod yn aelod o ofod er mwyn ymuno."</string>
<string name="screen_join_room_knock_action">"Anfon cais i ymuno"</string>
<string name="screen_join_room_knock_message_characters_count">"Nodau a ganiateir %1$d o %2$d"</string>
<string name="screen_join_room_knock_message_description">"Neges (dewisol)"</string>
<string name="screen_join_room_knock_sent_description">"Byddwch yn derbyn gwahoddiad i ymuno â\'r ystafell os caiff eich cais ei dderbyn."</string>
<string name="screen_join_room_knock_sent_title">"Anfonwyd y cais i ymuno"</string>
<string name="screen_join_room_loading_alert_message">"Doedd dim modd dangos rhagolwg yr ystafell. Gall hyn fod oherwydd problemau rhwydwaith neu weinydd."</string>
<string name="screen_join_room_loading_alert_title">"Doedd dim modd dangos rhagolwg yr ystafell hon"</string>
<string name="screen_join_room_space_not_supported_description">"Nid yw %1$s yn cefnogi gofodau eto. Gallwch gael mynediad i ofodau ar y we."</string>
<string name="screen_join_room_space_not_supported_title">"Nid yw gofodau\'n cael eu cefnogi eto"</string>
<string name="screen_join_room_subtitle_knock">"Cliciwch ar y botwm isod a bydd gweinyddwr ystafell yn cael ei hysbysu. Byddwch yn gallu ymuno â\'r sgwrs ar ôl ei chymeradwyo."</string>
<string name="screen_join_room_subtitle_no_preview">"Rhaid i chi fod yn aelod o\'r ystafell hon i weld hanes y neges."</string>
<string name="screen_join_room_title_knock">"Eisiau ymuno â\'r ystafell hon?"</string>
<string name="screen_join_room_title_no_preview">"Nid yw rhagolwg ar gael"</string>
</resources>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_by_message">"Du blev spærret af %1$s."</string>
<string name="screen_join_room_ban_message">"Du blev spærret"</string>
<string name="screen_join_room_ban_reason">"Årsag: %1$s."</string>
<string name="screen_join_room_cancel_knock_action">"Annuller anmodning"</string>
<string name="screen_join_room_cancel_knock_alert_confirmation">"Ja, annullér"</string>
<string name="screen_join_room_cancel_knock_alert_description">"Er du sikker på, at du vil annullere din anmodning om at deltage i dette rum?"</string>
<string name="screen_join_room_cancel_knock_alert_title">"Annullér anmodning om at deltage"</string>
<string name="screen_join_room_decline_and_block_alert_confirmation">"Ja, afvis og blokér"</string>
<string name="screen_join_room_decline_and_block_alert_message">"Er du sikker på, at du vil afvise invitationen til at deltage i dette rum? Dette forhindrer også %1$s i at kontakte dig eller invitere dig til andre rum."</string>
<string name="screen_join_room_decline_and_block_alert_title">"Afvis invitation og blokér"</string>
<string name="screen_join_room_decline_and_block_button_title">"Afvis og blokér"</string>
<string name="screen_join_room_fail_message">"Deltagelse fejlede."</string>
<string name="screen_join_room_fail_reason">"Du skal enten inviteres til at deltage, eller der kan være adgangsbegrænsninger."</string>
<string name="screen_join_room_forget_action">"Glem"</string>
<string name="screen_join_room_invite_required_message">"Du har brug for en invitation for at deltage"</string>
<string name="screen_join_room_invited_by">"Inviteret af"</string>
<string name="screen_join_room_join_action">"Deltag"</string>
<string name="screen_join_room_join_restricted_message">"Du skal muligvis være inviteret eller være medlem af en gruppe for at deltage."</string>
<string name="screen_join_room_knock_action">"Send anmodning om at deltage"</string>
<string name="screen_join_room_knock_message_characters_count">"Tilladte tegn %1$d af %2$d"</string>
<string name="screen_join_room_knock_message_description">"Besked (valgfrit)"</string>
<string name="screen_join_room_knock_sent_description">"Du vil modtage en invitation til at deltage i rummet, hvis din anmodning accepteres."</string>
<string name="screen_join_room_knock_sent_title">"Anmodning om at deltage sendt"</string>
<string name="screen_join_room_loading_alert_message">"Vi kunne ikke forhåndsvise rummet. Dette kan skyldes netværks- eller serverproblemer."</string>
<string name="screen_join_room_loading_alert_title">"Vi kunne ikke forhåndsvise rummet"</string>
<string name="screen_join_room_space_not_supported_description">"%1$s understøtter ikke grupper endnu. Du kan få adgang til grupper på nettet."</string>
<string name="screen_join_room_space_not_supported_title">"Grupper er ikke understøttet endnu"</string>
<string name="screen_join_room_subtitle_knock">"Klik på knappen nedenfor, og en rumadministrator vil blive underrettet. Du kan deltage i samtalen, når din anmodning er godkendt."</string>
<string name="screen_join_room_subtitle_no_preview">"Du skal være medlem af dette rum for at kunne se meddelelseshistorikken."</string>
<string name="screen_join_room_title_knock">"Vil du deltage i dette rum?"</string>
<string name="screen_join_room_title_no_preview">"Forhåndsvisning er ikke tilgængelig"</string>
</resources>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_by_message">"Du wurdest von %1$s gesperrt."</string>
<string name="screen_join_room_ban_message">"Du wurdest gesperrt"</string>
<string name="screen_join_room_ban_reason">"Grund:%1$s."</string>
<string name="screen_join_room_cancel_knock_action">"Anfrage abbrechen"</string>
<string name="screen_join_room_cancel_knock_alert_confirmation">"Ja, abbrechen"</string>
<string name="screen_join_room_cancel_knock_alert_description">"Willst du wirklich deine Anfrage zum Beitritt zu diesem Chat abbrechen?"</string>
<string name="screen_join_room_cancel_knock_alert_title">"Beitrittsanfrage abbrechen"</string>
<string name="screen_join_room_decline_and_block_alert_confirmation">"Ja, ablehnen &amp; blockieren"</string>
<string name="screen_join_room_decline_and_block_alert_message">"Bist du sicher, dass du die Einladung zu diesem Chat ablehnen möchtest? Dadurch wird auch jede weitere Kontaktaufnahme oder Chat Einladung von %1$s blockiert."</string>
<string name="screen_join_room_decline_and_block_alert_title">"Einladung ablehnen &amp; Nutzer blockieren"</string>
<string name="screen_join_room_decline_and_block_button_title">"Ablehnen und blockieren"</string>
<string name="screen_join_room_fail_message">"Beitritt fehlgeschlagen"</string>
<string name="screen_join_room_fail_reason">"Du musst entweder eingeladen werden, um beizutreten, oder es gibt möglicherweise Zugriffsbeschränkungen."</string>
<string name="screen_join_room_forget_action">"Vergessen"</string>
<string name="screen_join_room_invite_required_message">"Du benötigst eine Einladung, um beizutreten"</string>
<string name="screen_join_room_invited_by">"Eingeladen von"</string>
<string name="screen_join_room_join_action">"Beitreten"</string>
<string name="screen_join_room_join_restricted_message">"Möglicherweise musst du eingeladen werden oder ein Mitglied eines Spaces sein, um beitreten zu können."</string>
<string name="screen_join_room_knock_action">"Anklopfen"</string>
<string name="screen_join_room_knock_message_characters_count">"%1$d von %2$d erlaubte Zeichen"</string>
<string name="screen_join_room_knock_message_description">"Nachricht (optional)"</string>
<string name="screen_join_room_knock_sent_description">"Sollte deine Anfrage akzeptiert werden, erhältst du eine Einladung, dem Chat beizutreten."</string>
<string name="screen_join_room_knock_sent_title">"Beitrittsanfrage geschickt"</string>
<string name="screen_join_room_loading_alert_message">"Wir konnten die Chat Vorschau nicht anzeigen. Dies kann an Netzwerk- oder Serverproblemen liegen."</string>
<string name="screen_join_room_loading_alert_title">"Wir konnten diese Chat-Vorschau nicht anzeigen"</string>
<string name="screen_join_room_space_not_supported_description">"%1$s unterstützt noch keine Spaces. Du kannst auf Spaces im Web zugreifen."</string>
<string name="screen_join_room_space_not_supported_title">"Spaces werden noch nicht unterstützt"</string>
<string name="screen_join_room_subtitle_knock">"Klopfe an um einen Admin zu benachrichtigen. Nach der Freigabe kannst du dich an der Unterhaltung beteiligen."</string>
<string name="screen_join_room_subtitle_no_preview">"Du musst Mitglied in diesem Chat sein, um den Nachrichtenverlauf zu sehen."</string>
<string name="screen_join_room_title_knock">"Willst du diesem Chat beitreten?"</string>
<string name="screen_join_room_title_no_preview">"Vorschau nicht verfügbar"</string>
</resources>

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_by_message">"Αποκλειστήκατε από αυτή την αίθουσα από το χρήστη %1$s."</string>
<string name="screen_join_room_ban_message">"Σας απαγορεύτηκε η είσοδος σε αυτή την αίθουσα"</string>
<string name="screen_join_room_ban_reason">"Αιτία: %1$s."</string>
<string name="screen_join_room_cancel_knock_action">"Ακύρωση αιτήματος"</string>
<string name="screen_join_room_cancel_knock_alert_confirmation">"Ναι, ακύρωση"</string>
<string name="screen_join_room_cancel_knock_alert_description">"Είστε βέβαιοι ότι θέλετε να ακυρώσετε το αίτημά σας να συμμετάσχετε σε αυτή την αίθουσα;"</string>
<string name="screen_join_room_cancel_knock_alert_title">"Ακύρωση αίτησης συμμετοχής"</string>
<string name="screen_join_room_decline_and_block_alert_confirmation">"Ναι, απόρριψη και αποκλεισμός"</string>
<string name="screen_join_room_decline_and_block_alert_message">"Είστε βέβαιοι ότι θέλετε να απορρίψετε την πρόσκληση συμμετοχής σε αυτήν την αίθουσα; Αυτό θα εμποδίσει επίσης τον χρήστη %1$s να επικοινωνήσει μαζί σας ή να σας προσκαλέσει σε αίθουσες."</string>
<string name="screen_join_room_decline_and_block_alert_title">"Απόρριψη πρόσκλησης και αποκλεισμός"</string>
<string name="screen_join_room_decline_and_block_button_title">"Απόρριψη και αποκλεισμός"</string>
<string name="screen_join_room_fail_message">"Η συμμετοχή στην αίθουσα απέτυχε."</string>
<string name="screen_join_room_fail_reason">"Αυτή η αίθουσα είναι είτε μόνο για προσκεκλημένους είτε ενδέχεται να υπάρχουν περιορισμοί πρόσβασης σε επίπεδο χώρου."</string>
<string name="screen_join_room_forget_action">"Ξεχάστε αυτή την αίθουσα"</string>
<string name="screen_join_room_invite_required_message">"Χρειάζεστε πρόσκληση για να συμμετάσχετε σε αυτή την αίθουσα"</string>
<string name="screen_join_room_join_action">"Συμμετοχή"</string>
<string name="screen_join_room_join_restricted_message">"Ενδέχεται να χρειαστεί να προσκληθείτε ή να είστε μέλος ενός χώρου για να συμμετάσχετε."</string>
<string name="screen_join_room_knock_action">"Χτύπα για συμμετοχή"</string>
<string name="screen_join_room_knock_message_description">"Μήνυμα (προαιρετικό)"</string>
<string name="screen_join_room_knock_sent_description">"Θα λάβετε πρόσκληση για να συμμετάσχετε στην αίθουσα, εάν το αίτημά σας γίνει αποδεκτό."</string>
<string name="screen_join_room_knock_sent_title">"Το αίτημα συμμετοχής στάλθηκε"</string>
<string name="screen_join_room_loading_alert_message">"Δεν μπορέσαμε να εμφανίσουμε την προεπισκόπηση της αίθουσας. Αυτό μπορεί να οφείλεται σε προβλήματα δικτύου ή διακομιστή."</string>
<string name="screen_join_room_loading_alert_title">"Δεν μπορέσαμε να εμφανίσουμε αυτή την προεπισκόπηση αίθουσας"</string>
<string name="screen_join_room_space_not_supported_description">"Το %1$s δεν υποστηρίζει ακόμα χώρους. Μπορείς να έχεις πρόσβαση σε χώρους στον ιστό."</string>
<string name="screen_join_room_space_not_supported_title">"Οι Χώροι δεν υποστηρίζονται ακόμα"</string>
<string name="screen_join_room_subtitle_knock">"Κάντε κλικ στο παρακάτω κουμπί και θα ειδοποιηθεί ένας διαχειριστής της αίθουσας. Μόλις εγκριθείτε, θα μπορείτε να συμμετάσχετε στη συζήτηση."</string>
<string name="screen_join_room_subtitle_no_preview">"Πρέπει να είστε μέλος αυτής της αίθουσας για να δείτε το ιστορικό των μηνυμάτων."</string>
<string name="screen_join_room_title_knock">"Θέλετε να συμμετάσχετε σε αυτή την αίθουσα;"</string>
<string name="screen_join_room_title_no_preview">"Η προεπισκόπηση δεν είναι διαθέσιμη"</string>
</resources>

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_by_message">"Has sido vetado de esta sala por %1$s."</string>
<string name="screen_join_room_ban_message">"Has sido vetado de esta sala"</string>
<string name="screen_join_room_ban_reason">"Motivo: %1$s."</string>
<string name="screen_join_room_cancel_knock_action">"Cancelar solicitud"</string>
<string name="screen_join_room_cancel_knock_alert_confirmation">"Sí, cancelar"</string>
<string name="screen_join_room_cancel_knock_alert_description">"¿Estás seguro de que deseas cancelar tu solicitud de unión a esta sala?"</string>
<string name="screen_join_room_cancel_knock_alert_title">"Cancelar solicitud de unión"</string>
<string name="screen_join_room_decline_and_block_alert_confirmation">"Sí, rechazar y bloquear"</string>
<string name="screen_join_room_decline_and_block_alert_message">"¿Estás seguro de que deseas rechazar la invitación para unirte a esta sala? Esto también impedirá que %1$s pueda contactar contigo o invitarte a salas."</string>
<string name="screen_join_room_decline_and_block_alert_title">"Rechazar invitación y bloquear"</string>
<string name="screen_join_room_decline_and_block_button_title">"Rechazar y bloquear"</string>
<string name="screen_join_room_fail_message">"No se pudo unir a la sala."</string>
<string name="screen_join_room_fail_reason">"O bien solo se puede acceder a esta sala con invitación, o puede que haya restricciones de acceso a nivel de espacio."</string>
<string name="screen_join_room_forget_action">"Olvidar esta sala"</string>
<string name="screen_join_room_invite_required_message">"Necesitas una invitación para unirte a esta sala"</string>
<string name="screen_join_room_join_action">"Unirse"</string>
<string name="screen_join_room_join_restricted_message">"Es posible que necesites ser invitado o ser miembro de un espacio para poder unirte."</string>
<string name="screen_join_room_knock_action">"Enviar solicitud de unión"</string>
<string name="screen_join_room_knock_message_description">"Mensaje (opcional)"</string>
<string name="screen_join_room_knock_sent_description">"Recibirás una invitación para unirte a la sala si se acepta tu solicitud."</string>
<string name="screen_join_room_knock_sent_title">"Solicitud de unión enviada"</string>
<string name="screen_join_room_loading_alert_message">"No hemos podido mostrar la vista previa de la sala. Esto puede deberse a problemas de red o del servidor."</string>
<string name="screen_join_room_loading_alert_title">"No hemos podido mostrar la vista previa de esta sala"</string>
<string name="screen_join_room_space_not_supported_description">"%1$s aún no admite los espacios. Puedes acceder a los espacios en la web."</string>
<string name="screen_join_room_space_not_supported_title">"Todavía no se admiten los espacios"</string>
<string name="screen_join_room_subtitle_knock">"Haz clic en el botón que aparece a continuación y se notificará a un administrador de la sala. Podrás unirte a la conversación una vez que hayas sido aprobado."</string>
<string name="screen_join_room_subtitle_no_preview">"Debes ser miembro de esta sala para ver el historial de mensajes."</string>
<string name="screen_join_room_title_knock">"¿Quieres unirte a esta sala?"</string>
<string name="screen_join_room_title_no_preview">"La vista previa no está disponible"</string>
</resources>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_by_message">"%1$s keelas sinu ligipääsu siia jututuppa."</string>
<string name="screen_join_room_ban_message">"Sinul on ligipääsukeeld siia jututuppa"</string>
<string name="screen_join_room_ban_reason">"Põhjus: %1$s."</string>
<string name="screen_join_room_cancel_knock_action">"Tühista liitumispalve"</string>
<string name="screen_join_room_cancel_knock_alert_confirmation">"Jah, tühista"</string>
<string name="screen_join_room_cancel_knock_alert_description">"Kas sa oled kindel, et soovid tühistada oma palve jututoaga liitumiseks?"</string>
<string name="screen_join_room_cancel_knock_alert_title">"Tühista liitumispalve"</string>
<string name="screen_join_room_decline_and_block_alert_confirmation">"Jah, keeldu ja blokeeri"</string>
<string name="screen_join_room_decline_and_block_alert_message">"Kas sa oled kindel, et soovid keelduda kutsest sellesse jututuppa? Samaga kaob kasutajal %1$s võimalus sinuga suhelda ja saata sulle jututubade kutseid."</string>
<string name="screen_join_room_decline_and_block_alert_title">"Keeldu kutsest ja blokeeri"</string>
<string name="screen_join_room_decline_and_block_button_title">"Keeldu ja blokeeri"</string>
<string name="screen_join_room_fail_message">"Jututoaga liitumine ei õnnestunud"</string>
<string name="screen_join_room_fail_reason">"Ligipääs siia on võimalik vaid kutse alusel või siin kehtivad ligipääsupiirangud."</string>
<string name="screen_join_room_forget_action">"Unusta see jututuba"</string>
<string name="screen_join_room_invite_required_message">"Selle jututoaga liitumiseks vajad sa kutset"</string>
<string name="screen_join_room_invited_by">"Kutsuja"</string>
<string name="screen_join_room_join_action">"Liitu"</string>
<string name="screen_join_room_join_restricted_message">"Selle jututoaga liitumiseks sa vajad kutset või pead juba olema kogukonna liige."</string>
<string name="screen_join_room_knock_action">"Liitumiseks koputa jututoa uksele"</string>
<string name="screen_join_room_knock_message_characters_count">"Lubatud tähemärke: %1$d / %2$d"</string>
<string name="screen_join_room_knock_message_description">"Selgitus (kui soovid lisada)"</string>
<string name="screen_join_room_knock_sent_description">"Kui sinu liitumispalvega ollakse nõus, siis saad kutse jututoaga liitumiseks."</string>
<string name="screen_join_room_knock_sent_title">"Liitumispalve on saadetud"</string>
<string name="screen_join_room_loading_alert_message">"Me ei saanud jututoa eelvaadet näidata. See võib olla põhjustatud võrguühenduse või serveri vigadest."</string>
<string name="screen_join_room_loading_alert_title">"Meil ei õnnestunud selle jututoa eelvaadet kuvada"</string>
<string name="screen_join_room_space_not_supported_description">"%1$s veel ei toeta kogukondadega liitumise ja kasutamise võimalust. Vajadusel saad seda teha veebiliidese vahendusel."</string>
<string name="screen_join_room_space_not_supported_title">"Kogukonnad pole veel toetatud"</string>
<string name="screen_join_room_subtitle_knock">"Klõpsi allolevat nuppu ja jututoa haldaja saab asjakohase teate. Sa saad liituda, kui haldaja sinu soovi heaks kiidab."</string>
<string name="screen_join_room_subtitle_no_preview">"Sõnumite ajaloo vaatamiseks pead olema selle jututoa liige."</string>
<string name="screen_join_room_title_knock">"Kas sa soovid selle jututoaga liituda?"</string>
<string name="screen_join_room_title_no_preview">"Eelvaade pole saadaval"</string>
</resources>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_reason">"Arrazoia: %1$s."</string>
<string name="screen_join_room_cancel_knock_action">"Utzi eskaera bertan behera"</string>
<string name="screen_join_room_cancel_knock_alert_confirmation">"Bai, utzi bertan behera"</string>
<string name="screen_join_room_decline_and_block_alert_title">"Eman gonbidapenari ezetza eta blokeatu"</string>
<string name="screen_join_room_decline_and_block_button_title">"Baztertu eta blokeatu"</string>
<string name="screen_join_room_fail_message">"Gelara sartzeak huts egin du."</string>
<string name="screen_join_room_forget_action">"Ahaztu gela hau"</string>
<string name="screen_join_room_join_action">"Elkartu"</string>
<string name="screen_join_room_knock_action">"Bidali batzeko eskaera"</string>
<string name="screen_join_room_knock_message_description">"Mezua (aukerakoa)"</string>
<string name="screen_join_room_knock_sent_title">"Sartzeko eskaera bidali da"</string>
<string name="screen_join_room_space_not_supported_description">"%1$s ez da oraindik guneekin bateragarria. Webgunean sar zaitezke guneetara."</string>
<string name="screen_join_room_space_not_supported_title">"Oraindik ez da guneekin bateragarria"</string>
<string name="screen_join_room_subtitle_knock">"Klikatu beheko botoia eta gelako administratzaileari jakinaraziko zaio. Elkarrizketara batu ahal izango zara onartutakoan."</string>
<string name="screen_join_room_subtitle_no_preview">"Gela honetako kide izan behar zara mezuen historia ikusteko."</string>
<string name="screen_join_room_title_knock">"Gela honetan sartu nahi?"</string>
<string name="screen_join_room_title_no_preview">"Aurrebista ez dago erabilgarri"</string>
</resources>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_by_message">"به دست %1$s از این اتاق محروم شدید."</string>
<string name="screen_join_room_ban_message">"از این اتاق محروم شدید"</string>
<string name="screen_join_room_ban_reason">"دلیل: %1$s."</string>
<string name="screen_join_room_cancel_knock_action">"لغو درخواست"</string>
<string name="screen_join_room_cancel_knock_alert_confirmation">"بله. لغو"</string>
<string name="screen_join_room_cancel_knock_alert_title">"لغو درخواست پیوستن"</string>
<string name="screen_join_room_decline_and_block_alert_confirmation">"بله. رد و انسداد"</string>
<string name="screen_join_room_decline_and_block_alert_title">"رد دعوت و انسداد"</string>
<string name="screen_join_room_decline_and_block_button_title">"رد و انسداد"</string>
<string name="screen_join_room_fail_message">"پیوستن شکست خورد"</string>
<string name="screen_join_room_forget_action">"فراموشی این اتاق"</string>
<string name="screen_join_room_invite_required_message">"برای پیوستن به این اتاق نیاز به دعوت دارید"</string>
<string name="screen_join_room_invited_by">"دعوت شده از سوی"</string>
<string name="screen_join_room_join_action">"پیوستن"</string>
<string name="screen_join_room_join_restricted_message">"برای پیوستن به فضا باید دعوت شده باشید."</string>
<string name="screen_join_room_knock_action">"در زدن برای پیوستن"</string>
<string name="screen_join_room_knock_message_description">"پیام (اختیاری)"</string>
<string name="screen_join_room_knock_sent_title">"درخواست پیوستن فرستاده شد"</string>
<string name="screen_join_room_space_not_supported_description">"%1$s هنوز از فضاها پشتیبانی نمی‌کند. می‌توانید روی وب به فضاها دسترسی داشته باشید."</string>
<string name="screen_join_room_space_not_supported_title">"فضاها هنوز پشتیبانی نمی‌شوند"</string>
<string name="screen_join_room_subtitle_knock">"زدن روی این دکمه برای آگاه شدن مدیر اتاق. پس از تأیید می‌توانید به گفت‌وگو بپیوندید."</string>
<string name="screen_join_room_subtitle_no_preview">"برای دیدن تاریخچهٔ پیام باید عضو این اتاق باشید."</string>
<string name="screen_join_room_title_knock">"می‌خواهید به اتاق بپیوندید؟"</string>
<string name="screen_join_room_title_no_preview">"پیش‌نمایش موجود نیست"</string>
</resources>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_by_message">"%1$s antoi sinulle porttikiellon."</string>
<string name="screen_join_room_ban_message">"Sinulle on annettu porttikielto"</string>
<string name="screen_join_room_ban_reason">"Syy: %1$s."</string>
<string name="screen_join_room_cancel_knock_action">"Peruuta pyyntö"</string>
<string name="screen_join_room_cancel_knock_alert_confirmation">"Kyllä, peruuta"</string>
<string name="screen_join_room_cancel_knock_alert_description">"Haluatko varmasti peruuttaa pyyntösi liittyä tähän huoneeseen?"</string>
<string name="screen_join_room_cancel_knock_alert_title">"Peruuta liittymispyyntö"</string>
<string name="screen_join_room_decline_and_block_alert_confirmation">"Kyllä, hylkää ja estä"</string>
<string name="screen_join_room_decline_and_block_alert_message">"Oletko varma, että haluat kieltäytyä kutsusta liittyä tähän huoneeseen? Tämä estää myös käyttäjää %1$s ottamasta sinuun yhteyttä tai kutsumasta sinua huoneisiin."</string>
<string name="screen_join_room_decline_and_block_alert_title">"Hylkää kutsu ja estä"</string>
<string name="screen_join_room_decline_and_block_button_title">"Hylkää ja estä"</string>
<string name="screen_join_room_fail_message">"Liittyminen epäonnistui"</string>
<string name="screen_join_room_fail_reason">"Sinun on joko saatava kutsu liittyäksesi tai pääsyyn voi olla rajoituksia."</string>
<string name="screen_join_room_forget_action">"Unohda"</string>
<string name="screen_join_room_invite_required_message">"Tarvitset kutsun liittyäksesi"</string>
<string name="screen_join_room_invited_by">"Kutsuja"</string>
<string name="screen_join_room_join_action">"Liity"</string>
<string name="screen_join_room_join_restricted_message">"Saatat tarvita kutsun tai olla tilan jäsen, jotta voit liittyä."</string>
<string name="screen_join_room_knock_action">"Lähetä liittymispyyntö"</string>
<string name="screen_join_room_knock_message_characters_count">"%1$d merkkiä käytetty, %2$d merkkiä sallittu"</string>
<string name="screen_join_room_knock_message_description">"Viesti (valinnainen)"</string>
<string name="screen_join_room_knock_sent_description">"Saat kutsun liittyä huoneeseen, jos pyyntösi hyväksytään."</string>
<string name="screen_join_room_knock_sent_title">"Liittymispyyntö lähetetty"</string>
<string name="screen_join_room_loading_alert_message">"Emme voineet näyttää huoneen esikatselua. Tämä voi johtua verkko- tai palvelinongelmista."</string>
<string name="screen_join_room_loading_alert_title">"Emme voineet näyttää tämän huoneen esikatselua"</string>
<string name="screen_join_room_space_not_supported_description">"%1$s ei tue vielä tiloja. Voit käyttää tiloja selainversiolla."</string>
<string name="screen_join_room_space_not_supported_title">"Tiloja ei vielä tueta"</string>
<string name="screen_join_room_subtitle_knock">"Paina alla olevaa nappia ja huoneen ylläpitäjä saa ilmoituksen. Voit liittyä keskusteluun kun pyyntösi on hyväksytty."</string>
<string name="screen_join_room_subtitle_no_preview">"Sinun on oltava tämän huoneen jäsen, jotta voit nähdä viestihistorian."</string>
<string name="screen_join_room_title_knock">"Haluatko liittyä tähän huoneeseen?"</string>
<string name="screen_join_room_title_no_preview">"Esikatselu ei ole saatavilla"</string>
</resources>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_by_message">"Vous avez été banni(e) par %1$s."</string>
<string name="screen_join_room_ban_message">"Vous avez été banni(e)"</string>
<string name="screen_join_room_ban_reason">"Motif: %1$s."</string>
<string name="screen_join_room_cancel_knock_action">"Annuler la demande"</string>
<string name="screen_join_room_cancel_knock_alert_confirmation">"Oui, annuler"</string>
<string name="screen_join_room_cancel_knock_alert_description">"Êtes-vous sûr de vouloir annuler votre demande daccès à ce salon ?"</string>
<string name="screen_join_room_cancel_knock_alert_title">"Annuler la demande dadhésion"</string>
<string name="screen_join_room_decline_and_block_alert_confirmation">"Oui, refuser et bloquer"</string>
<string name="screen_join_room_decline_and_block_alert_message">"Êtes-vous sûr de vouloir refuser linvitation à rejoindre ce salon ? Cela empêchera également %1$s de vous contacter ou de vous inviter dans les salons."</string>
<string name="screen_join_room_decline_and_block_alert_title">"Refuser linvitation et bloquer"</string>
<string name="screen_join_room_decline_and_block_button_title">"Refuser et bloquer"</string>
<string name="screen_join_room_fail_message">"Lopération a échoué."</string>
<string name="screen_join_room_fail_reason">"Soit vous devez être invité(e) pour rejoindre, soit il peut y avoir des restrictions daccès."</string>
<string name="screen_join_room_forget_action">"Oublier"</string>
<string name="screen_join_room_invite_required_message">"Vous avez besoin dune invitation pour pouvoir rejoindre"</string>
<string name="screen_join_room_invited_by">"Invité(e) par"</string>
<string name="screen_join_room_join_action">"Rejoindre"</string>
<string name="screen_join_room_join_restricted_message">"Il est possible que vous deviez être invité ou être membre dun Espace pour pouvoir rejoindre le salon."</string>
<string name="screen_join_room_knock_action">"Demander à joindre"</string>
<string name="screen_join_room_knock_message_characters_count">"Caractères autorisés %1$d sur %2$d"</string>
<string name="screen_join_room_knock_message_description">"Message (facultatif)"</string>
<string name="screen_join_room_knock_sent_description">"Vous recevrez une invitation à rejoindre le salon si votre demande est acceptée."</string>
<string name="screen_join_room_knock_sent_title">"Demande de rejoindre le salon envoyée"</string>
<string name="screen_join_room_loading_alert_message">"Impossible dafficher laperçu du salon. Cela peut être dû à des problèmes de réseau ou de serveur."</string>
<string name="screen_join_room_loading_alert_title">"Impossible dafficher laperçu de ce salon"</string>
<string name="screen_join_room_space_not_supported_description">"Les Espaces ne sont pas encore pris en charge par %1$s. Vous pouvez voir les Espaces sur le Web."</string>
<string name="screen_join_room_space_not_supported_title">"Les Espaces ne sont pas encore pris en charge"</string>
<string name="screen_join_room_subtitle_knock">"Cliquez ci-dessous et un administrateur sera prévenu. Une fois votre demande approuvée, pour pourrez rejoindre la discussion."</string>
<string name="screen_join_room_subtitle_no_preview">"Vous devez être un membre du salon pour pouvoir lire lhistorique des messages."</string>
<string name="screen_join_room_title_knock">"Vous souhaitez rejoindre ce salon ?"</string>
<string name="screen_join_room_title_no_preview">"La prévisualisation nest pas disponible"</string>
</resources>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_by_message">"%1$s kitiltotta a szobából."</string>
<string name="screen_join_room_ban_message">"Kitiltották"</string>
<string name="screen_join_room_ban_reason">"Ok: %1$s."</string>
<string name="screen_join_room_cancel_knock_action">"Kérés visszavonása"</string>
<string name="screen_join_room_cancel_knock_alert_confirmation">"Igen, visszavonás"</string>
<string name="screen_join_room_cancel_knock_alert_description">"Biztos, hogy visszavonja a szobához való csatlakozási kérését?"</string>
<string name="screen_join_room_cancel_knock_alert_title">"Csatlakozási kérés visszavonása"</string>
<string name="screen_join_room_decline_and_block_alert_confirmation">"Igen, elutasítás és blokkolás"</string>
<string name="screen_join_room_decline_and_block_alert_message">"Biztos, hogy elutasítja a meghívást, hogy csatlakozzon ehhez a szobához? Ez azt is megakadályozza, hogy %1$s kapcsolatba lépjen Önnel, vagy szobákba hívja."</string>
<string name="screen_join_room_decline_and_block_alert_title">"Meghívó elutasítása és blokkolás"</string>
<string name="screen_join_room_decline_and_block_button_title">"Elutasítás és letiltás"</string>
<string name="screen_join_room_fail_message">"A csatlakozás sikertelen"</string>
<string name="screen_join_room_fail_reason">"Csatlakozáshoz meghívóra van szükség, vagy lehet, hogy korlátozva van a hozzáférés."</string>
<string name="screen_join_room_forget_action">"Elfelejt"</string>
<string name="screen_join_room_invite_required_message">"A csatlakozáshoz meghívóra van szükség."</string>
<string name="screen_join_room_invited_by">"Meghívta:"</string>
<string name="screen_join_room_join_action">"Csatlakozás"</string>
<string name="screen_join_room_join_restricted_message">"A csatlakozáshoz meghívásra vagy tértagságra lehet szüksége."</string>
<string name="screen_join_room_knock_action">"Kopogtasson a csatlakozáshoz"</string>
<string name="screen_join_room_knock_message_characters_count">"Engedélyezett karakterek: %1$d / %2$d"</string>
<string name="screen_join_room_knock_message_description">"Üzenet (nem kötelező)"</string>
<string name="screen_join_room_knock_sent_description">"Ha a kérését elfogadják, meghívót kap a szobához való csatlakozáshoz."</string>
<string name="screen_join_room_knock_sent_title">"Csatlakozási kérés elküldve"</string>
<string name="screen_join_room_loading_alert_message">"Nem tudtuk megjeleníteni a szoba előnézetét. Ennek az oka hálózati vagy kiszolgálóprobléma is lehet."</string>
<string name="screen_join_room_loading_alert_title">"Nem tudtuk megjeleníteni a szoba előnézetét"</string>
<string name="screen_join_room_space_not_supported_description">"Az %1$s még nem támogatja a tereket. A tereket a weben érheti el."</string>
<string name="screen_join_room_space_not_supported_title">"A terek még nem támogatottak"</string>
<string name="screen_join_room_subtitle_knock">"Kattintson az alábbi gombra, és a szoba adminisztrátora értesítést kap. A jóváhagyást követően csatlakozhat a beszélgetéshez."</string>
<string name="screen_join_room_subtitle_no_preview">"Az üzenetelőzmények megtekintéséhez a szoba tagjának kell lennie."</string>
<string name="screen_join_room_title_knock">"Csatlakozna ehhez a szobához?"</string>
<string name="screen_join_room_title_no_preview">"Az előnézet nem érhető el"</string>
</resources>

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_by_message">"Anda dicekal dari ruangan ini oleh %1$s."</string>
<string name="screen_join_room_ban_message">"Anda dicekal dari ruangan ini"</string>
<string name="screen_join_room_ban_reason">"Alasan: %1$s."</string>
<string name="screen_join_room_cancel_knock_action">"Batalkan permintaan"</string>
<string name="screen_join_room_cancel_knock_alert_confirmation">"Ya, batalkan"</string>
<string name="screen_join_room_cancel_knock_alert_description">"Apakah Anda yakin ingin membatalkan permintaan Anda untuk bergabung dengan ruangan ini?"</string>
<string name="screen_join_room_cancel_knock_alert_title">"Batalkan permintaan untuk bergabung"</string>
<string name="screen_join_room_decline_and_block_alert_confirmation">"Ya, tolak &amp; blokir"</string>
<string name="screen_join_room_decline_and_block_alert_message">"Apakah Anda yakin ingin menolak undangan untuk bergabung dengan ruangan ini? Ini juga akan mencegah %1$s menghubungi Anda atau mengundang Anda ke ruangan."</string>
<string name="screen_join_room_decline_and_block_alert_title">"Tolak undangan &amp; blokir"</string>
<string name="screen_join_room_decline_and_block_button_title">"Tolak dan blokir"</string>
<string name="screen_join_room_fail_message">"Bergabung dalam ruangan gagal."</string>
<string name="screen_join_room_fail_reason">"Ruangan ini hanya untuk undangan atau mungkin ada pembatasan akses pada tingkat space."</string>
<string name="screen_join_room_forget_action">"Lupakan ruangan ini"</string>
<string name="screen_join_room_invite_required_message">"Anda memerlukan undangan untuk bergabung dalam ruangan ini"</string>
<string name="screen_join_room_join_action">"Gabung"</string>
<string name="screen_join_room_join_restricted_message">"Anda mungkin perlu diundang atau menjadi anggota space untuk bergabung."</string>
<string name="screen_join_room_knock_action">"Ketuk untuk bergabung"</string>
<string name="screen_join_room_knock_message_description">"Pesan (opsional)"</string>
<string name="screen_join_room_knock_sent_description">"Anda akan menerima undangan untuk bergabung dengan ruangan jika permintaan Anda diterima."</string>
<string name="screen_join_room_knock_sent_title">"Permintaan untuk bergabung dikirim"</string>
<string name="screen_join_room_loading_alert_message">"Kami tidak dapat menampilkan pratinjau ruangan. Ini mungkin karena masalah jaringan atau server."</string>
<string name="screen_join_room_loading_alert_title">"Kami tidak dapat menampilkan pratinjau ruangan ini"</string>
<string name="screen_join_room_space_not_supported_description">"%1$s belum mendukung space. Anda dapat mengakses space di web."</string>
<string name="screen_join_room_space_not_supported_title">"Space belum didukung"</string>
<string name="screen_join_room_subtitle_knock">"Klik tombol di bawah ini dan administrator kamar akan diberi tahu. Anda akan dapat bergabung dengan percakapan setelah disetujui."</string>
<string name="screen_join_room_subtitle_no_preview">"Anda harus menjadi anggota ruangan ini untuk melihat riwayat pesan."</string>
<string name="screen_join_room_title_knock">"Ingin bergabung dengan ruangan ini?"</string>
<string name="screen_join_room_title_no_preview">"Pratinjau tidak tersedia"</string>
</resources>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_by_message">"Sei stato bannato da %1$s ."</string>
<string name="screen_join_room_ban_message">"Sei stato bannato"</string>
<string name="screen_join_room_ban_reason">"Motivo: %1$s"</string>
<string name="screen_join_room_cancel_knock_action">"Cancella richiesta"</string>
<string name="screen_join_room_cancel_knock_alert_confirmation">"Sì, annulla"</string>
<string name="screen_join_room_cancel_knock_alert_description">"Sei sicuro di voler annullare la tua richiesta di accesso a questa stanza?"</string>
<string name="screen_join_room_cancel_knock_alert_title">"Annulla la richiesta di accesso"</string>
<string name="screen_join_room_decline_and_block_alert_confirmation">"Sì, rifiuta e blocca"</string>
<string name="screen_join_room_decline_and_block_alert_message">"Sei sicuro di voler rifiutare l\'invito a entrare in questa stanza? Ciò impedirà a %1$s di contattarti o invitarti nuovamente in una stanza."</string>
<string name="screen_join_room_decline_and_block_alert_title">"Rifiuta invito e blocca"</string>
<string name="screen_join_room_decline_and_block_button_title">"Rifiuta e blocca"</string>
<string name="screen_join_room_fail_message">"Partecipazione non riuscita"</string>
<string name="screen_join_room_fail_reason">"Devi essere invitato per partecipare o potrebbero esserci delle restrizioni di accesso."</string>
<string name="screen_join_room_forget_action">"Dimentica"</string>
<string name="screen_join_room_invite_required_message">"Per partecipare è necessario un invito"</string>
<string name="screen_join_room_invited_by">"Invitato da"</string>
<string name="screen_join_room_join_action">"Entra"</string>
<string name="screen_join_room_join_restricted_message">"Potrebbe essere necessario essere invitati o essere membro di uno spazio per partecipare."</string>
<string name="screen_join_room_knock_action">"Bussa per partecipare"</string>
<string name="screen_join_room_knock_message_characters_count">"Caratteri consentiti: %1$d di %2$d"</string>
<string name="screen_join_room_knock_message_description">"Messaggio (opzionale)"</string>
<string name="screen_join_room_knock_sent_description">"Riceverai un invito a entrare nella stanza se la tua richiesta viene accettata."</string>
<string name="screen_join_room_knock_sent_title">"Richiesta di accesso inviata"</string>
<string name="screen_join_room_loading_alert_message">"Non è stato possibile visualizzare l\'anteprima della stanza. Ciò può essere dovuto a problemi di rete o del server."</string>
<string name="screen_join_room_loading_alert_title">"Non è stato possibile visualizzare l\'anteprima di questa stanza"</string>
<string name="screen_join_room_space_not_supported_description">"%1$s non supporta ancora gli spazi. Puoi accedere agli spazi sul web."</string>
<string name="screen_join_room_space_not_supported_title">"Gli spazi non sono ancora supportati"</string>
<string name="screen_join_room_subtitle_knock">"Clicca sul pulsante qui sotto e un amministratore della stanza riceverà una notifica. Potrai partecipare alla conversazione una volta approvato."</string>
<string name="screen_join_room_subtitle_no_preview">"Per visualizzare la cronologia dei messaggi devi essere un membro di questa stanza."</string>
<string name="screen_join_room_title_knock">"Vuoi entrare in questa stanza?"</string>
<string name="screen_join_room_title_no_preview">"L\'anteprima non è disponibile"</string>
</resources>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_join_action">"გაწევრიანება"</string>
</resources>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_by_message">"%1$s 에 의해 이 방에서 퇴장당했습니다."</string>
<string name="screen_join_room_ban_message">"당신은 이 방에서 차단되었습니다"</string>
<string name="screen_join_room_ban_reason">"이유: %1$s."</string>
<string name="screen_join_room_cancel_knock_action">"요청 취소"</string>
<string name="screen_join_room_cancel_knock_alert_confirmation">"네, 취소합니다"</string>
<string name="screen_join_room_cancel_knock_alert_description">"이 방에 대한 가입 요청을 정말로 취소하시겠습니까?"</string>
<string name="screen_join_room_cancel_knock_alert_title">"가입 요청 취소"</string>
<string name="screen_join_room_decline_and_block_alert_confirmation">"예, 거부 및 차단"</string>
<string name="screen_join_room_decline_and_block_alert_message">"이 방에 대한 초대 거부를 정말로 확인하시겠습니까? 이 경우 %1$s 에서 귀하에게 연락하거나 방에 초대할 수 없게 됩니다."</string>
<string name="screen_join_room_decline_and_block_alert_title">"초대 거부 및 차단"</string>
<string name="screen_join_room_decline_and_block_button_title">"거부 및 차단"</string>
<string name="screen_join_room_fail_message">"방에 참여하는데 실패했습니다."</string>
<string name="screen_join_room_fail_reason">"이 방은 초대 전용이거나 스페이스 수준에서 액세스 제한이 있을 수 있습니다."</string>
<string name="screen_join_room_forget_action">"이 방 지우기"</string>
<string name="screen_join_room_invite_required_message">"이 방에 참여하려면 초대장이 필요합니다."</string>
<string name="screen_join_room_join_action">"참가하기"</string>
<string name="screen_join_room_join_restricted_message">"참여하려면 초대 또는 스페이스의 회원이어야 할 수 있습니다."</string>
<string name="screen_join_room_knock_action">"가입 요청 보내기"</string>
<string name="screen_join_room_knock_message_characters_count">"%2$d의 %1$d 문자가 허용됨"</string>
<string name="screen_join_room_knock_message_description">"메시지 (선택 사항)"</string>
<string name="screen_join_room_knock_sent_description">"요청이 승인되면 방에 참여하기 위한 초대장이 발송됩니다."</string>
<string name="screen_join_room_knock_sent_title">"가입 요청이 전송되었습니다"</string>
<string name="screen_join_room_loading_alert_message">"방 미리보기를 표시할 수 없습니다. 네트워크 또는 서버 문제 때문일 수 있습니다."</string>
<string name="screen_join_room_loading_alert_title">"이 방 미리보기를 표시할 수 없습니다."</string>
<string name="screen_join_room_space_not_supported_description">"%1$s 아직 스페이스를 지원하지 않습니다. 웹에서 스페이스에 접속할 수 있습니다."</string>
<string name="screen_join_room_space_not_supported_title">"아직 스페이스가 지원되지 않습니다."</string>
<string name="screen_join_room_subtitle_knock">"아래 버튼을 클릭하면 방 관리자에게 알림이 전송됩니다. 승인이 완료되면 대화에 참여할 수 있습니다."</string>
<string name="screen_join_room_subtitle_no_preview">"이 방의 회원이어야만 메시지 기록을 볼 수 있습니다."</string>
<string name="screen_join_room_title_knock">"이 방에 참여하고 싶으신가요?"</string>
<string name="screen_join_room_title_no_preview">"미리보기 기능은 제공되지 않습니다."</string>
</resources>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_by_message">"Du ble utestengt av %1$s."</string>
<string name="screen_join_room_ban_message">"Du ble utestengt"</string>
<string name="screen_join_room_ban_reason">"Årsak: %1$s."</string>
<string name="screen_join_room_cancel_knock_action">"Avbryt forespørsel"</string>
<string name="screen_join_room_cancel_knock_alert_confirmation">"Ja, avbryt"</string>
<string name="screen_join_room_cancel_knock_alert_description">"Er du sikker på at du vil kansellere forespørselen din om å bli med i dette rommet?"</string>
<string name="screen_join_room_cancel_knock_alert_title">"Avbryt forespørsel om å bli med"</string>
<string name="screen_join_room_decline_and_block_alert_confirmation">"Ja, avslå og blokker"</string>
<string name="screen_join_room_decline_and_block_alert_message">"Er du sikker på at du vil avslå invitasjonen til å bli med i dette rommet? Dette vil også forhindre %1$s fra å kontakte deg eller invitere deg til rom."</string>
<string name="screen_join_room_decline_and_block_alert_title">"Avslå invitasjon og blokker"</string>
<string name="screen_join_room_decline_and_block_button_title">"Avslå og blokker"</string>
<string name="screen_join_room_fail_message">"Kunne ikke bli med"</string>
<string name="screen_join_room_fail_reason">"Du må enten bli invitert til å bli med, eller så kan det være begrensninger på tilgangen."</string>
<string name="screen_join_room_forget_action">"Glem"</string>
<string name="screen_join_room_invite_required_message">"Du trenger en invitasjon for å bli med"</string>
<string name="screen_join_room_invited_by">"Invitert av"</string>
<string name="screen_join_room_join_action">"Bli med"</string>
<string name="screen_join_room_join_restricted_message">"Du må kanskje bli invitert eller være medlem av et område for å bli med."</string>
<string name="screen_join_room_knock_action">"Send forespørsel om å bli med"</string>
<string name="screen_join_room_knock_message_characters_count">"Tillatte tegn %1$d av %2$d"</string>
<string name="screen_join_room_knock_message_description">"Melding (valgfritt)"</string>
<string name="screen_join_room_knock_sent_description">"Du vil motta en invitasjon til å bli med i rommet hvis forespørselen din blir akseptert."</string>
<string name="screen_join_room_knock_sent_title">"Forespørsel om å bli med sendt"</string>
<string name="screen_join_room_loading_alert_message">"Vi kunne ikke vise forhåndsvisningen av rommet. Dette kan skyldes nettverks- eller serverproblemer."</string>
<string name="screen_join_room_loading_alert_title">"Vi kunne ikke vise forhåndsvisning av dette rommet"</string>
<string name="screen_join_room_space_not_supported_description">"%1$s støtter ikke områder ennå. Du kan få tilgang til områder på nett."</string>
<string name="screen_join_room_space_not_supported_title">"Områder støttes ikke ennå"</string>
<string name="screen_join_room_subtitle_knock">"Klikk på knappen nedenfor, så vil en romadministrator bli varslet. Du vil kunne delta i samtalen når den er godkjent."</string>
<string name="screen_join_room_subtitle_no_preview">"Du må være medlem av dette rommet for å se meldingshistorikken."</string>
<string name="screen_join_room_title_knock">"Vil du bli med i dette rommet?"</string>
<string name="screen_join_room_title_no_preview">"Forhåndsvisning er ikke tilgjengelig"</string>
</resources>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_reason">"Reden: %1$s."</string>
<string name="screen_join_room_cancel_knock_action">"Verzoek annuleren"</string>
<string name="screen_join_room_decline_and_block_button_title">"Weigeren en blokkeren"</string>
<string name="screen_join_room_forget_action">"Deze kamer vergeten"</string>
<string name="screen_join_room_join_action">"Deelnemen"</string>
<string name="screen_join_room_knock_action">"Klop om deel te nemen"</string>
<string name="screen_join_room_knock_message_description">"Bericht (optioneel)"</string>
<string name="screen_join_room_knock_sent_description">"Je ontvangt een uitnodiging om deel te nemen aan de kamer als je aanvraag wordt geaccepteerd."</string>
<string name="screen_join_room_knock_sent_title">"Verzoek om toe te treden verzonden"</string>
<string name="screen_join_room_space_not_supported_description">"%1$s ondersteunt nog geen spaces. Je kunt spaces benaderen via de webbrowser."</string>
<string name="screen_join_room_space_not_supported_title">"Spaces worden nog niet ondersteund"</string>
<string name="screen_join_room_subtitle_knock">"Klik op de knop hieronder en een kamerbeheerder wordt op de hoogte gebracht. Na goedkeuring kun je deelnemen aan het gesprek."</string>
<string name="screen_join_room_subtitle_no_preview">"Je moet lid zijn van deze kamer om de berichtgeschiedenis te bekijken."</string>
<string name="screen_join_room_title_knock">"Wil je tot deze kamer toetreden?"</string>
<string name="screen_join_room_title_no_preview">"Voorbeeld is niet beschikbaar"</string>
</resources>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_by_message">"Zostałeś zbanowany przez %1$s ."</string>
<string name="screen_join_room_ban_message">"Zostałeś zbanowany"</string>
<string name="screen_join_room_ban_reason">"Powód: %1$s."</string>
<string name="screen_join_room_cancel_knock_action">"Anuluj prośbę"</string>
<string name="screen_join_room_cancel_knock_alert_confirmation">"Tak, anuluj"</string>
<string name="screen_join_room_cancel_knock_alert_description">"Czy na pewno chcesz anulować prośbę o dołączenie do tego pokoju?"</string>
<string name="screen_join_room_cancel_knock_alert_title">"Anuluj prośbę o dołączenie"</string>
<string name="screen_join_room_decline_and_block_alert_confirmation">"Tak, odrzuć i zablokuj"</string>
<string name="screen_join_room_decline_and_block_alert_message">"Czy na pewno chcesz odrzucić zaproszenie dołączenia do tego pokoju? %1$s nie będzie mógł się również z Tobą skontaktować, ani zaprosić Cię do pokoju."</string>
<string name="screen_join_room_decline_and_block_alert_title">"Odrzuć zaproszenie i zablokuj"</string>
<string name="screen_join_room_decline_and_block_button_title">"Odrzuć i zablokuj"</string>
<string name="screen_join_room_fail_message">"Nie udało się dołączyć do pokoju"</string>
<string name="screen_join_room_fail_reason">"Ten pokój wymaga zaproszenia lub dołączanie zostało ograniczone."</string>
<string name="screen_join_room_forget_action">"Zapomnij"</string>
<string name="screen_join_room_invite_required_message">"Aby dołączyć, potrzebujesz zaproszenia"</string>
<string name="screen_join_room_invited_by">"Zaproszony przez"</string>
<string name="screen_join_room_join_action">"Dołącz"</string>
<string name="screen_join_room_join_restricted_message">"Aby dołączyć, musisz uzyskać zaproszenie lub być członkiem danej przestrzeni."</string>
<string name="screen_join_room_knock_action">"Wyślij prośbę o dołączenie"</string>
<string name="screen_join_room_knock_message_characters_count">"Dozwolone znaki %1$d z %2$d"</string>
<string name="screen_join_room_knock_message_description">"Wiadomość (opcjonalne)"</string>
<string name="screen_join_room_knock_sent_description">"Otrzymasz zaproszenie dołączenia do pokoju, jeśli prośba zostanie zaakceptowana."</string>
<string name="screen_join_room_knock_sent_title">"Wysłano prośbę o dołączenie"</string>
<string name="screen_join_room_loading_alert_message">"Nie udało się wyświetlić podglądu pokoju. Może to być spowodowane problemami z siecią lub serwerem."</string>
<string name="screen_join_room_loading_alert_title">"Nie udało nam się wyświetlić podglądu tego pokoju"</string>
<string name="screen_join_room_space_not_supported_description">"%1$s jeszcze nie obsługuje przestrzeni. Uzyskaj dostęp do przestrzeni w wersji web."</string>
<string name="screen_join_room_space_not_supported_title">"Przestrzenie nie są jeszcze obsługiwane"</string>
<string name="screen_join_room_subtitle_knock">"Kliknij przycisk poniżej, aby powiadomić administratora pokoju. Po zatwierdzeniu będziesz mógł dołączyć do rozmowy."</string>
<string name="screen_join_room_subtitle_no_preview">"Musisz być członkiem tego pokoju, aby wyświetlić historię wiadomości."</string>
<string name="screen_join_room_title_knock">"Chcesz dołączyć do tego pokoju?"</string>
<string name="screen_join_room_title_no_preview">"Podgląd nie jest dostępny"</string>
</resources>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_by_message">"Você foi banido por %1$s."</string>
<string name="screen_join_room_ban_message">"Você foi banido"</string>
<string name="screen_join_room_ban_reason">"Motivo: %1$s."</string>
<string name="screen_join_room_cancel_knock_action">"Cancelar pedido"</string>
<string name="screen_join_room_cancel_knock_alert_confirmation">"Sim, cancelar"</string>
<string name="screen_join_room_cancel_knock_alert_description">"Tem a certeza de que pretende cancelar o seu pedido de adesão a esta sala?"</string>
<string name="screen_join_room_cancel_knock_alert_title">"Cancelar pedido de entrada"</string>
<string name="screen_join_room_decline_and_block_alert_confirmation">"Sim, recusar e bloquear"</string>
<string name="screen_join_room_decline_and_block_alert_message">"Tem certeza de que quer recusar o convite para entrar nesta sala? Isso também impedirá que %1$s entre em contato com você ou o convide para salas."</string>
<string name="screen_join_room_decline_and_block_alert_title">"Recusar convite e bloquear"</string>
<string name="screen_join_room_decline_and_block_button_title">"Recusar e bloquear"</string>
<string name="screen_join_room_fail_message">"Falha ao entrar"</string>
<string name="screen_join_room_fail_reason">"Você precisa ser convidado ou pode haver restrições ao acesso."</string>
<string name="screen_join_room_forget_action">"Esquecer"</string>
<string name="screen_join_room_invite_required_message">"Você precisa de um convite para entrar"</string>
<string name="screen_join_room_invited_by">"Convidado por"</string>
<string name="screen_join_room_join_action">"Entrar"</string>
<string name="screen_join_room_join_restricted_message">"Talvez você precise ser convidado ou ser membro de um espaço para participar."</string>
<string name="screen_join_room_knock_action">"Enviar solicitação para entrar"</string>
<string name="screen_join_room_knock_message_characters_count">"%1$d de %2$d caráteres permitidos"</string>
<string name="screen_join_room_knock_message_description">"Mensagem (opcional)"</string>
<string name="screen_join_room_knock_sent_description">"Você receberá um convite para entrar nesta sala se seu pedido for aceito."</string>
<string name="screen_join_room_knock_sent_title">"Pedido de entrada enviado"</string>
<string name="screen_join_room_loading_alert_message">"Não foi possível exibir a pré-visualização da sala. Isso pode ser devido a problemas de rede ou do servidor."</string>
<string name="screen_join_room_loading_alert_title">"Não foi possível exibir a pré-visualização desta sala"</string>
<string name="screen_join_room_space_not_supported_description">"%1$s não suporta espaços ainda. Você pode acessar os espaços na web."</string>
<string name="screen_join_room_space_not_supported_title">"Ainda não há suporte aos espaços"</string>
<string name="screen_join_room_subtitle_knock">"Clique no botão abaixo e um administrador da sala será notificado. Você poderá participar da conversa assim que for aprovado."</string>
<string name="screen_join_room_subtitle_no_preview">"Você deve ser um membro desta sala para visualizar o histórico de mensagens."</string>
<string name="screen_join_room_title_knock">"Quer entrar nesta sala?"</string>
<string name="screen_join_room_title_no_preview">"A pré-visualização não está disponível"</string>
</resources>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_by_message">"Foste banido(a) por %1$s."</string>
<string name="screen_join_room_ban_message">"Foste banido(a)"</string>
<string name="screen_join_room_ban_reason">"Razão: %1$s."</string>
<string name="screen_join_room_cancel_knock_action">"Cancelar pedido"</string>
<string name="screen_join_room_cancel_knock_alert_confirmation">"Sim, cancelar"</string>
<string name="screen_join_room_cancel_knock_alert_description">"Tens a certeza de que queres cancelar o teu pedido de entrada nesta sala?"</string>
<string name="screen_join_room_cancel_knock_alert_title">"Cancela o pedido de adesão"</string>
<string name="screen_join_room_decline_and_block_alert_confirmation">"Sim, recusar &amp; bloquear"</string>
<string name="screen_join_room_decline_and_block_alert_message">"Tens a certeza de que queres recusar o convite para entrar nesta sala? Isto também evitará que %1$s te contacte ou te convide para salas."</string>
<string name="screen_join_room_decline_and_block_alert_title">"Recusar convite &amp; bloquear"</string>
<string name="screen_join_room_decline_and_block_button_title">"Recusar e bloquear"</string>
<string name="screen_join_room_fail_message">"Falha ao entrar"</string>
<string name="screen_join_room_fail_reason">"A entrada pode estar limitada a convites ou pode haver uma outra limitação de acesso."</string>
<string name="screen_join_room_forget_action">"Esquecer"</string>
<string name="screen_join_room_invite_required_message">"Precisas de um convite para entrares"</string>
<string name="screen_join_room_invited_by">"Convidado por"</string>
<string name="screen_join_room_join_action">"Entrar"</string>
<string name="screen_join_room_join_restricted_message">"Podes ter que ser convidado ou pertenceres a um espaço para poderes entrar."</string>
<string name="screen_join_room_knock_action">"Bater à porta"</string>
<string name="screen_join_room_knock_message_characters_count">"%1$d de %2$d caracteres permitidos"</string>
<string name="screen_join_room_knock_message_description">"Mensagem (opcional)"</string>
<string name="screen_join_room_knock_sent_description">"Irás receber um convite para participar na sala se o pedido for aceite."</string>
<string name="screen_join_room_knock_sent_title">"Pedido de adesão enviado"</string>
<string name="screen_join_room_loading_alert_message">"Não conseguimos exibir a pré-visualização da sala. Isso pode ser devido a problemas de rede ou servidor."</string>
<string name="screen_join_room_loading_alert_title">"Não foi possível exibir a pré-visualização desta sala"</string>
<string name="screen_join_room_space_not_supported_description">"A %1$s ainda não funciona com espaços. Podes usá-los na aplicação web."</string>
<string name="screen_join_room_space_not_supported_title">"Os espaços ainda não estão implementados"</string>
<string name="screen_join_room_subtitle_knock">"Carrega no botão abaixo para notificar um administrador da sala. Poderás entrar quando te aprovarem."</string>
<string name="screen_join_room_subtitle_no_preview">"Apenas os participantes podem ver o histórico de mensagens."</string>
<string name="screen_join_room_title_knock">"Queres entrar nesta sala?"</string>
<string name="screen_join_room_title_no_preview">"Pré-visualização indisponível"</string>
</resources>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_by_message">"Ați fost exclus din această cameră de către %1$s."</string>
<string name="screen_join_room_ban_message">"Ați fost exclus din această cameră."</string>
<string name="screen_join_room_ban_reason">"Motiv: %1$s."</string>
<string name="screen_join_room_cancel_knock_action">"Anulați cererea"</string>
<string name="screen_join_room_cancel_knock_alert_confirmation">"Da, anulați"</string>
<string name="screen_join_room_cancel_knock_alert_description">"Sunteți sigur că doriți să anulați cererea de a vă alătura acestei camere?"</string>
<string name="screen_join_room_cancel_knock_alert_title">"Anulați cererea de alăturare"</string>
<string name="screen_join_room_decline_and_block_alert_confirmation">"Da, refuzați și blocați"</string>
<string name="screen_join_room_decline_and_block_alert_message">"Sunteți sigur că doriți să refuzați invitația de a vă alătura acestei camere? Acest lucru va împiedica, de asemenea, %1$s să vă contacteze sau să vă invite în camere."</string>
<string name="screen_join_room_decline_and_block_alert_title">"Refuzați invitația și blocați"</string>
<string name="screen_join_room_decline_and_block_button_title">"Refuzați și blocați"</string>
<string name="screen_join_room_fail_message">"Alăturarea la cameră a eșuat."</string>
<string name="screen_join_room_fail_reason">"Această cameră este fie accesibilă numai pe bază de invitație, fie exista restricții de acces la nivel de spațiu."</string>
<string name="screen_join_room_forget_action">"Uitați această cameră"</string>
<string name="screen_join_room_invite_required_message">"Aveți nevoie de o invitație pentru a vă alătura acestei camere."</string>
<string name="screen_join_room_invited_by">"Invitat de"</string>
<string name="screen_join_room_join_action">"Alăturați-vă"</string>
<string name="screen_join_room_join_restricted_message">"Este posibil să fie necesar să fiți invitat sau să fiți membru al unui spațiu pentru a vă alătura."</string>
<string name="screen_join_room_knock_action">"Trimiteți o cerere de alăturare"</string>
<string name="screen_join_room_knock_message_characters_count">"Caractere permise %1$d din %2$d"</string>
<string name="screen_join_room_knock_message_description">"Mesaj (opțional)"</string>
<string name="screen_join_room_knock_sent_description">"Veți primi o invitație de a vă alătura camerei dacă cererea dumneavoastră este acceptată."</string>
<string name="screen_join_room_knock_sent_title">"Cererea de alăturare a fost trimisă"</string>
<string name="screen_join_room_loading_alert_message">"Nu am putut afișa previzualizarea camerei. Este posibil ca acest lucru să se datoreze unor probleme de rețea sau de server."</string>
<string name="screen_join_room_loading_alert_title">"Nu am putut afișa previzualizarea acestei camere."</string>
<string name="screen_join_room_space_not_supported_description">"%1$s nu suporta încă spații. Puteți accesa spațiile pe web."</string>
<string name="screen_join_room_space_not_supported_title">"Spațiile nu sunt încă suportate"</string>
<string name="screen_join_room_subtitle_knock">"Faceți clic pe butonul de mai jos și un administrator de cameră va fi notificat. Veți putea să vă alăturați conversației odată aprobată."</string>
<string name="screen_join_room_subtitle_no_preview">"Trebuie să fiți membru al acestei camere pentru a vizualiza mesajele anterioare."</string>
<string name="screen_join_room_title_knock">"Doriți să vă alăturați acestei camere?"</string>
<string name="screen_join_room_title_no_preview">"Previzualizare indisponibilă"</string>
</resources>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_by_message">"Вы были заблокированы в комнате %1$s."</string>
<string name="screen_join_room_ban_message">"Вы были заблокированы в комнате"</string>
<string name="screen_join_room_ban_reason">"Причина: %1$s."</string>
<string name="screen_join_room_cancel_knock_action">"Отменить запрос"</string>
<string name="screen_join_room_cancel_knock_alert_confirmation">"Да, отменить"</string>
<string name="screen_join_room_cancel_knock_alert_description">"Вы действительно хотите отменить заявку на вступление в эту комнату?"</string>
<string name="screen_join_room_cancel_knock_alert_title">"Отменить запрос на присоединение"</string>
<string name="screen_join_room_decline_and_block_alert_confirmation">"Да, отклонить и заблокировать"</string>
<string name="screen_join_room_decline_and_block_alert_message">"Вы действительно хотите отклонить приглашение в эту комнате? Это также предотвратит %1$s возможность связываться с вами или приглашать вас в комнаты."</string>
<string name="screen_join_room_decline_and_block_alert_title">"Отклонить приглашение и заблокировать"</string>
<string name="screen_join_room_decline_and_block_button_title">"Отклонить и заблокировать"</string>
<string name="screen_join_room_fail_message">"Не удалось присоединиться к комнате."</string>
<string name="screen_join_room_fail_reason">"Доступ к комнате ограничен. Возможно вам нужно приглашение в комнату"</string>
<string name="screen_join_room_forget_action">"Забыть эту комнату"</string>
<string name="screen_join_room_invite_required_message">"Вам необходимо приглашение для того, чтобы присоединиться к этой комнате"</string>
<string name="screen_join_room_invited_by">"Приглашен"</string>
<string name="screen_join_room_join_action">"Присоединиться"</string>
<string name="screen_join_room_join_restricted_message">"Чтобы присоединиться, вам необходимо приглашение или быть участником сообщества."</string>
<string name="screen_join_room_knock_action">"Отправить запрос на присоединение"</string>
<string name="screen_join_room_knock_message_characters_count">"Разрешенные символы %1$d %2$d"</string>
<string name="screen_join_room_knock_message_description">"Сообщение (опционально)"</string>
<string name="screen_join_room_knock_sent_description">"Вы получите приглашение присоединиться к комнате, как только ваш запрос будет принят."</string>
<string name="screen_join_room_knock_sent_title">"Запрос на присоединение отправлен"</string>
<string name="screen_join_room_loading_alert_message">"Не удалось отобразить предварительный просмотр комнаты. Это может быть связано с проблемами сети или сервера."</string>
<string name="screen_join_room_loading_alert_title">"Мы не смогли отобразить предварительный просмотр этой комнаты"</string>
<string name="screen_join_room_space_not_supported_description">"%1$s еще не поддерживает пространства. Вы можете получить к ним доступ в веб-версии."</string>
<string name="screen_join_room_space_not_supported_title">"Пространства пока не поддерживаются"</string>
<string name="screen_join_room_subtitle_knock">"Нажмите кнопку ниже и администратор комнаты получит уведомление. После одобрения вы сможете присоединиться к обсуждению."</string>
<string name="screen_join_room_subtitle_no_preview">"Вы должны быть участником этой комнаты, чтобы просмотреть историю сообщений."</string>
<string name="screen_join_room_title_knock">"Хотите присоединиться к этой комнате?"</string>
<string name="screen_join_room_title_no_preview">"Предварительный просмотр недоступен"</string>
</resources>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_by_message">"Používateľ %1$s vám zakázal prístup."</string>
<string name="screen_join_room_ban_message">"Bol vám zakázaný vstup"</string>
<string name="screen_join_room_ban_reason">"Dôvod: %1$s."</string>
<string name="screen_join_room_cancel_knock_action">"Zrušiť žiadosť"</string>
<string name="screen_join_room_cancel_knock_alert_confirmation">"Áno, zrušiť"</string>
<string name="screen_join_room_cancel_knock_alert_description">"Ste si istí, že chcete zrušiť svoju žiadosť o vstup do tejto miestnosti?"</string>
<string name="screen_join_room_cancel_knock_alert_title">"Zrušiť žiadosť o pripojenie"</string>
<string name="screen_join_room_decline_and_block_alert_confirmation">"Áno, odmietnuť a zablokovať"</string>
<string name="screen_join_room_decline_and_block_alert_message">"Ste si istí, že chcete odmietnuť pozvanie na vstup do tejto miestnosti? To tiež zabráni tomu, aby vás %1$s kontaktoval/a alebo vás pozval/a do miestností."</string>
<string name="screen_join_room_decline_and_block_alert_title">"Odmietnuť pozvánku a zablokovať"</string>
<string name="screen_join_room_decline_and_block_button_title">"Odmietnuť a zablokovať"</string>
<string name="screen_join_room_fail_message">"Vstup sa nepodaril"</string>
<string name="screen_join_room_fail_reason">"Buď musíte byť pozvaní pripojiť sa, alebo môžu existovať obmedzenia prístupu."</string>
<string name="screen_join_room_forget_action">"Zabudnúť"</string>
<string name="screen_join_room_invite_required_message">"Potrebujete pozvanie, aby ste sa mohli pripojiť"</string>
<string name="screen_join_room_invited_by">"Pozvaný/á používateľom"</string>
<string name="screen_join_room_join_action">"Pripojiť sa"</string>
<string name="screen_join_room_join_restricted_message">"Možno budete musieť byť pozvaní alebo byť členom priestoru, aby ste sa mohli pripojiť."</string>
<string name="screen_join_room_knock_action">"Zaklopaním sa pripojíte"</string>
<string name="screen_join_room_knock_message_characters_count">"Povolené znaky %1$d z %2$d"</string>
<string name="screen_join_room_knock_message_description">"Správa (voliteľné)"</string>
<string name="screen_join_room_knock_sent_description">"Ak bude vaša žiadosť prijatá, dostanete pozvánku na vstup do miestnosti."</string>
<string name="screen_join_room_knock_sent_title">"Žiadosť o pripojenie bola odoslaná"</string>
<string name="screen_join_room_loading_alert_message">"Nepodarilo sa zobraziť ukážku miestnosti. Môže to byť spôsobené problémami so sieťou alebo serverom."</string>
<string name="screen_join_room_loading_alert_title">"Ukážku tejto miestnosti sa nepodarilo zobraziť"</string>
<string name="screen_join_room_space_not_supported_description">"%1$s zatiaľ nepodporuje priestory. K priestorom môžete pristupovať na webe."</string>
<string name="screen_join_room_space_not_supported_title">"Priestory zatiaľ nie sú podporované"</string>
<string name="screen_join_room_subtitle_knock">"Kliknite na tlačidlo nižšie a správca miestnosti bude informovaný. Po schválení sa budete môcť pripojiť ku konverzácii."</string>
<string name="screen_join_room_subtitle_no_preview">"Ak chcete zobraziť históriu správ, musíte byť členom tejto miestnosti."</string>
<string name="screen_join_room_title_knock">"Chcete sa pripojiť do tejto miestnosti?"</string>
<string name="screen_join_room_title_no_preview">"Náhľad nie je k dispozícii"</string>
</resources>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_by_message">"Du bannades från det här rummet av %1$s."</string>
<string name="screen_join_room_ban_message">"Du bannades från det här rummet"</string>
<string name="screen_join_room_ban_reason">"Anledning: %1$s."</string>
<string name="screen_join_room_cancel_knock_action">"Avbryt begäran"</string>
<string name="screen_join_room_cancel_knock_alert_confirmation">"Ja, avbryt"</string>
<string name="screen_join_room_cancel_knock_alert_description">"Är du säker på att du vill avbryta din begäran om att gå med i det här rummet?"</string>
<string name="screen_join_room_cancel_knock_alert_title">"Avbryt begäran om att gå med"</string>
<string name="screen_join_room_decline_and_block_alert_confirmation">"Ja, avvisa och blockera"</string>
<string name="screen_join_room_decline_and_block_alert_message">"Är du säker på att du vill avvisa inbjudan att gå med i det här rummet? Detta kommer också att hindra %1$s från att kontakta dig eller bjuda in dig till rum."</string>
<string name="screen_join_room_decline_and_block_alert_title">"Avvisa inbjudan och blockera"</string>
<string name="screen_join_room_decline_and_block_button_title">"Avvisa och blockera"</string>
<string name="screen_join_room_fail_message">"Misslyckades att gå med i rummet."</string>
<string name="screen_join_room_fail_reason">"Detta rum är antingen endast för inbjudna eller så kan det finnas begränsningar för åtkomst på utrymmesnivå."</string>
<string name="screen_join_room_forget_action">"Glöm det här rummet"</string>
<string name="screen_join_room_invite_required_message">"Du behöver en inbjudan för att gå med i detta rum"</string>
<string name="screen_join_room_join_action">"Gå med"</string>
<string name="screen_join_room_join_restricted_message">"Du kan behöva bli inbjuden eller vara medlem i ett utrymme för att gå med."</string>
<string name="screen_join_room_knock_action">"Knacka för att gå med"</string>
<string name="screen_join_room_knock_message_characters_count">"Tillåtna tecken %1$d av %2$d"</string>
<string name="screen_join_room_knock_message_description">"Meddelande (valfritt)"</string>
<string name="screen_join_room_knock_sent_description">"Du kommer att få en inbjudan att gå med i rummet om din begäran accepteras."</string>
<string name="screen_join_room_knock_sent_title">"Begäran om att gå med skickad"</string>
<string name="screen_join_room_loading_alert_message">"Vi kunde inte visa förhandsgranskningen av rummet. Detta kan bero på nätverks- eller serverproblem."</string>
<string name="screen_join_room_loading_alert_title">"Vi kunde inte visa förhandsgranskningen av rummet"</string>
<string name="screen_join_room_space_not_supported_description">"%1$s stöder inte utrymmen än. Du kan komma åt utrymmen på webben."</string>
<string name="screen_join_room_space_not_supported_title">"Utrymmen stöds inte ännu"</string>
<string name="screen_join_room_subtitle_knock">"Klicka på knappen nedan så kommer en rumsadministratör att meddelas. Du kommer att kunna gå med i konversationen när den har godkänts."</string>
<string name="screen_join_room_subtitle_no_preview">"Du måste vara medlem i det här rummet för att se meddelandehistoriken."</string>
<string name="screen_join_room_title_knock">"Vill du gå med i det här rummet?"</string>
<string name="screen_join_room_title_no_preview">"Förhandsgranskning är inte tillgänglig"</string>
</resources>

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_by_message">"%1$s tarafından bu odadan yasaklandınız."</string>
<string name="screen_join_room_ban_message">"Bu odadan yasaklandın"</string>
<string name="screen_join_room_ban_reason">"Neden: %1$s."</string>
<string name="screen_join_room_cancel_knock_action">"İsteği iptal et"</string>
<string name="screen_join_room_cancel_knock_alert_confirmation">"Evet, iptal et"</string>
<string name="screen_join_room_cancel_knock_alert_description">"Bu odaya katılma isteğinizi iptal etmek istediğinizden emin misiniz?"</string>
<string name="screen_join_room_cancel_knock_alert_title">"Katılma isteğini iptal et"</string>
<string name="screen_join_room_decline_and_block_alert_confirmation">"Evet, reddet ve engelle"</string>
<string name="screen_join_room_decline_and_block_alert_message">"Bu odaya katılma davetini reddetmek istediğinizden emin misiniz? Bu aynı zamanda %1$s sizinle iletişim kurmasını veya sizi odalara davet etmesini de engeller."</string>
<string name="screen_join_room_decline_and_block_alert_title">"Daveti reddet ve engelle"</string>
<string name="screen_join_room_fail_message">"Odaya katılım başarısız oldu."</string>
<string name="screen_join_room_fail_reason">"Bu odaya yalnızca davetle girilebilir veya alan düzeyinde erişim kısıtlamaları olabilir."</string>
<string name="screen_join_room_forget_action">"Bu odayı unut"</string>
<string name="screen_join_room_invite_required_message">"Bu odaya katılmak için bir davete ihtiyacınız var"</string>
<string name="screen_join_room_join_action">"Katıl"</string>
<string name="screen_join_room_join_restricted_message">"Katılmak için davet edilmeniz veya bir alana üye olmanız gerekebilir."</string>
<string name="screen_join_room_knock_action">"Katılma isteği gönder"</string>
<string name="screen_join_room_knock_message_description">"Mesaj (isteğe bağlı)"</string>
<string name="screen_join_room_knock_sent_description">"Talebiniz kabul edilirse odaya katılmanız için bir davet alacaksınız."</string>
<string name="screen_join_room_knock_sent_title">"Katılma isteği gönderildi"</string>
<string name="screen_join_room_loading_alert_message">"Oda önizlemesini görüntüleyemedik. Bunun nedeni ağ veya sunucu sorunları olabilir."</string>
<string name="screen_join_room_loading_alert_title">"Bu oda önizlemesini görüntüleyemedik"</string>
<string name="screen_join_room_space_not_supported_description">"%1$s henüz alanları desteklemiyor. Alanlara web üzerinden erişebilirsiniz."</string>
<string name="screen_join_room_space_not_supported_title">"Alanlar henüz desteklenmiyor"</string>
<string name="screen_join_room_subtitle_knock">"Aşağıdaki düğmeyi tıkladığınızda bir oda yöneticisi bilgilendirilecektir. Onaylandıktan sonra görüşmeye katılabilirsiniz."</string>
<string name="screen_join_room_subtitle_no_preview">"Mesaj geçmişini görüntülemek için bu odaya üye olmanız gerekmektedir."</string>
<string name="screen_join_room_title_knock">"Bu odaya katılmak ister misiniz?"</string>
<string name="screen_join_room_title_no_preview">"Önizleme mevcut değil"</string>
</resources>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_by_message">"%1$s забороняє вам відвідувати цю кімнату."</string>
<string name="screen_join_room_ban_message">"Вам заборонили відвідувати цю кімнату"</string>
<string name="screen_join_room_ban_reason">"Причина: %1$s."</string>
<string name="screen_join_room_cancel_knock_action">"Скасувати запит"</string>
<string name="screen_join_room_cancel_knock_alert_confirmation">"Так, скасувати"</string>
<string name="screen_join_room_cancel_knock_alert_description">"Ви впевнені, що бажаєте скасувати свій запит на приєднання до цієї кімнати?"</string>
<string name="screen_join_room_cancel_knock_alert_title">"Скасувати запит на приєднання"</string>
<string name="screen_join_room_decline_and_block_alert_confirmation">"Так, відхилити та заблокувати"</string>
<string name="screen_join_room_decline_and_block_alert_message">"Ви впевнені, що хочете відхилити запрошення приєднатися до цієї кімнати? Це також завадить %1$s зв\'язатися з вами або запрошувати вас в кімнати."</string>
<string name="screen_join_room_decline_and_block_alert_title">"Відхилити запрошення та заблокувати"</string>
<string name="screen_join_room_decline_and_block_button_title">"Відхилити та заблокувати"</string>
<string name="screen_join_room_fail_message">"Не вдалося приєднатися до кімнати."</string>
<string name="screen_join_room_fail_reason">"Ця кімната доступна лише за запрошенням або на рівні простору можуть бути обмеження доступу."</string>
<string name="screen_join_room_forget_action">"Забути цю кімнату"</string>
<string name="screen_join_room_invite_required_message">"Вам потрібне запрошення, щоб приєднатися до цієї кімнати"</string>
<string name="screen_join_room_join_action">"Доєднатися"</string>
<string name="screen_join_room_join_restricted_message">"Можливо, вам знадобиться отримати запрошення або стати учасником простору, щоб приєднатися."</string>
<string name="screen_join_room_knock_action">"Постукати, щоб приєднатися"</string>
<string name="screen_join_room_knock_message_characters_count">"Дозволені символи %1$d з %2$d"</string>
<string name="screen_join_room_knock_message_description">"Повідомлення (необов\'язково)"</string>
<string name="screen_join_room_knock_sent_description">"Ви отримаєте запрошення приєднатися до кімнати, якщо ваш запит буде прийнятий."</string>
<string name="screen_join_room_knock_sent_title">"Запит на приєднання надіслано"</string>
<string name="screen_join_room_loading_alert_message">"Ми не змогли показати попередній перегляд кімнати. Це може бути пов\'язано з проблемами мережі або сервера."</string>
<string name="screen_join_room_loading_alert_title">"Ми не можемо показати попередній перегляд цієї кімнати"</string>
<string name="screen_join_room_space_not_supported_description">"%1$s ще не підтримує простори. Ви можете отримати доступ до них у вебверсії."</string>
<string name="screen_join_room_space_not_supported_title">"Простори поки що не підтримуються"</string>
<string name="screen_join_room_subtitle_knock">"Натисніть кнопку нижче, і адміністратор кімнати отримає сповіщення. Ви зможете приєднатися до розмови після схвалення."</string>
<string name="screen_join_room_subtitle_no_preview">"Ви мусите бути учасником цієї кімнати, щоб переглядати історію повідомлень."</string>
<string name="screen_join_room_title_knock">"Хочете приєднатися до цієї кімнати?"</string>
<string name="screen_join_room_title_no_preview">"Попередній перегляд недоступний"</string>
</resources>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_join_action">"شامل ہوں"</string>
<string name="screen_join_room_knock_action">"شامل ہونے کی درخواست بھیجیں"</string>
<string name="screen_join_room_space_not_supported_description">"%1$s ابھی تک خالی جگہوں کی حمایت نہیں کرتا۔ آپ جال پر خالی جگہوں تک رسائی حاصل کرسکتے ہیں۔"</string>
<string name="screen_join_room_space_not_supported_title">"ابھی تک جگہیں تعاون یافتہ نہیں"</string>
<string name="screen_join_room_subtitle_knock">"نیچے دیئے گئے کلید پر دبائیں اور کمرے کے منتظم کو مطلع کیا جائے گا۔ منظور ہونے کے بعد آپ گفتگو میں شامل ہو سکیں گے۔"</string>
<string name="screen_join_room_subtitle_no_preview">"پیغام کی سرگزشت دیکھنے کے لیے آپ کا اس کمرے کا رکن ہونا ضروری ہے۔"</string>
<string name="screen_join_room_title_knock">"اس کمرے میں شامل ہونا چاہتے ہیں؟"</string>
<string name="screen_join_room_title_no_preview">"پیش منظر دستیاب نہیں ہے"</string>
</resources>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_by_message">"Siz %1$s tomonidan ushbu xonadan ban qilingansiz."</string>
<string name="screen_join_room_ban_message">"Siz bu xonadan chetlashtirilgansiz"</string>
<string name="screen_join_room_ban_reason">"Sababi: %1$s ."</string>
<string name="screen_join_room_cancel_knock_action">"Sorovni bekor qilish"</string>
<string name="screen_join_room_cancel_knock_alert_confirmation">"Ha, bekor qiling"</string>
<string name="screen_join_room_cancel_knock_alert_description">"Bu xonaga qoshilish sorovingizni bekor qilishni xohlayotganingizga ishonchingiz komilmi?"</string>
<string name="screen_join_room_cancel_knock_alert_title">"Qoshilish sorovini bekor qilish"</string>
<string name="screen_join_room_decline_and_block_alert_confirmation">"Ha, rad etish va bloklash"</string>
<string name="screen_join_room_decline_and_block_alert_message">"Ushbu xonaga qoshilish taklifini rad etishga ishonchingiz komilmi? Bu %1$sning siz bilan boglanishiga yoki sizni xonalarga taklif qilishiga ham tosqinlik qiladi."</string>
<string name="screen_join_room_decline_and_block_alert_title">"Taklifni rad etish va bloklash"</string>
<string name="screen_join_room_decline_and_block_button_title">"Rad etish va bloklash"</string>
<string name="screen_join_room_fail_message">"Xonaga qoshilish amalga oshmadi"</string>
<string name="screen_join_room_fail_reason">"Bu xona faqat taklif etilganlar uchun yoki bu maydonga kirish huquqi cheklangan bolishi mumkin."</string>
<string name="screen_join_room_forget_action">"Bu xonani esdan chiqarish"</string>
<string name="screen_join_room_invite_required_message">"Bu xonaga kirish uchun taklifnoma kerak"</string>
<string name="screen_join_room_join_action">"Qo\'shilish"</string>
<string name="screen_join_room_join_restricted_message">"Qoshilish uchun sizga taklif kerak yoki siz maydonga azo bolishingiz kerak."</string>
<string name="screen_join_room_knock_action">"Qoʻshilish soʻrovini yuborish"</string>
<string name="screen_join_room_knock_message_characters_count">"Ruxsat etilgan belgilar: %1$d / %2$d"</string>
<string name="screen_join_room_knock_message_description">"Xabar (ixtiyoriy)"</string>
<string name="screen_join_room_knock_sent_description">"Agar sorovingiz qabul qilinsa, xonaga qoshilish taklifini olasiz."</string>
<string name="screen_join_room_knock_sent_title">"Qoshilish sorovi yuborildi"</string>
<string name="screen_join_room_loading_alert_message">"Xona korinishini namoyish eta olmadik. Bu tarmoq yoki server muammolari tufayli yuz bergan bolishi mumkin."</string>
<string name="screen_join_room_loading_alert_title">"Biz bu xonani oldindan korishni korsata olmadik "</string>
<string name="screen_join_room_space_not_supported_description">"%1$s hali maydon xizmatini qoʻllab-quvvatlamaydi. maydonga veb-sayt orqali kirishingiz mumkin."</string>
<string name="screen_join_room_space_not_supported_title">"Maydonlar hali qoʻllab-quvvatlanmaydi"</string>
<string name="screen_join_room_subtitle_knock">"Quyidagi tugmani bosing va xona administratoriga xabar beriladi. Ruxsat berilgandan soʻng suhbatga qoʻshilishingiz mumkin boʻladi."</string>
<string name="screen_join_room_subtitle_no_preview">"Xabarlar tarixini koʻrish uchun siz ushbu xonaning aʼzosi boʻlishingiz shart."</string>
<string name="screen_join_room_title_knock">"Bu xonaga qoʻshilishni xohlaysizmi?"</string>
<string name="screen_join_room_title_no_preview">"Oldindan koʻrish imkoni yoʻq"</string>
</resources>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_by_message">"您被 %1$s 禁止。"</string>
<string name="screen_join_room_ban_message">"您被禁止了"</string>
<string name="screen_join_room_ban_reason">"理由:%1$s。"</string>
<string name="screen_join_room_cancel_knock_action">"取消請求"</string>
<string name="screen_join_room_cancel_knock_alert_confirmation">"是的,取消"</string>
<string name="screen_join_room_cancel_knock_alert_description">"您確定您想要取消加入此聊天室的請求嗎?"</string>
<string name="screen_join_room_cancel_knock_alert_title">"取消加入請求"</string>
<string name="screen_join_room_decline_and_block_alert_confirmation">"是的,拒絕並封鎖"</string>
<string name="screen_join_room_decline_and_block_alert_message">"您確定要拒絕加入此聊天室的邀請嗎?這也會防止 %1$s 聯絡您或邀請您加入聊天室。"</string>
<string name="screen_join_room_decline_and_block_alert_title">"拒絕邀請並封鎖"</string>
<string name="screen_join_room_decline_and_block_button_title">"拒絕並封鎖"</string>
<string name="screen_join_room_fail_message">"加入失敗。"</string>
<string name="screen_join_room_fail_reason">"您必須獲得邀請才能加入,或者可能存在存取限制。"</string>
<string name="screen_join_room_forget_action">"忘記"</string>
<string name="screen_join_room_invite_required_message">"您需要獲得邀請才能加入"</string>
<string name="screen_join_room_invited_by">"邀請者"</string>
<string name="screen_join_room_join_action">"加入"</string>
<string name="screen_join_room_join_restricted_message">"您可能需要被邀請成為空間的成員才能加入。"</string>
<string name="screen_join_room_knock_action">"傳送加入請求"</string>
<string name="screen_join_room_knock_message_characters_count">"允許的字元 %1$d 中的 %2$d"</string>
<string name="screen_join_room_knock_message_description">"訊息(選擇性)"</string>
<string name="screen_join_room_knock_sent_description">"若接受了您的請求,您將會收到加入聊天是的邀請。"</string>
<string name="screen_join_room_knock_sent_title">"已傳送加入請求"</string>
<string name="screen_join_room_loading_alert_message">"我們無法顯示聊天室預覽。這可能是因為網路或伺服器問題所致。"</string>
<string name="screen_join_room_loading_alert_title">"我們無法顯示此聊天室的預覽"</string>
<string name="screen_join_room_space_not_supported_description">"%1$s 尚未支援空間。您可以在網頁上存取空間。"</string>
<string name="screen_join_room_space_not_supported_title">"尚未支援空間"</string>
<string name="screen_join_room_subtitle_knock">"點選下方按鈕將會通知聊天試管里員。一旦核准,您就可以加入對話。"</string>
<string name="screen_join_room_subtitle_no_preview">"您必須是此聊天室的成員才能檢視訊息歷史紀錄。"</string>
<string name="screen_join_room_title_knock">"想要加入此聊天室?"</string>
<string name="screen_join_room_title_no_preview">"無法使用預覽"</string>
</resources>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_by_message">"您已被禁止访问%1$s。"</string>
<string name="screen_join_room_ban_message">"你已被禁止访问"</string>
<string name="screen_join_room_ban_reason">"理由:%1$s。"</string>
<string name="screen_join_room_cancel_knock_action">"取消请求"</string>
<string name="screen_join_room_cancel_knock_alert_confirmation">"是的,取消"</string>
<string name="screen_join_room_cancel_knock_alert_description">"您确定要取消加入此房间的请求吗?"</string>
<string name="screen_join_room_cancel_knock_alert_title">"取消加入申请"</string>
<string name="screen_join_room_decline_and_block_alert_confirmation">"是的,拒绝并屏蔽"</string>
<string name="screen_join_room_decline_and_block_alert_message">"您确定要拒绝加入此房间的邀请吗?这也将阻止%1$s 与您联系或邀请您加入房间。"</string>
<string name="screen_join_room_decline_and_block_alert_title">"拒绝邀请并屏蔽"</string>
<string name="screen_join_room_decline_and_block_button_title">"拒绝并屏蔽"</string>
<string name="screen_join_room_fail_message">"加入失败"</string>
<string name="screen_join_room_fail_reason">"您需要被邀请加入,否则可能会受到访问限制。"</string>
<string name="screen_join_room_forget_action">"忘记"</string>
<string name="screen_join_room_invite_required_message">"您需要邀请才能加入"</string>
<string name="screen_join_room_invited_by">"受邀于"</string>
<string name="screen_join_room_join_action">"加入"</string>
<string name="screen_join_room_join_restricted_message">"您可能需要受到邀请或成为某个空间的成员才能加入。"</string>
<string name="screen_join_room_knock_action">"加入聊天室"</string>
<string name="screen_join_room_knock_message_characters_count">"允许的字符数量 %2$d中的%1$d"</string>
<string name="screen_join_room_knock_message_description">"消息(可选)"</string>
<string name="screen_join_room_knock_sent_description">"如果您的请求被接受,您将收到加入房间的邀请。"</string>
<string name="screen_join_room_knock_sent_title">"加入请求已发送"</string>
<string name="screen_join_room_loading_alert_message">"无法显示房间预览。这可能是由于网络或服务器问题造成的。"</string>
<string name="screen_join_room_loading_alert_title">"无法显示此房间预览"</string>
<string name="screen_join_room_space_not_supported_description">"%1$s 尚不支持空间。您可以通过 Web 端访问空间"</string>
<string name="screen_join_room_space_not_supported_title">"空间尚不支持"</string>
<string name="screen_join_room_subtitle_knock">"点击下面的按钮,系统将通知聊天室管理员。获得批准后将能够加入对话。"</string>
<string name="screen_join_room_subtitle_no_preview">"只有聊天室成员才能查看消息历史记录。"</string>
<string name="screen_join_room_title_knock">"想加入这个聊天室吗?"</string>
<string name="screen_join_room_title_no_preview">"预览不可用"</string>
</resources>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_join_room_ban_by_message">"You were banned by %1$s."</string>
<string name="screen_join_room_ban_message">"You were banned"</string>
<string name="screen_join_room_ban_reason">"Reason: %1$s."</string>
<string name="screen_join_room_cancel_knock_action">"Cancel request"</string>
<string name="screen_join_room_cancel_knock_alert_confirmation">"Yes, cancel"</string>
<string name="screen_join_room_cancel_knock_alert_description">"Are you sure that you want to cancel your request to join this room?"</string>
<string name="screen_join_room_cancel_knock_alert_title">"Cancel request to join"</string>
<string name="screen_join_room_decline_and_block_alert_confirmation">"Yes, decline &amp; block"</string>
<string name="screen_join_room_decline_and_block_alert_message">"Are you sure you want to decline the invite to join this room? This will also prevent %1$s from contacting you or inviting you to rooms."</string>
<string name="screen_join_room_decline_and_block_alert_title">"Decline invite &amp; block"</string>
<string name="screen_join_room_decline_and_block_button_title">"Decline and block"</string>
<string name="screen_join_room_fail_message">"Joining failed"</string>
<string name="screen_join_room_fail_reason">"You either need to be invited to join or there might be restrictions to access."</string>
<string name="screen_join_room_forget_action">"Forget"</string>
<string name="screen_join_room_invite_required_message">"You need an invite in order to join"</string>
<string name="screen_join_room_invited_by">"Invited by"</string>
<string name="screen_join_room_join_action">"Join"</string>
<string name="screen_join_room_join_restricted_message">"You may need to be invited or be a member of a space in order to join."</string>
<string name="screen_join_room_knock_action">"Send request to join"</string>
<string name="screen_join_room_knock_message_characters_count">"Allowed characters %1$d of %2$d"</string>
<string name="screen_join_room_knock_message_description">"Message (optional)"</string>
<string name="screen_join_room_knock_sent_description">"You will receive an invite to join the room if your request is accepted."</string>
<string name="screen_join_room_knock_sent_title">"Request to join sent"</string>
<string name="screen_join_room_loading_alert_message">"We could not display the room preview. This may be due to network or server issues."</string>
<string name="screen_join_room_loading_alert_title">"We couldnt display this room preview"</string>
<string name="screen_join_room_space_not_supported_description">"%1$s does not support spaces yet. You can access spaces on web."</string>
<string name="screen_join_room_space_not_supported_title">"Spaces are not supported yet"</string>
<string name="screen_join_room_subtitle_knock">"Click the button below and a room administrator will be notified. Youll be able to join the conversation once approved."</string>
<string name="screen_join_room_subtitle_no_preview">"You must be a member of this room to view the message history."</string>
<string name="screen_join_room_title_knock">"Want to join this room?"</string>
<string name="screen_join_room_title_no_preview">"Preview is not available"</string>
</resources>