Merge pull request #418 from vector-im/feature/fre/create_room_layout_improvements
Create Room - Layouts cleanup
This commit is contained in:
commit
ef684e63fd
20 changed files with 100 additions and 78 deletions
|
|
@ -27,5 +27,5 @@ data class CreateRoomConfig(
|
||||||
val topic: String? = null,
|
val topic: String? = null,
|
||||||
val avatarUri: Uri? = null,
|
val avatarUri: Uri? = null,
|
||||||
val invites: ImmutableList<MatrixUser> = persistentListOf(),
|
val invites: ImmutableList<MatrixUser> = persistentListOf(),
|
||||||
val privacy: RoomPrivacy? = null,
|
val privacy: RoomPrivacy = RoomPrivacy.Private,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ class CreateRoomDataStore @Inject constructor(
|
||||||
createRoomConfigFlow.tryEmit(createRoomConfigFlow.value.copy(avatarUri = uri))
|
createRoomConfigFlow.tryEmit(createRoomConfigFlow.value.copy(avatarUri = uri))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setPrivacy(privacy: RoomPrivacy?) {
|
fun setPrivacy(privacy: RoomPrivacy) {
|
||||||
createRoomConfigFlow.tryEmit(createRoomConfigFlow.value.copy(privacy = privacy))
|
createRoomConfigFlow.tryEmit(createRoomConfigFlow.value.copy(privacy = privacy))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@ fun LabelledTextField(
|
||||||
value = value,
|
value = value,
|
||||||
placeholder = { Text(placeholder) },
|
placeholder = { Text(placeholder) },
|
||||||
onValueChange = onValueChange,
|
onValueChange = onValueChange,
|
||||||
|
singleLine = maxLines == 1,
|
||||||
maxLines = maxLines,
|
maxLines = maxLines,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ import io.element.android.libraries.matrix.api.user.MatrixUser
|
||||||
sealed interface ConfigureRoomEvents {
|
sealed interface ConfigureRoomEvents {
|
||||||
data class RoomNameChanged(val name: String) : ConfigureRoomEvents
|
data class RoomNameChanged(val name: String) : ConfigureRoomEvents
|
||||||
data class TopicChanged(val topic: String) : ConfigureRoomEvents
|
data class TopicChanged(val topic: String) : ConfigureRoomEvents
|
||||||
data class RoomPrivacyChanged(val privacy: RoomPrivacy?) : ConfigureRoomEvents
|
data class RoomPrivacyChanged(val privacy: RoomPrivacy) : ConfigureRoomEvents
|
||||||
data class RemoveFromSelection(val matrixUser: MatrixUser) : ConfigureRoomEvents
|
data class RemoveFromSelection(val matrixUser: MatrixUser) : ConfigureRoomEvents
|
||||||
data class CreateRoom(val config: CreateRoomConfig) : ConfigureRoomEvents
|
data class CreateRoom(val config: CreateRoomConfig) : ConfigureRoomEvents
|
||||||
data class HandleAvatarAction(val action: AvatarAction) : ConfigureRoomEvents
|
data class HandleAvatarAction(val action: AvatarAction) : ConfigureRoomEvents
|
||||||
|
|
|
||||||
|
|
@ -56,11 +56,6 @@ class ConfigureRoomPresenter @Inject constructor(
|
||||||
@Composable
|
@Composable
|
||||||
override fun present(): ConfigureRoomState {
|
override fun present(): ConfigureRoomState {
|
||||||
val createRoomConfig = dataStore.getCreateRoomConfig().collectAsState(CreateRoomConfig())
|
val createRoomConfig = dataStore.getCreateRoomConfig().collectAsState(CreateRoomConfig())
|
||||||
val isCreateButtonEnabled by remember(createRoomConfig.value.roomName, createRoomConfig.value.privacy) {
|
|
||||||
derivedStateOf {
|
|
||||||
createRoomConfig.value.roomName.isNullOrEmpty().not() && createRoomConfig.value.privacy != null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val cameraPhotoPicker = mediaPickerProvider.registerCameraPhotoPicker(
|
val cameraPhotoPicker = mediaPickerProvider.registerCameraPhotoPicker(
|
||||||
onResult = { uri -> if (uri != null) dataStore.setAvatarUri(uri = uri, cached = true) },
|
onResult = { uri -> if (uri != null) dataStore.setAvatarUri(uri = uri, cached = true) },
|
||||||
|
|
@ -108,7 +103,6 @@ class ConfigureRoomPresenter @Inject constructor(
|
||||||
|
|
||||||
return ConfigureRoomState(
|
return ConfigureRoomState(
|
||||||
config = createRoomConfig.value,
|
config = createRoomConfig.value,
|
||||||
isCreateButtonEnabled = isCreateButtonEnabled,
|
|
||||||
avatarActions = avatarActions,
|
avatarActions = avatarActions,
|
||||||
createRoomAction = createRoomAction.value,
|
createRoomAction = createRoomAction.value,
|
||||||
eventSink = ::handleEvents,
|
eventSink = ::handleEvents,
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,9 @@ import kotlinx.collections.immutable.ImmutableList
|
||||||
|
|
||||||
data class ConfigureRoomState(
|
data class ConfigureRoomState(
|
||||||
val config: CreateRoomConfig,
|
val config: CreateRoomConfig,
|
||||||
val isCreateButtonEnabled: Boolean,
|
|
||||||
val avatarActions: ImmutableList<AvatarAction>,
|
val avatarActions: ImmutableList<AvatarAction>,
|
||||||
val createRoomAction: Async<RoomId>,
|
val createRoomAction: Async<RoomId>,
|
||||||
val eventSink: (ConfigureRoomEvents) -> Unit
|
val eventSink: (ConfigureRoomEvents) -> Unit
|
||||||
)
|
) {
|
||||||
|
val isCreateButtonEnabled: Boolean = config.roomName.isNullOrEmpty().not()
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,16 +31,14 @@ open class ConfigureRoomStateProvider : PreviewParameterProvider<ConfigureRoomSt
|
||||||
roomName = "Room 101",
|
roomName = "Room 101",
|
||||||
topic = "Room topic for this room when the text goes onto multiple lines and is really long, there shouldn’t be more than 3 lines",
|
topic = "Room topic for this room when the text goes onto multiple lines and is really long, there shouldn’t be more than 3 lines",
|
||||||
invites = aListOfSelectedUsers(),
|
invites = aListOfSelectedUsers(),
|
||||||
privacy = RoomPrivacy.Private,
|
privacy = RoomPrivacy.Public,
|
||||||
),
|
),
|
||||||
isCreateButtonEnabled = true,
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun aConfigureRoomState() = ConfigureRoomState(
|
fun aConfigureRoomState() = ConfigureRoomState(
|
||||||
config = CreateRoomConfig(),
|
config = CreateRoomConfig(),
|
||||||
isCreateButtonEnabled = false,
|
|
||||||
avatarActions = persistentListOf(),
|
avatarActions = persistentListOf(),
|
||||||
createRoomAction = Async.Uninitialized,
|
createRoomAction = Async.Uninitialized,
|
||||||
eventSink = { },
|
eventSink = { },
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,13 @@
|
||||||
package io.element.android.features.createroom.impl.configureroom
|
package io.element.android.features.createroom.impl.configureroom
|
||||||
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import androidx.compose.foundation.gestures.detectTapGestures
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
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.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.selection.selectableGroup
|
import androidx.compose.foundation.selection.selectableGroup
|
||||||
import androidx.compose.material.ExperimentalMaterialApi
|
import androidx.compose.material.ExperimentalMaterialApi
|
||||||
import androidx.compose.material.ModalBottomSheetValue
|
import androidx.compose.material.ModalBottomSheetValue
|
||||||
|
|
@ -33,6 +34,9 @@ import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.focus.FocusManager
|
||||||
|
import androidx.compose.ui.input.pointer.pointerInput
|
||||||
|
import androidx.compose.ui.platform.LocalFocusManager
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
|
@ -68,6 +72,7 @@ fun ConfigureRoomView(
|
||||||
onRoomCreated: (RoomId) -> Unit = {},
|
onRoomCreated: (RoomId) -> Unit = {},
|
||||||
) {
|
) {
|
||||||
val coroutineScope = rememberCoroutineScope()
|
val coroutineScope = rememberCoroutineScope()
|
||||||
|
val focusManager = LocalFocusManager.current
|
||||||
val itemActionsBottomSheetState = rememberModalBottomSheetState(
|
val itemActionsBottomSheetState = rememberModalBottomSheetState(
|
||||||
initialValue = ModalBottomSheetValue.Hidden,
|
initialValue = ModalBottomSheetValue.Hidden,
|
||||||
)
|
)
|
||||||
|
|
@ -79,50 +84,67 @@ fun ConfigureRoomView(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onAvatarClicked() {
|
fun onAvatarClicked() {
|
||||||
|
focusManager.clearFocus()
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
itemActionsBottomSheetState.show()
|
itemActionsBottomSheetState.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = modifier,
|
modifier = modifier.clearFocusOnTap(focusManager),
|
||||||
topBar = {
|
topBar = {
|
||||||
ConfigureRoomToolbar(
|
ConfigureRoomToolbar(
|
||||||
isNextActionEnabled = state.isCreateButtonEnabled,
|
isNextActionEnabled = state.isCreateButtonEnabled,
|
||||||
onBackPressed = onBackPressed,
|
onBackPressed = onBackPressed,
|
||||||
onNextPressed = {
|
onNextPressed = {
|
||||||
|
focusManager.clearFocus()
|
||||||
state.eventSink(ConfigureRoomEvents.CreateRoom(state.config))
|
state.eventSink(ConfigureRoomEvents.CreateRoom(state.config))
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
) { padding ->
|
) { padding ->
|
||||||
Column(
|
LazyColumn(
|
||||||
modifier = Modifier.padding(padding),
|
modifier = Modifier.padding(padding),
|
||||||
verticalArrangement = Arrangement.spacedBy(24.dp),
|
verticalArrangement = Arrangement.spacedBy(24.dp),
|
||||||
) {
|
) {
|
||||||
RoomNameWithAvatar(
|
item {
|
||||||
modifier = Modifier.padding(horizontal = 16.dp),
|
RoomNameWithAvatar(
|
||||||
avatarUri = state.config.avatarUri,
|
modifier = Modifier.padding(horizontal = 16.dp),
|
||||||
roomName = state.config.roomName.orEmpty(),
|
avatarUri = state.config.avatarUri,
|
||||||
onAvatarClick = ::onAvatarClicked,
|
roomName = state.config.roomName.orEmpty(),
|
||||||
onRoomNameChanged = { state.eventSink(ConfigureRoomEvents.RoomNameChanged(it)) },
|
onAvatarClick = ::onAvatarClicked,
|
||||||
)
|
onRoomNameChanged = { state.eventSink(ConfigureRoomEvents.RoomNameChanged(it)) },
|
||||||
RoomTopic(
|
)
|
||||||
modifier = Modifier.padding(horizontal = 16.dp),
|
}
|
||||||
topic = state.config.topic.orEmpty(),
|
item {
|
||||||
onTopicChanged = { state.eventSink(ConfigureRoomEvents.TopicChanged(it)) },
|
RoomTopic(
|
||||||
)
|
modifier = Modifier.padding(horizontal = 16.dp),
|
||||||
SelectedUsersList(
|
topic = state.config.topic.orEmpty(),
|
||||||
contentPadding = PaddingValues(horizontal = 24.dp),
|
onTopicChanged = { state.eventSink(ConfigureRoomEvents.TopicChanged(it)) },
|
||||||
selectedUsers = state.config.invites,
|
)
|
||||||
onUserRemoved = { state.eventSink(ConfigureRoomEvents.RemoveFromSelection(it)) },
|
}
|
||||||
)
|
if (state.config.invites.isNotEmpty()) {
|
||||||
Spacer(Modifier.weight(1f))
|
item {
|
||||||
RoomPrivacyOptions(
|
SelectedUsersList(
|
||||||
modifier = Modifier.padding(bottom = 40.dp),
|
contentPadding = PaddingValues(horizontal = 24.dp),
|
||||||
selected = state.config.privacy,
|
selectedUsers = state.config.invites,
|
||||||
onOptionSelected = { state.eventSink(ConfigureRoomEvents.RoomPrivacyChanged(it.privacy)) },
|
onUserRemoved = {
|
||||||
)
|
focusManager.clearFocus()
|
||||||
|
state.eventSink(ConfigureRoomEvents.RemoveFromSelection(it))
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
item {
|
||||||
|
RoomPrivacyOptions(
|
||||||
|
modifier = Modifier.padding(bottom = 40.dp),
|
||||||
|
selected = state.config.privacy,
|
||||||
|
onOptionSelected = {
|
||||||
|
focusManager.clearFocus()
|
||||||
|
state.eventSink(ConfigureRoomEvents.RoomPrivacyChanged(it.privacy))
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -259,3 +281,11 @@ private fun ContentToPreview(state: ConfigureRoomState) {
|
||||||
state = state,
|
state = state,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun Modifier.clearFocusOnTap(focusManager: FocusManager): Modifier =
|
||||||
|
pointerInput(Unit) {
|
||||||
|
detectTapGestures(onTap = {
|
||||||
|
focusManager.clearFocus()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ fun CreateRoomRootView(
|
||||||
|
|
||||||
when (state.startDmAction) {
|
when (state.startDmAction) {
|
||||||
is Async.Loading -> {
|
is Async.Loading -> {
|
||||||
ProgressDialog(text = stringResource(id = StringR.string.common_creating_room))
|
ProgressDialog(text = stringResource(id = StringR.string.common_starting_chat))
|
||||||
}
|
}
|
||||||
|
|
||||||
is Async.Failure -> {
|
is Async.Failure -> {
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ class ConfigureRoomPresenterTests {
|
||||||
assertThat(initialState.config.topic).isNull()
|
assertThat(initialState.config.topic).isNull()
|
||||||
assertThat(initialState.config.invites).isEmpty()
|
assertThat(initialState.config.invites).isEmpty()
|
||||||
assertThat(initialState.config.avatarUri).isNull()
|
assertThat(initialState.config.avatarUri).isNull()
|
||||||
assertThat(initialState.config.privacy).isNull()
|
assertThat(initialState.config.privacy).isEqualTo(RoomPrivacy.Private)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -115,13 +115,6 @@ class ConfigureRoomPresenterTests {
|
||||||
var newState: ConfigureRoomState = awaitItem()
|
var newState: ConfigureRoomState = awaitItem()
|
||||||
config = config.copy(roomName = A_ROOM_NAME)
|
config = config.copy(roomName = A_ROOM_NAME)
|
||||||
assertThat(newState.config).isEqualTo(config)
|
assertThat(newState.config).isEqualTo(config)
|
||||||
assertThat(newState.isCreateButtonEnabled).isFalse()
|
|
||||||
|
|
||||||
// Select privacy
|
|
||||||
newState.eventSink(ConfigureRoomEvents.RoomPrivacyChanged(RoomPrivacy.Private))
|
|
||||||
newState = awaitItem()
|
|
||||||
config = config.copy(privacy = RoomPrivacy.Private)
|
|
||||||
assertThat(newState.config).isEqualTo(config)
|
|
||||||
assertThat(newState.isCreateButtonEnabled).isTrue()
|
assertThat(newState.isCreateButtonEnabled).isTrue()
|
||||||
|
|
||||||
// Clear room name
|
// Clear room name
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,24 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<plurals name="screen_room_member_list_header_title">
|
<plurals name="screen_room_member_list_header_title">
|
||||||
<item quantity="one">"1 person"</item>
|
<item quantity="one">"1 person"</item>
|
||||||
<item quantity="other">"%1$d people"</item>
|
<item quantity="other">"%1$d people"</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="screen_room_details_encryption_enabled_subtitle">"Messages are secured with locks. Only you and the recipients have the unique keys to unlock them."</string>
|
<string name="screen_room_details_already_a_member">"Already a member"</string>
|
||||||
<string name="screen_room_details_encryption_enabled_title">"Message encryption enabled"</string>
|
<string name="screen_room_details_already_invited">"Already invited"</string>
|
||||||
<string name="screen_room_details_share_room_title">"Share room"</string>
|
<string name="screen_room_details_encryption_enabled_subtitle">"Messages are secured with locks. Only you and the recipients have the unique keys to unlock them."</string>
|
||||||
<string name="screen_room_member_list_pending_header_title">"Pending"</string>
|
<string name="screen_room_details_encryption_enabled_title">"Message encryption enabled"</string>
|
||||||
<string name="screen_dm_details_block_alert_action">"Block"</string>
|
<string name="screen_room_details_share_room_title">"Share room"</string>
|
||||||
<string name="screen_dm_details_block_alert_description">"Blocked users will not be able to send you messages and all message by them will be hidden. You can reverse this action anytime."</string>
|
<string name="screen_room_member_list_pending_header_title">"Pending"</string>
|
||||||
<string name="screen_dm_details_block_user">"Block user"</string>
|
<string name="screen_dm_details_block_alert_action">"Block"</string>
|
||||||
<string name="screen_dm_details_unblock_alert_action">"Unblock"</string>
|
<string name="screen_dm_details_block_alert_description">"Blocked users will not be able to send you messages and all message by them will be hidden. You can reverse this action anytime."</string>
|
||||||
<string name="screen_dm_details_unblock_alert_description">"On unblocking the user, you will be able to see all messages by them again."</string>
|
<string name="screen_dm_details_block_user">"Block user"</string>
|
||||||
<string name="screen_dm_details_unblock_user">"Unblock user"</string>
|
<string name="screen_dm_details_unblock_alert_action">"Unblock"</string>
|
||||||
|
<string name="screen_dm_details_unblock_alert_description">"On unblocking the user, you will be able to see all messages by them again."</string>
|
||||||
|
<string name="screen_dm_details_unblock_user">"Unblock user"</string>
|
||||||
<string name="screen_room_details_invite_people_title">"Invite people"</string>
|
<string name="screen_room_details_invite_people_title">"Invite people"</string>
|
||||||
<string name="screen_room_details_leave_room_title">"Leave room"</string>
|
<string name="screen_room_details_leave_room_title">"Leave room"</string>
|
||||||
<string name="screen_room_details_people_title">"People"</string>
|
<string name="screen_room_details_people_title">"People"</string>
|
||||||
<string name="screen_room_details_security_title">"Security"</string>
|
<string name="screen_room_details_security_title">"Security"</string>
|
||||||
<string name="screen_room_details_topic_title">"Topic"</string>
|
<string name="screen_room_details_topic_title">"Topic"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ fun SearchBar(
|
||||||
|
|
||||||
@Preview(group = PreviewGroup.Search)
|
@Preview(group = PreviewGroup.Search)
|
||||||
@Composable
|
@Composable
|
||||||
internal fun DockedSearchBarPreview() = ElementThemedPreview { ContentToPreview() }
|
internal fun SearchBarPreview() = ElementThemedPreview { ContentToPreview() }
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@
|
||||||
<string name="common_developer_options">"Developer options"</string>
|
<string name="common_developer_options">"Developer options"</string>
|
||||||
<string name="common_edited_suffix">"(edited)"</string>
|
<string name="common_edited_suffix">"(edited)"</string>
|
||||||
<string name="common_editing">"Editing"</string>
|
<string name="common_editing">"Editing"</string>
|
||||||
|
<string name="common_emote">"* %1$s %2$s"</string>
|
||||||
<string name="common_encryption_enabled">"Encryption enabled"</string>
|
<string name="common_encryption_enabled">"Encryption enabled"</string>
|
||||||
<string name="common_error">"Error"</string>
|
<string name="common_error">"Error"</string>
|
||||||
<string name="common_file">"File"</string>
|
<string name="common_file">"File"</string>
|
||||||
|
|
@ -84,12 +85,14 @@
|
||||||
<string name="common_report_a_bug">"Report a bug"</string>
|
<string name="common_report_a_bug">"Report a bug"</string>
|
||||||
<string name="common_report_submitted">"Report submitted"</string>
|
<string name="common_report_submitted">"Report submitted"</string>
|
||||||
<string name="common_search_for_someone">"Search for someone"</string>
|
<string name="common_search_for_someone">"Search for someone"</string>
|
||||||
|
<string name="common_search_results">"Search results"</string>
|
||||||
<string name="common_security">"Security"</string>
|
<string name="common_security">"Security"</string>
|
||||||
<string name="common_select_your_server">"Select your server"</string>
|
<string name="common_select_your_server">"Select your server"</string>
|
||||||
<string name="common_sending">"Sending…"</string>
|
<string name="common_sending">"Sending…"</string>
|
||||||
<string name="common_server_not_supported">"Server not supported"</string>
|
<string name="common_server_not_supported">"Server not supported"</string>
|
||||||
<string name="common_server_url">"Server URL"</string>
|
<string name="common_server_url">"Server URL"</string>
|
||||||
<string name="common_settings">"Settings"</string>
|
<string name="common_settings">"Settings"</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_suggestions">"Suggestions"</string>
|
<string name="common_suggestions">"Suggestions"</string>
|
||||||
|
|
@ -159,4 +162,4 @@
|
||||||
<string name="screen_analytics_settings_read_terms">"You can read all our terms %1$s."</string>
|
<string name="screen_analytics_settings_read_terms">"You can read all our terms %1$s."</string>
|
||||||
<string name="screen_analytics_settings_read_terms_content_link">"here"</string>
|
<string name="screen_analytics_settings_read_terms_content_link">"here"</string>
|
||||||
<string name="screen_report_content_block_user">"Block user"</string>
|
<string name="screen_report_content_block_user">"Block user"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:24ad0b5edc27ddddca573b37f82579715d880793c0dc880248d2b572dd6d6a40
|
oid sha256:a9da3afa82783ded1e686a36eb969b8e097de853e9c6dadea24884f7975c0720
|
||||||
size 64379
|
size 63729
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:b0c9d4eaaaf6a691f43d25e0855ee056b69fa090ad8c53b26732c8f2532e2138
|
oid sha256:e2c200874d6fa8f4fe07da69a7879eb264fb8941c1ab9654162cb76586c52936
|
||||||
size 103384
|
size 103326
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:4023481d2a045d7e0d824db81b28ee47c4bcdc568d98537b3573d554e0b76e32
|
oid sha256:e48bb979a1d328871157847862723b8342cd8c2704750045bbf24592e143a5e0
|
||||||
size 58445
|
size 57874
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:8f953d0df467ad4cd1ae24291e9593945b945712506f093bdcae3da975f8ca91
|
oid sha256:4320fd1900a120a737ba2a56e6c1f55cf671eb0e8c1791dc605994d333feb0c2
|
||||||
size 96800
|
size 96888
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:8f29da5d5aeb65659b065b7bd6afe276f83e020545a027780d2391308d1a4076
|
oid sha256:56c23bd0880524cc56b713c93c5358e9f3771291c20f7a149bad00465f3f987a
|
||||||
size 20750
|
size 20648
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:ae3e8c4e952b97628d026dfe78781aef894d6c2e742ac6ae1f1a2c0170df159e
|
oid sha256:f12591531cfdce24378003dda48940c20d8c9cf7bfac73ac1e7713e925bfac4d
|
||||||
size 20382
|
size 20214
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue