Create spaces (#5982)
* Allow creating a space with `CreateRoomParameters` * Add 'Create space' menu item in the spaces home screen. Also, imports new strings related to spaces. * Link the 'Create space' button with the screen to create the space * Unify room access and visibility for `ConfigureRoom`, use the updated design * Fix `EditRoomDetails` avatar size (68dp) * Replace `EditableAvatarView` and `UnsavedAvatar` copmonents with `AvatarPickerView` * `AvatarDataFetcherFactory`: Make sure we use a fallback image fetcher when the URL is not an MXC one (a local one, i.e.). This removes the previous need for a separate `UnsavedAvatarView` * Use `AvatarPickerView` in all the screens where `EditableAvatarView` was used * Improve naming and previews * Update strings, remove unused ones for `RoomAccessItem` * Make `isSpace` part of the `CreateRoomConfig` * Ensure the content fits in the screenshots for `AvatarPickerSizesPreview` * Add `AvatarDataFetcherFactoryTest` * Add new feature flag for creating spaces * Fix ripple being too large for the `Pick` state * Tweak margins and section titles a bit * Add preview for `HomeTopBar` with the spaces case * Update screenshots --------- Co-authored-by: ElementBot <android@element.io>
This commit is contained in:
parent
a234eb3e29
commit
03d14087e6
150 changed files with 1097 additions and 778 deletions
|
|
@ -47,6 +47,7 @@ import io.element.android.appnav.room.RoomFlowNode
|
||||||
import io.element.android.appnav.room.RoomNavigationTarget
|
import io.element.android.appnav.room.RoomNavigationTarget
|
||||||
import io.element.android.appnav.room.joined.JoinedRoomLoadedFlowNode
|
import io.element.android.appnav.room.joined.JoinedRoomLoadedFlowNode
|
||||||
import io.element.android.compound.colors.SemanticColorsLightDark
|
import io.element.android.compound.colors.SemanticColorsLightDark
|
||||||
|
import io.element.android.features.createroom.api.CreateRoomEntryPoint
|
||||||
import io.element.android.features.enterprise.api.EnterpriseService
|
import io.element.android.features.enterprise.api.EnterpriseService
|
||||||
import io.element.android.features.enterprise.api.SessionEnterpriseService
|
import io.element.android.features.enterprise.api.SessionEnterpriseService
|
||||||
import io.element.android.features.ftue.api.FtueEntryPoint
|
import io.element.android.features.ftue.api.FtueEntryPoint
|
||||||
|
|
@ -144,6 +145,7 @@ class LoggedInFlowNode(
|
||||||
snackbarDispatcher: SnackbarDispatcher,
|
snackbarDispatcher: SnackbarDispatcher,
|
||||||
private val analyticsService: AnalyticsService,
|
private val analyticsService: AnalyticsService,
|
||||||
private val analyticsRoomListStateWatcher: AnalyticsRoomListStateWatcher,
|
private val analyticsRoomListStateWatcher: AnalyticsRoomListStateWatcher,
|
||||||
|
private val createRoomEntryPoint: CreateRoomEntryPoint,
|
||||||
) : BaseFlowNode<LoggedInFlowNode.NavTarget>(
|
) : BaseFlowNode<LoggedInFlowNode.NavTarget>(
|
||||||
backstack = BackStack(
|
backstack = BackStack(
|
||||||
initialElement = NavTarget.Placeholder,
|
initialElement = NavTarget.Placeholder,
|
||||||
|
|
@ -287,6 +289,9 @@ class LoggedInFlowNode(
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data object CreateRoom : NavTarget
|
data object CreateRoom : NavTarget
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
|
data object CreateSpace : NavTarget
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data class SecureBackup(
|
data class SecureBackup(
|
||||||
val initialElement: SecureBackupEntryPoint.InitialTarget = SecureBackupEntryPoint.InitialTarget.Root
|
val initialElement: SecureBackupEntryPoint.InitialTarget = SecureBackupEntryPoint.InitialTarget.Root
|
||||||
|
|
@ -338,6 +343,10 @@ class LoggedInFlowNode(
|
||||||
backstack.push(NavTarget.CreateRoom)
|
backstack.push(NavTarget.CreateRoom)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun navigateToCreateSpace() {
|
||||||
|
backstack.push(NavTarget.CreateSpace)
|
||||||
|
}
|
||||||
|
|
||||||
override fun navigateToSetUpRecovery() {
|
override fun navigateToSetUpRecovery() {
|
||||||
backstack.push(NavTarget.SecureBackup(initialElement = SecureBackupEntryPoint.InitialTarget.Root))
|
backstack.push(NavTarget.SecureBackup(initialElement = SecureBackupEntryPoint.InitialTarget.Root))
|
||||||
}
|
}
|
||||||
|
|
@ -469,6 +478,14 @@ class LoggedInFlowNode(
|
||||||
callback = callback,
|
callback = callback,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
is NavTarget.CreateSpace -> {
|
||||||
|
val callback = object : CreateRoomEntryPoint.Callback {
|
||||||
|
override fun onRoomCreated(roomId: RoomId) {
|
||||||
|
backstack.replace(NavTarget.Room(roomIdOrAlias = RoomIdOrAlias.Id(roomId), serverNames = emptyList()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
createRoomEntryPoint.createNode(isSpace = true, parentNode = this, buildContext = buildContext, callback = callback)
|
||||||
|
}
|
||||||
is NavTarget.SecureBackup -> {
|
is NavTarget.SecureBackup -> {
|
||||||
secureBackupEntryPoint.createNode(
|
secureBackupEntryPoint.createNode(
|
||||||
parentNode = this,
|
parentNode = this,
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
|
|
||||||
interface CreateRoomEntryPoint : FeatureEntryPoint {
|
interface CreateRoomEntryPoint : FeatureEntryPoint {
|
||||||
fun createNode(
|
fun createNode(
|
||||||
|
isSpace: Boolean,
|
||||||
parentNode: Node,
|
parentNode: Node,
|
||||||
buildContext: BuildContext,
|
buildContext: BuildContext,
|
||||||
callback: Callback,
|
callback: Callback,
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import io.element.android.features.createroom.impl.addpeople.AddPeopleNode
|
||||||
import io.element.android.features.createroom.impl.configureroom.ConfigureRoomNode
|
import io.element.android.features.createroom.impl.configureroom.ConfigureRoomNode
|
||||||
import io.element.android.libraries.architecture.BackstackView
|
import io.element.android.libraries.architecture.BackstackView
|
||||||
import io.element.android.libraries.architecture.BaseFlowNode
|
import io.element.android.libraries.architecture.BaseFlowNode
|
||||||
|
import io.element.android.libraries.architecture.NodeInputs
|
||||||
import io.element.android.libraries.architecture.callback
|
import io.element.android.libraries.architecture.callback
|
||||||
import io.element.android.libraries.architecture.createNode
|
import io.element.android.libraries.architecture.createNode
|
||||||
import io.element.android.libraries.di.SessionScope
|
import io.element.android.libraries.di.SessionScope
|
||||||
|
|
@ -37,23 +38,29 @@ class CreateRoomFlowNode(
|
||||||
@Assisted plugins: List<Plugin>,
|
@Assisted plugins: List<Plugin>,
|
||||||
) : BaseFlowNode<CreateRoomFlowNode.NavTarget>(
|
) : BaseFlowNode<CreateRoomFlowNode.NavTarget>(
|
||||||
backstack = BackStack(
|
backstack = BackStack(
|
||||||
initialElement = NavTarget.ConfigureRoom,
|
initialElement = NavTarget.ConfigureRoom(isSpace = plugins.filterIsInstance<Inputs>().first().isSpace),
|
||||||
savedStateMap = buildContext.savedStateMap,
|
savedStateMap = buildContext.savedStateMap,
|
||||||
),
|
),
|
||||||
buildContext = buildContext,
|
buildContext = buildContext,
|
||||||
plugins = plugins
|
plugins = plugins
|
||||||
) {
|
) {
|
||||||
|
@Parcelize
|
||||||
|
data class Inputs(
|
||||||
|
val isSpace: Boolean
|
||||||
|
) : NodeInputs, Parcelable
|
||||||
|
|
||||||
private val callback: CreateRoomEntryPoint.Callback = callback()
|
private val callback: CreateRoomEntryPoint.Callback = callback()
|
||||||
|
|
||||||
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
|
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
|
||||||
return when (navTarget) {
|
return when (navTarget) {
|
||||||
NavTarget.ConfigureRoom -> {
|
is NavTarget.ConfigureRoom -> {
|
||||||
|
val inputs = ConfigureRoomNode.Inputs(isSpace = navTarget.isSpace)
|
||||||
val callback = object : ConfigureRoomNode.Callback {
|
val callback = object : ConfigureRoomNode.Callback {
|
||||||
override fun onCreateRoomSuccess(roomId: RoomId) {
|
override fun onCreateRoomSuccess(roomId: RoomId) {
|
||||||
backstack.replace(NavTarget.AddPeople(roomId))
|
backstack.replace(NavTarget.AddPeople(roomId))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
createNode<ConfigureRoomNode>(buildContext, plugins = listOf(callback))
|
createNode<ConfigureRoomNode>(buildContext, plugins = listOf(inputs, callback))
|
||||||
}
|
}
|
||||||
is NavTarget.AddPeople -> {
|
is NavTarget.AddPeople -> {
|
||||||
val inputs = AddPeopleNode.Inputs(navTarget.roomId)
|
val inputs = AddPeopleNode.Inputs(navTarget.roomId)
|
||||||
|
|
@ -74,7 +81,7 @@ class CreateRoomFlowNode(
|
||||||
|
|
||||||
sealed interface NavTarget : Parcelable {
|
sealed interface NavTarget : Parcelable {
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data object ConfigureRoom : NavTarget
|
data class ConfigureRoom(val isSpace: Boolean) : NavTarget
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data class AddPeople(val roomId: RoomId) : NavTarget
|
data class AddPeople(val roomId: RoomId) : NavTarget
|
||||||
|
|
|
||||||
|
|
@ -18,10 +18,12 @@ import io.element.android.libraries.di.SessionScope
|
||||||
@ContributesBinding(SessionScope::class)
|
@ContributesBinding(SessionScope::class)
|
||||||
class DefaultCreateRoomEntryPoint : CreateRoomEntryPoint {
|
class DefaultCreateRoomEntryPoint : CreateRoomEntryPoint {
|
||||||
override fun createNode(
|
override fun createNode(
|
||||||
|
isSpace: Boolean,
|
||||||
parentNode: Node,
|
parentNode: Node,
|
||||||
buildContext: BuildContext,
|
buildContext: BuildContext,
|
||||||
callback: CreateRoomEntryPoint.Callback,
|
callback: CreateRoomEntryPoint.Callback,
|
||||||
): Node {
|
): Node {
|
||||||
return parentNode.createNode<CreateRoomFlowNode>(buildContext, listOf(callback))
|
val inputs = CreateRoomFlowNode.Inputs(isSpace)
|
||||||
|
return parentNode.createNode<CreateRoomFlowNode>(buildContext, listOf(inputs, callback))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
package io.element.android.features.createroom.impl.configureroom
|
package io.element.android.features.createroom.impl.configureroom
|
||||||
|
|
||||||
|
import android.os.Parcelable
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import com.bumble.appyx.core.lifecycle.subscribe
|
import com.bumble.appyx.core.lifecycle.subscribe
|
||||||
|
|
@ -18,23 +19,35 @@ import dev.zacsweers.metro.Assisted
|
||||||
import dev.zacsweers.metro.AssistedInject
|
import dev.zacsweers.metro.AssistedInject
|
||||||
import im.vector.app.features.analytics.plan.MobileScreen
|
import im.vector.app.features.analytics.plan.MobileScreen
|
||||||
import io.element.android.annotations.ContributesNode
|
import io.element.android.annotations.ContributesNode
|
||||||
|
import io.element.android.libraries.architecture.NodeInputs
|
||||||
import io.element.android.libraries.architecture.callback
|
import io.element.android.libraries.architecture.callback
|
||||||
|
import io.element.android.libraries.architecture.inputs
|
||||||
import io.element.android.libraries.di.SessionScope
|
import io.element.android.libraries.di.SessionScope
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
import io.element.android.services.analytics.api.AnalyticsService
|
import io.element.android.services.analytics.api.AnalyticsService
|
||||||
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
@ContributesNode(SessionScope::class)
|
@ContributesNode(SessionScope::class)
|
||||||
@AssistedInject
|
@AssistedInject
|
||||||
class ConfigureRoomNode(
|
class ConfigureRoomNode(
|
||||||
@Assisted buildContext: BuildContext,
|
@Assisted buildContext: BuildContext,
|
||||||
@Assisted plugins: List<Plugin>,
|
@Assisted plugins: List<Plugin>,
|
||||||
private val presenter: ConfigureRoomPresenter,
|
presenterFactory: ConfigureRoomPresenter.Factory,
|
||||||
private val analyticsService: AnalyticsService,
|
private val analyticsService: AnalyticsService,
|
||||||
) : Node(buildContext, plugins = plugins) {
|
) : Node(buildContext, plugins = plugins) {
|
||||||
interface Callback : Plugin {
|
interface Callback : Plugin {
|
||||||
fun onCreateRoomSuccess(roomId: RoomId)
|
fun onCreateRoomSuccess(roomId: RoomId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
|
data class Inputs(
|
||||||
|
val isSpace: Boolean,
|
||||||
|
) : NodeInputs, Parcelable
|
||||||
|
|
||||||
|
private val inputs = inputs<Inputs>()
|
||||||
|
|
||||||
|
private val presenter = presenterFactory.create(inputs.isSpace)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
lifecycle.subscribe(
|
lifecycle.subscribe(
|
||||||
onResume = {
|
onResume = {
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,9 @@ import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import dev.zacsweers.metro.Inject
|
import dev.zacsweers.metro.Assisted
|
||||||
|
import dev.zacsweers.metro.AssistedFactory
|
||||||
|
import dev.zacsweers.metro.AssistedInject
|
||||||
import im.vector.app.features.analytics.plan.CreatedRoom
|
import im.vector.app.features.analytics.plan.CreatedRoom
|
||||||
import io.element.android.libraries.architecture.AsyncAction
|
import io.element.android.libraries.architecture.AsyncAction
|
||||||
import io.element.android.libraries.architecture.Presenter
|
import io.element.android.libraries.architecture.Presenter
|
||||||
|
|
@ -49,8 +51,9 @@ import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import kotlin.jvm.optionals.getOrDefault
|
import kotlin.jvm.optionals.getOrDefault
|
||||||
|
|
||||||
@Inject
|
@AssistedInject
|
||||||
class ConfigureRoomPresenter(
|
class ConfigureRoomPresenter(
|
||||||
|
@Assisted private val isSpace: Boolean,
|
||||||
private val dataStore: CreateRoomConfigStore,
|
private val dataStore: CreateRoomConfigStore,
|
||||||
private val matrixClient: MatrixClient,
|
private val matrixClient: MatrixClient,
|
||||||
private val mediaPickerProvider: PickerProvider,
|
private val mediaPickerProvider: PickerProvider,
|
||||||
|
|
@ -61,13 +64,22 @@ class ConfigureRoomPresenter(
|
||||||
private val roomAliasHelper: RoomAliasHelper,
|
private val roomAliasHelper: RoomAliasHelper,
|
||||||
private val mediaOptimizationConfigProvider: MediaOptimizationConfigProvider,
|
private val mediaOptimizationConfigProvider: MediaOptimizationConfigProvider,
|
||||||
) : Presenter<ConfigureRoomState> {
|
) : Presenter<ConfigureRoomState> {
|
||||||
|
@AssistedFactory
|
||||||
|
interface Factory {
|
||||||
|
fun create(isSpace: Boolean): ConfigureRoomPresenter
|
||||||
|
}
|
||||||
|
|
||||||
private val cameraPermissionPresenter: PermissionsPresenter = permissionsPresenterFactory.create(android.Manifest.permission.CAMERA)
|
private val cameraPermissionPresenter: PermissionsPresenter = permissionsPresenterFactory.create(android.Manifest.permission.CAMERA)
|
||||||
private var pendingPermissionRequest = false
|
private var pendingPermissionRequest = false
|
||||||
|
|
||||||
|
init {
|
||||||
|
dataStore.setIsSpace(isSpace)
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun present(): ConfigureRoomState {
|
override fun present(): ConfigureRoomState {
|
||||||
val cameraPermissionState = cameraPermissionPresenter.present()
|
val cameraPermissionState = cameraPermissionPresenter.present()
|
||||||
val createRoomConfig by dataStore.getCreateRoomConfigFlow().collectAsState(CreateRoomConfig())
|
val createRoomConfig by dataStore.getCreateRoomConfigFlow().collectAsState()
|
||||||
val homeserverName = remember { matrixClient.userIdServerName() }
|
val homeserverName = remember { matrixClient.userIdServerName() }
|
||||||
val isKnockFeatureEnabled by remember {
|
val isKnockFeatureEnabled by remember {
|
||||||
featureFlagService.isFeatureEnabledFlow(FeatureFlags.Knock)
|
featureFlagService.isFeatureEnabledFlow(FeatureFlags.Knock)
|
||||||
|
|
@ -171,7 +183,8 @@ class ConfigureRoomPresenter(
|
||||||
preset = RoomPreset.PUBLIC_CHAT,
|
preset = RoomPreset.PUBLIC_CHAT,
|
||||||
invite = config.invites.map { it.userId },
|
invite = config.invites.map { it.userId },
|
||||||
avatar = avatarUrl,
|
avatar = avatarUrl,
|
||||||
roomAliasName = config.roomVisibility.roomAddress()
|
roomAliasName = config.roomVisibility.roomAddress(),
|
||||||
|
isSpace = isSpace,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
CreateRoomParameters(
|
CreateRoomParameters(
|
||||||
|
|
@ -184,6 +197,7 @@ class ConfigureRoomPresenter(
|
||||||
preset = RoomPreset.PRIVATE_CHAT,
|
preset = RoomPreset.PRIVATE_CHAT,
|
||||||
invite = config.invites.map { it.userId },
|
invite = config.invites.map { it.userId },
|
||||||
avatar = avatarUrl,
|
avatar = avatarUrl,
|
||||||
|
isSpace = isSpace,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
matrixClient.createRoom(params)
|
matrixClient.createRoom(params)
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,18 @@ open class ConfigureRoomStateProvider : PreviewParameterProvider<ConfigureRoomSt
|
||||||
),
|
),
|
||||||
roomAddressValidity = RoomAddressValidity.Valid,
|
roomAddressValidity = RoomAddressValidity.Valid,
|
||||||
),
|
),
|
||||||
|
aConfigureRoomState(
|
||||||
|
config = CreateRoomConfig(
|
||||||
|
isSpace = true,
|
||||||
|
roomName = "Space 101",
|
||||||
|
topic = "Space topic for this space when the text goes onto multiple lines and is really long, there shouldn’t be more than 3 lines",
|
||||||
|
roomVisibility = RoomVisibilityState.Public(
|
||||||
|
roomAddress = RoomAddress.AutoFilled("Space-101"),
|
||||||
|
roomAccess = RoomAccess.Anyone,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
roomAddressValidity = RoomAddressValidity.Valid,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,16 @@
|
||||||
|
|
||||||
package io.element.android.features.createroom.impl.configureroom
|
package io.element.android.features.createroom.impl.configureroom
|
||||||
|
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.ColumnScope
|
import androidx.compose.foundation.layout.ColumnScope
|
||||||
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
|
||||||
import androidx.compose.foundation.layout.consumeWindowInsets
|
import androidx.compose.foundation.layout.consumeWindowInsets
|
||||||
import androidx.compose.foundation.layout.imePadding
|
import androidx.compose.foundation.layout.imePadding
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.selection.selectableGroup
|
import androidx.compose.foundation.selection.selectableGroup
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
|
|
@ -27,10 +28,9 @@ import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalFocusManager
|
import androidx.compose.ui.platform.LocalFocusManager
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.semantics.clearAndSetSemantics
|
|
||||||
import androidx.compose.ui.semantics.contentDescription
|
|
||||||
import androidx.compose.ui.text.input.KeyboardCapitalization
|
import androidx.compose.ui.text.input.KeyboardCapitalization
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
@ -41,15 +41,18 @@ import io.element.android.libraries.designsystem.atomic.atoms.RoundedIconAtom
|
||||||
import io.element.android.libraries.designsystem.atomic.atoms.RoundedIconAtomSize
|
import io.element.android.libraries.designsystem.atomic.atoms.RoundedIconAtomSize
|
||||||
import io.element.android.libraries.designsystem.components.async.AsyncActionView
|
import io.element.android.libraries.designsystem.components.async.AsyncActionView
|
||||||
import io.element.android.libraries.designsystem.components.async.AsyncActionViewDefaults
|
import io.element.android.libraries.designsystem.components.async.AsyncActionViewDefaults
|
||||||
|
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
||||||
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
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.avatar.AvatarType
|
||||||
import io.element.android.libraries.designsystem.components.button.BackButton
|
import io.element.android.libraries.designsystem.components.button.BackButton
|
||||||
import io.element.android.libraries.designsystem.components.list.ListItemContent
|
import io.element.android.libraries.designsystem.components.list.ListItemContent
|
||||||
|
import io.element.android.libraries.designsystem.icons.CompoundDrawables
|
||||||
import io.element.android.libraries.designsystem.modifiers.clearFocusOnTap
|
import io.element.android.libraries.designsystem.modifiers.clearFocusOnTap
|
||||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||||
import io.element.android.libraries.designsystem.preview.PreviewWithLargeHeight
|
import io.element.android.libraries.designsystem.preview.PreviewWithLargeHeight
|
||||||
import io.element.android.libraries.designsystem.theme.components.ListItem
|
import io.element.android.libraries.designsystem.theme.components.ListItem
|
||||||
|
import io.element.android.libraries.designsystem.theme.components.ListSectionHeader
|
||||||
import io.element.android.libraries.designsystem.theme.components.Scaffold
|
import io.element.android.libraries.designsystem.theme.components.Scaffold
|
||||||
import io.element.android.libraries.designsystem.theme.components.Text
|
import io.element.android.libraries.designsystem.theme.components.Text
|
||||||
import io.element.android.libraries.designsystem.theme.components.TextButton
|
import io.element.android.libraries.designsystem.theme.components.TextButton
|
||||||
|
|
@ -57,10 +60,12 @@ 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.components.TopAppBar
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
import io.element.android.libraries.matrix.ui.components.AvatarActionBottomSheet
|
import io.element.android.libraries.matrix.ui.components.AvatarActionBottomSheet
|
||||||
import io.element.android.libraries.matrix.ui.components.UnsavedAvatar
|
import io.element.android.libraries.matrix.ui.components.AvatarPickerState
|
||||||
|
import io.element.android.libraries.matrix.ui.components.AvatarPickerView
|
||||||
import io.element.android.libraries.matrix.ui.room.address.RoomAddressField
|
import io.element.android.libraries.matrix.ui.room.address.RoomAddressField
|
||||||
import io.element.android.libraries.permissions.api.PermissionsView
|
import io.element.android.libraries.permissions.api.PermissionsView
|
||||||
import io.element.android.libraries.ui.strings.CommonStrings
|
import io.element.android.libraries.ui.strings.CommonStrings
|
||||||
|
import kotlin.jvm.optionals.getOrNull
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ConfigureRoomView(
|
fun ConfigureRoomView(
|
||||||
|
|
@ -69,6 +74,7 @@ fun ConfigureRoomView(
|
||||||
onCreateRoomSuccess: (RoomId) -> Unit,
|
onCreateRoomSuccess: (RoomId) -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
|
val isSpace = state.config.isSpace
|
||||||
val focusManager = LocalFocusManager.current
|
val focusManager = LocalFocusManager.current
|
||||||
val isAvatarActionsSheetVisible = remember { mutableStateOf(false) }
|
val isAvatarActionsSheetVisible = remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
|
@ -81,6 +87,7 @@ fun ConfigureRoomView(
|
||||||
modifier = modifier.clearFocusOnTap(focusManager),
|
modifier = modifier.clearFocusOnTap(focusManager),
|
||||||
topBar = {
|
topBar = {
|
||||||
ConfigureRoomToolbar(
|
ConfigureRoomToolbar(
|
||||||
|
isSpace = isSpace,
|
||||||
isNextActionEnabled = state.isValid,
|
isNextActionEnabled = state.isValid,
|
||||||
onBackClick = onBackClick,
|
onBackClick = onBackClick,
|
||||||
onNextClick = {
|
onNextClick = {
|
||||||
|
|
@ -96,9 +103,10 @@ fun ConfigureRoomView(
|
||||||
.imePadding()
|
.imePadding()
|
||||||
.verticalScroll(rememberScrollState())
|
.verticalScroll(rememberScrollState())
|
||||||
.consumeWindowInsets(padding),
|
.consumeWindowInsets(padding),
|
||||||
verticalArrangement = Arrangement.spacedBy(24.dp),
|
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||||
) {
|
) {
|
||||||
RoomNameWithAvatar(
|
RoomNameWithAvatar(
|
||||||
|
isSpace = isSpace,
|
||||||
modifier = Modifier.padding(horizontal = 16.dp),
|
modifier = Modifier.padding(horizontal = 16.dp),
|
||||||
avatarUri = state.config.avatarUri,
|
avatarUri = state.config.avatarUri,
|
||||||
roomName = state.config.roomName.orEmpty(),
|
roomName = state.config.roomName.orEmpty(),
|
||||||
|
|
@ -110,37 +118,35 @@ fun ConfigureRoomView(
|
||||||
topic = state.config.topic.orEmpty(),
|
topic = state.config.topic.orEmpty(),
|
||||||
onTopicChange = { state.eventSink(ConfigureRoomEvents.TopicChanged(it)) },
|
onTopicChange = { state.eventSink(ConfigureRoomEvents.TopicChanged(it)) },
|
||||||
)
|
)
|
||||||
RoomVisibilityOptions(
|
|
||||||
|
RoomVisibilityAndAccessOptions(
|
||||||
selected = when (state.config.roomVisibility) {
|
selected = when (state.config.roomVisibility) {
|
||||||
is RoomVisibilityState.Private -> RoomVisibilityItem.Private
|
is RoomVisibilityState.Private -> RoomVisibilityItem.Private
|
||||||
is RoomVisibilityState.Public -> RoomVisibilityItem.Public
|
is RoomVisibilityState.Public -> when (state.config.roomVisibility.roomAccess) {
|
||||||
|
RoomAccess.Knocking -> RoomVisibilityItem.AskToJoin
|
||||||
|
RoomAccess.Anyone -> RoomVisibilityItem.Public
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
isKnockingEnabled = state.isKnockFeatureEnabled,
|
||||||
onOptionClick = {
|
onOptionClick = {
|
||||||
focusManager.clearFocus()
|
focusManager.clearFocus()
|
||||||
state.eventSink(ConfigureRoomEvents.RoomVisibilityChanged(it))
|
state.eventSink(ConfigureRoomEvents.RoomVisibilityChanged(it))
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if (state.config.roomVisibility is RoomVisibilityState.Public && state.isKnockFeatureEnabled) {
|
|
||||||
RoomAccessOptions(
|
if (state.config.roomVisibility !is RoomVisibilityState.Private) {
|
||||||
selected = when (state.config.roomVisibility.roomAccess) {
|
Column {
|
||||||
RoomAccess.Anyone -> RoomAccessItem.Anyone
|
ListSectionHeader(title = stringResource(R.string.screen_create_room_room_address_section_title))
|
||||||
RoomAccess.Knocking -> RoomAccessItem.AskToJoin
|
RoomAddressField(
|
||||||
},
|
modifier = Modifier.padding(horizontal = 16.dp),
|
||||||
onOptionClick = {
|
address = state.config.roomVisibility.roomAddress().getOrNull().orEmpty(),
|
||||||
focusManager.clearFocus()
|
homeserverName = state.homeserverName,
|
||||||
state.eventSink(ConfigureRoomEvents.RoomAccessChanged(it))
|
addressValidity = state.roomAddressValidity,
|
||||||
},
|
onAddressChange = { state.eventSink(ConfigureRoomEvents.RoomAddressChanged(it)) },
|
||||||
)
|
label = null,
|
||||||
RoomAddressField(
|
supportingText = stringResource(R.string.screen_create_room_room_address_section_footer),
|
||||||
modifier = Modifier.padding(horizontal = 16.dp),
|
)
|
||||||
address = state.config.roomVisibility.roomAddress.value,
|
}
|
||||||
homeserverName = state.homeserverName,
|
|
||||||
addressValidity = state.roomAddressValidity,
|
|
||||||
onAddressChange = { state.eventSink(ConfigureRoomEvents.RoomAddressChanged(it)) },
|
|
||||||
label = stringResource(R.string.screen_create_room_room_address_section_title),
|
|
||||||
supportingText = stringResource(R.string.screen_create_room_room_address_section_footer),
|
|
||||||
)
|
|
||||||
Spacer(Modifier)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -156,11 +162,11 @@ fun ConfigureRoomView(
|
||||||
async = state.createRoomAction,
|
async = state.createRoomAction,
|
||||||
progressDialog = {
|
progressDialog = {
|
||||||
AsyncActionViewDefaults.ProgressDialog(
|
AsyncActionViewDefaults.ProgressDialog(
|
||||||
progressText = stringResource(CommonStrings.common_creating_room),
|
progressText = stringResource(if (isSpace) CommonStrings.common_creating_space else CommonStrings.common_creating_room),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
onSuccess = { onCreateRoomSuccess(it) },
|
onSuccess = { onCreateRoomSuccess(it) },
|
||||||
errorMessage = { stringResource(R.string.screen_create_room_error_creating_room) },
|
errorMessage = { stringResource(if (isSpace) R.string.screen_create_room_error_creating_space else R.string.screen_create_room_error_creating_room) },
|
||||||
onRetry = { state.eventSink(ConfigureRoomEvents.CreateRoom) },
|
onRetry = { state.eventSink(ConfigureRoomEvents.CreateRoom) },
|
||||||
onErrorDismiss = { state.eventSink(ConfigureRoomEvents.CancelCreateRoom) },
|
onErrorDismiss = { state.eventSink(ConfigureRoomEvents.CancelCreateRoom) },
|
||||||
)
|
)
|
||||||
|
|
@ -173,12 +179,13 @@ fun ConfigureRoomView(
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun ConfigureRoomToolbar(
|
private fun ConfigureRoomToolbar(
|
||||||
|
isSpace: Boolean,
|
||||||
isNextActionEnabled: Boolean,
|
isNextActionEnabled: Boolean,
|
||||||
onBackClick: () -> Unit,
|
onBackClick: () -> Unit,
|
||||||
onNextClick: () -> Unit,
|
onNextClick: () -> Unit,
|
||||||
) {
|
) {
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
titleStr = stringResource(R.string.screen_create_room_title),
|
titleStr = stringResource(if (isSpace) R.string.screen_create_room_new_space_title else R.string.screen_create_room_new_room_title),
|
||||||
navigationIcon = { BackButton(onClick = onBackClick) },
|
navigationIcon = { BackButton(onClick = onBackClick) },
|
||||||
actions = {
|
actions = {
|
||||||
TextButton(
|
TextButton(
|
||||||
|
|
@ -192,6 +199,7 @@ private fun ConfigureRoomToolbar(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun RoomNameWithAvatar(
|
private fun RoomNameWithAvatar(
|
||||||
|
isSpace: Boolean,
|
||||||
avatarUri: String?,
|
avatarUri: String?,
|
||||||
roomName: String,
|
roomName: String,
|
||||||
onAvatarClick: () -> Unit,
|
onAvatarClick: () -> Unit,
|
||||||
|
|
@ -203,25 +211,33 @@ private fun RoomNameWithAvatar(
|
||||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
) {
|
) {
|
||||||
val a11yAvatar = stringResource(CommonStrings.a11y_room_avatar)
|
Box(
|
||||||
UnsavedAvatar(
|
modifier = Modifier.padding(end = 8.dp).size(AvatarSize.EditRoomDetails.dp),
|
||||||
avatarUri = avatarUri,
|
contentAlignment = Alignment.Center,
|
||||||
avatarSize = AvatarSize.EditRoomDetails,
|
) {
|
||||||
avatarType = AvatarType.Room(),
|
val avatarState = remember(avatarUri) {
|
||||||
modifier = Modifier
|
if (avatarUri != null) {
|
||||||
.clickable(
|
AvatarPickerState.Selected(
|
||||||
onClick = onAvatarClick,
|
avatarData = AvatarData(id = "#", name = null, url = avatarUri, size = AvatarSize.EditRoomDetails),
|
||||||
onClickLabel = stringResource(CommonStrings.action_open_context_menu),
|
type = if (isSpace) AvatarType.Space() else AvatarType.Room(),
|
||||||
)
|
)
|
||||||
.clearAndSetSemantics {
|
} else {
|
||||||
contentDescription = a11yAvatar
|
val containerSize = 48.dp
|
||||||
},
|
val padding = PaddingValues((AvatarSize.EditRoomDetails.dp - containerSize) / 2)
|
||||||
)
|
AvatarPickerState.Pick(buttonSize = 48.dp, iconSize = 24.dp, externalPadding = padding)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AvatarPickerView(
|
||||||
|
state = avatarState,
|
||||||
|
onClick = onAvatarClick,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
TextField(
|
TextField(
|
||||||
label = stringResource(R.string.screen_create_room_room_name_label),
|
modifier = Modifier.padding(bottom = 18.dp),
|
||||||
|
label = stringResource(CommonStrings.common_name),
|
||||||
value = roomName,
|
value = roomName,
|
||||||
placeholder = stringResource(CommonStrings.common_room_name_placeholder),
|
placeholder = stringResource(R.string.screen_create_room_name_placeholder),
|
||||||
singleLine = true,
|
singleLine = true,
|
||||||
onValueChange = onChangeRoomName,
|
onValueChange = onChangeRoomName,
|
||||||
)
|
)
|
||||||
|
|
@ -240,7 +256,7 @@ private fun RoomTopic(
|
||||||
value = topic,
|
value = topic,
|
||||||
onValueChange = onTopicChange,
|
onValueChange = onTopicChange,
|
||||||
maxLines = 3,
|
maxLines = 3,
|
||||||
supportingText = stringResource(CommonStrings.common_topic_placeholder),
|
placeholder = stringResource(R.string.screen_create_room_topic_placeholder),
|
||||||
keyboardOptions = KeyboardOptions(
|
keyboardOptions = KeyboardOptions(
|
||||||
capitalization = KeyboardCapitalization.Sentences,
|
capitalization = KeyboardCapitalization.Sentences,
|
||||||
),
|
),
|
||||||
|
|
@ -256,38 +272,58 @@ private fun ConfigureRoomOptions(
|
||||||
Column(
|
Column(
|
||||||
modifier = modifier.selectableGroup()
|
modifier = modifier.selectableGroup()
|
||||||
) {
|
) {
|
||||||
Text(
|
ListSectionHeader(title = title)
|
||||||
text = title,
|
|
||||||
style = ElementTheme.typography.fontBodyLgMedium,
|
|
||||||
color = ElementTheme.colors.textPrimary,
|
|
||||||
modifier = Modifier.padding(horizontal = 16.dp),
|
|
||||||
)
|
|
||||||
content()
|
content()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun RoomVisibilityOptions(
|
private fun RoomVisibilityAndAccessOptions(
|
||||||
selected: RoomVisibilityItem,
|
selected: RoomVisibilityItem,
|
||||||
|
isKnockingEnabled: Boolean,
|
||||||
onOptionClick: (RoomVisibilityItem) -> Unit,
|
onOptionClick: (RoomVisibilityItem) -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
ConfigureRoomOptions(
|
ConfigureRoomOptions(
|
||||||
title = stringResource(R.string.screen_create_room_room_visibility_section_title),
|
title = stringResource(R.string.screen_create_room_room_access_section_title),
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
) {
|
) {
|
||||||
RoomVisibilityItem.entries.forEach { item ->
|
RoomVisibilityItem.entries.forEach { item ->
|
||||||
|
if (item == RoomVisibilityItem.AskToJoin && !isKnockingEnabled) {
|
||||||
|
return@forEach
|
||||||
|
}
|
||||||
|
|
||||||
val isSelected = item == selected
|
val isSelected = item == selected
|
||||||
ListItem(
|
ListItem(
|
||||||
leadingContent = ListItemContent.Custom {
|
leadingContent = ListItemContent.Custom {
|
||||||
RoundedIconAtom(
|
RoundedIconAtom(
|
||||||
size = RoundedIconAtomSize.Big,
|
size = RoundedIconAtomSize.Big,
|
||||||
resourceId = item.icon,
|
resourceId = when (item) {
|
||||||
|
RoomVisibilityItem.Public -> CompoundDrawables.ic_compound_public
|
||||||
|
RoomVisibilityItem.AskToJoin -> CompoundDrawables.ic_compound_user_add
|
||||||
|
RoomVisibilityItem.Private -> CompoundDrawables.ic_compound_lock
|
||||||
|
},
|
||||||
tint = if (isSelected) ElementTheme.colors.iconPrimary else ElementTheme.colors.iconSecondary,
|
tint = if (isSelected) ElementTheme.colors.iconPrimary else ElementTheme.colors.iconSecondary,
|
||||||
|
backgroundTint = Color.Transparent,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
headlineContent = { Text(text = stringResource(item.title)) },
|
headlineContent = {
|
||||||
supportingContent = { Text(text = stringResource(item.description)) },
|
val title = when (item) {
|
||||||
|
RoomVisibilityItem.Public -> stringResource(R.string.screen_create_room_public_option_title)
|
||||||
|
RoomVisibilityItem.AskToJoin -> stringResource(R.string.screen_create_room_room_access_section_knocking_option_title)
|
||||||
|
RoomVisibilityItem.Private -> stringResource(R.string.screen_create_room_private_option_title)
|
||||||
|
}
|
||||||
|
Text(text = title)
|
||||||
|
},
|
||||||
|
supportingContent = {
|
||||||
|
// TODO handle description of items in a certain space/org
|
||||||
|
val description = when (item) {
|
||||||
|
RoomVisibilityItem.Public -> stringResource(R.string.screen_create_room_public_option_short_description)
|
||||||
|
RoomVisibilityItem.AskToJoin -> stringResource(R.string.screen_create_room_room_access_section_knocking_option_description)
|
||||||
|
RoomVisibilityItem.Private -> stringResource(R.string.screen_create_room_private_option_description)
|
||||||
|
}
|
||||||
|
Text(text = description)
|
||||||
|
},
|
||||||
trailingContent = ListItemContent.RadioButton(selected = isSelected),
|
trailingContent = ListItemContent.RadioButton(selected = isSelected),
|
||||||
onClick = { onOptionClick(item) },
|
onClick = { onOptionClick(item) },
|
||||||
)
|
)
|
||||||
|
|
@ -295,27 +331,6 @@ private fun RoomVisibilityOptions(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun RoomAccessOptions(
|
|
||||||
selected: RoomAccessItem,
|
|
||||||
onOptionClick: (RoomAccessItem) -> Unit,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
ConfigureRoomOptions(
|
|
||||||
title = stringResource(R.string.screen_create_room_room_access_section_header),
|
|
||||||
modifier = modifier,
|
|
||||||
) {
|
|
||||||
RoomAccessItem.entries.forEach { item ->
|
|
||||||
ListItem(
|
|
||||||
headlineContent = { Text(text = stringResource(item.title)) },
|
|
||||||
supportingContent = { Text(text = stringResource(item.description)) },
|
|
||||||
trailingContent = ListItemContent.RadioButton(selected = item == selected),
|
|
||||||
onClick = { onOptionClick(item) },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@PreviewWithLargeHeight
|
@PreviewWithLargeHeight
|
||||||
@Composable
|
@Composable
|
||||||
internal fun ConfigureRoomViewLightPreview(@PreviewParameter(ConfigureRoomStateProvider::class) state: ConfigureRoomState) =
|
internal fun ConfigureRoomViewLightPreview(@PreviewParameter(ConfigureRoomStateProvider::class) state: ConfigureRoomState) =
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
|
|
||||||
data class CreateRoomConfig(
|
data class CreateRoomConfig(
|
||||||
|
val isSpace: Boolean = false,
|
||||||
val roomName: String? = null,
|
val roomName: String? = null,
|
||||||
val topic: String? = null,
|
val topic: String? = null,
|
||||||
val avatarUri: String? = null,
|
val avatarUri: String? = null,
|
||||||
|
|
|
||||||
|
|
@ -72,11 +72,11 @@ class CreateRoomConfigStore(
|
||||||
config.copy(
|
config.copy(
|
||||||
roomVisibility = when (visibility) {
|
roomVisibility = when (visibility) {
|
||||||
RoomVisibilityItem.Private -> RoomVisibilityState.Private
|
RoomVisibilityItem.Private -> RoomVisibilityState.Private
|
||||||
RoomVisibilityItem.Public -> {
|
RoomVisibilityItem.Public, RoomVisibilityItem.AskToJoin -> {
|
||||||
val roomAliasName = roomAliasHelper.roomAliasNameFromRoomDisplayName(config.roomName.orEmpty())
|
val roomAliasName = roomAliasHelper.roomAliasNameFromRoomDisplayName(config.roomName.orEmpty())
|
||||||
RoomVisibilityState.Public(
|
RoomVisibilityState.Public(
|
||||||
roomAddress = RoomAddress.AutoFilled(roomAliasName),
|
roomAddress = RoomAddress.AutoFilled(roomAliasName),
|
||||||
roomAccess = RoomAccess.Anyone,
|
roomAccess = if (visibility == RoomVisibilityItem.AskToJoin) RoomAccess.Knocking else RoomAccess.Anyone,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -114,6 +114,12 @@ class CreateRoomConfigStore(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setIsSpace(isSpace: Boolean) {
|
||||||
|
createRoomConfigFlow.getAndUpdate { config ->
|
||||||
|
config.copy(isSpace = isSpace)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun clearCachedData() {
|
fun clearCachedData() {
|
||||||
cachedAvatarUri = null
|
cachedAvatarUri = null
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,19 +8,7 @@
|
||||||
|
|
||||||
package io.element.android.features.createroom.impl.configureroom
|
package io.element.android.features.createroom.impl.configureroom
|
||||||
|
|
||||||
import androidx.annotation.StringRes
|
enum class RoomAccessItem {
|
||||||
import io.element.android.features.createroom.impl.R
|
Anyone,
|
||||||
|
AskToJoin,
|
||||||
enum class RoomAccessItem(
|
|
||||||
@StringRes val title: Int,
|
|
||||||
@StringRes val description: Int
|
|
||||||
) {
|
|
||||||
Anyone(
|
|
||||||
title = R.string.screen_create_room_room_access_section_anyone_option_title,
|
|
||||||
description = R.string.screen_create_room_room_access_section_anyone_option_description,
|
|
||||||
),
|
|
||||||
AskToJoin(
|
|
||||||
title = R.string.screen_create_room_room_access_section_knocking_option_title,
|
|
||||||
description = R.string.screen_create_room_room_access_section_knocking_option_description,
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,24 +8,8 @@
|
||||||
|
|
||||||
package io.element.android.features.createroom.impl.configureroom
|
package io.element.android.features.createroom.impl.configureroom
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes
|
enum class RoomVisibilityItem {
|
||||||
import androidx.annotation.StringRes
|
Public,
|
||||||
import io.element.android.features.createroom.impl.R
|
AskToJoin,
|
||||||
import io.element.android.libraries.designsystem.icons.CompoundDrawables
|
Private
|
||||||
|
|
||||||
enum class RoomVisibilityItem(
|
|
||||||
@DrawableRes val icon: Int,
|
|
||||||
@StringRes val title: Int,
|
|
||||||
@StringRes val description: Int
|
|
||||||
) {
|
|
||||||
Private(
|
|
||||||
icon = CompoundDrawables.ic_compound_lock,
|
|
||||||
title = R.string.screen_create_room_private_option_title,
|
|
||||||
description = R.string.screen_create_room_private_option_description,
|
|
||||||
),
|
|
||||||
Public(
|
|
||||||
icon = CompoundDrawables.ic_compound_public,
|
|
||||||
title = R.string.screen_create_room_public_option_title,
|
|
||||||
description = R.string.screen_create_room_public_option_description,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,6 @@
|
||||||
<string name="screen_create_room_public_option_description">"Любы можа знайсці гэты пакой.
|
<string name="screen_create_room_public_option_description">"Любы можа знайсці гэты пакой.
|
||||||
Вы можаце змяніць гэта ў любы час у наладах пакоя."</string>
|
Вы можаце змяніць гэта ў любы час у наладах пакоя."</string>
|
||||||
<string name="screen_create_room_public_option_title">"Публічны пакой"</string>
|
<string name="screen_create_room_public_option_title">"Публічны пакой"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"Хто заўгодна"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"Доступ у пакой"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"Папрасіце далучыцца"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"Папрасіце далучыцца"</string>
|
||||||
<string name="screen_create_room_room_name_label">"Назва пакоя"</string>
|
|
||||||
<string name="screen_create_room_title">"Стварыце пакой"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Тэма (неабавязкова)"</string>
|
<string name="screen_create_room_topic_label">"Тэма (неабавязкова)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,7 @@
|
||||||
<string name="screen_create_room_public_option_description">"Всеки може да намери тази стая.
|
<string name="screen_create_room_public_option_description">"Всеки може да намери тази стая.
|
||||||
Можете да промените това по всяко време в настройките на стаята."</string>
|
Можете да промените това по всяко време в настройките на стаята."</string>
|
||||||
<string name="screen_create_room_public_option_title">"Общодостъпна стая"</string>
|
<string name="screen_create_room_public_option_title">"Общодостъпна стая"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"Всеки може да се присъедини към тази стая"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"Всеки"</string>
|
|
||||||
<string name="screen_create_room_room_address_section_footer">"За да бъде тази стая видима в директорията на общодостъпните стаи, ще ви е необходим адрес на стаята."</string>
|
<string name="screen_create_room_room_address_section_footer">"За да бъде тази стая видима в директорията на общодостъпните стаи, ще ви е необходим адрес на стаята."</string>
|
||||||
<string name="screen_create_room_room_name_label">"Име на стаята"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">"Видимост на стаята"</string>
|
<string name="screen_create_room_room_visibility_section_title">"Видимост на стаята"</string>
|
||||||
<string name="screen_create_room_title">"Създаване на стая"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Тема за разговор (незадължително)"</string>
|
<string name="screen_create_room_topic_label">"Тема за разговор (незадължително)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,10 @@
|
||||||
<string name="screen_create_room_public_option_description">"Tuto místnost může najít kdokoli.
|
<string name="screen_create_room_public_option_description">"Tuto místnost může najít kdokoli.
|
||||||
To můžete kdykoli změnit v nastavení místnosti."</string>
|
To můžete kdykoli změnit v nastavení místnosti."</string>
|
||||||
<string name="screen_create_room_public_option_title">"Veřejná místnost"</string>
|
<string name="screen_create_room_public_option_title">"Veřejná místnost"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"Do této místnosti může vstoupit kdokoli"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"Kdokoliv"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"Přístup do místnosti"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_description">"Kdokoli může požádat o vstup do místnosti, ale správce nebo moderátor bude muset žádost přijmout"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_description">"Kdokoli může požádat o vstup do místnosti, ale správce nebo moderátor bude muset žádost přijmout"</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"Požádat o připojení"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"Požádat o připojení"</string>
|
||||||
<string name="screen_create_room_room_address_section_footer">"Aby byla tato místnost viditelná v adresáři veřejných místností, budete potřebovat adresu místnosti."</string>
|
<string name="screen_create_room_room_address_section_footer">"Aby byla tato místnost viditelná v adresáři veřejných místností, budete potřebovat adresu místnosti."</string>
|
||||||
<string name="screen_create_room_room_address_section_title">"Adresa místnosti"</string>
|
<string name="screen_create_room_room_address_section_title">"Adresa místnosti"</string>
|
||||||
<string name="screen_create_room_room_name_label">"Název místnosti"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">"Viditelnost místnosti"</string>
|
<string name="screen_create_room_room_visibility_section_title">"Viditelnost místnosti"</string>
|
||||||
<string name="screen_create_room_title">"Vytvořit místnost"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Téma (nepovinné)"</string>
|
<string name="screen_create_room_topic_label">"Téma (nepovinné)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,10 @@
|
||||||
<string name="screen_create_room_public_option_description">"Gall unrhyw un ddod o hyd i\'r ystafell hon.
|
<string name="screen_create_room_public_option_description">"Gall unrhyw un ddod o hyd i\'r ystafell hon.
|
||||||
Gallwch newid hyn unrhyw bryd yng ngosodiadau ystafell."</string>
|
Gallwch newid hyn unrhyw bryd yng ngosodiadau ystafell."</string>
|
||||||
<string name="screen_create_room_public_option_title">"Ystafell gyhoeddus"</string>
|
<string name="screen_create_room_public_option_title">"Ystafell gyhoeddus"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"Gall unrhyw un ymuno â\'r ystafell hon"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"Unrhyw un"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"Mynediad i\'r Ystafell"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_description">"Gall unrhyw un ofyn am gael ymuno â\'r ystafell ond bydd rhaid i weinyddwr neu gymedrolwr dderbyn y cais"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_description">"Gall unrhyw un ofyn am gael ymuno â\'r ystafell ond bydd rhaid i weinyddwr neu gymedrolwr dderbyn y cais"</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"Gofyn i gael ymuno"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"Gofyn i gael ymuno"</string>
|
||||||
<string name="screen_create_room_room_address_section_footer">"Er mwyn i\'r ystafell hon fod yn weladwy yn y cyfeiriadur ystafelloedd cyhoeddus, bydd angen cyfeiriad ystafell arnoch."</string>
|
<string name="screen_create_room_room_address_section_footer">"Er mwyn i\'r ystafell hon fod yn weladwy yn y cyfeiriadur ystafelloedd cyhoeddus, bydd angen cyfeiriad ystafell arnoch."</string>
|
||||||
<string name="screen_create_room_room_address_section_title">"Cyfeiriad yr ystafell"</string>
|
<string name="screen_create_room_room_address_section_title">"Cyfeiriad yr ystafell"</string>
|
||||||
<string name="screen_create_room_room_name_label">"Enw\'r ystafell"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">"Gwelededd yr ystafell"</string>
|
<string name="screen_create_room_room_visibility_section_title">"Gwelededd yr ystafell"</string>
|
||||||
<string name="screen_create_room_title">"Creu ystafell"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Pwnc (dewisol)"</string>
|
<string name="screen_create_room_topic_label">"Pwnc (dewisol)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,10 @@
|
||||||
<string name="screen_create_room_public_option_description">"Alle kan finde dette rum.
|
<string name="screen_create_room_public_option_description">"Alle kan finde dette rum.
|
||||||
Du kan ændre dette når som helst i rummets indstillinger."</string>
|
Du kan ændre dette når som helst i rummets indstillinger."</string>
|
||||||
<string name="screen_create_room_public_option_title">"Offentligt rum"</string>
|
<string name="screen_create_room_public_option_title">"Offentligt rum"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"Alle kan deltage i dette rum"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"Enhver"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"Adgang til rummet"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_description">"Alle kan bede om at deltage i rummet, men en administrator eller en moderator skal acceptere anmodningen"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_description">"Alle kan bede om at deltage i rummet, men en administrator eller en moderator skal acceptere anmodningen"</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"Spørg om at deltage"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"Spørg om at deltage"</string>
|
||||||
<string name="screen_create_room_room_address_section_footer">"Hvis dette rum skal være synligt i det offentlige register, skal du bruge en rum-adresse."</string>
|
<string name="screen_create_room_room_address_section_footer">"Hvis dette rum skal være synligt i det offentlige register, skal du bruge en rum-adresse."</string>
|
||||||
<string name="screen_create_room_room_address_section_title">"Rummets adresse"</string>
|
<string name="screen_create_room_room_address_section_title">"Rummets adresse"</string>
|
||||||
<string name="screen_create_room_room_name_label">"Navn på rum"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">"Rummets synlighed"</string>
|
<string name="screen_create_room_room_visibility_section_title">"Rummets synlighed"</string>
|
||||||
<string name="screen_create_room_title">"Opret et rum"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Emne (valgfrit)"</string>
|
<string name="screen_create_room_topic_label">"Emne (valgfrit)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,10 @@
|
||||||
<string name="screen_create_room_public_option_description">"Jeder kann diesen Chat finden.
|
<string name="screen_create_room_public_option_description">"Jeder kann diesen Chat finden.
|
||||||
Du kannst dies jederzeit in den Einstellungen des Chats ändern."</string>
|
Du kannst dies jederzeit in den Einstellungen des Chats ändern."</string>
|
||||||
<string name="screen_create_room_public_option_title">"Öffentlicher Chat"</string>
|
<string name="screen_create_room_public_option_title">"Öffentlicher Chat"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"Jeder darf diesem Chat beitreten"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"Jeder"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"Chat Zugang"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_description">"Jeder kann den Beitritt zum Chat erbitten, aber ein Admin oder Moderator muss die Anfrage akzeptieren."</string>
|
<string name="screen_create_room_room_access_section_knocking_option_description">"Jeder kann den Beitritt zum Chat erbitten, aber ein Admin oder Moderator muss die Anfrage akzeptieren."</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"Beitritt beantragen"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"Beitritt beantragen"</string>
|
||||||
<string name="screen_create_room_room_address_section_footer">"Du benötigst eine Chat-Adresse, damit dieser Chat im öffentlichen Verzeichnis sichtbar ist."</string>
|
<string name="screen_create_room_room_address_section_footer">"Du benötigst eine Chat-Adresse, damit dieser Chat im öffentlichen Verzeichnis sichtbar ist."</string>
|
||||||
<string name="screen_create_room_room_address_section_title">"Chatroom Adresse"</string>
|
<string name="screen_create_room_room_address_section_title">"Chatroom Adresse"</string>
|
||||||
<string name="screen_create_room_room_name_label">"Chat-Name"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">" Sichtbarkeit des Chats"</string>
|
<string name="screen_create_room_room_visibility_section_title">" Sichtbarkeit des Chats"</string>
|
||||||
<string name="screen_create_room_title">"Chat erstellen"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Thema (optional)"</string>
|
<string name="screen_create_room_topic_label">"Thema (optional)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,10 @@
|
||||||
<string name="screen_create_room_public_option_description">"Ο καθένας μπορεί να βρει αυτή την αίθουσα.
|
<string name="screen_create_room_public_option_description">"Ο καθένας μπορεί να βρει αυτή την αίθουσα.
|
||||||
Αυτό μπορείτε να το αλλάξετε ανά πάσα στιγμή στις ρυθμίσεις της αίθουσας."</string>
|
Αυτό μπορείτε να το αλλάξετε ανά πάσα στιγμή στις ρυθμίσεις της αίθουσας."</string>
|
||||||
<string name="screen_create_room_public_option_title">"Δημόσια αίθουσα"</string>
|
<string name="screen_create_room_public_option_title">"Δημόσια αίθουσα"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"Οποιοσδήποτε μπορεί να συμμετάσχει σε αυτή την αίθουσα"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"Οποιοσδήποτε"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"Πρόσβαση στην Αίθουσα"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_description">"Οποιοσδήποτε μπορεί να ζητήσει να συμμετάσχει στην αίθουσα, αλλά ένας διαχειριστής ή ένας συντονιστής θα πρέπει να αποδεχτεί το αίτημα"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_description">"Οποιοσδήποτε μπορεί να ζητήσει να συμμετάσχει στην αίθουσα, αλλά ένας διαχειριστής ή ένας συντονιστής θα πρέπει να αποδεχτεί το αίτημα"</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"Αίτημα συμμετοχής"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"Αίτημα συμμετοχής"</string>
|
||||||
<string name="screen_create_room_room_address_section_footer">"Για να είναι ορατή αυτή η αίθουσα στον δημόσιο κατάλογο αιθουσών, θα χρειαστείτε μια διεύθυνση αίθουσας."</string>
|
<string name="screen_create_room_room_address_section_footer">"Για να είναι ορατή αυτή η αίθουσα στον δημόσιο κατάλογο αιθουσών, θα χρειαστείτε μια διεύθυνση αίθουσας."</string>
|
||||||
<string name="screen_create_room_room_address_section_title">"Διεύθυνση δωματίου"</string>
|
<string name="screen_create_room_room_address_section_title">"Διεύθυνση δωματίου"</string>
|
||||||
<string name="screen_create_room_room_name_label">"Όνομα αίθουσας"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">"Ορατότητα αίθουσας"</string>
|
<string name="screen_create_room_room_visibility_section_title">"Ορατότητα αίθουσας"</string>
|
||||||
<string name="screen_create_room_title">"Δημιουργία αίθουσας"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Θέμα (προαιρετικό)"</string>
|
<string name="screen_create_room_topic_label">"Θέμα (προαιρετικό)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,14 +8,9 @@
|
||||||
<string name="screen_create_room_public_option_description">"Cualquiera puede encontrar esta sala.
|
<string name="screen_create_room_public_option_description">"Cualquiera puede encontrar esta sala.
|
||||||
Puedes cambiar esto en cualquier momento en los ajustes de la sala."</string>
|
Puedes cambiar esto en cualquier momento en los ajustes de la sala."</string>
|
||||||
<string name="screen_create_room_public_option_title">"Sala pública"</string>
|
<string name="screen_create_room_public_option_title">"Sala pública"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"Cualquiera puede unirse a esta sala"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"Cualquiera"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"Acceso a la sala"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_description">"Cualquiera puede solicitar unirse a la sala, pero un administrador o un moderador tendrá que aceptar la solicitud"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_description">"Cualquiera puede solicitar unirse a la sala, pero un administrador o un moderador tendrá que aceptar la solicitud"</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"Solicitud para unirse"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"Solicitud para unirse"</string>
|
||||||
<string name="screen_create_room_room_address_section_footer">"Para que esta sala sea visible en el directorio de salas públicas, necesitarás una dirección de sala."</string>
|
<string name="screen_create_room_room_address_section_footer">"Para que esta sala sea visible en el directorio de salas públicas, necesitarás una dirección de sala."</string>
|
||||||
<string name="screen_create_room_room_name_label">"Nombre de la sala"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">"Visibilidad de la sala"</string>
|
<string name="screen_create_room_room_visibility_section_title">"Visibilidad de la sala"</string>
|
||||||
<string name="screen_create_room_title">"Crear una sala"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Tema (opcional)"</string>
|
<string name="screen_create_room_topic_label">"Tema (opcional)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,10 @@
|
||||||
<string name="screen_create_room_public_option_description">"Kõik saavad seda jututuba leida.
|
<string name="screen_create_room_public_option_description">"Kõik saavad seda jututuba leida.
|
||||||
Sa võid seda jututoa seadistustest alati muuta."</string>
|
Sa võid seda jututoa seadistustest alati muuta."</string>
|
||||||
<string name="screen_create_room_public_option_title">"Avalik jututuba"</string>
|
<string name="screen_create_room_public_option_title">"Avalik jututuba"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"Kõik võivad selle jututoaga liituda"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"Kõik kasutajad"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"Ligipääs jututoale"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_description">"Kõik võivad paluda selle jututoaga liitumist, kuid peakasutaja või moderaator peavad selle kinnitama"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_description">"Kõik võivad paluda selle jututoaga liitumist, kuid peakasutaja või moderaator peavad selle kinnitama"</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"Küsi võimalust liitumiseks"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"Küsi võimalust liitumiseks"</string>
|
||||||
<string name="screen_create_room_room_address_section_footer">"Selleks, et see jututuba oleks nähtav jututubade avalikus kataloogis, sa vajad jututoa aadressi."</string>
|
<string name="screen_create_room_room_address_section_footer">"Selleks, et see jututuba oleks nähtav jututubade avalikus kataloogis, sa vajad jututoa aadressi."</string>
|
||||||
<string name="screen_create_room_room_address_section_title">"Jututoa aadress"</string>
|
<string name="screen_create_room_room_address_section_title">"Jututoa aadress"</string>
|
||||||
<string name="screen_create_room_room_name_label">"Jututoa nimi"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">"Jututoa nähtavus"</string>
|
<string name="screen_create_room_room_visibility_section_title">"Jututoa nähtavus"</string>
|
||||||
<string name="screen_create_room_title">"Loo jututuba"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Teema (kui soovid lisada)"</string>
|
<string name="screen_create_room_topic_label">"Teema (kui soovid lisada)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,7 @@
|
||||||
<string name="screen_create_room_public_option_description">"Edonork aurki dezake gela hau.
|
<string name="screen_create_room_public_option_description">"Edonork aurki dezake gela hau.
|
||||||
Gelaren ezarpenetan aldatu dezakezu hobespena."</string>
|
Gelaren ezarpenetan aldatu dezakezu hobespena."</string>
|
||||||
<string name="screen_create_room_public_option_title">"Gela publikoa"</string>
|
<string name="screen_create_room_public_option_title">"Gela publikoa"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"Edonor sar daiteke gela honetara"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"Edonork"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"Gelarako sarbidea"</string>
|
|
||||||
<string name="screen_create_room_room_address_section_title">"Gelaren helbidea"</string>
|
<string name="screen_create_room_room_address_section_title">"Gelaren helbidea"</string>
|
||||||
<string name="screen_create_room_room_name_label">"Gelaren izena"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">"Gelaren ikusgarritasuna"</string>
|
<string name="screen_create_room_room_visibility_section_title">"Gelaren ikusgarritasuna"</string>
|
||||||
<string name="screen_create_room_title">"Sortu gela"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Mintzagaia (aukerakoa)"</string>
|
<string name="screen_create_room_topic_label">"Mintzagaia (aukerakoa)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,8 @@
|
||||||
<string name="screen_create_room_public_option_description">"هرکسی میتواند اتاق را بیابد.
|
<string name="screen_create_room_public_option_description">"هرکسی میتواند اتاق را بیابد.
|
||||||
میتوانید بعداً در تظیمات اتاق عوضش کنید."</string>
|
میتوانید بعداً در تظیمات اتاق عوضش کنید."</string>
|
||||||
<string name="screen_create_room_public_option_title">"اتاق عمومی"</string>
|
<string name="screen_create_room_public_option_title">"اتاق عمومی"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"هرکسی میتواند به این اتاق بپیوندد"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"هرکسی"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"دسترسی اتاق"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"درخواست دعوت"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"درخواست دعوت"</string>
|
||||||
<string name="screen_create_room_room_address_section_title">"نشانی اتاق"</string>
|
<string name="screen_create_room_room_address_section_title">"نشانی اتاق"</string>
|
||||||
<string name="screen_create_room_room_name_label">"نام اتاق"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">"نمایانی اتاق"</string>
|
<string name="screen_create_room_room_visibility_section_title">"نمایانی اتاق"</string>
|
||||||
<string name="screen_create_room_title">"ایجاد اتاق"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"موضوع (اختیاری)"</string>
|
<string name="screen_create_room_topic_label">"موضوع (اختیاری)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,10 @@
|
||||||
<string name="screen_create_room_public_option_description">"Kuka tahansa voi löytää tämän huoneen.
|
<string name="screen_create_room_public_option_description">"Kuka tahansa voi löytää tämän huoneen.
|
||||||
Voit muuttaa tämän milloin tahansa huoneen asetuksista."</string>
|
Voit muuttaa tämän milloin tahansa huoneen asetuksista."</string>
|
||||||
<string name="screen_create_room_public_option_title">"Julkinen huone"</string>
|
<string name="screen_create_room_public_option_title">"Julkinen huone"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"Kuka tahansa voi liittyä tähän huoneeseen"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"Kuka tahansa"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"Huoneeseen Pääsy"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_description">"Kuka tahansa voi pyytää saada liittyä huoneeseen, mutta ylläpitäjän tai valvojan on hyväksyttävä pyyntö"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_description">"Kuka tahansa voi pyytää saada liittyä huoneeseen, mutta ylläpitäjän tai valvojan on hyväksyttävä pyyntö"</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"Pyydä liittymistä"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"Pyydä liittymistä"</string>
|
||||||
<string name="screen_create_room_room_address_section_footer">"Jotta tämä huone näkyisi julkisessa huonehakemistossa, tarvitset huoneen osoitteen."</string>
|
<string name="screen_create_room_room_address_section_footer">"Jotta tämä huone näkyisi julkisessa huonehakemistossa, tarvitset huoneen osoitteen."</string>
|
||||||
<string name="screen_create_room_room_address_section_title">"Huoneen osoite"</string>
|
<string name="screen_create_room_room_address_section_title">"Huoneen osoite"</string>
|
||||||
<string name="screen_create_room_room_name_label">"Huoneen nimi"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">"Huoneen näkyvyys"</string>
|
<string name="screen_create_room_room_visibility_section_title">"Huoneen näkyvyys"</string>
|
||||||
<string name="screen_create_room_title">"Luo huone"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Aihe (valinnainen)"</string>
|
<string name="screen_create_room_topic_label">"Aihe (valinnainen)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,10 @@
|
||||||
<string name="screen_create_room_public_option_description">"N’importe qui peut trouver ce salon.
|
<string name="screen_create_room_public_option_description">"N’importe qui peut trouver ce salon.
|
||||||
Vous pouvez modifier cela à tout moment dans les paramètres du salon."</string>
|
Vous pouvez modifier cela à tout moment dans les paramètres du salon."</string>
|
||||||
<string name="screen_create_room_public_option_title">"Salon public"</string>
|
<string name="screen_create_room_public_option_title">"Salon public"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"Tout le monde peut rejoindre ce salon"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"Tout le monde"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"Accès au salon"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_description">"Tout le monde peut demander à rejoindre le salon, mais un administrateur ou un modérateur devra accepter la demande"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_description">"Tout le monde peut demander à rejoindre le salon, mais un administrateur ou un modérateur devra accepter la demande"</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"Demander à rejoindre"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"Demander à rejoindre"</string>
|
||||||
<string name="screen_create_room_room_address_section_footer">"Pour que ce salon soit visible dans le répertoire des salons publics, vous aurez besoin d’une adresse de salon."</string>
|
<string name="screen_create_room_room_address_section_footer">"Pour que ce salon soit visible dans le répertoire des salons publics, vous aurez besoin d’une adresse de salon."</string>
|
||||||
<string name="screen_create_room_room_address_section_title">"Adresse du salon"</string>
|
<string name="screen_create_room_room_address_section_title">"Adresse du salon"</string>
|
||||||
<string name="screen_create_room_room_name_label">"Nom du salon"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">"Visibilité du salon"</string>
|
<string name="screen_create_room_room_visibility_section_title">"Visibilité du salon"</string>
|
||||||
<string name="screen_create_room_title">"Créer un salon"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Sujet (facultatif)"</string>
|
<string name="screen_create_room_topic_label">"Sujet (facultatif)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,10 @@
|
||||||
<string name="screen_create_room_public_option_description">"Svatko može pronaći ovu sobu.
|
<string name="screen_create_room_public_option_description">"Svatko može pronaći ovu sobu.
|
||||||
To možete u svakom trenutku promijeniti u postavkama sobe."</string>
|
To možete u svakom trenutku promijeniti u postavkama sobe."</string>
|
||||||
<string name="screen_create_room_public_option_title">"Javna soba"</string>
|
<string name="screen_create_room_public_option_title">"Javna soba"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"Svatko se može pridružiti ovoj sobi"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"Svatko"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"Pristup sobi"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_description">"Svatko može zatražiti pridruživanje sobi, ali administrator ili moderator morat će prihvatiti zahtjev."</string>
|
<string name="screen_create_room_room_access_section_knocking_option_description">"Svatko može zatražiti pridruživanje sobi, ali administrator ili moderator morat će prihvatiti zahtjev."</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"Zatraži pridruživanje"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"Zatraži pridruživanje"</string>
|
||||||
<string name="screen_create_room_room_address_section_footer">"Da bi ova soba bila vidljiva u javnom direktoriju soba, trebat će vam adresa sobe."</string>
|
<string name="screen_create_room_room_address_section_footer">"Da bi ova soba bila vidljiva u javnom direktoriju soba, trebat će vam adresa sobe."</string>
|
||||||
<string name="screen_create_room_room_address_section_title">"Adresa sobe"</string>
|
<string name="screen_create_room_room_address_section_title">"Adresa sobe"</string>
|
||||||
<string name="screen_create_room_room_name_label">"Naziv sobe"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">"Vidljivost sobe"</string>
|
<string name="screen_create_room_room_visibility_section_title">"Vidljivost sobe"</string>
|
||||||
<string name="screen_create_room_title">"Stvori sobu"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Tema (neobavezno)"</string>
|
<string name="screen_create_room_topic_label">"Tema (neobavezno)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,10 @@
|
||||||
<string name="screen_create_room_public_option_description">"Bárki megtalálhatja ezt a szobát.
|
<string name="screen_create_room_public_option_description">"Bárki megtalálhatja ezt a szobát.
|
||||||
Ezt bármikor módosíthatja a szobabeállításokban."</string>
|
Ezt bármikor módosíthatja a szobabeállításokban."</string>
|
||||||
<string name="screen_create_room_public_option_title">"Nyilvános szoba"</string>
|
<string name="screen_create_room_public_option_title">"Nyilvános szoba"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"Bárki csatlakozhat ehhez a szobához"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"Bárki"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"Szobahozzáférés"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_description">"Bárki kérheti, hogy csatlakozzon a szobához, de egy adminisztrátornak vagy moderátornak el kell fogadnia a kérést"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_description">"Bárki kérheti, hogy csatlakozzon a szobához, de egy adminisztrátornak vagy moderátornak el kell fogadnia a kérést"</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"Csatlakozás kérése"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"Csatlakozás kérése"</string>
|
||||||
<string name="screen_create_room_room_address_section_footer">"Ahhoz, hogy ez a szoba látható legyen a nyilvános szobák címtárában, meg kell adnia a szoba címét."</string>
|
<string name="screen_create_room_room_address_section_footer">"Ahhoz, hogy ez a szoba látható legyen a nyilvános szobák címtárában, meg kell adnia a szoba címét."</string>
|
||||||
<string name="screen_create_room_room_address_section_title">"Szoba címe"</string>
|
<string name="screen_create_room_room_address_section_title">"Szoba címe"</string>
|
||||||
<string name="screen_create_room_room_name_label">"Szoba neve"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">"Szoba láthatósága"</string>
|
<string name="screen_create_room_room_visibility_section_title">"Szoba láthatósága"</string>
|
||||||
<string name="screen_create_room_title">"Szoba létrehozása"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Téma (nem kötelező)"</string>
|
<string name="screen_create_room_topic_label">"Téma (nem kötelező)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,10 @@
|
||||||
<string name="screen_create_room_public_option_description">"Siapa pun dapat mencari ruangan ini.
|
<string name="screen_create_room_public_option_description">"Siapa pun dapat mencari ruangan ini.
|
||||||
Anda dapat mengubah ini kapan pun dalam pengaturan ruangan."</string>
|
Anda dapat mengubah ini kapan pun dalam pengaturan ruangan."</string>
|
||||||
<string name="screen_create_room_public_option_title">"Ruangan publik"</string>
|
<string name="screen_create_room_public_option_title">"Ruangan publik"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"Siapa pun dapat bergabung dengan ruangan ini"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"Siapa pun"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"Akses Ruangan"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_description">"Siapa pun dapat meminta untuk bergabung dengan ruangan tetapi administrator atau moderator harus menerima permintaan tersebut"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_description">"Siapa pun dapat meminta untuk bergabung dengan ruangan tetapi administrator atau moderator harus menerima permintaan tersebut"</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"Minta untuk bergabung"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"Minta untuk bergabung"</string>
|
||||||
<string name="screen_create_room_room_address_section_footer">"Supaya ruangan ini terlihat di direktori ruangan publik, Anda memerlukan alamat ruangan."</string>
|
<string name="screen_create_room_room_address_section_footer">"Supaya ruangan ini terlihat di direktori ruangan publik, Anda memerlukan alamat ruangan."</string>
|
||||||
<string name="screen_create_room_room_address_section_title">"Alamat ruangan"</string>
|
<string name="screen_create_room_room_address_section_title">"Alamat ruangan"</string>
|
||||||
<string name="screen_create_room_room_name_label">"Nama ruangan"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">"Keterlihatan ruangan"</string>
|
<string name="screen_create_room_room_visibility_section_title">"Keterlihatan ruangan"</string>
|
||||||
<string name="screen_create_room_title">"Buat ruangan"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Topik (opsional)"</string>
|
<string name="screen_create_room_topic_label">"Topik (opsional)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,10 @@
|
||||||
<string name="screen_create_room_public_option_description">"Chiunque può trovare questa stanza.
|
<string name="screen_create_room_public_option_description">"Chiunque può trovare questa stanza.
|
||||||
Puoi modificarlo in qualsiasi momento nelle impostazioni della stanza."</string>
|
Puoi modificarlo in qualsiasi momento nelle impostazioni della stanza."</string>
|
||||||
<string name="screen_create_room_public_option_title">"Stanza pubblica"</string>
|
<string name="screen_create_room_public_option_title">"Stanza pubblica"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"Chiunque può entrare in questa stanza"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"Chiunque"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"Accesso alla stanza"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_description">"Chiunque può chiedere di entrare nella stanza, ma un amministratore o un moderatore dovrà accettare la richiesta"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_description">"Chiunque può chiedere di entrare nella stanza, ma un amministratore o un moderatore dovrà accettare la richiesta"</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"Chiedi di entrare"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"Chiedi di entrare"</string>
|
||||||
<string name="screen_create_room_room_address_section_footer">"Affinché questa stanza sia visibile nell\'elenco delle stanze pubbliche, è necessario un indirizzo della stanza."</string>
|
<string name="screen_create_room_room_address_section_footer">"Affinché questa stanza sia visibile nell\'elenco delle stanze pubbliche, è necessario un indirizzo della stanza."</string>
|
||||||
<string name="screen_create_room_room_address_section_title">"Indirizzo della stanza"</string>
|
<string name="screen_create_room_room_address_section_title">"Indirizzo della stanza"</string>
|
||||||
<string name="screen_create_room_room_name_label">"Nome stanza"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">"Visibilità della stanza"</string>
|
<string name="screen_create_room_room_visibility_section_title">"Visibilità della stanza"</string>
|
||||||
<string name="screen_create_room_title">"Crea una stanza"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Argomento (facoltativo)"</string>
|
<string name="screen_create_room_topic_label">"Argomento (facoltativo)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,5 @@
|
||||||
<string name="screen_create_room_private_option_title">"კერძო ოთახი"</string>
|
<string name="screen_create_room_private_option_title">"კერძო ოთახი"</string>
|
||||||
<string name="screen_create_room_public_option_description">"ყველას ამ ოთახის მოძებნა შეუძლია.
|
<string name="screen_create_room_public_option_description">"ყველას ამ ოთახის მოძებნა შეუძლია.
|
||||||
თქვენ ნებისმიერ დროს შეგიძლიათ ამის შეცვლა ოთახის პარამეტრებში."</string>
|
თქვენ ნებისმიერ დროს შეგიძლიათ ამის შეცვლა ოთახის პარამეტრებში."</string>
|
||||||
<string name="screen_create_room_room_name_label">"ოთახის სახელი"</string>
|
|
||||||
<string name="screen_create_room_title">"ოთახის შექმნა"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"თემა (სურვილისამებრ)"</string>
|
<string name="screen_create_room_topic_label">"თემა (სურვილისამებრ)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,14 +8,9 @@
|
||||||
<string name="screen_create_room_public_option_description">"누구나 이 방을 찾을 수 있습니다.
|
<string name="screen_create_room_public_option_description">"누구나 이 방을 찾을 수 있습니다.
|
||||||
방 설정에서 언제든지 변경할 수 있습니다."</string>
|
방 설정에서 언제든지 변경할 수 있습니다."</string>
|
||||||
<string name="screen_create_room_public_option_title">"공개 방"</string>
|
<string name="screen_create_room_public_option_title">"공개 방"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"누구나 이 방에 참여할 수 있습니다."</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"누구나"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"방 액세스"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_description">"누구나 방에 참여 요청을 할 수 있지만, 관리자나 운영자가 요청을 수락해야 합니다."</string>
|
<string name="screen_create_room_room_access_section_knocking_option_description">"누구나 방에 참여 요청을 할 수 있지만, 관리자나 운영자가 요청을 수락해야 합니다."</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"참가 요청"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"참가 요청"</string>
|
||||||
<string name="screen_create_room_room_address_section_footer">"이 방이 공개 방 디렉토리에 표시되려면 방 주소가 필요합니다."</string>
|
<string name="screen_create_room_room_address_section_footer">"이 방이 공개 방 디렉토리에 표시되려면 방 주소가 필요합니다."</string>
|
||||||
<string name="screen_create_room_room_name_label">"방 이름"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">"방 표시 여부"</string>
|
<string name="screen_create_room_room_visibility_section_title">"방 표시 여부"</string>
|
||||||
<string name="screen_create_room_title">"방 만들기"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"주제 (선택)"</string>
|
<string name="screen_create_room_topic_label">"주제 (선택)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,5 @@
|
||||||
<string name="screen_create_room_private_option_title">"Privatus kambarys"</string>
|
<string name="screen_create_room_private_option_title">"Privatus kambarys"</string>
|
||||||
<string name="screen_create_room_public_option_description">"Bet kas gali rasti šį kambarį.
|
<string name="screen_create_room_public_option_description">"Bet kas gali rasti šį kambarį.
|
||||||
Tai galite bet kada pakeisti kambario nustatymuose."</string>
|
Tai galite bet kada pakeisti kambario nustatymuose."</string>
|
||||||
<string name="screen_create_room_room_name_label">"Kambario pavadinimas"</string>
|
|
||||||
<string name="screen_create_room_title">"Kurti kambarį"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Tema (nebūtina)"</string>
|
<string name="screen_create_room_topic_label">"Tema (nebūtina)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,10 @@
|
||||||
<string name="screen_create_room_public_option_description">"Alle kan finne dette rommet.
|
<string name="screen_create_room_public_option_description">"Alle kan finne dette rommet.
|
||||||
Du kan endre dette når som helst i rominnstillingene."</string>
|
Du kan endre dette når som helst i rominnstillingene."</string>
|
||||||
<string name="screen_create_room_public_option_title">"Offentlig rom"</string>
|
<string name="screen_create_room_public_option_title">"Offentlig rom"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"Alle kan bli med i dette rommet"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"Alle"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"Tilgang til rom"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_description">"Alle kan be om å få bli med i rommet, men en administrator eller moderator må godta forespørselen"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_description">"Alle kan be om å få bli med i rommet, men en administrator eller moderator må godta forespørselen"</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"Be om å bli med"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"Be om å bli med"</string>
|
||||||
<string name="screen_create_room_room_address_section_footer">"For at dette rommet skal være synlig i den offentlige romkatalogen, trenger du en romadresse."</string>
|
<string name="screen_create_room_room_address_section_footer">"For at dette rommet skal være synlig i den offentlige romkatalogen, trenger du en romadresse."</string>
|
||||||
<string name="screen_create_room_room_address_section_title">"Romadresse"</string>
|
<string name="screen_create_room_room_address_section_title">"Romadresse"</string>
|
||||||
<string name="screen_create_room_room_name_label">"Romnavn"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">"Romsynlighet"</string>
|
<string name="screen_create_room_room_visibility_section_title">"Romsynlighet"</string>
|
||||||
<string name="screen_create_room_title">"Opprett et rom"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Emne (valgfritt)"</string>
|
<string name="screen_create_room_topic_label">"Emne (valgfritt)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,7 @@
|
||||||
<string name="screen_create_room_public_option_description">"Iedereen kan deze kamer vinden.
|
<string name="screen_create_room_public_option_description">"Iedereen kan deze kamer vinden.
|
||||||
Je kunt dit op elk gewenst moment wijzigen in de kamerinstellingen."</string>
|
Je kunt dit op elk gewenst moment wijzigen in de kamerinstellingen."</string>
|
||||||
<string name="screen_create_room_public_option_title">"Openbare kamer"</string>
|
<string name="screen_create_room_public_option_title">"Openbare kamer"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"Iedereen kan toetreden tot deze kamer"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"Iedereen"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"Toegang tot de kamer"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_description">"Iedereen kan vragen om toe te treden tot de kamer, maar een beheerder of moderator moet het verzoek accepteren"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_description">"Iedereen kan vragen om toe te treden tot de kamer, maar een beheerder of moderator moet het verzoek accepteren"</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"Vraag om toe te treden"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"Vraag om toe te treden"</string>
|
||||||
<string name="screen_create_room_room_name_label">"Naam van de kamer"</string>
|
|
||||||
<string name="screen_create_room_title">"Creëer een kamer"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Onderwerp (optioneel)"</string>
|
<string name="screen_create_room_topic_label">"Onderwerp (optioneel)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,10 @@
|
||||||
<string name="screen_create_room_public_option_description">"Każdy może znaleźć ten pokój.
|
<string name="screen_create_room_public_option_description">"Każdy może znaleźć ten pokój.
|
||||||
Możesz to zmienić w ustawieniach pokoju."</string>
|
Możesz to zmienić w ustawieniach pokoju."</string>
|
||||||
<string name="screen_create_room_public_option_title">"Pokój publiczny"</string>
|
<string name="screen_create_room_public_option_title">"Pokój publiczny"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"Każdy może dołączyć do tego pokoju"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"Wszyscy"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"Dostęp do pokoju"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_description">"Każdy może poprosić o dołączenie do pokoju, ale administrator lub moderator będzie musiał zatwierdzić prośbę"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_description">"Każdy może poprosić o dołączenie do pokoju, ale administrator lub moderator będzie musiał zatwierdzić prośbę"</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"Poproś o dołączenie"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"Poproś o dołączenie"</string>
|
||||||
<string name="screen_create_room_room_address_section_footer">"Aby ten pokój był widoczny w katalogu pomieszczeń publicznych, będziesz potrzebował adres pokoju."</string>
|
<string name="screen_create_room_room_address_section_footer">"Aby ten pokój był widoczny w katalogu pomieszczeń publicznych, będziesz potrzebował adres pokoju."</string>
|
||||||
<string name="screen_create_room_room_address_section_title">"Adres pokoju"</string>
|
<string name="screen_create_room_room_address_section_title">"Adres pokoju"</string>
|
||||||
<string name="screen_create_room_room_name_label">"Nazwa pokoju"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">"Widoczność pomieszczenia"</string>
|
<string name="screen_create_room_room_visibility_section_title">"Widoczność pomieszczenia"</string>
|
||||||
<string name="screen_create_room_title">"Utwórz pokój"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Temat (opcjonalnie)"</string>
|
<string name="screen_create_room_topic_label">"Temat (opcjonalnie)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,10 @@
|
||||||
<string name="screen_create_room_public_option_description">"Qualquer um pode encontrar esta sala.
|
<string name="screen_create_room_public_option_description">"Qualquer um pode encontrar esta sala.
|
||||||
Você pode mudar isso a qualquer momento nas configurações da sala."</string>
|
Você pode mudar isso a qualquer momento nas configurações da sala."</string>
|
||||||
<string name="screen_create_room_public_option_title">"Sala pública"</string>
|
<string name="screen_create_room_public_option_title">"Sala pública"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"Qualquer pessoa pode entrar nesta sala"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"Qualquer pessoa"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"Acesso à sala"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_description">"Qualquer pessoa pode pedir para entrar na sala, mas um administrador ou moderador terá de aceitar a solicitação"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_description">"Qualquer pessoa pode pedir para entrar na sala, mas um administrador ou moderador terá de aceitar a solicitação"</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"Pedir para entrar"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"Pedir para entrar"</string>
|
||||||
<string name="screen_create_room_room_address_section_footer">"Para que esta sala fique visível no diretório público de salas, você precisará de um endereço de sala."</string>
|
<string name="screen_create_room_room_address_section_footer">"Para que esta sala fique visível no diretório público de salas, você precisará de um endereço de sala."</string>
|
||||||
<string name="screen_create_room_room_address_section_title">"Endereço da sala"</string>
|
<string name="screen_create_room_room_address_section_title">"Endereço da sala"</string>
|
||||||
<string name="screen_create_room_room_name_label">"Nome da sala"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">"Visibilidade da sala"</string>
|
<string name="screen_create_room_room_visibility_section_title">"Visibilidade da sala"</string>
|
||||||
<string name="screen_create_room_title">"Criar uma sala"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Tópico (opcional)"</string>
|
<string name="screen_create_room_topic_label">"Tópico (opcional)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,10 @@
|
||||||
<string name="screen_create_room_public_option_description">"Qualquer um pode encontrar esta sala.
|
<string name="screen_create_room_public_option_description">"Qualquer um pode encontrar esta sala.
|
||||||
Pode alterar esta opção nas definições da sala."</string>
|
Pode alterar esta opção nas definições da sala."</string>
|
||||||
<string name="screen_create_room_public_option_title">"Sala pública"</string>
|
<string name="screen_create_room_public_option_title">"Sala pública"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"Qualquer pessoa pode entrar nesta sala"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"Qualquer pessoa"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"Acesso à sala"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_description">"Qualquer pessoa pode pedir para entrar na sala, mas um administrador ou um moderador terá de aceitar o pedido"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_description">"Qualquer pessoa pode pedir para entrar na sala, mas um administrador ou um moderador terá de aceitar o pedido"</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"Pedir para participar"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"Pedir para participar"</string>
|
||||||
<string name="screen_create_room_room_address_section_footer">"Para que esta sala seja visível no diretório público de salas, precisas de um endereço de sala."</string>
|
<string name="screen_create_room_room_address_section_footer">"Para que esta sala seja visível no diretório público de salas, precisas de um endereço de sala."</string>
|
||||||
<string name="screen_create_room_room_address_section_title">"Endereço da sala"</string>
|
<string name="screen_create_room_room_address_section_title">"Endereço da sala"</string>
|
||||||
<string name="screen_create_room_room_name_label">"Nome da sala"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">"Visibilidade da sala"</string>
|
<string name="screen_create_room_room_visibility_section_title">"Visibilidade da sala"</string>
|
||||||
<string name="screen_create_room_title">"Criar uma sala"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Descrição (opcional)"</string>
|
<string name="screen_create_room_topic_label">"Descrição (opcional)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,10 @@
|
||||||
<string name="screen_create_room_public_option_description">"Oricine poate găsi această cameră.
|
<string name="screen_create_room_public_option_description">"Oricine poate găsi această cameră.
|
||||||
Puteți modifica acest lucru oricând în setări."</string>
|
Puteți modifica acest lucru oricând în setări."</string>
|
||||||
<string name="screen_create_room_public_option_title">"Cameră publică"</string>
|
<string name="screen_create_room_public_option_title">"Cameră publică"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"Oricine se poate alătura acestei camere"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"Oricine"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"Acces la cameră"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_description">"Oricine poate cere să se alăture camerei, dar un administrator sau un moderator va trebui să accepte cererea"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_description">"Oricine poate cere să se alăture camerei, dar un administrator sau un moderator va trebui să accepte cererea"</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"Cereți să vă alăturați"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"Cereți să vă alăturați"</string>
|
||||||
<string name="screen_create_room_room_address_section_footer">"Pentru ca această cameră să fie vizibilă în directorul de camere publice, veți avea nevoie de o adresă de cameră."</string>
|
<string name="screen_create_room_room_address_section_footer">"Pentru ca această cameră să fie vizibilă în directorul de camere publice, veți avea nevoie de o adresă de cameră."</string>
|
||||||
<string name="screen_create_room_room_address_section_title">"Adresa camerei"</string>
|
<string name="screen_create_room_room_address_section_title">"Adresa camerei"</string>
|
||||||
<string name="screen_create_room_room_name_label">"Numele camerei"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">"Vizibilitatea camerei"</string>
|
<string name="screen_create_room_room_visibility_section_title">"Vizibilitatea camerei"</string>
|
||||||
<string name="screen_create_room_title">"Creați o cameră"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Subiect (opțional)"</string>
|
<string name="screen_create_room_topic_label">"Subiect (opțional)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,10 @@
|
||||||
<string name="screen_create_room_public_option_description">"Любой желающий может найти эту комнату.
|
<string name="screen_create_room_public_option_description">"Любой желающий может найти эту комнату.
|
||||||
Вы можете изменить это в любое время в настройках комнаты."</string>
|
Вы можете изменить это в любое время в настройках комнаты."</string>
|
||||||
<string name="screen_create_room_public_option_title">"Общедоступная комната"</string>
|
<string name="screen_create_room_public_option_title">"Общедоступная комната"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"Любой желающий может присоединиться к этой комнате"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"Любой"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"Доступ в комнату"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_description">"Любой желающий может подать заявку на присоединение к комнате, но администратор или модератор должен будет принять запрос."</string>
|
<string name="screen_create_room_room_access_section_knocking_option_description">"Любой желающий может подать заявку на присоединение к комнате, но администратор или модератор должен будет принять запрос."</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"Попросить присоединиться"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"Попросить присоединиться"</string>
|
||||||
<string name="screen_create_room_room_address_section_footer">"Чтобы эта комната была видна в каталоге общедоступных, вам необходим ее адрес"</string>
|
<string name="screen_create_room_room_address_section_footer">"Чтобы эта комната была видна в каталоге общедоступных, вам необходим ее адрес"</string>
|
||||||
<string name="screen_create_room_room_address_section_title">"Адрес комнаты"</string>
|
<string name="screen_create_room_room_address_section_title">"Адрес комнаты"</string>
|
||||||
<string name="screen_create_room_room_name_label">"Название комнаты"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">"Видимость комнаты"</string>
|
<string name="screen_create_room_room_visibility_section_title">"Видимость комнаты"</string>
|
||||||
<string name="screen_create_room_title">"Создать комнату"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Тема (необязательно)"</string>
|
<string name="screen_create_room_topic_label">"Тема (необязательно)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,10 @@
|
||||||
<string name="screen_create_room_public_option_description">"Túto miestnosť môže nájsť ktokoľvek.
|
<string name="screen_create_room_public_option_description">"Túto miestnosť môže nájsť ktokoľvek.
|
||||||
Môžete to kedykoľvek zmeniť v nastaveniach miestnosti."</string>
|
Môžete to kedykoľvek zmeniť v nastaveniach miestnosti."</string>
|
||||||
<string name="screen_create_room_public_option_title">"Verejná miestnosť"</string>
|
<string name="screen_create_room_public_option_title">"Verejná miestnosť"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"Do tejto miestnosti sa môže pripojiť ktokoľvek"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"Ktokoľvek"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"Prístup do miestnosti"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_description">"Ktokoľvek môže požiadať o pripojenie sa k miestnosti, ale administrátor alebo moderátor bude musieť žiadosť schváliť"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_description">"Ktokoľvek môže požiadať o pripojenie sa k miestnosti, ale administrátor alebo moderátor bude musieť žiadosť schváliť"</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"Požiadať o pripojenie"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"Požiadať o pripojenie"</string>
|
||||||
<string name="screen_create_room_room_address_section_footer">"Aby bola táto miestnosť viditeľná v adresári verejných miestností, budete potrebovať adresu miestnosti."</string>
|
<string name="screen_create_room_room_address_section_footer">"Aby bola táto miestnosť viditeľná v adresári verejných miestností, budete potrebovať adresu miestnosti."</string>
|
||||||
<string name="screen_create_room_room_address_section_title">"Adresa miestnosti"</string>
|
<string name="screen_create_room_room_address_section_title">"Adresa miestnosti"</string>
|
||||||
<string name="screen_create_room_room_name_label">"Názov miestnosti"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">"Viditeľnosť miestnosti"</string>
|
<string name="screen_create_room_room_visibility_section_title">"Viditeľnosť miestnosti"</string>
|
||||||
<string name="screen_create_room_title">"Vytvoriť miestnosť"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Téma (voliteľné)"</string>
|
<string name="screen_create_room_topic_label">"Téma (voliteľné)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,10 @@
|
||||||
<string name="screen_create_room_public_option_description">"Vem som helst kan hitta det här rummet.
|
<string name="screen_create_room_public_option_description">"Vem som helst kan hitta det här rummet.
|
||||||
Du kan ändra detta när som helst i rumsinställningarna."</string>
|
Du kan ändra detta när som helst i rumsinställningarna."</string>
|
||||||
<string name="screen_create_room_public_option_title">"Offentligt rum"</string>
|
<string name="screen_create_room_public_option_title">"Offentligt rum"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"Vem som helst kan gå med i det här rummet"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"Vem som helst"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"Rumsåtkomst"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_description">"Vem som helst kan be om att gå med i rummet men en administratör eller en moderator måste acceptera begäran"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_description">"Vem som helst kan be om att gå med i rummet men en administratör eller en moderator måste acceptera begäran"</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"Be om att gå med"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"Be om att gå med"</string>
|
||||||
<string name="screen_create_room_room_address_section_footer">"För att detta rum ska vara synligt i den allmänna rumskatalogen behöver du en rumsadress."</string>
|
<string name="screen_create_room_room_address_section_footer">"För att detta rum ska vara synligt i den allmänna rumskatalogen behöver du en rumsadress."</string>
|
||||||
<string name="screen_create_room_room_address_section_title">"Rumsadress"</string>
|
<string name="screen_create_room_room_address_section_title">"Rumsadress"</string>
|
||||||
<string name="screen_create_room_room_name_label">"Rumsnamn"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">"Rumssynlighet"</string>
|
<string name="screen_create_room_room_visibility_section_title">"Rumssynlighet"</string>
|
||||||
<string name="screen_create_room_title">"Skapa ett rum"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Ämne (valfritt)"</string>
|
<string name="screen_create_room_topic_label">"Ämne (valfritt)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,10 @@
|
||||||
<string name="screen_create_room_public_option_description">"Bu odayı herkes bulabilir.
|
<string name="screen_create_room_public_option_description">"Bu odayı herkes bulabilir.
|
||||||
Bunu istediğiniz zaman oda ayarlarından değiştirebilirsiniz."</string>
|
Bunu istediğiniz zaman oda ayarlarından değiştirebilirsiniz."</string>
|
||||||
<string name="screen_create_room_public_option_title">"Herkese açık oda"</string>
|
<string name="screen_create_room_public_option_title">"Herkese açık oda"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"Bu odaya herkes katılabilir"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"Herkes"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"Oda Erişimi"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_description">"Herkes odaya katılmayı isteyebilir ancak bir yönetici veya moderatörün isteği kabul etmesi gerekecektir"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_description">"Herkes odaya katılmayı isteyebilir ancak bir yönetici veya moderatörün isteği kabul etmesi gerekecektir"</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"Katılmak için sor"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"Katılmak için sor"</string>
|
||||||
<string name="screen_create_room_room_address_section_footer">"Bu odanın genel oda dizininde görünür olması için bir oda adresine ihtiyacınız olacaktır."</string>
|
<string name="screen_create_room_room_address_section_footer">"Bu odanın genel oda dizininde görünür olması için bir oda adresine ihtiyacınız olacaktır."</string>
|
||||||
<string name="screen_create_room_room_address_section_title">"Oda adresi"</string>
|
<string name="screen_create_room_room_address_section_title">"Oda adresi"</string>
|
||||||
<string name="screen_create_room_room_name_label">"Oda adı"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">"Oda görünürlüğü"</string>
|
<string name="screen_create_room_room_visibility_section_title">"Oda görünürlüğü"</string>
|
||||||
<string name="screen_create_room_title">"Bir oda oluştur"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Konu (isteğe bağlı)"</string>
|
<string name="screen_create_room_topic_label">"Konu (isteğe bağlı)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,10 @@
|
||||||
<string name="screen_create_room_public_option_description">"Будь-хто може знайти цю кімнату.
|
<string name="screen_create_room_public_option_description">"Будь-хто може знайти цю кімнату.
|
||||||
Ви можете змінити це в будь-який час у налаштуваннях кімнати."</string>
|
Ви можете змінити це в будь-який час у налаштуваннях кімнати."</string>
|
||||||
<string name="screen_create_room_public_option_title">"Загальнодоступна кімната"</string>
|
<string name="screen_create_room_public_option_title">"Загальнодоступна кімната"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"Будь-хто може приєднатися до цієї кімнати"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"Кожний"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"Доступ до кімнати"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_description">"Будь-хто може попросити приєднатися до кімнати, але адміністратор або модератор повинен буде прийняти запит"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_description">"Будь-хто може попросити приєднатися до кімнати, але адміністратор або модератор повинен буде прийняти запит"</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"Запросити приєднатися"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"Запросити приєднатися"</string>
|
||||||
<string name="screen_create_room_room_address_section_footer">"Щоб цю кімнату було видно в каталозі загальнодоступних кімнат, вам знадобиться її адреса."</string>
|
<string name="screen_create_room_room_address_section_footer">"Щоб цю кімнату було видно в каталозі загальнодоступних кімнат, вам знадобиться її адреса."</string>
|
||||||
<string name="screen_create_room_room_address_section_title">"Адреса кімнати"</string>
|
<string name="screen_create_room_room_address_section_title">"Адреса кімнати"</string>
|
||||||
<string name="screen_create_room_room_name_label">"Назва кімнати"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">"Видимість кімнати"</string>
|
<string name="screen_create_room_room_visibility_section_title">"Видимість кімнати"</string>
|
||||||
<string name="screen_create_room_title">"Створити кімнату"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Тема (необов\'язково)"</string>
|
<string name="screen_create_room_topic_label">"Тема (необов\'язково)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,5 @@
|
||||||
<string name="screen_create_room_public_option_description">"کوئی بھی یہ کمرہ ڈھونڈ سکتا ہے۔
|
<string name="screen_create_room_public_option_description">"کوئی بھی یہ کمرہ ڈھونڈ سکتا ہے۔
|
||||||
آپ اسے کمرے کی ترتیبات میں کسی بھی وقت تبدیل کرسکتے ہیں۔"</string>
|
آپ اسے کمرے کی ترتیبات میں کسی بھی وقت تبدیل کرسکتے ہیں۔"</string>
|
||||||
<string name="screen_create_room_public_option_title">"عوامی کمرہ"</string>
|
<string name="screen_create_room_public_option_title">"عوامی کمرہ"</string>
|
||||||
<string name="screen_create_room_room_name_label">"کمرے کا نام"</string>
|
|
||||||
<string name="screen_create_room_title">"ایک کمرہ بنائیں"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"موضوع (اختیاری)"</string>
|
<string name="screen_create_room_topic_label">"موضوع (اختیاری)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,14 +8,9 @@
|
||||||
<string name="screen_create_room_public_option_description">"Bu xonani har kim topishi mumkin.
|
<string name="screen_create_room_public_option_description">"Bu xonani har kim topishi mumkin.
|
||||||
Buni xona sozlamalaridan istalgan vaqtda oʻzgartirishingiz mumkin."</string>
|
Buni xona sozlamalaridan istalgan vaqtda oʻzgartirishingiz mumkin."</string>
|
||||||
<string name="screen_create_room_public_option_title">"Jamoat xonasi"</string>
|
<string name="screen_create_room_public_option_title">"Jamoat xonasi"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"Bu xonaga istalgan kishi qo‘shilishi mumkin"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"Har kim"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"Xonaga kirish"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_description">"Xonaga qo‘shilishni istalgan kishi so‘rashi mumkin, lekin administrator yoki moderator so‘rovni qabul qilishi kerak"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_description">"Xonaga qo‘shilishni istalgan kishi so‘rashi mumkin, lekin administrator yoki moderator so‘rovni qabul qilishi kerak"</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"Qo‘shilishni so‘rang"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"Qo‘shilishni so‘rang"</string>
|
||||||
<string name="screen_create_room_room_address_section_footer">"Ushbu xona ommaviy xonalar ro‘yxatida ko‘rinishi uchun sizga xona manzili kerak bo‘ladi."</string>
|
<string name="screen_create_room_room_address_section_footer">"Ushbu xona ommaviy xonalar ro‘yxatida ko‘rinishi uchun sizga xona manzili kerak bo‘ladi."</string>
|
||||||
<string name="screen_create_room_room_name_label">"Xona nomi"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">"Xonaning ko‘rinishi"</string>
|
<string name="screen_create_room_room_visibility_section_title">"Xonaning ko‘rinishi"</string>
|
||||||
<string name="screen_create_room_title">"Xonani yaratish"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Mavzu (ixtiyoriy)"</string>
|
<string name="screen_create_room_topic_label">"Mavzu (ixtiyoriy)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,10 @@
|
||||||
<string name="screen_create_room_public_option_description">"任何人都可以找到此聊天室。
|
<string name="screen_create_room_public_option_description">"任何人都可以找到此聊天室。
|
||||||
您隨時都可以在聊天室設定中變更此設定。"</string>
|
您隨時都可以在聊天室設定中變更此設定。"</string>
|
||||||
<string name="screen_create_room_public_option_title">"公開的聊天室"</string>
|
<string name="screen_create_room_public_option_title">"公開的聊天室"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"任何人都可以加入此聊天室"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"任何人"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"聊天室存取權"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_description">"任何人都可以要求加入聊天室,但管理員或版主必須接受該請求"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_description">"任何人都可以要求加入聊天室,但管理員或版主必須接受該請求"</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"要求加入"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"要求加入"</string>
|
||||||
<string name="screen_create_room_room_address_section_footer">"為了讓此聊天室在公開聊天室目錄中可見,您需要聊天室地址。"</string>
|
<string name="screen_create_room_room_address_section_footer">"為了讓此聊天室在公開聊天室目錄中可見,您需要聊天室地址。"</string>
|
||||||
<string name="screen_create_room_room_address_section_title">"聊天室地址"</string>
|
<string name="screen_create_room_room_address_section_title">"聊天室地址"</string>
|
||||||
<string name="screen_create_room_room_name_label">"聊天室名稱"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">"聊天室能見度"</string>
|
<string name="screen_create_room_room_visibility_section_title">"聊天室能見度"</string>
|
||||||
<string name="screen_create_room_title">"建立聊天室"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"主題(非必填)"</string>
|
<string name="screen_create_room_topic_label">"主題(非必填)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,10 @@
|
||||||
<string name="screen_create_room_public_option_description">"任何人都能找到此聊天室。
|
<string name="screen_create_room_public_option_description">"任何人都能找到此聊天室。
|
||||||
你可以随时在聊天室设置中更改。"</string>
|
你可以随时在聊天室设置中更改。"</string>
|
||||||
<string name="screen_create_room_public_option_title">"公共聊天室"</string>
|
<string name="screen_create_room_public_option_title">"公共聊天室"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"任何人都可以加入此房间"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"任何人"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_header">"房间访问权限"</string>
|
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_description">"任何人都可以请求加入房间,但必须由管理员或审核人接受"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_description">"任何人都可以请求加入房间,但必须由管理员或审核人接受"</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"请求加入"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"请求加入"</string>
|
||||||
<string name="screen_create_room_room_address_section_footer">"要使该房间在公开房间目录中可见,您需要一个房间地址。"</string>
|
<string name="screen_create_room_room_address_section_footer">"要使该房间在公开房间目录中可见,您需要一个房间地址。"</string>
|
||||||
<string name="screen_create_room_room_address_section_title">"房间地址"</string>
|
<string name="screen_create_room_room_address_section_title">"房间地址"</string>
|
||||||
<string name="screen_create_room_room_name_label">"聊天室名称"</string>
|
|
||||||
<string name="screen_create_room_room_visibility_section_title">"房间可见性"</string>
|
<string name="screen_create_room_room_visibility_section_title">"房间可见性"</string>
|
||||||
<string name="screen_create_room_title">"创建聊天室"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"主题(可选)"</string>
|
<string name="screen_create_room_topic_label">"主题(可选)"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -3,20 +3,26 @@
|
||||||
<string name="screen_create_room_action_create_room">"New room"</string>
|
<string name="screen_create_room_action_create_room">"New room"</string>
|
||||||
<string name="screen_create_room_add_people_title">"Invite people"</string>
|
<string name="screen_create_room_add_people_title">"Invite people"</string>
|
||||||
<string name="screen_create_room_error_creating_room">"An error occurred when creating the room"</string>
|
<string name="screen_create_room_error_creating_room">"An error occurred when creating the room"</string>
|
||||||
<string name="screen_create_room_private_option_description">"Only people invited can access this room. All messages are end-to-end encrypted."</string>
|
<string name="screen_create_room_error_creating_space">"The space could not be created because of an unknown error. Try again later."</string>
|
||||||
<string name="screen_create_room_private_option_title">"Private room"</string>
|
<string name="screen_create_room_name_placeholder">"Add name…"</string>
|
||||||
|
<string name="screen_create_room_new_room_title">"New room"</string>
|
||||||
|
<string name="screen_create_room_new_space_title">"New space"</string>
|
||||||
|
<string name="screen_create_room_private_option_description">"Only people invited can join."</string>
|
||||||
|
<string name="screen_create_room_private_option_title">"Private"</string>
|
||||||
<string name="screen_create_room_public_option_description">"Anyone can find this room.
|
<string name="screen_create_room_public_option_description">"Anyone can find this room.
|
||||||
You can change this anytime in room settings."</string>
|
You can change this anytime in room settings."</string>
|
||||||
<string name="screen_create_room_public_option_title">"Public room"</string>
|
<string name="screen_create_room_public_option_short_description">"Anyone can join."</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_description">"Anyone can join this room"</string>
|
<string name="screen_create_room_public_option_title">"Public"</string>
|
||||||
<string name="screen_create_room_room_access_section_anyone_option_title">"Anyone"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_description">"Anyone can ask to join but an administrator or a moderator must accept the request."</string>
|
||||||
<string name="screen_create_room_room_access_section_header">"Room Access"</string>
|
<string name="screen_create_room_room_access_section_knocking_option_title">"Allow ask to join"</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_description">"Anyone can ask to join the room but an administrator or a moderator will have to accept the request"</string>
|
<string name="screen_create_room_room_access_section_private_option_description">"Only people invited can join."</string>
|
||||||
<string name="screen_create_room_room_access_section_knocking_option_title">"Ask to join"</string>
|
<string name="screen_create_room_room_access_section_private_option_title">"Private"</string>
|
||||||
<string name="screen_create_room_room_address_section_footer">"In order for this room to be visible in the public room directory, you will need a room address."</string>
|
<string name="screen_create_room_room_access_section_public_option_description">"Anyone can join."</string>
|
||||||
<string name="screen_create_room_room_address_section_title">"Room address"</string>
|
<string name="screen_create_room_room_access_section_public_option_title">"Public"</string>
|
||||||
<string name="screen_create_room_room_name_label">"Room name"</string>
|
<string name="screen_create_room_room_access_section_title">"Who has access"</string>
|
||||||
|
<string name="screen_create_room_room_address_section_footer">"You’ll need an address in order to make it visible in the public directory."</string>
|
||||||
|
<string name="screen_create_room_room_address_section_title">"Address"</string>
|
||||||
<string name="screen_create_room_room_visibility_section_title">"Room visibility"</string>
|
<string name="screen_create_room_room_visibility_section_title">"Room visibility"</string>
|
||||||
<string name="screen_create_room_title">"Create a room"</string>
|
|
||||||
<string name="screen_create_room_topic_label">"Topic (optional)"</string>
|
<string name="screen_create_room_topic_label">"Topic (optional)"</string>
|
||||||
|
<string name="screen_create_room_topic_placeholder">"Add description…"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ class DefaultCreateRoomEntryPointTest {
|
||||||
override fun onRoomCreated(roomId: RoomId) = lambdaError()
|
override fun onRoomCreated(roomId: RoomId) = lambdaError()
|
||||||
}
|
}
|
||||||
val result = entryPoint.createNode(
|
val result = entryPoint.createNode(
|
||||||
|
isSpace = false,
|
||||||
parentNode = parentNode,
|
parentNode = parentNode,
|
||||||
buildContext = BuildContext.root(null),
|
buildContext = BuildContext.root(null),
|
||||||
callback = callback,
|
callback = callback,
|
||||||
|
|
|
||||||
|
|
@ -380,6 +380,7 @@ class ConfigureRoomPresenterTest {
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun createConfigureRoomPresenter(
|
private fun createConfigureRoomPresenter(
|
||||||
|
isSpace: Boolean = false,
|
||||||
roomAliasHelper: RoomAliasHelper = FakeRoomAliasHelper(),
|
roomAliasHelper: RoomAliasHelper = FakeRoomAliasHelper(),
|
||||||
dataStore: CreateRoomConfigStore = CreateRoomConfigStore(roomAliasHelper),
|
dataStore: CreateRoomConfigStore = CreateRoomConfigStore(roomAliasHelper),
|
||||||
matrixClient: MatrixClient = createMatrixClient(),
|
matrixClient: MatrixClient = createMatrixClient(),
|
||||||
|
|
@ -390,6 +391,7 @@ class ConfigureRoomPresenterTest {
|
||||||
isKnockFeatureEnabled: Boolean = true,
|
isKnockFeatureEnabled: Boolean = true,
|
||||||
mediaOptimizationConfigProvider: FakeMediaOptimizationConfigProvider = FakeMediaOptimizationConfigProvider(),
|
mediaOptimizationConfigProvider: FakeMediaOptimizationConfigProvider = FakeMediaOptimizationConfigProvider(),
|
||||||
) = ConfigureRoomPresenter(
|
) = ConfigureRoomPresenter(
|
||||||
|
isSpace = isSpace,
|
||||||
dataStore = dataStore,
|
dataStore = dataStore,
|
||||||
matrixClient = matrixClient,
|
matrixClient = matrixClient,
|
||||||
mediaPickerProvider = pickerProvider,
|
mediaPickerProvider = pickerProvider,
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
|
||||||
class FakeCreateRoomEntryPoint : CreateRoomEntryPoint {
|
class FakeCreateRoomEntryPoint : CreateRoomEntryPoint {
|
||||||
override fun createNode(
|
override fun createNode(
|
||||||
|
isSpace: Boolean,
|
||||||
parentNode: Node,
|
parentNode: Node,
|
||||||
buildContext: BuildContext,
|
buildContext: BuildContext,
|
||||||
callback: CreateRoomEntryPoint.Callback,
|
callback: CreateRoomEntryPoint.Callback,
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ interface HomeEntryPoint : FeatureEntryPoint {
|
||||||
interface Callback : Plugin {
|
interface Callback : Plugin {
|
||||||
fun navigateToRoom(roomId: RoomId, joinedRoom: JoinedRoom?)
|
fun navigateToRoom(roomId: RoomId, joinedRoom: JoinedRoom?)
|
||||||
fun navigateToCreateRoom()
|
fun navigateToCreateRoom()
|
||||||
|
fun navigateToCreateSpace()
|
||||||
fun navigateToSettings()
|
fun navigateToSettings()
|
||||||
fun navigateToSetUpRecovery()
|
fun navigateToSetUpRecovery()
|
||||||
fun navigateToEnterRecoveryKey()
|
fun navigateToEnterRecoveryKey()
|
||||||
|
|
|
||||||
|
|
@ -220,6 +220,7 @@ class HomeFlowNode(
|
||||||
onRoomClick = ::navigateToRoom,
|
onRoomClick = ::navigateToRoom,
|
||||||
onSettingsClick = callback::navigateToSettings,
|
onSettingsClick = callback::navigateToSettings,
|
||||||
onStartChatClick = callback::navigateToCreateRoom,
|
onStartChatClick = callback::navigateToCreateRoom,
|
||||||
|
onCreateSpaceClick = callback::navigateToCreateSpace,
|
||||||
onSetUpRecoveryClick = callback::navigateToSetUpRecovery,
|
onSetUpRecoveryClick = callback::navigateToSetUpRecovery,
|
||||||
onConfirmRecoveryKeyClick = callback::navigateToEnterRecoveryKey,
|
onConfirmRecoveryKeyClick = callback::navigateToEnterRecoveryKey,
|
||||||
onRoomSettingsClick = callback::navigateToRoomSettings,
|
onRoomSettingsClick = callback::navigateToRoomSettings,
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@ fun HomeView(
|
||||||
onSetUpRecoveryClick: () -> Unit,
|
onSetUpRecoveryClick: () -> Unit,
|
||||||
onConfirmRecoveryKeyClick: () -> Unit,
|
onConfirmRecoveryKeyClick: () -> Unit,
|
||||||
onStartChatClick: () -> Unit,
|
onStartChatClick: () -> Unit,
|
||||||
|
onCreateSpaceClick: () -> Unit,
|
||||||
onRoomSettingsClick: (roomId: RoomId) -> Unit,
|
onRoomSettingsClick: (roomId: RoomId) -> Unit,
|
||||||
onMenuActionClick: (RoomListMenuAction) -> Unit,
|
onMenuActionClick: (RoomListMenuAction) -> Unit,
|
||||||
onReportRoomClick: (roomId: RoomId) -> Unit,
|
onReportRoomClick: (roomId: RoomId) -> Unit,
|
||||||
|
|
@ -113,6 +114,7 @@ fun HomeView(
|
||||||
onRoomClick = { if (firstThrottler.canHandle()) onRoomClick(it) },
|
onRoomClick = { if (firstThrottler.canHandle()) onRoomClick(it) },
|
||||||
onOpenSettings = { if (firstThrottler.canHandle()) onSettingsClick() },
|
onOpenSettings = { if (firstThrottler.canHandle()) onSettingsClick() },
|
||||||
onStartChatClick = { if (firstThrottler.canHandle()) onStartChatClick() },
|
onStartChatClick = { if (firstThrottler.canHandle()) onStartChatClick() },
|
||||||
|
onCreateSpaceClick = { if (firstThrottler.canHandle()) onCreateSpaceClick() },
|
||||||
onMenuActionClick = onMenuActionClick,
|
onMenuActionClick = onMenuActionClick,
|
||||||
)
|
)
|
||||||
// This overlaid view will only be visible when state.displaySearchResults is true
|
// This overlaid view will only be visible when state.displaySearchResults is true
|
||||||
|
|
@ -138,6 +140,7 @@ private fun HomeScaffold(
|
||||||
onRoomClick: (RoomId) -> Unit,
|
onRoomClick: (RoomId) -> Unit,
|
||||||
onOpenSettings: () -> Unit,
|
onOpenSettings: () -> Unit,
|
||||||
onStartChatClick: () -> Unit,
|
onStartChatClick: () -> Unit,
|
||||||
|
onCreateSpaceClick: () -> Unit,
|
||||||
onMenuActionClick: (RoomListMenuAction) -> Unit,
|
onMenuActionClick: (RoomListMenuAction) -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
|
|
@ -164,6 +167,7 @@ private fun HomeScaffold(
|
||||||
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||||
topBar = {
|
topBar = {
|
||||||
HomeTopBar(
|
HomeTopBar(
|
||||||
|
selectedNavigationItem = state.currentHomeNavigationBarItem,
|
||||||
title = stringResource(state.currentHomeNavigationBarItem.labelRes),
|
title = stringResource(state.currentHomeNavigationBarItem.labelRes),
|
||||||
currentUserAndNeighbors = state.currentUserAndNeighbors,
|
currentUserAndNeighbors = state.currentUserAndNeighbors,
|
||||||
showAvatarIndicator = state.showAvatarIndicator,
|
showAvatarIndicator = state.showAvatarIndicator,
|
||||||
|
|
@ -174,10 +178,11 @@ private fun HomeScaffold(
|
||||||
onAccountSwitch = {
|
onAccountSwitch = {
|
||||||
state.eventSink(HomeEvents.SwitchToAccount(it))
|
state.eventSink(HomeEvents.SwitchToAccount(it))
|
||||||
},
|
},
|
||||||
|
onCreateSpace = onCreateSpaceClick,
|
||||||
scrollBehavior = scrollBehavior,
|
scrollBehavior = scrollBehavior,
|
||||||
displayMenuItems = state.displayActions,
|
|
||||||
displayFilters = state.displayRoomListFilters,
|
displayFilters = state.displayRoomListFilters,
|
||||||
filtersState = roomListState.filtersState,
|
filtersState = roomListState.filtersState,
|
||||||
|
canCreateSpaces = state.homeSpacesState.canCreateSpaces,
|
||||||
canReportBug = state.canReportBug,
|
canReportBug = state.canReportBug,
|
||||||
modifier = Modifier.hazeEffect(
|
modifier = Modifier.hazeEffect(
|
||||||
state = hazeState,
|
state = hazeState,
|
||||||
|
|
@ -328,6 +333,7 @@ internal fun HomeViewPreview(@PreviewParameter(HomeStateProvider::class) state:
|
||||||
onSetUpRecoveryClick = {},
|
onSetUpRecoveryClick = {},
|
||||||
onConfirmRecoveryKeyClick = {},
|
onConfirmRecoveryKeyClick = {},
|
||||||
onStartChatClick = {},
|
onStartChatClick = {},
|
||||||
|
onCreateSpaceClick = {},
|
||||||
onRoomSettingsClick = {},
|
onRoomSettingsClick = {},
|
||||||
onReportRoomClick = {},
|
onReportRoomClick = {},
|
||||||
onMenuActionClick = {},
|
onMenuActionClick = {},
|
||||||
|
|
@ -347,6 +353,7 @@ internal fun HomeViewA11yPreview() = ElementPreview {
|
||||||
onSetUpRecoveryClick = {},
|
onSetUpRecoveryClick = {},
|
||||||
onConfirmRecoveryKeyClick = {},
|
onConfirmRecoveryKeyClick = {},
|
||||||
onStartChatClick = {},
|
onStartChatClick = {},
|
||||||
|
onCreateSpaceClick = {},
|
||||||
onRoomSettingsClick = {},
|
onRoomSettingsClick = {},
|
||||||
onReportRoomClick = {},
|
onReportRoomClick = {},
|
||||||
onMenuActionClick = {},
|
onMenuActionClick = {},
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ import androidx.compose.ui.unit.dp
|
||||||
import io.element.android.appconfig.RoomListConfig
|
import io.element.android.appconfig.RoomListConfig
|
||||||
import io.element.android.compound.theme.ElementTheme
|
import io.element.android.compound.theme.ElementTheme
|
||||||
import io.element.android.compound.tokens.generated.CompoundIcons
|
import io.element.android.compound.tokens.generated.CompoundIcons
|
||||||
|
import io.element.android.features.home.impl.HomeNavigationBarItem
|
||||||
import io.element.android.features.home.impl.R
|
import io.element.android.features.home.impl.R
|
||||||
import io.element.android.features.home.impl.filters.RoomListFiltersState
|
import io.element.android.features.home.impl.filters.RoomListFiltersState
|
||||||
import io.element.android.features.home.impl.filters.RoomListFiltersView
|
import io.element.android.features.home.impl.filters.RoomListFiltersView
|
||||||
|
|
@ -73,6 +74,7 @@ import kotlinx.collections.immutable.toImmutableList
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun HomeTopBar(
|
fun HomeTopBar(
|
||||||
|
selectedNavigationItem: HomeNavigationBarItem,
|
||||||
title: String,
|
title: String,
|
||||||
currentUserAndNeighbors: ImmutableList<MatrixUser>,
|
currentUserAndNeighbors: ImmutableList<MatrixUser>,
|
||||||
showAvatarIndicator: Boolean,
|
showAvatarIndicator: Boolean,
|
||||||
|
|
@ -81,8 +83,9 @@ fun HomeTopBar(
|
||||||
onMenuActionClick: (RoomListMenuAction) -> Unit,
|
onMenuActionClick: (RoomListMenuAction) -> Unit,
|
||||||
onOpenSettings: () -> Unit,
|
onOpenSettings: () -> Unit,
|
||||||
onAccountSwitch: (SessionId) -> Unit,
|
onAccountSwitch: (SessionId) -> Unit,
|
||||||
|
onCreateSpace: () -> Unit,
|
||||||
scrollBehavior: TopAppBarScrollBehavior,
|
scrollBehavior: TopAppBarScrollBehavior,
|
||||||
displayMenuItems: Boolean,
|
canCreateSpaces: Boolean,
|
||||||
canReportBug: Boolean,
|
canReportBug: Boolean,
|
||||||
displayFilters: Boolean,
|
displayFilters: Boolean,
|
||||||
filtersState: RoomListFiltersState,
|
filtersState: RoomListFiltersState,
|
||||||
|
|
@ -117,63 +120,16 @@ fun HomeTopBar(
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
if (displayMenuItems) {
|
when (selectedNavigationItem) {
|
||||||
IconButton(
|
HomeNavigationBarItem.Chats -> RoomListMenuItems(
|
||||||
onClick = onToggleSearch,
|
onToggleSearch = onToggleSearch,
|
||||||
) {
|
onMenuActionClick = onMenuActionClick,
|
||||||
Icon(
|
canReportBug = canReportBug
|
||||||
imageVector = CompoundIcons.Search(),
|
)
|
||||||
contentDescription = stringResource(CommonStrings.action_search),
|
HomeNavigationBarItem.Spaces -> SpacesMenuItems(
|
||||||
)
|
canCreateSpaces = canCreateSpaces,
|
||||||
}
|
onCreateSpace = onCreateSpace
|
||||||
if (RoomListConfig.HAS_DROP_DOWN_MENU) {
|
)
|
||||||
var showMenu by remember { mutableStateOf(false) }
|
|
||||||
IconButton(
|
|
||||||
onClick = { showMenu = !showMenu }
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
imageVector = CompoundIcons.OverflowVertical(),
|
|
||||||
contentDescription = null,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
DropdownMenu(
|
|
||||||
expanded = showMenu,
|
|
||||||
onDismissRequest = { showMenu = false }
|
|
||||||
) {
|
|
||||||
if (RoomListConfig.SHOW_INVITE_MENU_ITEM) {
|
|
||||||
DropdownMenuItem(
|
|
||||||
onClick = {
|
|
||||||
showMenu = false
|
|
||||||
onMenuActionClick(RoomListMenuAction.InviteFriends)
|
|
||||||
},
|
|
||||||
text = { Text(stringResource(id = CommonStrings.action_invite)) },
|
|
||||||
leadingIcon = {
|
|
||||||
Icon(
|
|
||||||
imageVector = CompoundIcons.ShareAndroid(),
|
|
||||||
tint = ElementTheme.colors.iconSecondary,
|
|
||||||
contentDescription = null,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (RoomListConfig.SHOW_REPORT_PROBLEM_MENU_ITEM && canReportBug) {
|
|
||||||
DropdownMenuItem(
|
|
||||||
onClick = {
|
|
||||||
showMenu = false
|
|
||||||
onMenuActionClick(RoomListMenuAction.ReportBug)
|
|
||||||
},
|
|
||||||
text = { Text(stringResource(id = CommonStrings.common_report_a_problem)) },
|
|
||||||
leadingIcon = {
|
|
||||||
Icon(
|
|
||||||
imageVector = CompoundIcons.ChatProblem(),
|
|
||||||
tint = ElementTheme.colors.iconSecondary,
|
|
||||||
contentDescription = null,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// We want a 16dp left padding for the navigationIcon :
|
// We want a 16dp left padding for the navigationIcon :
|
||||||
|
|
@ -193,6 +149,85 @@ fun HomeTopBar(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun RoomListMenuItems(
|
||||||
|
onToggleSearch: () -> Unit,
|
||||||
|
onMenuActionClick: (RoomListMenuAction) -> Unit,
|
||||||
|
canReportBug: Boolean,
|
||||||
|
) {
|
||||||
|
IconButton(
|
||||||
|
onClick = onToggleSearch,
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = CompoundIcons.Search(),
|
||||||
|
contentDescription = stringResource(CommonStrings.action_search),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (RoomListConfig.HAS_DROP_DOWN_MENU) {
|
||||||
|
var showMenu by remember { mutableStateOf(false) }
|
||||||
|
IconButton(
|
||||||
|
onClick = { showMenu = !showMenu }
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = CompoundIcons.OverflowVertical(),
|
||||||
|
contentDescription = null,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
DropdownMenu(
|
||||||
|
expanded = showMenu,
|
||||||
|
onDismissRequest = { showMenu = false }
|
||||||
|
) {
|
||||||
|
if (RoomListConfig.SHOW_INVITE_MENU_ITEM) {
|
||||||
|
DropdownMenuItem(
|
||||||
|
onClick = {
|
||||||
|
showMenu = false
|
||||||
|
onMenuActionClick(RoomListMenuAction.InviteFriends)
|
||||||
|
},
|
||||||
|
text = { Text(stringResource(id = CommonStrings.action_invite)) },
|
||||||
|
leadingIcon = {
|
||||||
|
Icon(
|
||||||
|
imageVector = CompoundIcons.ShareAndroid(),
|
||||||
|
tint = ElementTheme.colors.iconSecondary,
|
||||||
|
contentDescription = null,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (RoomListConfig.SHOW_REPORT_PROBLEM_MENU_ITEM && canReportBug) {
|
||||||
|
DropdownMenuItem(
|
||||||
|
onClick = {
|
||||||
|
showMenu = false
|
||||||
|
onMenuActionClick(RoomListMenuAction.ReportBug)
|
||||||
|
},
|
||||||
|
text = { Text(stringResource(id = CommonStrings.common_report_a_problem)) },
|
||||||
|
leadingIcon = {
|
||||||
|
Icon(
|
||||||
|
imageVector = CompoundIcons.ChatProblem(),
|
||||||
|
tint = ElementTheme.colors.iconSecondary,
|
||||||
|
contentDescription = null,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun SpacesMenuItems(
|
||||||
|
canCreateSpaces: Boolean,
|
||||||
|
onCreateSpace: () -> Unit
|
||||||
|
) {
|
||||||
|
if (canCreateSpaces) {
|
||||||
|
IconButton(onClick = onCreateSpace) {
|
||||||
|
Icon(
|
||||||
|
imageVector = CompoundIcons.Plus(),
|
||||||
|
contentDescription = stringResource(CommonStrings.action_create_space)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun NavigationIcon(
|
private fun NavigationIcon(
|
||||||
currentUserAndNeighbors: ImmutableList<MatrixUser>,
|
currentUserAndNeighbors: ImmutableList<MatrixUser>,
|
||||||
|
|
@ -273,6 +308,7 @@ private fun AccountIcon(
|
||||||
@Composable
|
@Composable
|
||||||
internal fun HomeTopBarPreview() = ElementPreview {
|
internal fun HomeTopBarPreview() = ElementPreview {
|
||||||
HomeTopBar(
|
HomeTopBar(
|
||||||
|
selectedNavigationItem = HomeNavigationBarItem.Chats,
|
||||||
title = stringResource(R.string.screen_roomlist_main_space_title),
|
title = stringResource(R.string.screen_roomlist_main_space_title),
|
||||||
currentUserAndNeighbors = persistentListOf(MatrixUser(UserId("@id:domain"), "Alice")),
|
currentUserAndNeighbors = persistentListOf(MatrixUser(UserId("@id:domain"), "Alice")),
|
||||||
showAvatarIndicator = false,
|
showAvatarIndicator = false,
|
||||||
|
|
@ -281,7 +317,8 @@ internal fun HomeTopBarPreview() = ElementPreview {
|
||||||
onOpenSettings = {},
|
onOpenSettings = {},
|
||||||
onAccountSwitch = {},
|
onAccountSwitch = {},
|
||||||
onToggleSearch = {},
|
onToggleSearch = {},
|
||||||
displayMenuItems = true,
|
onCreateSpace = {},
|
||||||
|
canCreateSpaces = true,
|
||||||
canReportBug = true,
|
canReportBug = true,
|
||||||
displayFilters = true,
|
displayFilters = true,
|
||||||
filtersState = aRoomListFiltersState(),
|
filtersState = aRoomListFiltersState(),
|
||||||
|
|
@ -289,11 +326,35 @@ internal fun HomeTopBarPreview() = ElementPreview {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@PreviewsDayNight
|
||||||
|
@Composable
|
||||||
|
internal fun HomeTopBarSpacesPreview() = ElementPreview {
|
||||||
|
HomeTopBar(
|
||||||
|
selectedNavigationItem = HomeNavigationBarItem.Spaces,
|
||||||
|
title = stringResource(R.string.screen_home_tab_spaces),
|
||||||
|
currentUserAndNeighbors = persistentListOf(MatrixUser(UserId("@id:domain"), "Alice")),
|
||||||
|
showAvatarIndicator = false,
|
||||||
|
areSearchResultsDisplayed = false,
|
||||||
|
scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState()),
|
||||||
|
onOpenSettings = {},
|
||||||
|
onAccountSwitch = {},
|
||||||
|
onToggleSearch = {},
|
||||||
|
onCreateSpace = {},
|
||||||
|
canCreateSpaces = true,
|
||||||
|
canReportBug = true,
|
||||||
|
displayFilters = false,
|
||||||
|
filtersState = aRoomListFiltersState(),
|
||||||
|
onMenuActionClick = {},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@PreviewsDayNight
|
@PreviewsDayNight
|
||||||
@Composable
|
@Composable
|
||||||
internal fun HomeTopBarWithIndicatorPreview() = ElementPreview {
|
internal fun HomeTopBarWithIndicatorPreview() = ElementPreview {
|
||||||
HomeTopBar(
|
HomeTopBar(
|
||||||
|
selectedNavigationItem = HomeNavigationBarItem.Chats,
|
||||||
title = stringResource(R.string.screen_roomlist_main_space_title),
|
title = stringResource(R.string.screen_roomlist_main_space_title),
|
||||||
currentUserAndNeighbors = persistentListOf(MatrixUser(UserId("@id:domain"), "Alice")),
|
currentUserAndNeighbors = persistentListOf(MatrixUser(UserId("@id:domain"), "Alice")),
|
||||||
showAvatarIndicator = true,
|
showAvatarIndicator = true,
|
||||||
|
|
@ -302,7 +363,8 @@ internal fun HomeTopBarWithIndicatorPreview() = ElementPreview {
|
||||||
onOpenSettings = {},
|
onOpenSettings = {},
|
||||||
onAccountSwitch = {},
|
onAccountSwitch = {},
|
||||||
onToggleSearch = {},
|
onToggleSearch = {},
|
||||||
displayMenuItems = true,
|
onCreateSpace = {},
|
||||||
|
canCreateSpaces = true,
|
||||||
canReportBug = true,
|
canReportBug = true,
|
||||||
displayFilters = true,
|
displayFilters = true,
|
||||||
filtersState = aRoomListFiltersState(),
|
filtersState = aRoomListFiltersState(),
|
||||||
|
|
@ -315,6 +377,7 @@ internal fun HomeTopBarWithIndicatorPreview() = ElementPreview {
|
||||||
@Composable
|
@Composable
|
||||||
internal fun HomeTopBarMultiAccountPreview() = ElementPreview {
|
internal fun HomeTopBarMultiAccountPreview() = ElementPreview {
|
||||||
HomeTopBar(
|
HomeTopBar(
|
||||||
|
selectedNavigationItem = HomeNavigationBarItem.Chats,
|
||||||
title = stringResource(R.string.screen_roomlist_main_space_title),
|
title = stringResource(R.string.screen_roomlist_main_space_title),
|
||||||
currentUserAndNeighbors = aMatrixUserList().take(3).toImmutableList(),
|
currentUserAndNeighbors = aMatrixUserList().take(3).toImmutableList(),
|
||||||
showAvatarIndicator = false,
|
showAvatarIndicator = false,
|
||||||
|
|
@ -323,7 +386,8 @@ internal fun HomeTopBarMultiAccountPreview() = ElementPreview {
|
||||||
onOpenSettings = {},
|
onOpenSettings = {},
|
||||||
onAccountSwitch = {},
|
onAccountSwitch = {},
|
||||||
onToggleSearch = {},
|
onToggleSearch = {},
|
||||||
displayMenuItems = true,
|
onCreateSpace = {},
|
||||||
|
canCreateSpaces = true,
|
||||||
canReportBug = true,
|
canReportBug = true,
|
||||||
displayFilters = true,
|
displayFilters = true,
|
||||||
filtersState = aRoomListFiltersState(),
|
filtersState = aRoomListFiltersState(),
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@ import androidx.compose.runtime.remember
|
||||||
import dev.zacsweers.metro.Inject
|
import dev.zacsweers.metro.Inject
|
||||||
import io.element.android.features.invite.api.SeenInvitesStore
|
import io.element.android.features.invite.api.SeenInvitesStore
|
||||||
import io.element.android.libraries.architecture.Presenter
|
import io.element.android.libraries.architecture.Presenter
|
||||||
|
import io.element.android.libraries.featureflag.api.FeatureFlagService
|
||||||
|
import io.element.android.libraries.featureflag.api.FeatureFlags
|
||||||
import io.element.android.libraries.matrix.api.MatrixClient
|
import io.element.android.libraries.matrix.api.MatrixClient
|
||||||
import io.element.android.libraries.matrix.ui.safety.rememberHideInvitesAvatar
|
import io.element.android.libraries.matrix.ui.safety.rememberHideInvitesAvatar
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
|
|
@ -27,9 +29,11 @@ import kotlinx.coroutines.flow.map
|
||||||
class HomeSpacesPresenter(
|
class HomeSpacesPresenter(
|
||||||
private val client: MatrixClient,
|
private val client: MatrixClient,
|
||||||
private val seenInvitesStore: SeenInvitesStore,
|
private val seenInvitesStore: SeenInvitesStore,
|
||||||
|
private val featureFlagsService: FeatureFlagService,
|
||||||
) : Presenter<HomeSpacesState> {
|
) : Presenter<HomeSpacesState> {
|
||||||
@Composable
|
@Composable
|
||||||
override fun present(): HomeSpacesState {
|
override fun present(): HomeSpacesState {
|
||||||
|
val canCreateSpaces by featureFlagsService.isFeatureEnabledFlow(FeatureFlags.CreateSpaces).collectAsState(false)
|
||||||
val hideInvitesAvatar by client.rememberHideInvitesAvatar()
|
val hideInvitesAvatar by client.rememberHideInvitesAvatar()
|
||||||
val spaceRooms by remember {
|
val spaceRooms by remember {
|
||||||
client.spaceService.spaceRoomsFlow.map { it.toImmutableList() }
|
client.spaceService.spaceRoomsFlow.map { it.toImmutableList() }
|
||||||
|
|
@ -48,6 +52,7 @@ class HomeSpacesPresenter(
|
||||||
spaceRooms = spaceRooms,
|
spaceRooms = spaceRooms,
|
||||||
seenSpaceInvites = seenSpaceInvites,
|
seenSpaceInvites = seenSpaceInvites,
|
||||||
hideInvitesAvatar = hideInvitesAvatar,
|
hideInvitesAvatar = hideInvitesAvatar,
|
||||||
|
canCreateSpaces = canCreateSpaces,
|
||||||
eventSink = ::handleEvent,
|
eventSink = ::handleEvent,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ data class HomeSpacesState(
|
||||||
val spaceRooms: ImmutableList<SpaceRoom>,
|
val spaceRooms: ImmutableList<SpaceRoom>,
|
||||||
val seenSpaceInvites: ImmutableSet<RoomId>,
|
val seenSpaceInvites: ImmutableSet<RoomId>,
|
||||||
val hideInvitesAvatar: Boolean,
|
val hideInvitesAvatar: Boolean,
|
||||||
|
val canCreateSpaces: Boolean,
|
||||||
val eventSink: (HomeSpacesEvents) -> Unit,
|
val eventSink: (HomeSpacesEvents) -> Unit,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,13 @@ open class HomeSpacesStateProvider : PreviewParameterProvider<HomeSpacesState> {
|
||||||
),
|
),
|
||||||
spaceRooms = aListOfSpaceRooms(),
|
spaceRooms = aListOfSpaceRooms(),
|
||||||
),
|
),
|
||||||
|
aHomeSpacesState(
|
||||||
|
space = CurrentSpace.Space(
|
||||||
|
spaceRoom = aSpaceRoom(roomId = RoomId("!mySpace:example.com"))
|
||||||
|
),
|
||||||
|
spaceRooms = aListOfSpaceRooms(),
|
||||||
|
canCreateSpaces = false,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -38,12 +45,14 @@ internal fun aHomeSpacesState(
|
||||||
spaceRooms: List<SpaceRoom> = aListOfSpaceRooms(),
|
spaceRooms: List<SpaceRoom> = aListOfSpaceRooms(),
|
||||||
seenSpaceInvites: Set<RoomId> = emptySet(),
|
seenSpaceInvites: Set<RoomId> = emptySet(),
|
||||||
hideInvitesAvatar: Boolean = false,
|
hideInvitesAvatar: Boolean = false,
|
||||||
|
canCreateSpaces: Boolean = true,
|
||||||
eventSink: (HomeSpacesEvents) -> Unit = {},
|
eventSink: (HomeSpacesEvents) -> Unit = {},
|
||||||
) = HomeSpacesState(
|
) = HomeSpacesState(
|
||||||
space = space,
|
space = space,
|
||||||
spaceRooms = spaceRooms.toImmutableList(),
|
spaceRooms = spaceRooms.toImmutableList(),
|
||||||
seenSpaceInvites = seenSpaceInvites.toImmutableSet(),
|
seenSpaceInvites = seenSpaceInvites.toImmutableSet(),
|
||||||
hideInvitesAvatar = hideInvitesAvatar,
|
hideInvitesAvatar = hideInvitesAvatar,
|
||||||
|
canCreateSpaces = canCreateSpaces,
|
||||||
eventSink = eventSink,
|
eventSink = eventSink,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ class DefaultHomeEntryPointTest {
|
||||||
val callback = object : HomeEntryPoint.Callback {
|
val callback = object : HomeEntryPoint.Callback {
|
||||||
override fun navigateToRoom(roomId: RoomId, joinedRoom: JoinedRoom?) = lambdaError()
|
override fun navigateToRoom(roomId: RoomId, joinedRoom: JoinedRoom?) = lambdaError()
|
||||||
override fun navigateToCreateRoom() = lambdaError()
|
override fun navigateToCreateRoom() = lambdaError()
|
||||||
|
override fun navigateToCreateSpace() = lambdaError()
|
||||||
override fun navigateToSettings() = lambdaError()
|
override fun navigateToSettings() = lambdaError()
|
||||||
override fun navigateToSetUpRecovery() = lambdaError()
|
override fun navigateToSetUpRecovery() = lambdaError()
|
||||||
override fun navigateToEnterRecoveryKey() = lambdaError()
|
override fun navigateToEnterRecoveryKey() = lambdaError()
|
||||||
|
|
|
||||||
|
|
@ -273,6 +273,7 @@ private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setRoomL
|
||||||
onSetUpRecoveryClick: () -> Unit = EnsureNeverCalled(),
|
onSetUpRecoveryClick: () -> Unit = EnsureNeverCalled(),
|
||||||
onConfirmRecoveryKeyClick: () -> Unit = EnsureNeverCalled(),
|
onConfirmRecoveryKeyClick: () -> Unit = EnsureNeverCalled(),
|
||||||
onCreateRoomClick: () -> Unit = EnsureNeverCalled(),
|
onCreateRoomClick: () -> Unit = EnsureNeverCalled(),
|
||||||
|
onCreateSpaceClick: () -> Unit = EnsureNeverCalled(),
|
||||||
onRoomSettingsClick: (RoomId) -> Unit = EnsureNeverCalledWithParam(),
|
onRoomSettingsClick: (RoomId) -> Unit = EnsureNeverCalledWithParam(),
|
||||||
onMenuActionClick: (RoomListMenuAction) -> Unit = EnsureNeverCalledWithParam(),
|
onMenuActionClick: (RoomListMenuAction) -> Unit = EnsureNeverCalledWithParam(),
|
||||||
onReportRoomClick: (RoomId) -> Unit = EnsureNeverCalledWithParam(),
|
onReportRoomClick: (RoomId) -> Unit = EnsureNeverCalledWithParam(),
|
||||||
|
|
@ -286,6 +287,7 @@ private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setRoomL
|
||||||
onSetUpRecoveryClick = onSetUpRecoveryClick,
|
onSetUpRecoveryClick = onSetUpRecoveryClick,
|
||||||
onConfirmRecoveryKeyClick = onConfirmRecoveryKeyClick,
|
onConfirmRecoveryKeyClick = onConfirmRecoveryKeyClick,
|
||||||
onStartChatClick = onCreateRoomClick,
|
onStartChatClick = onCreateRoomClick,
|
||||||
|
onCreateSpaceClick = onCreateSpaceClick,
|
||||||
onRoomSettingsClick = onRoomSettingsClick,
|
onRoomSettingsClick = onRoomSettingsClick,
|
||||||
onMenuActionClick = onMenuActionClick,
|
onMenuActionClick = onMenuActionClick,
|
||||||
onDeclineInviteAndBlockUser = onDeclineInviteAndBlockUser,
|
onDeclineInviteAndBlockUser = onDeclineInviteAndBlockUser,
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,9 @@ package io.element.android.features.home.impl.spaces
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import io.element.android.features.invite.api.SeenInvitesStore
|
import io.element.android.features.invite.api.SeenInvitesStore
|
||||||
import io.element.android.features.invite.test.InMemorySeenInvitesStore
|
import io.element.android.features.invite.test.InMemorySeenInvitesStore
|
||||||
|
import io.element.android.libraries.featureflag.api.FeatureFlagService
|
||||||
|
import io.element.android.libraries.featureflag.api.FeatureFlags
|
||||||
|
import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
|
||||||
import io.element.android.libraries.matrix.api.MatrixClient
|
import io.element.android.libraries.matrix.api.MatrixClient
|
||||||
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||||
import io.element.android.tests.testutils.test
|
import io.element.android.tests.testutils.test
|
||||||
|
|
@ -23,18 +26,25 @@ class HomeSpacesPresenterTest {
|
||||||
val presenter = createPresenter()
|
val presenter = createPresenter()
|
||||||
presenter.test {
|
presenter.test {
|
||||||
val state = awaitItem()
|
val state = awaitItem()
|
||||||
|
// canCreateSpaces is initially false
|
||||||
|
assertThat(state.canCreateSpaces).isFalse()
|
||||||
assertThat(state.space).isEqualTo(CurrentSpace.Root)
|
assertThat(state.space).isEqualTo(CurrentSpace.Root)
|
||||||
assertThat(state.spaceRooms).isEmpty()
|
assertThat(state.spaceRooms).isEmpty()
|
||||||
assertThat(state.hideInvitesAvatar).isFalse()
|
assertThat(state.hideInvitesAvatar).isFalse()
|
||||||
assertThat(state.seenSpaceInvites).isEmpty()
|
assertThat(state.seenSpaceInvites).isEmpty()
|
||||||
|
|
||||||
|
// It'll eventually be true
|
||||||
|
assertThat(awaitItem().canCreateSpaces).isTrue()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createPresenter(
|
private fun createPresenter(
|
||||||
client: MatrixClient = FakeMatrixClient(),
|
client: MatrixClient = FakeMatrixClient(),
|
||||||
seenInvitesStore: SeenInvitesStore = InMemorySeenInvitesStore(),
|
seenInvitesStore: SeenInvitesStore = InMemorySeenInvitesStore(),
|
||||||
|
featureFlagsService: FeatureFlagService = FakeFeatureFlagService(initialState = mapOf(FeatureFlags.CreateSpaces.key to true)),
|
||||||
) = HomeSpacesPresenter(
|
) = HomeSpacesPresenter(
|
||||||
client = client,
|
client = client,
|
||||||
seenInvitesStore = seenInvitesStore,
|
seenInvitesStore = seenInvitesStore,
|
||||||
|
featureFlagsService = featureFlagsService,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ import io.element.android.features.preferences.impl.R
|
||||||
import io.element.android.libraries.architecture.AsyncAction
|
import io.element.android.libraries.architecture.AsyncAction
|
||||||
import io.element.android.libraries.designsystem.components.async.AsyncActionView
|
import io.element.android.libraries.designsystem.components.async.AsyncActionView
|
||||||
import io.element.android.libraries.designsystem.components.async.AsyncActionViewDefaults
|
import io.element.android.libraries.designsystem.components.async.AsyncActionViewDefaults
|
||||||
|
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
||||||
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
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.avatar.AvatarType
|
||||||
import io.element.android.libraries.designsystem.components.button.BackButton
|
import io.element.android.libraries.designsystem.components.button.BackButton
|
||||||
|
|
@ -47,7 +48,8 @@ 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.TextField
|
||||||
import io.element.android.libraries.designsystem.theme.components.TopAppBar
|
import io.element.android.libraries.designsystem.theme.components.TopAppBar
|
||||||
import io.element.android.libraries.matrix.ui.components.AvatarActionBottomSheet
|
import io.element.android.libraries.matrix.ui.components.AvatarActionBottomSheet
|
||||||
import io.element.android.libraries.matrix.ui.components.EditableAvatarView
|
import io.element.android.libraries.matrix.ui.components.AvatarPickerState
|
||||||
|
import io.element.android.libraries.matrix.ui.components.AvatarPickerView
|
||||||
import io.element.android.libraries.permissions.api.PermissionsView
|
import io.element.android.libraries.permissions.api.PermissionsView
|
||||||
import io.element.android.libraries.ui.strings.CommonStrings
|
import io.element.android.libraries.ui.strings.CommonStrings
|
||||||
|
|
||||||
|
|
@ -103,13 +105,17 @@ fun EditUserProfileView(
|
||||||
.verticalScroll(rememberScrollState())
|
.verticalScroll(rememberScrollState())
|
||||||
) {
|
) {
|
||||||
Spacer(modifier = Modifier.height(24.dp))
|
Spacer(modifier = Modifier.height(24.dp))
|
||||||
EditableAvatarView(
|
val avatarPickerState = remember(state.userAvatarUrl) {
|
||||||
matrixId = state.userId.value,
|
val size = AvatarSize.EditProfileDetails
|
||||||
displayName = state.displayName,
|
val type = AvatarType.User
|
||||||
avatarUrl = state.userAvatarUrl,
|
AvatarPickerState.Selected(
|
||||||
avatarSize = AvatarSize.EditProfileDetails,
|
avatarData = AvatarData(id = state.userId.value, name = state.displayName, size = size, url = state.userAvatarUrl),
|
||||||
avatarType = AvatarType.User,
|
type = type
|
||||||
onAvatarClick = { onAvatarClick() },
|
)
|
||||||
|
}
|
||||||
|
AvatarPickerView(
|
||||||
|
state = avatarPickerState,
|
||||||
|
onClick = ::onAvatarClick,
|
||||||
modifier = Modifier.align(Alignment.CenterHorizontally),
|
modifier = Modifier.align(Alignment.CenterHorizontally),
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@
|
||||||
<string name="screen_room_details_profile_row_title">"Profile"</string>
|
<string name="screen_room_details_profile_row_title">"Profile"</string>
|
||||||
<string name="screen_room_details_requests_to_join_title">"Requests to join"</string>
|
<string name="screen_room_details_requests_to_join_title">"Requests to join"</string>
|
||||||
<string name="screen_room_details_roles_and_permissions">"Roles & permissions"</string>
|
<string name="screen_room_details_roles_and_permissions">"Roles & permissions"</string>
|
||||||
<string name="screen_room_details_room_name_label">"Room name"</string>
|
<string name="screen_room_details_room_name_label">"Name"</string>
|
||||||
<string name="screen_room_details_security_and_privacy_title">"Security & privacy"</string>
|
<string name="screen_room_details_security_and_privacy_title">"Security & privacy"</string>
|
||||||
<string name="screen_room_details_security_title">"Security"</string>
|
<string name="screen_room_details_security_title">"Security"</string>
|
||||||
<string name="screen_room_details_share_room_title">"Share room"</string>
|
<string name="screen_room_details_share_room_title">"Share room"</string>
|
||||||
|
|
@ -143,7 +143,7 @@ We do not recommend enabling encryption for rooms that anyone can find and join.
|
||||||
<string name="screen_security_and_privacy_encryption_toggle_title">"Enable end-to-end encryption"</string>
|
<string name="screen_security_and_privacy_encryption_toggle_title">"Enable end-to-end encryption"</string>
|
||||||
<string name="screen_security_and_privacy_room_access_anyone_option_description">"Anyone can join."</string>
|
<string name="screen_security_and_privacy_room_access_anyone_option_description">"Anyone can join."</string>
|
||||||
<string name="screen_security_and_privacy_room_access_anyone_option_title">"Anyone"</string>
|
<string name="screen_security_and_privacy_room_access_anyone_option_title">"Anyone"</string>
|
||||||
<string name="screen_security_and_privacy_room_access_footer">"Choose which spaces’ members can join this room without an invitation. %1$s"</string>
|
<string name="screen_security_and_privacy_room_access_footer">"Choose which spaces’ members can join this room without an invitation. %1$s"</string>
|
||||||
<string name="screen_security_and_privacy_room_access_footer_manage_spaces_action">"Manage spaces"</string>
|
<string name="screen_security_and_privacy_room_access_footer_manage_spaces_action">"Manage spaces"</string>
|
||||||
<string name="screen_security_and_privacy_room_access_invite_only_option_description">"Only invited people can join."</string>
|
<string name="screen_security_and_privacy_room_access_invite_only_option_description">"Only invited people can join."</string>
|
||||||
<string name="screen_security_and_privacy_room_access_invite_only_option_title">"Invite only"</string>
|
<string name="screen_security_and_privacy_room_access_invite_only_option_title">"Invite only"</string>
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ package io.element.android.features.roomdetailsedit.impl
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.imePadding
|
import androidx.compose.foundation.layout.imePadding
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
|
@ -24,6 +23,7 @@ import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalFocusManager
|
import androidx.compose.ui.platform.LocalFocusManager
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
|
@ -33,6 +33,7 @@ import androidx.compose.ui.unit.dp
|
||||||
import io.element.android.libraries.architecture.AsyncAction
|
import io.element.android.libraries.architecture.AsyncAction
|
||||||
import io.element.android.libraries.designsystem.components.async.AsyncActionView
|
import io.element.android.libraries.designsystem.components.async.AsyncActionView
|
||||||
import io.element.android.libraries.designsystem.components.async.AsyncActionViewDefaults
|
import io.element.android.libraries.designsystem.components.async.AsyncActionViewDefaults
|
||||||
|
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
||||||
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
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.avatar.AvatarType
|
||||||
import io.element.android.libraries.designsystem.components.button.BackButton
|
import io.element.android.libraries.designsystem.components.button.BackButton
|
||||||
|
|
@ -45,7 +46,8 @@ 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.TextField
|
||||||
import io.element.android.libraries.designsystem.theme.components.TopAppBar
|
import io.element.android.libraries.designsystem.theme.components.TopAppBar
|
||||||
import io.element.android.libraries.matrix.ui.components.AvatarActionBottomSheet
|
import io.element.android.libraries.matrix.ui.components.AvatarActionBottomSheet
|
||||||
import io.element.android.libraries.matrix.ui.components.EditableAvatarView
|
import io.element.android.libraries.matrix.ui.components.AvatarPickerState
|
||||||
|
import io.element.android.libraries.matrix.ui.components.AvatarPickerView
|
||||||
import io.element.android.libraries.permissions.api.PermissionsView
|
import io.element.android.libraries.permissions.api.PermissionsView
|
||||||
import io.element.android.libraries.ui.strings.CommonStrings
|
import io.element.android.libraries.ui.strings.CommonStrings
|
||||||
|
|
||||||
|
|
@ -99,20 +101,18 @@ fun RoomDetailsEditView(
|
||||||
.verticalScroll(rememberScrollState())
|
.verticalScroll(rememberScrollState())
|
||||||
) {
|
) {
|
||||||
Spacer(modifier = Modifier.height(24.dp))
|
Spacer(modifier = Modifier.height(24.dp))
|
||||||
EditableAvatarView(
|
val avatarPickerState = remember(state.roomAvatarUrl) {
|
||||||
matrixId = state.roomId.value,
|
val size = AvatarSize.EditRoomDetails
|
||||||
// As per Element Web, we use the raw name for the avatar as well
|
val type = AvatarType.Room()
|
||||||
displayName = state.roomRawName,
|
AvatarPickerState.Selected(
|
||||||
avatarUrl = state.roomAvatarUrl,
|
avatarData = AvatarData(id = state.roomId.value, name = state.roomRawName, size = size, url = state.roomAvatarUrl),
|
||||||
avatarSize = AvatarSize.EditRoomDetails,
|
type = type
|
||||||
avatarType = if (state.isSpace) {
|
)
|
||||||
AvatarType.Space()
|
}
|
||||||
} else {
|
AvatarPickerView(
|
||||||
AvatarType.Room()
|
state = avatarPickerState,
|
||||||
},
|
onClick = ::onAvatarClick,
|
||||||
enabled = state.canChangeAvatar,
|
modifier = Modifier.align(Alignment.CenterHorizontally),
|
||||||
onAvatarClick = ::onAvatarClick,
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.height(32.dp))
|
Spacer(modifier = Modifier.height(32.dp))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ We do not recommend enabling encryption for rooms that anyone can find and join.
|
||||||
<string name="screen_security_and_privacy_encryption_toggle_title">"Enable end-to-end encryption"</string>
|
<string name="screen_security_and_privacy_encryption_toggle_title">"Enable end-to-end encryption"</string>
|
||||||
<string name="screen_security_and_privacy_room_access_anyone_option_description">"Anyone can join."</string>
|
<string name="screen_security_and_privacy_room_access_anyone_option_description">"Anyone can join."</string>
|
||||||
<string name="screen_security_and_privacy_room_access_anyone_option_title">"Anyone"</string>
|
<string name="screen_security_and_privacy_room_access_anyone_option_title">"Anyone"</string>
|
||||||
<string name="screen_security_and_privacy_room_access_footer">"Choose which spaces’ members can join this room without an invitation. %1$s"</string>
|
<string name="screen_security_and_privacy_room_access_footer">"Choose which spaces’ members can join this room without an invitation. %1$s"</string>
|
||||||
<string name="screen_security_and_privacy_room_access_footer_manage_spaces_action">"Manage spaces"</string>
|
<string name="screen_security_and_privacy_room_access_footer_manage_spaces_action">"Manage spaces"</string>
|
||||||
<string name="screen_security_and_privacy_room_access_invite_only_option_description">"Only invited people can join."</string>
|
<string name="screen_security_and_privacy_room_access_invite_only_option_description">"Only invited people can join."</string>
|
||||||
<string name="screen_security_and_privacy_room_access_invite_only_option_title">"Invite only"</string>
|
<string name="screen_security_and_privacy_room_access_invite_only_option_title">"Invite only"</string>
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,7 @@ class StartChatFlowNode(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
createRoomEntryPoint.createNode(
|
createRoomEntryPoint.createNode(
|
||||||
|
isSpace = false,
|
||||||
parentNode = this,
|
parentNode = this,
|
||||||
buildContext = buildContext,
|
buildContext = buildContext,
|
||||||
callback = callback,
|
callback = callback,
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ enum class AvatarSize(val dp: Dp) {
|
||||||
RoomInviteItem(52.dp),
|
RoomInviteItem(52.dp),
|
||||||
InviteSender(16.dp),
|
InviteSender(16.dp),
|
||||||
|
|
||||||
EditRoomDetails(70.dp),
|
EditRoomDetails(68.dp),
|
||||||
RoomListManageUser(96.dp),
|
RoomListManageUser(96.dp),
|
||||||
|
|
||||||
NotificationsOptIn(32.dp),
|
NotificationsOptIn(32.dp),
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,13 @@ enum class FeatureFlags(
|
||||||
defaultValue = { false },
|
defaultValue = { false },
|
||||||
isFinished = false,
|
isFinished = false,
|
||||||
),
|
),
|
||||||
|
CreateSpaces(
|
||||||
|
key = "feature.createSpaces",
|
||||||
|
title = "Create spaces",
|
||||||
|
description = "Allow creating spaces.",
|
||||||
|
defaultValue = { false },
|
||||||
|
isFinished = false,
|
||||||
|
),
|
||||||
SpaceSettings(
|
SpaceSettings(
|
||||||
key = "feature.spaceSettings",
|
key = "feature.spaceSettings",
|
||||||
title = "Space settings",
|
title = "Space settings",
|
||||||
|
|
|
||||||
|
|
@ -26,4 +26,5 @@ data class CreateRoomParameters(
|
||||||
val joinRuleOverride: JoinRule? = null,
|
val joinRuleOverride: JoinRule? = null,
|
||||||
val historyVisibilityOverride: RoomHistoryVisibility? = null,
|
val historyVisibilityOverride: RoomHistoryVisibility? = null,
|
||||||
val roomAliasName: Optional<String> = Optional.empty(),
|
val roomAliasName: Optional<String> = Optional.empty(),
|
||||||
|
val isSpace: Boolean = false,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -393,6 +393,7 @@ class RustMatrixClient(
|
||||||
joinRuleOverride = createRoomParams.joinRuleOverride?.map(),
|
joinRuleOverride = createRoomParams.joinRuleOverride?.map(),
|
||||||
historyVisibilityOverride = createRoomParams.historyVisibilityOverride?.map(),
|
historyVisibilityOverride = createRoomParams.historyVisibilityOverride?.map(),
|
||||||
canonicalAlias = createRoomParams.roomAliasName.getOrNull(),
|
canonicalAlias = createRoomParams.roomAliasName.getOrNull(),
|
||||||
|
isSpace = createRoomParams.isSpace,
|
||||||
)
|
)
|
||||||
val roomId = RoomId(innerClient.createRoom(rustParams))
|
val roomId = RoomId(innerClient.createRoom(rustParams))
|
||||||
// Wait to receive the room back from the sync but do not returns failure if it fails.
|
// Wait to receive the room back from the sync but do not returns failure if it fails.
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ package io.element.android.libraries.matrix.ui.media
|
||||||
import coil3.ImageLoader
|
import coil3.ImageLoader
|
||||||
import coil3.fetch.Fetcher
|
import coil3.fetch.Fetcher
|
||||||
import coil3.request.Options
|
import coil3.request.Options
|
||||||
|
import coil3.toUri
|
||||||
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
||||||
import io.element.android.libraries.matrix.api.media.MatrixMediaLoader
|
import io.element.android.libraries.matrix.api.media.MatrixMediaLoader
|
||||||
|
|
||||||
|
|
@ -21,10 +22,19 @@ internal class AvatarDataFetcherFactory(
|
||||||
data: AvatarData,
|
data: AvatarData,
|
||||||
options: Options,
|
options: Options,
|
||||||
imageLoader: ImageLoader
|
imageLoader: ImageLoader
|
||||||
): Fetcher {
|
): Fetcher? {
|
||||||
return CoilMediaFetcher(
|
return when {
|
||||||
mediaLoader = matrixMediaLoader,
|
data.url == null -> null
|
||||||
mediaData = data.toMediaRequestData(),
|
data.url?.startsWith("mxc") == true -> CoilMediaFetcher(
|
||||||
)
|
mediaLoader = matrixMediaLoader,
|
||||||
|
mediaData = data.toMediaRequestData(),
|
||||||
|
)
|
||||||
|
else -> {
|
||||||
|
// If the URL does not use the mxc scheme, it might be a local one using `content://`, try using a fallback fetcher
|
||||||
|
data.url?.toUri()?.let { uri ->
|
||||||
|
imageLoader.components.newFetcher(uri, options, imageLoader)
|
||||||
|
}?.first
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2026 Element Creations Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||||
|
* Please see LICENSE files in the repository root for full details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.element.android.libraries.matrix.ui.media
|
||||||
|
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import coil3.ComponentRegistry
|
||||||
|
import coil3.ImageLoader
|
||||||
|
import coil3.asImage
|
||||||
|
import coil3.disk.DiskCache
|
||||||
|
import coil3.memory.MemoryCache
|
||||||
|
import coil3.request.Disposable
|
||||||
|
import coil3.request.ImageRequest
|
||||||
|
import coil3.request.ImageResult
|
||||||
|
import coil3.request.Options
|
||||||
|
import coil3.request.SuccessResult
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.libraries.designsystem.components.avatar.anAvatarData
|
||||||
|
import io.element.android.libraries.matrix.test.media.FakeMatrixMediaLoader
|
||||||
|
import io.mockk.mockk
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class AvatarDataFetcherFactoryTest {
|
||||||
|
@Test
|
||||||
|
fun `create - with mxc returns CoilMediaFetcher`() {
|
||||||
|
val factory = AvatarDataFetcherFactory(matrixMediaLoader = FakeMatrixMediaLoader())
|
||||||
|
|
||||||
|
val fetcher = factory.create(anAvatarData(url = "mxc://test"), Options(mockk()), imageLoader = FakeImageLoader())
|
||||||
|
assertThat(fetcher).isInstanceOf(CoilMediaFetcher::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `create - with http or https returns null, which means fallback default fetcher will be used`() {
|
||||||
|
val factory = AvatarDataFetcherFactory(matrixMediaLoader = FakeMatrixMediaLoader())
|
||||||
|
|
||||||
|
val fetcherHttp = factory.create(anAvatarData(url = "http://test"), Options(mockk()), imageLoader = FakeImageLoader())
|
||||||
|
assertThat(fetcherHttp).isNull()
|
||||||
|
|
||||||
|
val fetcherHttps = factory.create(anAvatarData(url = "https://test"), Options(mockk()), imageLoader = FakeImageLoader())
|
||||||
|
assertThat(fetcherHttps).isNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `create - with content scheme returns null, which means fallback default fetcher will be used`() {
|
||||||
|
val factory = AvatarDataFetcherFactory(matrixMediaLoader = FakeMatrixMediaLoader())
|
||||||
|
|
||||||
|
val fetcher = factory.create(anAvatarData(url = "content://test"), Options(mockk()), imageLoader = FakeImageLoader())
|
||||||
|
assertThat(fetcher).isNull()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class FakeImageLoader : ImageLoader {
|
||||||
|
override val defaults: ImageRequest.Defaults = ImageRequest.Defaults.DEFAULT
|
||||||
|
override val components: ComponentRegistry = ComponentRegistry.Builder().build()
|
||||||
|
override val memoryCache: MemoryCache? = null
|
||||||
|
override val diskCache: DiskCache? = null
|
||||||
|
|
||||||
|
override fun enqueue(request: ImageRequest): Disposable {
|
||||||
|
return mockk()
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun execute(request: ImageRequest): ImageResult {
|
||||||
|
return SuccessResult(
|
||||||
|
image = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8).asImage(),
|
||||||
|
request = request,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun shutdown() {}
|
||||||
|
|
||||||
|
override fun newBuilder(): ImageLoader.Builder {
|
||||||
|
return ImageLoader.Builder(mockk())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,436 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2026 Element Creations Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||||
|
* Please see LICENSE files in the repository root for full details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.element.android.libraries.matrix.ui.components
|
||||||
|
|
||||||
|
import androidx.annotation.DrawableRes
|
||||||
|
import androidx.compose.foundation.BorderStroke
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.border
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.BoxScope
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.offset
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
|
import androidx.compose.material3.ripple
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.draw.drawWithContent
|
||||||
|
import androidx.compose.ui.geometry.Offset
|
||||||
|
import androidx.compose.ui.graphics.BlendMode
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.graphics.CompositingStrategy
|
||||||
|
import androidx.compose.ui.graphics.graphicsLayer
|
||||||
|
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.semantics.clearAndSetSemantics
|
||||||
|
import androidx.compose.ui.semantics.contentDescription
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
|
import androidx.compose.ui.unit.LayoutDirection
|
||||||
|
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.libraries.designsystem.components.avatar.Avatar
|
||||||
|
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
||||||
|
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
||||||
|
import io.element.android.libraries.designsystem.components.avatar.AvatarType
|
||||||
|
import io.element.android.libraries.designsystem.icons.CompoundDrawables
|
||||||
|
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||||
|
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||||
|
import io.element.android.libraries.designsystem.theme.components.HorizontalDivider
|
||||||
|
import io.element.android.libraries.designsystem.theme.components.Icon
|
||||||
|
import io.element.android.libraries.designsystem.theme.components.Text
|
||||||
|
import io.element.android.libraries.testtags.TestTags
|
||||||
|
import io.element.android.libraries.testtags.testTag
|
||||||
|
import io.element.android.libraries.ui.strings.CommonStrings
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Avatar picker view, based on https://www.figma.com/design/kcnHxunG1LDWXsJhaNuiHz/ER-145--Spaces-on-Element-X?node-id=5918-97417&t=JYDQysgjS33AZb74-4
|
||||||
|
*
|
||||||
|
* It takes a [state], which can be [AvatarPickerState.Pick] for displaying the 'pick avatar' button, or [AvatarPickerState.Selected] when an avatar has
|
||||||
|
* already been selected.
|
||||||
|
*
|
||||||
|
* Note: this function contains lots of 'magic numbers', but those are just the fractions used to scale the different dimensions based on the Figma design.
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
fun AvatarPickerView(
|
||||||
|
state: AvatarPickerState,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
onClick: (() -> Unit) = {},
|
||||||
|
onClickLabel: String? = stringResource(CommonStrings.a11y_edit_avatar),
|
||||||
|
enabled: Boolean = true,
|
||||||
|
) {
|
||||||
|
val a11yAvatar = stringResource(CommonStrings.a11y_avatar)
|
||||||
|
|
||||||
|
val clickableModifier = Modifier.clickable(
|
||||||
|
enabled = enabled,
|
||||||
|
interactionSource = remember { MutableInteractionSource() },
|
||||||
|
onClickLabel = onClickLabel,
|
||||||
|
onClick = onClick,
|
||||||
|
indication = ripple(bounded = false),
|
||||||
|
)
|
||||||
|
.testTag(TestTags.editAvatar)
|
||||||
|
.clearAndSetSemantics {
|
||||||
|
contentDescription = a11yAvatar
|
||||||
|
}
|
||||||
|
|
||||||
|
val layoutDirection = LocalLayoutDirection.current
|
||||||
|
|
||||||
|
fun eraseBackgroundModifier(
|
||||||
|
parentWidth: Dp,
|
||||||
|
editIconRadius: Dp,
|
||||||
|
) = Modifier
|
||||||
|
.graphicsLayer {
|
||||||
|
compositingStrategy = CompositingStrategy.Offscreen
|
||||||
|
}
|
||||||
|
.drawWithContent {
|
||||||
|
drawContent()
|
||||||
|
drawCircle(
|
||||||
|
color = Color.Black,
|
||||||
|
center = Offset(
|
||||||
|
x = if (layoutDirection == LayoutDirection.Ltr) {
|
||||||
|
parentWidth.toPx() - editIconRadius.toPx() * 0.48f
|
||||||
|
} else {
|
||||||
|
editIconRadius.toPx() * 0.48f
|
||||||
|
},
|
||||||
|
y = size.height - editIconRadius.toPx(),
|
||||||
|
),
|
||||||
|
radius = editIconRadius.toPx() * 1.2f,
|
||||||
|
blendMode = BlendMode.Clear,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
when (state) {
|
||||||
|
is AvatarPickerState.Pick -> {
|
||||||
|
PickButton(
|
||||||
|
buttonSize = state.buttonSize,
|
||||||
|
iconSize = state.iconSize,
|
||||||
|
iconId = state.iconId,
|
||||||
|
modifier = modifier.padding(state.externalPadding).then(clickableModifier),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is AvatarPickerState.Selected -> {
|
||||||
|
Box(modifier = modifier) {
|
||||||
|
Avatar(
|
||||||
|
avatarData = state.avatarData,
|
||||||
|
avatarType = state.type,
|
||||||
|
modifier = clickableModifier.then(eraseBackgroundModifier(state.avatarData.size.dp, state.avatarData.size.dp * 0.225f)),
|
||||||
|
)
|
||||||
|
|
||||||
|
OverlayEditButton(editButtonSize = state.avatarData.size.dp * 0.44f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun PickButton(
|
||||||
|
buttonSize: Dp,
|
||||||
|
iconSize: Dp,
|
||||||
|
@DrawableRes iconId: Int,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = modifier
|
||||||
|
.size(buttonSize)
|
||||||
|
.clip(CircleShape)
|
||||||
|
.border(BorderStroke(1.dp, ElementTheme.colors.borderInteractiveSecondary), shape = CircleShape)
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
resourceId = iconId,
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.Center)
|
||||||
|
.size(iconSize),
|
||||||
|
tint = ElementTheme.colors.iconPrimary,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun BoxScope.OverlayEditButton(editButtonSize: Dp) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.align(Alignment.BottomEnd)
|
||||||
|
.size(editButtonSize)
|
||||||
|
.offset(x = editButtonSize * 0.266f)
|
||||||
|
.clip(CircleShape)
|
||||||
|
.background(ElementTheme.colors.bgCanvasDefault)
|
||||||
|
.border(BorderStroke(1.dp, ElementTheme.colors.borderInteractiveSecondary), shape = CircleShape),
|
||||||
|
contentAlignment = Alignment.Center,
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
modifier = Modifier.size(editButtonSize * 0.66f),
|
||||||
|
imageVector = CompoundIcons.Edit(),
|
||||||
|
contentDescription = null,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
sealed interface AvatarPickerState {
|
||||||
|
data class Pick(
|
||||||
|
val buttonSize: Dp,
|
||||||
|
val iconSize: Dp = buttonSize / 2,
|
||||||
|
val externalPadding: PaddingValues = PaddingValues.Zero,
|
||||||
|
@DrawableRes val iconId: Int = CompoundDrawables.ic_compound_take_photo,
|
||||||
|
) : AvatarPickerState
|
||||||
|
|
||||||
|
data class Selected(
|
||||||
|
val avatarData: AvatarData,
|
||||||
|
val type: AvatarType,
|
||||||
|
) : AvatarPickerState
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreviewsDayNight
|
||||||
|
@Composable
|
||||||
|
internal fun AvatarPickerViewPreview() = ElementPreview {
|
||||||
|
PreviewContent()
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreviewsDayNight
|
||||||
|
@Composable
|
||||||
|
internal fun AvatarPickerViewRtlPreview() = CompositionLocalProvider(
|
||||||
|
LocalLayoutDirection provides LayoutDirection.Rtl,
|
||||||
|
) {
|
||||||
|
ElementPreview { PreviewContent() }
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreviewsDayNight
|
||||||
|
@Composable
|
||||||
|
internal fun AvatarPickerSizesPreview() = ElementPreview {
|
||||||
|
Column {
|
||||||
|
Row {
|
||||||
|
AvatarPickerView(AvatarPickerState.Pick(buttonSize = 24.dp, externalPadding = PaddingValues(6.dp)), onClick = {})
|
||||||
|
AvatarPickerView(AvatarPickerState.Pick(buttonSize = 32.dp, externalPadding = PaddingValues(6.dp)), onClick = {})
|
||||||
|
AvatarPickerView(AvatarPickerState.Pick(buttonSize = 48.dp, externalPadding = PaddingValues(6.dp)), onClick = {})
|
||||||
|
AvatarPickerView(AvatarPickerState.Pick(buttonSize = 64.dp, externalPadding = PaddingValues(6.dp)), onClick = {})
|
||||||
|
AvatarPickerView(AvatarPickerState.Pick(buttonSize = 96.dp, externalPadding = PaddingValues(6.dp)), onClick = {})
|
||||||
|
}
|
||||||
|
Row {
|
||||||
|
AvatarPickerView(
|
||||||
|
AvatarPickerState.Selected(
|
||||||
|
avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.TimelineThreadLatestEventSender),
|
||||||
|
type = AvatarType.User
|
||||||
|
),
|
||||||
|
onClick = {},
|
||||||
|
modifier = Modifier.padding(6.dp)
|
||||||
|
)
|
||||||
|
AvatarPickerView(
|
||||||
|
AvatarPickerState.Selected(
|
||||||
|
avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.ReadReceiptList),
|
||||||
|
type = AvatarType.User
|
||||||
|
),
|
||||||
|
onClick = {},
|
||||||
|
modifier = Modifier.padding(6.dp)
|
||||||
|
)
|
||||||
|
AvatarPickerView(
|
||||||
|
AvatarPickerState.Selected(
|
||||||
|
avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.SelectedUser),
|
||||||
|
type = AvatarType.User
|
||||||
|
),
|
||||||
|
onClick = {},
|
||||||
|
modifier = Modifier.padding(6.dp)
|
||||||
|
)
|
||||||
|
AvatarPickerView(
|
||||||
|
AvatarPickerState.Selected(
|
||||||
|
avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.EditRoomDetails),
|
||||||
|
type = AvatarType.User
|
||||||
|
),
|
||||||
|
onClick = {},
|
||||||
|
modifier = Modifier.padding(6.dp)
|
||||||
|
)
|
||||||
|
AvatarPickerView(
|
||||||
|
AvatarPickerState.Selected(
|
||||||
|
avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.RoomListManageUser),
|
||||||
|
type = AvatarType.User
|
||||||
|
),
|
||||||
|
onClick = {},
|
||||||
|
modifier = Modifier.padding(6.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Row {
|
||||||
|
AvatarPickerView(
|
||||||
|
AvatarPickerState.Selected(
|
||||||
|
avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.TimelineThreadLatestEventSender),
|
||||||
|
type = AvatarType.Space()
|
||||||
|
),
|
||||||
|
onClick = {},
|
||||||
|
modifier = Modifier.padding(6.dp)
|
||||||
|
)
|
||||||
|
AvatarPickerView(
|
||||||
|
AvatarPickerState.Selected(
|
||||||
|
avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.ReadReceiptList),
|
||||||
|
type = AvatarType.Space()
|
||||||
|
),
|
||||||
|
onClick = {},
|
||||||
|
modifier = Modifier.padding(6.dp)
|
||||||
|
)
|
||||||
|
AvatarPickerView(
|
||||||
|
AvatarPickerState.Selected(
|
||||||
|
avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.SelectedUser),
|
||||||
|
type = AvatarType.Space()
|
||||||
|
),
|
||||||
|
onClick = {},
|
||||||
|
modifier = Modifier.padding(6.dp)
|
||||||
|
)
|
||||||
|
AvatarPickerView(
|
||||||
|
AvatarPickerState.Selected(
|
||||||
|
avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.EditRoomDetails),
|
||||||
|
type = AvatarType.Space()
|
||||||
|
),
|
||||||
|
onClick = {},
|
||||||
|
modifier = Modifier.padding(6.dp)
|
||||||
|
)
|
||||||
|
AvatarPickerView(
|
||||||
|
AvatarPickerState.Selected(
|
||||||
|
avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.RoomListManageUser),
|
||||||
|
type = AvatarType.Space()
|
||||||
|
),
|
||||||
|
onClick = {},
|
||||||
|
modifier = Modifier.padding(6.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun PreviewContent() {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
|
) {
|
||||||
|
Text("Pick image")
|
||||||
|
AvatarPickerView(AvatarPickerState.Pick(buttonSize = 48.dp, externalPadding = PaddingValues(6.dp)), onClick = {})
|
||||||
|
HorizontalDivider()
|
||||||
|
|
||||||
|
Text("User avatar")
|
||||||
|
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly) {
|
||||||
|
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||||
|
Text("No url")
|
||||||
|
AvatarPickerView(
|
||||||
|
AvatarPickerState.Selected(
|
||||||
|
avatarData = AvatarData("@user:example.com", "User", null, size = AvatarSize.EditRoomDetails),
|
||||||
|
type = AvatarType.User
|
||||||
|
),
|
||||||
|
onClick = {},
|
||||||
|
modifier = Modifier.padding(10.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||||
|
Text("Local")
|
||||||
|
AvatarPickerView(
|
||||||
|
AvatarPickerState.Selected(
|
||||||
|
avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.EditRoomDetails),
|
||||||
|
type = AvatarType.User
|
||||||
|
),
|
||||||
|
onClick = {},
|
||||||
|
modifier = Modifier.padding(10.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||||
|
Text("MXC")
|
||||||
|
AvatarPickerView(
|
||||||
|
AvatarPickerState.Selected(
|
||||||
|
avatarData = AvatarData("@user:example.com", "User", "mxc://test", size = AvatarSize.EditRoomDetails),
|
||||||
|
type = AvatarType.User
|
||||||
|
),
|
||||||
|
onClick = {},
|
||||||
|
modifier = Modifier.padding(10.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HorizontalDivider()
|
||||||
|
|
||||||
|
Text("Room avatar")
|
||||||
|
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly) {
|
||||||
|
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||||
|
Text("No url")
|
||||||
|
AvatarPickerView(
|
||||||
|
AvatarPickerState.Selected(
|
||||||
|
avatarData = AvatarData("!room:example.com", "Room", null, size = AvatarSize.EditRoomDetails),
|
||||||
|
type = AvatarType.Room()
|
||||||
|
),
|
||||||
|
onClick = {},
|
||||||
|
modifier = Modifier.padding(10.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||||
|
Text("Local")
|
||||||
|
AvatarPickerView(
|
||||||
|
AvatarPickerState.Selected(
|
||||||
|
avatarData = AvatarData("!room:example.com", "Room", "content://test", size = AvatarSize.EditRoomDetails),
|
||||||
|
type = AvatarType.Room()
|
||||||
|
),
|
||||||
|
onClick = {},
|
||||||
|
modifier = Modifier.padding(10.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||||
|
Text("MXC")
|
||||||
|
AvatarPickerView(
|
||||||
|
AvatarPickerState.Selected(
|
||||||
|
avatarData = AvatarData("!room:example.com", "Room", "mxc://test", size = AvatarSize.EditRoomDetails),
|
||||||
|
type = AvatarType.Room()
|
||||||
|
),
|
||||||
|
onClick = {},
|
||||||
|
modifier = Modifier.padding(10.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HorizontalDivider()
|
||||||
|
|
||||||
|
Text("Space avatar")
|
||||||
|
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly) {
|
||||||
|
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||||
|
Text("No url")
|
||||||
|
AvatarPickerView(
|
||||||
|
AvatarPickerState.Selected(
|
||||||
|
avatarData = AvatarData("!room:example.com", "Space", null, size = AvatarSize.EditRoomDetails),
|
||||||
|
type = AvatarType.Space()
|
||||||
|
),
|
||||||
|
onClick = {},
|
||||||
|
modifier = Modifier.padding(10.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||||
|
Text("Local")
|
||||||
|
AvatarPickerView(
|
||||||
|
AvatarPickerState.Selected(
|
||||||
|
avatarData = AvatarData("!room:example.com", "Space", "content://test", size = AvatarSize.EditRoomDetails),
|
||||||
|
type = AvatarType.Space()
|
||||||
|
),
|
||||||
|
onClick = {},
|
||||||
|
modifier = Modifier.padding(10.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||||
|
Text("MXC")
|
||||||
|
AvatarPickerView(
|
||||||
|
AvatarPickerState.Selected(
|
||||||
|
avatarData = AvatarData("!room:example.com", "Space", "mxc://test", size = AvatarSize.EditRoomDetails),
|
||||||
|
type = AvatarType.Space()
|
||||||
|
),
|
||||||
|
onClick = {},
|
||||||
|
modifier = Modifier.padding(10.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,157 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2025 Element Creations Ltd.
|
|
||||||
* Copyright 2023-2025 New Vector Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
|
||||||
* Please see LICENSE files in the repository root for full details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.element.android.libraries.matrix.ui.components
|
|
||||||
|
|
||||||
import androidx.compose.foundation.border
|
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.layout.size
|
|
||||||
import androidx.compose.foundation.layout.wrapContentSize
|
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
|
||||||
import androidx.compose.material3.ripple
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.draw.drawWithContent
|
|
||||||
import androidx.compose.ui.geometry.Offset
|
|
||||||
import androidx.compose.ui.graphics.BlendMode
|
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.graphics.CompositingStrategy
|
|
||||||
import androidx.compose.ui.graphics.graphicsLayer
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.semantics.clearAndSetSemantics
|
|
||||||
import androidx.compose.ui.semantics.contentDescription
|
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
|
||||||
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.libraries.designsystem.components.avatar.Avatar
|
|
||||||
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
|
||||||
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
|
||||||
import io.element.android.libraries.designsystem.components.avatar.AvatarType
|
|
||||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
|
||||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
|
||||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
|
||||||
import io.element.android.libraries.designsystem.utils.CommonDrawables
|
|
||||||
import io.element.android.libraries.testtags.TestTags
|
|
||||||
import io.element.android.libraries.testtags.testTag
|
|
||||||
import io.element.android.libraries.ui.strings.CommonStrings
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun EditableAvatarView(
|
|
||||||
matrixId: String,
|
|
||||||
displayName: String?,
|
|
||||||
avatarUrl: String?,
|
|
||||||
avatarSize: AvatarSize,
|
|
||||||
avatarType: AvatarType,
|
|
||||||
onAvatarClick: () -> Unit,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
enabled: Boolean = true,
|
|
||||||
) {
|
|
||||||
val a11yAvatar = stringResource(CommonStrings.a11y_avatar)
|
|
||||||
val editIconRadius = 15.dp
|
|
||||||
val parentHeight = avatarSize.dp
|
|
||||||
val parentWidth = avatarSize.dp + editIconRadius / 2f
|
|
||||||
Box(
|
|
||||||
modifier = modifier
|
|
||||||
.wrapContentSize()
|
|
||||||
.size(height = parentHeight, width = parentWidth)
|
|
||||||
.clickable(
|
|
||||||
enabled = enabled,
|
|
||||||
interactionSource = remember { MutableInteractionSource() },
|
|
||||||
onClickLabel = stringResource(CommonStrings.a11y_edit_avatar),
|
|
||||||
onClick = onAvatarClick,
|
|
||||||
indication = ripple(bounded = false),
|
|
||||||
)
|
|
||||||
.testTag(TestTags.editAvatar)
|
|
||||||
.clearAndSetSemantics {
|
|
||||||
contentDescription = a11yAvatar
|
|
||||||
},
|
|
||||||
) {
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.graphicsLayer {
|
|
||||||
compositingStrategy = CompositingStrategy.Offscreen
|
|
||||||
}
|
|
||||||
.drawWithContent {
|
|
||||||
drawContent()
|
|
||||||
drawCircle(
|
|
||||||
color = Color.Black,
|
|
||||||
center = Offset(
|
|
||||||
x = parentWidth.toPx() - editIconRadius.toPx(),
|
|
||||||
y = size.height - editIconRadius.toPx(),
|
|
||||||
),
|
|
||||||
radius = (editIconRadius + 4.dp).toPx(),
|
|
||||||
blendMode = BlendMode.Clear,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
when {
|
|
||||||
avatarUrl == null || avatarUrl.startsWith("mxc://") -> {
|
|
||||||
Avatar(
|
|
||||||
avatarData = AvatarData(
|
|
||||||
id = matrixId,
|
|
||||||
name = displayName,
|
|
||||||
url = avatarUrl,
|
|
||||||
size = avatarSize,
|
|
||||||
),
|
|
||||||
avatarType = avatarType,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
UnsavedAvatar(
|
|
||||||
avatarUri = avatarUrl,
|
|
||||||
avatarSize = avatarSize,
|
|
||||||
avatarType = avatarType,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Icon(
|
|
||||||
modifier = Modifier
|
|
||||||
.align(Alignment.BottomEnd)
|
|
||||||
.size(editIconRadius * 2)
|
|
||||||
.border(1.dp, ElementTheme.colors.borderInteractiveSecondary, CircleShape)
|
|
||||||
.padding(6.dp),
|
|
||||||
imageVector = CompoundIcons.Edit(),
|
|
||||||
contentDescription = null,
|
|
||||||
tint = ElementTheme.colors.iconPrimary,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@PreviewsDayNight
|
|
||||||
@Composable
|
|
||||||
internal fun EditableAvatarViewPreview(
|
|
||||||
@PreviewParameter(EditableAvatarViewUriProvider::class) uri: String?
|
|
||||||
) = ElementPreview(
|
|
||||||
drawableFallbackForImages = CommonDrawables.sample_avatar,
|
|
||||||
) {
|
|
||||||
EditableAvatarView(
|
|
||||||
matrixId = "id",
|
|
||||||
displayName = "Room",
|
|
||||||
avatarUrl = uri,
|
|
||||||
avatarSize = AvatarSize.RoomDetailsHeader,
|
|
||||||
avatarType = AvatarType.User,
|
|
||||||
onAvatarClick = {},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
open class EditableAvatarViewUriProvider : PreviewParameterProvider<String?> {
|
|
||||||
override val values: Sequence<String?>
|
|
||||||
get() = sequenceOf(
|
|
||||||
null,
|
|
||||||
"mxc://matrix.org/123456",
|
|
||||||
"https://example.com/avatar.jpg",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
@ -1,93 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2025 Element Creations Ltd.
|
|
||||||
* Copyright 2023-2025 New Vector Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
|
||||||
* Please see LICENSE files in the repository root for full details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.element.android.libraries.matrix.ui.components
|
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.layout.size
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.outlined.AddAPhoto
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
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.painter.ColorPainter
|
|
||||||
import androidx.compose.ui.layout.ContentScale
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import coil3.compose.AsyncImage
|
|
||||||
import coil3.request.ImageRequest
|
|
||||||
import io.element.android.compound.theme.ElementTheme
|
|
||||||
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.avatar.avatarShape
|
|
||||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
|
||||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
|
||||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
|
||||||
import io.element.android.libraries.designsystem.theme.temporaryColorBgSpecial
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An avatar that the user has selected, but which has not yet been uploaded to Matrix.
|
|
||||||
*
|
|
||||||
* The image is loaded from a local resource instead of from a MXC URI.
|
|
||||||
*/
|
|
||||||
@Composable
|
|
||||||
fun UnsavedAvatar(
|
|
||||||
avatarUri: String?,
|
|
||||||
avatarSize: AvatarSize,
|
|
||||||
avatarType: AvatarType,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
val commonModifier = modifier
|
|
||||||
.size(avatarSize.dp)
|
|
||||||
.clip(avatarType.avatarShape(avatarSize.dp))
|
|
||||||
|
|
||||||
if (avatarUri != null) {
|
|
||||||
val context = LocalContext.current
|
|
||||||
val model = ImageRequest.Builder(context)
|
|
||||||
.data(avatarUri)
|
|
||||||
.build()
|
|
||||||
AsyncImage(
|
|
||||||
modifier = commonModifier,
|
|
||||||
model = model,
|
|
||||||
placeholder = ColorPainter(MaterialTheme.colorScheme.surfaceVariant),
|
|
||||||
contentScale = ContentScale.Crop,
|
|
||||||
contentDescription = null,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
Box(modifier = commonModifier.background(ElementTheme.colors.temporaryColorBgSpecial)) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Outlined.AddAPhoto,
|
|
||||||
contentDescription = null,
|
|
||||||
modifier = Modifier
|
|
||||||
.align(Alignment.Center)
|
|
||||||
.size(avatarSize.dp * 4 / 7),
|
|
||||||
tint = ElementTheme.colors.iconSecondary,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@PreviewsDayNight
|
|
||||||
@Composable
|
|
||||||
internal fun UnsavedAvatarPreview() = ElementPreview {
|
|
||||||
Row(
|
|
||||||
modifier = Modifier.padding(8.dp),
|
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
|
||||||
) {
|
|
||||||
UnsavedAvatar(null, AvatarSize.EditRoomDetails, AvatarType.User)
|
|
||||||
UnsavedAvatar("", AvatarSize.EditRoomDetails, AvatarType.User)
|
|
||||||
UnsavedAvatar(null, AvatarSize.EditRoomDetails, AvatarType.Space())
|
|
||||||
UnsavedAvatar("", AvatarSize.EditRoomDetails, AvatarType.Space())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -27,7 +27,7 @@ fun RoomAddressField(
|
||||||
homeserverName: String,
|
homeserverName: String,
|
||||||
addressValidity: RoomAddressValidity,
|
addressValidity: RoomAddressValidity,
|
||||||
onAddressChange: (String) -> Unit,
|
onAddressChange: (String) -> Unit,
|
||||||
label: String,
|
label: String?,
|
||||||
supportingText: String,
|
supportingText: String,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@
|
||||||
<string name="a11y_your_avatar">"Your avatar"</string>
|
<string name="a11y_your_avatar">"Your avatar"</string>
|
||||||
<string name="action_accept">"Accept"</string>
|
<string name="action_accept">"Accept"</string>
|
||||||
<string name="action_add_caption">"Add caption"</string>
|
<string name="action_add_caption">"Add caption"</string>
|
||||||
|
<string name="action_add_existing_rooms">"Add existing rooms"</string>
|
||||||
<string name="action_add_to_timeline">"Add to timeline"</string>
|
<string name="action_add_to_timeline">"Add to timeline"</string>
|
||||||
<string name="action_back">"Back"</string>
|
<string name="action_back">"Back"</string>
|
||||||
<string name="action_call">"Call"</string>
|
<string name="action_call">"Call"</string>
|
||||||
|
|
@ -75,6 +76,7 @@
|
||||||
<string name="action_copy_text">"Copy text"</string>
|
<string name="action_copy_text">"Copy text"</string>
|
||||||
<string name="action_create">"Create"</string>
|
<string name="action_create">"Create"</string>
|
||||||
<string name="action_create_a_room">"Create a room"</string>
|
<string name="action_create_a_room">"Create a room"</string>
|
||||||
|
<string name="action_create_space">"Create space"</string>
|
||||||
<string name="action_deactivate">"Deactivate"</string>
|
<string name="action_deactivate">"Deactivate"</string>
|
||||||
<string name="action_deactivate_account">"Deactivate account"</string>
|
<string name="action_deactivate_account">"Deactivate account"</string>
|
||||||
<string name="action_decline">"Decline"</string>
|
<string name="action_decline">"Decline"</string>
|
||||||
|
|
@ -112,6 +114,7 @@
|
||||||
<string name="action_load_more">"Load more"</string>
|
<string name="action_load_more">"Load more"</string>
|
||||||
<string name="action_manage_account">"Manage account"</string>
|
<string name="action_manage_account">"Manage account"</string>
|
||||||
<string name="action_manage_devices">"Manage devices"</string>
|
<string name="action_manage_devices">"Manage devices"</string>
|
||||||
|
<string name="action_manage_rooms">"Manage rooms"</string>
|
||||||
<string name="action_message">"Message"</string>
|
<string name="action_message">"Message"</string>
|
||||||
<string name="action_minimize">"Minimise"</string>
|
<string name="action_minimize">"Minimise"</string>
|
||||||
<string name="action_next">"Next"</string>
|
<string name="action_next">"Next"</string>
|
||||||
|
|
@ -191,6 +194,7 @@
|
||||||
<string name="common_copied_to_clipboard">"Copied to clipboard"</string>
|
<string name="common_copied_to_clipboard">"Copied to clipboard"</string>
|
||||||
<string name="common_copyright">"Copyright"</string>
|
<string name="common_copyright">"Copyright"</string>
|
||||||
<string name="common_creating_room">"Creating room…"</string>
|
<string name="common_creating_room">"Creating room…"</string>
|
||||||
|
<string name="common_creating_space">"Creating space…"</string>
|
||||||
<string name="common_current_user_canceled_knock">"Request canceled"</string>
|
<string name="common_current_user_canceled_knock">"Request canceled"</string>
|
||||||
<string name="common_current_user_left_room">"Left room"</string>
|
<string name="common_current_user_left_room">"Left room"</string>
|
||||||
<string name="common_current_user_left_space">"Left space"</string>
|
<string name="common_current_user_left_space">"Left space"</string>
|
||||||
|
|
@ -337,6 +341,7 @@ Reason: %1$s."</string>
|
||||||
<string name="common_starting_chat">"Starting chat…"</string>
|
<string name="common_starting_chat">"Starting chat…"</string>
|
||||||
<string name="common_sticker">"Sticker"</string>
|
<string name="common_sticker">"Sticker"</string>
|
||||||
<string name="common_success">"Success"</string>
|
<string name="common_success">"Success"</string>
|
||||||
|
<string name="common_suggested">"Suggested"</string>
|
||||||
<string name="common_suggestions">"Suggestions"</string>
|
<string name="common_suggestions">"Suggestions"</string>
|
||||||
<string name="common_syncing">"Syncing"</string>
|
<string name="common_syncing">"Syncing"</string>
|
||||||
<string name="common_system">"System"</string>
|
<string name="common_system">"System"</string>
|
||||||
|
|
@ -473,6 +478,7 @@ Are you sure you want to continue?"</string>
|
||||||
<string name="screen_share_this_location_action">"Share this location"</string>
|
<string name="screen_share_this_location_action">"Share this location"</string>
|
||||||
<string name="screen_space_list_description">"Spaces you have created or joined."</string>
|
<string name="screen_space_list_description">"Spaces you have created or joined."</string>
|
||||||
<string name="screen_space_list_details">"%1$s • %2$s"</string>
|
<string name="screen_space_list_details">"%1$s • %2$s"</string>
|
||||||
|
<string name="screen_space_list_empty_state_title">"Create spaces to organize rooms"</string>
|
||||||
<string name="screen_space_list_parent_space">"%1$s space"</string>
|
<string name="screen_space_list_parent_space">"%1$s space"</string>
|
||||||
<string name="screen_space_list_title">"Spaces"</string>
|
<string name="screen_space_list_title">"Spaces"</string>
|
||||||
<string name="screen_space_menu_action_members">"View members"</string>
|
<string name="screen_space_menu_action_members">"View members"</string>
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,9 @@ class KonsistPreviewTest {
|
||||||
private val previewNameExceptions = listOf(
|
private val previewNameExceptions = listOf(
|
||||||
"AsyncIndicatorFailurePreview",
|
"AsyncIndicatorFailurePreview",
|
||||||
"AsyncIndicatorLoadingPreview",
|
"AsyncIndicatorLoadingPreview",
|
||||||
|
"AvatarPickerSizesPreview",
|
||||||
|
"AvatarPickerViewPreview",
|
||||||
|
"AvatarPickerViewRtlPreview",
|
||||||
"BackgroundVerticalGradientDisabledPreview",
|
"BackgroundVerticalGradientDisabledPreview",
|
||||||
"BackgroundVerticalGradientPreview",
|
"BackgroundVerticalGradientPreview",
|
||||||
"ColorAliasesPreview",
|
"ColorAliasesPreview",
|
||||||
|
|
@ -86,6 +89,7 @@ class KonsistPreviewTest {
|
||||||
"GradientFloatingActionButtonCircleShapePreview",
|
"GradientFloatingActionButtonCircleShapePreview",
|
||||||
"HeaderFooterPageScrollablePreview",
|
"HeaderFooterPageScrollablePreview",
|
||||||
"HomeTopBarMultiAccountPreview",
|
"HomeTopBarMultiAccountPreview",
|
||||||
|
"HomeTopBarSpacesPreview",
|
||||||
"HomeTopBarWithIndicatorPreview",
|
"HomeTopBarWithIndicatorPreview",
|
||||||
"IconsOtherPreview",
|
"IconsOtherPreview",
|
||||||
"MarkdownTextComposerEditPreview",
|
"MarkdownTextComposerEditPreview",
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:61d96e2f91d217a1112421633426692fc5a2c35e9756d4980bd75fb3088a4b8f
|
oid sha256:9719e20a56fa6bcbd6afd5fd4cef5877af0d0664dfb9559e84dd332d1a161b7f
|
||||||
size 29568
|
size 29538
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:4cf57997e6ca0c7244811154564f27c2af135f0a85dc4598e16df51251096b65
|
oid sha256:20c185481e6a13fbccae6e4d8c02752222f8cfcc5c03398c255666beb5df5cc4
|
||||||
size 35844
|
size 34243
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:6f8f4593373a4229d852a8b4e2e3b937796e45135a032afbbd0563a4fa5e651c
|
oid sha256:2d0fb8d4c5acde1b03908f15eb959d3e544917a53c529f5971804eb674f989fa
|
||||||
size 56375
|
size 41893
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:5c80c8f9ee81b35b6054a10872e14d4fc4d8654b7747a620ea4b9a79d3595265
|
oid sha256:a601ab64bac5f2c11480892e4b81dcaf3b9fe72afd222f6f42d1e5f577220a8c
|
||||||
size 56756
|
size 42786
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:27c31889281d6ba95448b033a07f1e41bc1c55bed26840cc796283a0f9368bf0
|
oid sha256:f8a2dd4b01f32b9325e9adf8340f18b6776ff20c06f4e27590bde207d802b3c8
|
||||||
size 58454
|
size 44542
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:6f8f4593373a4229d852a8b4e2e3b937796e45135a032afbbd0563a4fa5e651c
|
oid sha256:2d0fb8d4c5acde1b03908f15eb959d3e544917a53c529f5971804eb674f989fa
|
||||||
size 56375
|
size 41893
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:f0f2a05605785d5a9484e6e34b03c6074125927f6b8130f5e60f54e3922d7bc4
|
||||||
|
size 42863
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:f3e9fb42af90f7db14c02d572366ce59808ebd551cac7cc8552ee308d65f7c83
|
oid sha256:9c955974f899511eb023e0b25f067cff55edd6d360ebbba5081df5662445d0e4
|
||||||
size 30607
|
size 30753
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:3b9bb30aec0b92dd5d352dd9dec4d26177ecb38a10c2984bab5c4bd4584b9b2d
|
oid sha256:fd25259e89b4a8833c884727d23fb503b53099b698ff2eafd812bf70422b5cbe
|
||||||
size 36992
|
size 35631
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:0c7b44d045dbea3f47c774465be245046e972ade8ad6b9240df956c685dcbd59
|
oid sha256:30a4f34c42cb57b3cbd08114fef8531175890d46d0033f0dc5d1337189e33d1c
|
||||||
size 58228
|
size 43653
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:3ee8385caada3a2739834bbabe1411d2f6da4d645d5b99cf07a6da96fe5eabb9
|
oid sha256:ab5d721149a96e53f850d7792653b0b71d41124c0db82d653ad79c66c72dabee
|
||||||
size 58584
|
size 44600
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:fb1bff539ab70b3d8bb8ae5f5490374e855c9b7807d1868b0aa1cffacc10e1f5
|
oid sha256:b7a8c9c3cb8f877d3dc2deb1b918666143c73aed34fdd3d3961bc2530f32d0f5
|
||||||
size 60382
|
size 46369
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:0c7b44d045dbea3f47c774465be245046e972ade8ad6b9240df956c685dcbd59
|
oid sha256:30a4f34c42cb57b3cbd08114fef8531175890d46d0033f0dc5d1337189e33d1c
|
||||||
size 58228
|
size 43653
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:d3cb687ded32d38164cb67657b495958f1632457d1e49ede0d8c9f1b1f5a287b
|
||||||
|
size 44675
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:08e7f4dad9666652eea98b7ecf807f2d0050024a59e8b25113b00d7584ff7fa7
|
||||||
|
size 12382
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:d8d8783952c0fd66f6ca762b79061d26abdf6aedbf601266292a6507da674792
|
||||||
|
size 11419
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:542d8ba6a6031fe2789cf111f333eef22acf95281f57421ace2c7b5b0a599cc2
|
||||||
|
size 41140
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:c31cd78bc054610be05012cdba7eb0cbc770435b0e12bc065f6eae4a773ca39e
|
||||||
|
size 40121
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:27c5418d421ca6cf0069e34ca3e22ca807203d252b9c1424eca447f070fbbbdf
|
oid sha256:d398e399f468705b9f78283535c2b0e3f44f8be0456cf99bb9b3611746cd0af2
|
||||||
size 54177
|
size 54380
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:fc4c11b4d2c83b179409083ca36fcb95e44b7d8c51abd23e9c07f4d3be8a339c
|
oid sha256:7fce6676e186e13f14ea8cc8436fdbcadcf41bf84a1999104794bd2245814337
|
||||||
size 52626
|
size 52805
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:5896d5e6fd21697d6270aedb4389eee0d57a9796536b847ae657f57e6c2dab3d
|
oid sha256:4f3dff815d0233a7a3716ec2298e06f78bf3b52806412c4f628a81ed53e841c3
|
||||||
size 20974
|
size 21818
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:95100c25fb085329f8968a765a4f4359678be67309d5e086ead311c48cfda29f
|
oid sha256:bbadbe374c9a0235af368e9ceedd9aadd4cd736ca7f68592a656b2bd854fe3de
|
||||||
size 67826
|
size 63364
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue