From c0cf534845d55ca1572d95ee67f0a23ff17c3d84 Mon Sep 17 00:00:00 2001 From: Constantin Wartenburger Date: Sat, 10 Oct 2020 16:36:04 +0200 Subject: [PATCH 001/656] Added commands from element web --- .../im/vector/app/features/command/Command.kt | 7 +- .../app/features/command/CommandParser.kt | 79 ++++++++++++++++--- .../app/features/command/ParsedCommand.kt | 7 +- .../home/room/detail/RoomDetailFragment.kt | 1 + .../home/room/detail/RoomDetailViewEvents.kt | 12 +-- .../home/room/detail/RoomDetailViewModel.kt | 68 +++++++++++++--- vector/src/main/res/values/strings.xml | 5 ++ 7 files changed, 149 insertions(+), 30 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/command/Command.kt b/vector/src/main/java/im/vector/app/features/command/Command.kt index db429f9e58..c1b30b2744 100644 --- a/vector/src/main/java/im/vector/app/features/command/Command.kt +++ b/vector/src/main/java/im/vector/app/features/command/Command.kt @@ -28,8 +28,11 @@ enum class Command(val command: String, val parameters: String, @StringRes val d EMOTE("/me", "", R.string.command_description_emote), BAN_USER("/ban", " [reason]", R.string.command_description_ban_user), UNBAN_USER("/unban", " [reason]", R.string.command_description_unban_user), + IGNORE_USER("/ignore", " [reason]", R.string.command_description_ignore_user), + UNIGNORE_USER("/unignore", "", R.string.command_description_unignore_user), SET_USER_POWER_LEVEL("/op", " []", R.string.command_description_op_user), RESET_USER_POWER_LEVEL("/deop", "", R.string.command_description_deop_user), + ROOM_NAME("/roomname", " [reason]", R.string.command_description_room_name), INVITE("/invite", " [reason]", R.string.command_description_invite_user), JOIN_ROOM("/join", " [reason]", R.string.command_description_join_room), PART("/part", " [reason]", R.string.command_description_part_room), @@ -42,8 +45,10 @@ enum class Command(val command: String, val parameters: String, @StringRes val d CLEAR_SCALAR_TOKEN("/clear_scalar_token", "", R.string.command_description_clear_scalar_token), SPOILER("/spoiler", "", R.string.command_description_spoiler), POLL("/poll", "Question | Option 1 | Option 2 ...", R.string.command_description_poll), - SHRUG("/shrug", "", R.string.command_description_shrug), + SHRUG("/shrug", "[]", R.string.command_description_shrug), + LENNY("/lenny", "[]", R.string.command_description_lenny), PLAIN("/plain", "", R.string.command_description_plain), + WHOIS("/whois", "", R.string.command_description_whois), DISCARD_SESSION("/discardsession", "", R.string.command_description_discard_session); val length diff --git a/vector/src/main/java/im/vector/app/features/command/CommandParser.kt b/vector/src/main/java/im/vector/app/features/command/CommandParser.kt index 94de6bf265..fd7d587c1c 100644 --- a/vector/src/main/java/im/vector/app/features/command/CommandParser.kt +++ b/vector/src/main/java/im/vector/app/features/command/CommandParser.kt @@ -102,7 +102,7 @@ object CommandParser { ParsedCommand.SendRainbowEmote(message) } - Command.JOIN_ROOM.command -> { + Command.JOIN_ROOM.command -> { if (messageParts.size >= 2) { val roomAlias = messageParts[1] @@ -120,7 +120,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.JOIN_ROOM) } } - Command.PART.command -> { + Command.PART.command -> { if (messageParts.size >= 2) { val roomAlias = messageParts[1] @@ -138,7 +138,16 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.PART) } } - Command.INVITE.command -> { + Command.ROOM_NAME.command -> { + val newRoomName = textMessage.substring(Command.ROOM_NAME.command.length).trim() + + if (newRoomName.isNotEmpty()) { + ParsedCommand.ChangeRoomName(newRoomName) + } else { + ParsedCommand.ErrorSyntax(Command.ROOM_NAME) + } + } + Command.INVITE.command -> { if (messageParts.size >= 2) { val userId = messageParts[1] @@ -183,7 +192,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.KICK_USER) } } - Command.BAN_USER.command -> { + Command.BAN_USER.command -> { if (messageParts.size >= 2) { val userId = messageParts[1] @@ -201,7 +210,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.BAN_USER) } } - Command.UNBAN_USER.command -> { + Command.UNBAN_USER.command -> { if (messageParts.size >= 2) { val userId = messageParts[1] @@ -219,7 +228,33 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.UNBAN_USER) } } - Command.SET_USER_POWER_LEVEL.command -> { + Command.IGNORE_USER.command -> { + if (messageParts.size == 2) { + val userId = messageParts[1] + + if (MatrixPatterns.isUserId(userId)) { + ParsedCommand.IgnoreUser(userId) + } else { + ParsedCommand.ErrorSyntax(Command.IGNORE_USER) + } + } else { + ParsedCommand.ErrorSyntax(Command.IGNORE_USER) + } + } + Command.UNIGNORE_USER.command -> { + if (messageParts.size == 2) { + val userId = messageParts[1] + + if (MatrixPatterns.isUserId(userId)) { + ParsedCommand.UnignoreUser(userId) + } else { + ParsedCommand.ErrorSyntax(Command.UNIGNORE_USER) + } + } else { + ParsedCommand.ErrorSyntax(Command.UNIGNORE_USER) + } + } + Command.SET_USER_POWER_LEVEL.command -> { if (messageParts.size == 3) { val userId = messageParts[1] if (MatrixPatterns.isUserId(userId)) { @@ -252,7 +287,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.SET_USER_POWER_LEVEL) } } - Command.MARKDOWN.command -> { + Command.MARKDOWN.command -> { if (messageParts.size == 2) { when { "on".equals(messageParts[1], true) -> ParsedCommand.SetMarkdown(true) @@ -263,23 +298,28 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.MARKDOWN) } } - Command.CLEAR_SCALAR_TOKEN.command -> { + Command.CLEAR_SCALAR_TOKEN.command -> { if (messageParts.size == 1) { ParsedCommand.ClearScalarToken } else { ParsedCommand.ErrorSyntax(Command.CLEAR_SCALAR_TOKEN) } } - Command.SPOILER.command -> { + Command.SPOILER.command -> { val message = textMessage.substring(Command.SPOILER.command.length).trim() ParsedCommand.SendSpoiler(message) } - Command.SHRUG.command -> { + Command.SHRUG.command -> { val message = textMessage.substring(Command.SHRUG.command.length).trim() ParsedCommand.SendShrug(message) } - Command.POLL.command -> { + Command.LENNY.command -> { + val message = textMessage.substring(Command.LENNY.command.length).trim() + + ParsedCommand.SendLenny(message) + } + Command.POLL.command -> { val rawCommand = textMessage.substring(Command.POLL.command.length).trim() val split = rawCommand.split("|").map { it.trim() } if (split.size > 2) { @@ -288,10 +328,23 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.POLL) } } - Command.DISCARD_SESSION.command -> { + Command.DISCARD_SESSION.command -> { ParsedCommand.DiscardSession } - else -> { + Command.WHOIS.command -> { + if (messageParts.size == 2) { + val userId = messageParts[1] + + if (MatrixPatterns.isUserId(userId)) { + ParsedCommand.ShowUser(userId) + } else { + ParsedCommand.ErrorSyntax(Command.WHOIS) + } + } else { + ParsedCommand.ErrorSyntax(Command.WHOIS) + } + } + else -> { // Unknown command ParsedCommand.ErrorUnknownSlashCommand(slashCommand) } diff --git a/vector/src/main/java/im/vector/app/features/command/ParsedCommand.kt b/vector/src/main/java/im/vector/app/features/command/ParsedCommand.kt index bdfa7779fb..54043f343a 100644 --- a/vector/src/main/java/im/vector/app/features/command/ParsedCommand.kt +++ b/vector/src/main/java/im/vector/app/features/command/ParsedCommand.kt @@ -41,7 +41,10 @@ sealed class ParsedCommand { class SendRainbowEmote(val message: CharSequence) : ParsedCommand() class BanUser(val userId: String, val reason: String?) : ParsedCommand() class UnbanUser(val userId: String, val reason: String?) : ParsedCommand() + class IgnoreUser(val userId: String) : ParsedCommand() + class UnignoreUser(val userId: String) : ParsedCommand() class SetUserPowerLevel(val userId: String, val powerLevel: Int?) : ParsedCommand() + class ChangeRoomName(val name: String) : ParsedCommand() class Invite(val userId: String, val reason: String?) : ParsedCommand() class Invite3Pid(val threePid: ThreePid) : ParsedCommand() class JoinRoom(val roomAlias: String, val reason: String?) : ParsedCommand() @@ -53,6 +56,8 @@ sealed class ParsedCommand { object ClearScalarToken : ParsedCommand() class SendSpoiler(val message: String) : ParsedCommand() class SendShrug(val message: CharSequence) : ParsedCommand() + class SendLenny(val message: CharSequence) : ParsedCommand() class SendPoll(val question: String, val options: List) : ParsedCommand() - object DiscardSession: ParsedCommand() + object DiscardSession : ParsedCommand() + class ShowUser(val userId: String) : ParsedCommand() } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt index 51aeda2aab..a9c2307566 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt @@ -359,6 +359,7 @@ class RoomDetailFragment @Inject constructor( is RoomDetailViewEvents.SendMessageResult -> renderSendMessageResult(it) is RoomDetailViewEvents.ShowE2EErrorMessage -> displayE2eError(it.withHeldCode) RoomDetailViewEvents.DisplayPromptForIntegrationManager -> displayPromptForIntegrationManager() + is RoomDetailViewEvents.OpenRoomMemberProfile -> openRoomMemberProfile(it.userId) is RoomDetailViewEvents.OpenStickerPicker -> openStickerPicker(it) is RoomDetailViewEvents.DisplayEnableIntegrationsWarning -> displayDisabledIntegrationDialog() is RoomDetailViewEvents.OpenIntegrationManager -> openIntegrationManager() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt index 29ed43f17d..b747075622 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt @@ -64,14 +64,16 @@ sealed class RoomDetailViewEvents : VectorViewEvents { abstract class SendMessageResult : RoomDetailViewEvents() - object DisplayPromptForIntegrationManager: RoomDetailViewEvents() + object DisplayPromptForIntegrationManager : RoomDetailViewEvents() - object DisplayEnableIntegrationsWarning: RoomDetailViewEvents() + object DisplayEnableIntegrationsWarning : RoomDetailViewEvents() - data class OpenStickerPicker(val widget: Widget): RoomDetailViewEvents() + data class OpenRoomMemberProfile(val userId: String) : RoomDetailViewEvents() - object OpenIntegrationManager: RoomDetailViewEvents() - object OpenActiveWidgetBottomSheet: RoomDetailViewEvents() + data class OpenStickerPicker(val widget: Widget) : RoomDetailViewEvents() + + object OpenIntegrationManager : RoomDetailViewEvents() + object OpenActiveWidgetBottomSheet : RoomDetailViewEvents() data class RequestNativeWidgetPermission(val widget: Widget, val domain: String, val grantedEvents: RoomDetailViewEvents) : RoomDetailViewEvents() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt index 1b5e928843..2e7109b5e7 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt @@ -571,6 +571,10 @@ class RoomDetailViewModel @AssistedInject constructor( _viewEvents.post(RoomDetailViewEvents.MessageSent) popDraft() } + is ParsedCommand.ChangeRoomName -> { + handleChangeRoomNameSlashCommand(slashCommandResult) + popDraft() + } is ParsedCommand.Invite -> { handleInviteSlashCommand(slashCommandResult) popDraft() @@ -593,12 +597,20 @@ class RoomDetailViewModel @AssistedInject constructor( if (slashCommandResult.enable) R.string.markdown_has_been_enabled else R.string.markdown_has_been_disabled)) popDraft() } + is ParsedCommand.BanUser -> { + handleBanSlashCommand(slashCommandResult) + popDraft() + } is ParsedCommand.UnbanUser -> { handleUnbanSlashCommand(slashCommandResult) popDraft() } - is ParsedCommand.BanUser -> { - handleBanSlashCommand(slashCommandResult) + is ParsedCommand.IgnoreUser -> { + handleIgnoreSlashCommand(slashCommandResult) + popDraft() + } + is ParsedCommand.UnignoreUser -> { + handleUnignoreSlashCommand(slashCommandResult) popDraft() } is ParsedCommand.KickUser -> { @@ -641,14 +653,12 @@ class RoomDetailViewModel @AssistedInject constructor( popDraft() } is ParsedCommand.SendShrug -> { - val sequence = buildString { - append("¯\\_(ツ)_/¯") - if (slashCommandResult.message.isNotEmpty()) { - append(" ") - append(slashCommandResult.message) - } - } - room.sendTextMessage(sequence) + sendPrefixedMessage("¯\\_(ツ)_/¯", slashCommandResult.message) + _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled()) + popDraft() + } + is ParsedCommand.SendLenny -> { + sendPrefixedMessage("( ͡° ͜ʖ ͡°)", slashCommandResult.message) _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled()) popDraft() } @@ -665,6 +675,11 @@ class RoomDetailViewModel @AssistedInject constructor( handleChangeDisplayNameSlashCommand(slashCommandResult) popDraft() } + is ParsedCommand.ShowUser -> { + _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled()) + handleWhoisSlashCommand(slashCommandResult) + popDraft() + } is ParsedCommand.DiscardSession -> { if (room.isEncrypted()) { session.cryptoService().discardOutboundSession(room.roomId) @@ -786,6 +801,12 @@ class RoomDetailViewModel @AssistedInject constructor( } } + private fun handleChangeRoomNameSlashCommand(changeRoomName: ParsedCommand.ChangeRoomName) { + launchSlashCommandFlow { + room.updateName(changeRoomName.name, it) + } + } + private fun handleInviteSlashCommand(invite: ParsedCommand.Invite) { launchSlashCommandFlow { room.invite(invite.userId, invite.reason, it) @@ -833,6 +854,33 @@ class RoomDetailViewModel @AssistedInject constructor( } } + private fun handleIgnoreSlashCommand(ignore: ParsedCommand.IgnoreUser) { + launchSlashCommandFlow { + session.ignoreUserIds(listOf(ignore.userId), it) + } + } + + private fun handleUnignoreSlashCommand(unignore: ParsedCommand.UnignoreUser) { + launchSlashCommandFlow { + session.unIgnoreUserIds(listOf(unignore.userId), it) + } + } + + private fun handleWhoisSlashCommand(whois: ParsedCommand.ShowUser) { + _viewEvents.post(RoomDetailViewEvents.OpenRoomMemberProfile(whois.userId)) + } + + private fun sendPrefixedMessage(prefix: String, message: CharSequence) { + val sequence = buildString { + append(prefix) + if (message.isNotEmpty()) { + append(" ") + append(message) + } + } + room.sendTextMessage(sequence) + } + private fun launchSlashCommandFlow(lambda: (MatrixCallback) -> Unit) { _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled()) val matrixCallback = object : MatrixCallback { diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index c025054f98..f87b45cd05 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1287,8 +1287,11 @@ Displays action Bans user with given id Unbans user with given id + Ignores a user, hiding their messages from you + Stops ignoring a user, showing their messages going forward Define the power level of a user Deops user with given id + Sets the room name Invites user with given id to current room Joins room with given alias Leave room @@ -1297,6 +1300,7 @@ Changes your display nickname On/Off markdown To fix Matrix Apps management + Displays information about a user Markdown has been enabled. Markdown has been disabled. @@ -2063,6 +2067,7 @@ Element may crash more often when an unexpected error occurs Prepends ¯\\_(ツ)_/¯ to a plain-text message + Prepends ( ͡° ͜ʖ ͡°) to a plain-text message "Enable encryption" "Once enabled, encryption cannot be disabled." From 13960561c00d6a44d8e44d7f8586be66075aeeb5 Mon Sep 17 00:00:00 2001 From: Constantin Wartenburger Date: Sat, 10 Oct 2020 18:34:31 +0200 Subject: [PATCH 002/656] Added /myroomnick command --- .../im/vector/app/features/command/Command.kt | 1 + .../app/features/command/CommandParser.kt | 23 +++++++++++++------ .../app/features/command/ParsedCommand.kt | 1 + .../home/room/detail/RoomDetailViewModel.kt | 15 ++++++++++++ vector/src/main/res/values/strings.xml | 1 + 5 files changed, 34 insertions(+), 7 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/command/Command.kt b/vector/src/main/java/im/vector/app/features/command/Command.kt index c1b30b2744..1db1639b1d 100644 --- a/vector/src/main/java/im/vector/app/features/command/Command.kt +++ b/vector/src/main/java/im/vector/app/features/command/Command.kt @@ -39,6 +39,7 @@ enum class Command(val command: String, val parameters: String, @StringRes val d TOPIC("/topic", "", R.string.command_description_topic), KICK_USER("/kick", " [reason]", R.string.command_description_kick_user), CHANGE_DISPLAY_NAME("/nick", "", R.string.command_description_nick), + CHANGE_DISPLAY_NAME_FOR_ROOM("/myroomnick", "", R.string.command_description_room_nick), MARKDOWN("/markdown", "", R.string.command_description_markdown), RAINBOW("/rainbow", "", R.string.command_description_rainbow), RAINBOW_EMOTE("/rainbowme", "", R.string.command_description_rainbow_emote), diff --git a/vector/src/main/java/im/vector/app/features/command/CommandParser.kt b/vector/src/main/java/im/vector/app/features/command/CommandParser.kt index fd7d587c1c..e09b6a842d 100644 --- a/vector/src/main/java/im/vector/app/features/command/CommandParser.kt +++ b/vector/src/main/java/im/vector/app/features/command/CommandParser.kt @@ -60,7 +60,7 @@ object CommandParser { } return when (val slashCommand = messageParts.first()) { - Command.PLAIN.command -> { + Command.PLAIN.command -> { val text = textMessage.substring(Command.PLAIN.command.length).trim() if (text.isNotEmpty()) { @@ -69,7 +69,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.PLAIN) } } - Command.CHANGE_DISPLAY_NAME.command -> { + Command.CHANGE_DISPLAY_NAME.command -> { val newDisplayName = textMessage.substring(Command.CHANGE_DISPLAY_NAME.command.length).trim() if (newDisplayName.isNotEmpty()) { @@ -78,7 +78,16 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.CHANGE_DISPLAY_NAME) } } - Command.TOPIC.command -> { + Command.CHANGE_DISPLAY_NAME_FOR_ROOM.command -> { + val newDisplayName = textMessage.substring(Command.CHANGE_DISPLAY_NAME_FOR_ROOM.command.length).trim() + + if (newDisplayName.isNotEmpty()) { + ParsedCommand.ChangeDisplayNameForRoom(newDisplayName) + } else { + ParsedCommand.ErrorSyntax(Command.CHANGE_DISPLAY_NAME_FOR_ROOM) + } + } + Command.TOPIC.command -> { val newTopic = textMessage.substring(Command.TOPIC.command.length).trim() if (newTopic.isNotEmpty()) { @@ -87,22 +96,22 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.TOPIC) } } - Command.EMOTE.command -> { + Command.EMOTE.command -> { val message = textMessage.subSequence(Command.EMOTE.command.length, textMessage.length).trim() ParsedCommand.SendEmote(message) } - Command.RAINBOW.command -> { + Command.RAINBOW.command -> { val message = textMessage.subSequence(Command.RAINBOW.command.length, textMessage.length).trim() ParsedCommand.SendRainbow(message) } - Command.RAINBOW_EMOTE.command -> { + Command.RAINBOW_EMOTE.command -> { val message = textMessage.subSequence(Command.RAINBOW_EMOTE.command.length, textMessage.length).trim() ParsedCommand.SendRainbowEmote(message) } - Command.JOIN_ROOM.command -> { + Command.JOIN_ROOM.command -> { if (messageParts.size >= 2) { val roomAlias = messageParts[1] diff --git a/vector/src/main/java/im/vector/app/features/command/ParsedCommand.kt b/vector/src/main/java/im/vector/app/features/command/ParsedCommand.kt index 54043f343a..60b4e1c3a2 100644 --- a/vector/src/main/java/im/vector/app/features/command/ParsedCommand.kt +++ b/vector/src/main/java/im/vector/app/features/command/ParsedCommand.kt @@ -52,6 +52,7 @@ sealed class ParsedCommand { class ChangeTopic(val topic: String) : ParsedCommand() class KickUser(val userId: String, val reason: String?) : ParsedCommand() class ChangeDisplayName(val displayName: String) : ParsedCommand() + class ChangeDisplayNameForRoom(val displayName: String) : ParsedCommand() class SetMarkdown(val enable: Boolean) : ParsedCommand() object ClearScalarToken : ParsedCommand() class SendSpoiler(val message: String) : ParsedCommand() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt index 2e7109b5e7..10942f17bf 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt @@ -74,6 +74,7 @@ import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent +import org.matrix.android.sdk.api.session.room.model.RoomMemberContent import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.message.MessageContent @@ -675,6 +676,10 @@ class RoomDetailViewModel @AssistedInject constructor( handleChangeDisplayNameSlashCommand(slashCommandResult) popDraft() } + is ParsedCommand.ChangeDisplayNameForRoom -> { + handleChangeDisplayNameForRoomSlashCommand(slashCommandResult) + popDraft() + } is ParsedCommand.ShowUser -> { _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled()) handleWhoisSlashCommand(slashCommandResult) @@ -836,6 +841,16 @@ class RoomDetailViewModel @AssistedInject constructor( } } + private fun handleChangeDisplayNameForRoomSlashCommand(changeDisplayName: ParsedCommand.ChangeDisplayNameForRoom) { + val content = room.getStateEvent(EventType.STATE_ROOM_MEMBER, QueryStringValue.Equals(session.myUserId)) + ?.content?.toModel() + ?: RoomMemberContent(membership = Membership.JOIN) + + launchSlashCommandFlow { + room.sendStateEvent(EventType.STATE_ROOM_MEMBER, session.myUserId, content.copy(displayName = changeDisplayName.displayName).toContent(), it) + } + } + private fun handleKickSlashCommand(kick: ParsedCommand.KickUser) { launchSlashCommandFlow { room.kick(kick.userId, kick.reason, it) diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index f87b45cd05..33c648d647 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1298,6 +1298,7 @@ Set the room topic Kicks user with given id Changes your display nickname + Changes your display nickname On/Off markdown To fix Matrix Apps management Displays information about a user From 1a40b65b53677b79b3d6beb34335fdd9d3dab80a Mon Sep 17 00:00:00 2001 From: Constantin Wartenburger Date: Sun, 11 Oct 2020 18:56:13 +0200 Subject: [PATCH 003/656] Added /myroomavatar command (without upload) --- .../im/vector/app/features/command/Command.kt | 3 +- .../app/features/command/CommandParser.kt | 51 ++++++++++++------- .../app/features/command/ParsedCommand.kt | 1 + .../home/room/detail/RoomDetailViewModel.kt | 18 +++++-- vector/src/main/res/values/strings.xml | 3 +- 5 files changed, 52 insertions(+), 24 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/command/Command.kt b/vector/src/main/java/im/vector/app/features/command/Command.kt index 1db1639b1d..fd0623dc05 100644 --- a/vector/src/main/java/im/vector/app/features/command/Command.kt +++ b/vector/src/main/java/im/vector/app/features/command/Command.kt @@ -39,7 +39,8 @@ enum class Command(val command: String, val parameters: String, @StringRes val d TOPIC("/topic", "", R.string.command_description_topic), KICK_USER("/kick", " [reason]", R.string.command_description_kick_user), CHANGE_DISPLAY_NAME("/nick", "", R.string.command_description_nick), - CHANGE_DISPLAY_NAME_FOR_ROOM("/myroomnick", "", R.string.command_description_room_nick), + CHANGE_DISPLAY_NAME_FOR_ROOM("/myroomnick", "", R.string.command_description_nick_for_room), + CHANGE_AVATAR_FOR_ROOM("/myroomavatar", "", R.string.command_description_avatar_for_room), MARKDOWN("/markdown", "", R.string.command_description_markdown), RAINBOW("/rainbow", "", R.string.command_description_rainbow), RAINBOW_EMOTE("/rainbowme", "", R.string.command_description_rainbow_emote), diff --git a/vector/src/main/java/im/vector/app/features/command/CommandParser.kt b/vector/src/main/java/im/vector/app/features/command/CommandParser.kt index e09b6a842d..d5fb9a41b6 100644 --- a/vector/src/main/java/im/vector/app/features/command/CommandParser.kt +++ b/vector/src/main/java/im/vector/app/features/command/CommandParser.kt @@ -87,6 +87,19 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.CHANGE_DISPLAY_NAME_FOR_ROOM) } } + Command.CHANGE_AVATAR_FOR_ROOM.command -> { + if (messageParts.size == 2) { + val url = messageParts[1] + + if (url.isNotEmpty()) { + ParsedCommand.ChangeAvatarForRoom(url) + } else { + ParsedCommand.ErrorSyntax(Command.CHANGE_AVATAR_FOR_ROOM) + } + } else { + ParsedCommand.ErrorSyntax(Command.CHANGE_AVATAR_FOR_ROOM) + } + } Command.TOPIC.command -> { val newTopic = textMessage.substring(Command.TOPIC.command.length).trim() @@ -129,7 +142,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.JOIN_ROOM) } } - Command.PART.command -> { + Command.PART.command -> { if (messageParts.size >= 2) { val roomAlias = messageParts[1] @@ -147,7 +160,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.PART) } } - Command.ROOM_NAME.command -> { + Command.ROOM_NAME.command -> { val newRoomName = textMessage.substring(Command.ROOM_NAME.command.length).trim() if (newRoomName.isNotEmpty()) { @@ -156,7 +169,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.ROOM_NAME) } } - Command.INVITE.command -> { + Command.INVITE.command -> { if (messageParts.size >= 2) { val userId = messageParts[1] @@ -183,7 +196,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.INVITE) } } - Command.KICK_USER.command -> { + Command.KICK_USER.command -> { if (messageParts.size >= 2) { val userId = messageParts[1] @@ -201,7 +214,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.KICK_USER) } } - Command.BAN_USER.command -> { + Command.BAN_USER.command -> { if (messageParts.size >= 2) { val userId = messageParts[1] @@ -219,7 +232,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.BAN_USER) } } - Command.UNBAN_USER.command -> { + Command.UNBAN_USER.command -> { if (messageParts.size >= 2) { val userId = messageParts[1] @@ -237,7 +250,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.UNBAN_USER) } } - Command.IGNORE_USER.command -> { + Command.IGNORE_USER.command -> { if (messageParts.size == 2) { val userId = messageParts[1] @@ -250,7 +263,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.IGNORE_USER) } } - Command.UNIGNORE_USER.command -> { + Command.UNIGNORE_USER.command -> { if (messageParts.size == 2) { val userId = messageParts[1] @@ -263,7 +276,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.UNIGNORE_USER) } } - Command.SET_USER_POWER_LEVEL.command -> { + Command.SET_USER_POWER_LEVEL.command -> { if (messageParts.size == 3) { val userId = messageParts[1] if (MatrixPatterns.isUserId(userId)) { @@ -283,7 +296,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.SET_USER_POWER_LEVEL) } } - Command.RESET_USER_POWER_LEVEL.command -> { + Command.RESET_USER_POWER_LEVEL.command -> { if (messageParts.size == 2) { val userId = messageParts[1] @@ -296,7 +309,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.SET_USER_POWER_LEVEL) } } - Command.MARKDOWN.command -> { + Command.MARKDOWN.command -> { if (messageParts.size == 2) { when { "on".equals(messageParts[1], true) -> ParsedCommand.SetMarkdown(true) @@ -307,28 +320,28 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.MARKDOWN) } } - Command.CLEAR_SCALAR_TOKEN.command -> { + Command.CLEAR_SCALAR_TOKEN.command -> { if (messageParts.size == 1) { ParsedCommand.ClearScalarToken } else { ParsedCommand.ErrorSyntax(Command.CLEAR_SCALAR_TOKEN) } } - Command.SPOILER.command -> { + Command.SPOILER.command -> { val message = textMessage.substring(Command.SPOILER.command.length).trim() ParsedCommand.SendSpoiler(message) } - Command.SHRUG.command -> { + Command.SHRUG.command -> { val message = textMessage.substring(Command.SHRUG.command.length).trim() ParsedCommand.SendShrug(message) } - Command.LENNY.command -> { + Command.LENNY.command -> { val message = textMessage.substring(Command.LENNY.command.length).trim() ParsedCommand.SendLenny(message) } - Command.POLL.command -> { + Command.POLL.command -> { val rawCommand = textMessage.substring(Command.POLL.command.length).trim() val split = rawCommand.split("|").map { it.trim() } if (split.size > 2) { @@ -337,10 +350,10 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.POLL) } } - Command.DISCARD_SESSION.command -> { + Command.DISCARD_SESSION.command -> { ParsedCommand.DiscardSession } - Command.WHOIS.command -> { + Command.WHOIS.command -> { if (messageParts.size == 2) { val userId = messageParts[1] @@ -353,7 +366,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.WHOIS) } } - else -> { + else -> { // Unknown command ParsedCommand.ErrorUnknownSlashCommand(slashCommand) } diff --git a/vector/src/main/java/im/vector/app/features/command/ParsedCommand.kt b/vector/src/main/java/im/vector/app/features/command/ParsedCommand.kt index 60b4e1c3a2..f0dcbc9663 100644 --- a/vector/src/main/java/im/vector/app/features/command/ParsedCommand.kt +++ b/vector/src/main/java/im/vector/app/features/command/ParsedCommand.kt @@ -53,6 +53,7 @@ sealed class ParsedCommand { class KickUser(val userId: String, val reason: String?) : ParsedCommand() class ChangeDisplayName(val displayName: String) : ParsedCommand() class ChangeDisplayNameForRoom(val displayName: String) : ParsedCommand() + class ChangeAvatarForRoom(val url: String) : ParsedCommand() class SetMarkdown(val enable: Boolean) : ParsedCommand() object ClearScalarToken : ParsedCommand() class SendSpoiler(val message: String) : ParsedCommand() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt index 10942f17bf..e84eb5520c 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt @@ -680,6 +680,10 @@ class RoomDetailViewModel @AssistedInject constructor( handleChangeDisplayNameForRoomSlashCommand(slashCommandResult) popDraft() } + is ParsedCommand.ChangeAvatarForRoom -> { + handleChangeAvatarForRoomSlashCommand(slashCommandResult) + popDraft() + } is ParsedCommand.ShowUser -> { _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled()) handleWhoisSlashCommand(slashCommandResult) @@ -841,13 +845,21 @@ class RoomDetailViewModel @AssistedInject constructor( } } - private fun handleChangeDisplayNameForRoomSlashCommand(changeDisplayName: ParsedCommand.ChangeDisplayNameForRoom) { - val content = room.getStateEvent(EventType.STATE_ROOM_MEMBER, QueryStringValue.Equals(session.myUserId)) + private fun getLastMemberEvent(): RoomMemberContent { + return room.getStateEvent(EventType.STATE_ROOM_MEMBER, QueryStringValue.Equals(session.myUserId)) ?.content?.toModel() ?: RoomMemberContent(membership = Membership.JOIN) + } + private fun handleChangeDisplayNameForRoomSlashCommand(changeDisplayName: ParsedCommand.ChangeDisplayNameForRoom) { launchSlashCommandFlow { - room.sendStateEvent(EventType.STATE_ROOM_MEMBER, session.myUserId, content.copy(displayName = changeDisplayName.displayName).toContent(), it) + room.sendStateEvent(EventType.STATE_ROOM_MEMBER, session.myUserId, getLastMemberEvent().copy(displayName = changeDisplayName.displayName).toContent(), it) + } + } + + private fun handleChangeAvatarForRoomSlashCommand(changeAvatar: ParsedCommand.ChangeAvatarForRoom) { + launchSlashCommandFlow { + room.sendStateEvent(EventType.STATE_ROOM_MEMBER, session.myUserId, getLastMemberEvent().copy(avatarUrl = changeAvatar.url).toContent(), it) } } diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 33c648d647..823d567f20 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1298,7 +1298,8 @@ Set the room topic Kicks user with given id Changes your display nickname - Changes your display nickname + Changes your display nickname in the current room only + Changes your avatar in this current room only On/Off markdown To fix Matrix Apps management Displays information about a user From 24c67660c12d8ac402e50dee16a2c2f6ea94dae1 Mon Sep 17 00:00:00 2001 From: Constantin Wartenburger Date: Mon, 12 Oct 2020 17:43:07 +0200 Subject: [PATCH 004/656] Added /roomavatar command (not upload) --- .../im/vector/app/features/command/Command.kt | 3 ++- .../vector/app/features/command/CommandParser.kt | 15 ++++++++++++++- .../vector/app/features/command/ParsedCommand.kt | 1 + .../home/room/detail/RoomDetailViewModel.kt | 11 +++++++++++ vector/src/main/res/values/strings.xml | 1 + 5 files changed, 29 insertions(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/command/Command.kt b/vector/src/main/java/im/vector/app/features/command/Command.kt index fd0623dc05..b74b608e32 100644 --- a/vector/src/main/java/im/vector/app/features/command/Command.kt +++ b/vector/src/main/java/im/vector/app/features/command/Command.kt @@ -32,7 +32,7 @@ enum class Command(val command: String, val parameters: String, @StringRes val d UNIGNORE_USER("/unignore", "", R.string.command_description_unignore_user), SET_USER_POWER_LEVEL("/op", " []", R.string.command_description_op_user), RESET_USER_POWER_LEVEL("/deop", "", R.string.command_description_deop_user), - ROOM_NAME("/roomname", " [reason]", R.string.command_description_room_name), + ROOM_NAME("/roomname", "", R.string.command_description_room_name), INVITE("/invite", " [reason]", R.string.command_description_invite_user), JOIN_ROOM("/join", " [reason]", R.string.command_description_join_room), PART("/part", " [reason]", R.string.command_description_part_room), @@ -40,6 +40,7 @@ enum class Command(val command: String, val parameters: String, @StringRes val d KICK_USER("/kick", " [reason]", R.string.command_description_kick_user), CHANGE_DISPLAY_NAME("/nick", "", R.string.command_description_nick), CHANGE_DISPLAY_NAME_FOR_ROOM("/myroomnick", "", R.string.command_description_nick_for_room), + ROOM_AVATAR("/roomavatar", "", R.string.command_description_room_avatar), CHANGE_AVATAR_FOR_ROOM("/myroomavatar", "", R.string.command_description_avatar_for_room), MARKDOWN("/markdown", "", R.string.command_description_markdown), RAINBOW("/rainbow", "", R.string.command_description_rainbow), diff --git a/vector/src/main/java/im/vector/app/features/command/CommandParser.kt b/vector/src/main/java/im/vector/app/features/command/CommandParser.kt index d5fb9a41b6..41961c209a 100644 --- a/vector/src/main/java/im/vector/app/features/command/CommandParser.kt +++ b/vector/src/main/java/im/vector/app/features/command/CommandParser.kt @@ -87,11 +87,24 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.CHANGE_DISPLAY_NAME_FOR_ROOM) } } + Command.ROOM_AVATAR.command -> { + if (messageParts.size == 2) { + val url = messageParts[1] + + if (url.isNotEmpty() && url.startsWith("mxc://")) { + ParsedCommand.ChangeRoomAvatar(url) + } else { + ParsedCommand.ErrorSyntax(Command.ROOM_AVATAR) + } + } else { + ParsedCommand.ErrorSyntax(Command.ROOM_AVATAR) + } + } Command.CHANGE_AVATAR_FOR_ROOM.command -> { if (messageParts.size == 2) { val url = messageParts[1] - if (url.isNotEmpty()) { + if (url.isNotEmpty() && url.startsWith("mxc://")) { ParsedCommand.ChangeAvatarForRoom(url) } else { ParsedCommand.ErrorSyntax(Command.CHANGE_AVATAR_FOR_ROOM) diff --git a/vector/src/main/java/im/vector/app/features/command/ParsedCommand.kt b/vector/src/main/java/im/vector/app/features/command/ParsedCommand.kt index f0dcbc9663..16f2eaac29 100644 --- a/vector/src/main/java/im/vector/app/features/command/ParsedCommand.kt +++ b/vector/src/main/java/im/vector/app/features/command/ParsedCommand.kt @@ -53,6 +53,7 @@ sealed class ParsedCommand { class KickUser(val userId: String, val reason: String?) : ParsedCommand() class ChangeDisplayName(val displayName: String) : ParsedCommand() class ChangeDisplayNameForRoom(val displayName: String) : ParsedCommand() + class ChangeRoomAvatar(val url: String) : ParsedCommand() class ChangeAvatarForRoom(val url: String) : ParsedCommand() class SetMarkdown(val enable: Boolean) : ParsedCommand() object ClearScalarToken : ParsedCommand() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt index e84eb5520c..737cdf61b0 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt @@ -74,6 +74,7 @@ import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent +import org.matrix.android.sdk.api.session.room.model.RoomAvatarContent import org.matrix.android.sdk.api.session.room.model.RoomMemberContent import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary @@ -680,6 +681,10 @@ class RoomDetailViewModel @AssistedInject constructor( handleChangeDisplayNameForRoomSlashCommand(slashCommandResult) popDraft() } + is ParsedCommand.ChangeRoomAvatar -> { + handleChangeRoomAvatarSlashCommand(slashCommandResult) + popDraft() + } is ParsedCommand.ChangeAvatarForRoom -> { handleChangeAvatarForRoomSlashCommand(slashCommandResult) popDraft() @@ -857,6 +862,12 @@ class RoomDetailViewModel @AssistedInject constructor( } } + private fun handleChangeRoomAvatarSlashCommand(changeAvatar: ParsedCommand.ChangeRoomAvatar) { + launchSlashCommandFlow { + room.sendStateEvent(EventType.STATE_ROOM_AVATAR, null, RoomAvatarContent(changeAvatar.url).toContent(), it) + } + } + private fun handleChangeAvatarForRoomSlashCommand(changeAvatar: ParsedCommand.ChangeAvatarForRoom) { launchSlashCommandFlow { room.sendStateEvent(EventType.STATE_ROOM_MEMBER, session.myUserId, getLastMemberEvent().copy(avatarUrl = changeAvatar.url).toContent(), it) diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 823d567f20..909ef01b4c 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1299,6 +1299,7 @@ Kicks user with given id Changes your display nickname Changes your display nickname in the current room only + Changes the avatar of the current room Changes your avatar in this current room only On/Off markdown To fix Matrix Apps management From 5b6727408b5498aa553f7781ecb63d2b2863066b Mon Sep 17 00:00:00 2001 From: Constantin Wartenburger Date: Tue, 13 Oct 2020 15:10:57 +0200 Subject: [PATCH 005/656] Fix wrong parameter name --- .../src/main/java/im/vector/app/features/command/Command.kt | 2 +- .../main/java/im/vector/app/features/command/CommandParser.kt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/command/Command.kt b/vector/src/main/java/im/vector/app/features/command/Command.kt index b74b608e32..81bbf8177d 100644 --- a/vector/src/main/java/im/vector/app/features/command/Command.kt +++ b/vector/src/main/java/im/vector/app/features/command/Command.kt @@ -32,7 +32,7 @@ enum class Command(val command: String, val parameters: String, @StringRes val d UNIGNORE_USER("/unignore", "", R.string.command_description_unignore_user), SET_USER_POWER_LEVEL("/op", " []", R.string.command_description_op_user), RESET_USER_POWER_LEVEL("/deop", "", R.string.command_description_deop_user), - ROOM_NAME("/roomname", "", R.string.command_description_room_name), + ROOM_NAME("/roomname", "", R.string.command_description_room_name), INVITE("/invite", " [reason]", R.string.command_description_invite_user), JOIN_ROOM("/join", " [reason]", R.string.command_description_join_room), PART("/part", " [reason]", R.string.command_description_part_room), diff --git a/vector/src/main/java/im/vector/app/features/command/CommandParser.kt b/vector/src/main/java/im/vector/app/features/command/CommandParser.kt index 41961c209a..29eba00490 100644 --- a/vector/src/main/java/im/vector/app/features/command/CommandParser.kt +++ b/vector/src/main/java/im/vector/app/features/command/CommandParser.kt @@ -91,7 +91,7 @@ object CommandParser { if (messageParts.size == 2) { val url = messageParts[1] - if (url.isNotEmpty() && url.startsWith("mxc://")) { + if (url.startsWith("mxc://")) { ParsedCommand.ChangeRoomAvatar(url) } else { ParsedCommand.ErrorSyntax(Command.ROOM_AVATAR) @@ -104,7 +104,7 @@ object CommandParser { if (messageParts.size == 2) { val url = messageParts[1] - if (url.isNotEmpty() && url.startsWith("mxc://")) { + if (url.startsWith("mxc://")) { ParsedCommand.ChangeAvatarForRoom(url) } else { ParsedCommand.ErrorSyntax(Command.CHANGE_AVATAR_FOR_ROOM) From 451c2379ec3b9ca4430eff872d48d2287871a931 Mon Sep 17 00:00:00 2001 From: SpiritCroc Date: Fri, 28 May 2021 15:16:04 +0200 Subject: [PATCH 006/656] Do not notify again for old events Resending the notification here can trigger other system components or apps that listen to new notifications, such as connected smart watches or automation tools. Fixes https://github.com/vector-im/element-android/issues/1673 --- changelog.d/1673.bugfix | 1 + .../app/features/notifications/NotificationDrawerManager.kt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 changelog.d/1673.bugfix diff --git a/changelog.d/1673.bugfix b/changelog.d/1673.bugfix new file mode 100644 index 0000000000..b0459f34b8 --- /dev/null +++ b/changelog.d/1673.bugfix @@ -0,0 +1 @@ +Avoid resending notifications that are already shown diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt index 37ed1e654a..fd15455391 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt @@ -457,7 +457,7 @@ class NotificationDrawerManager @Inject constructor(private val context: Context if (eventList.isEmpty() || eventList.all { it.isRedacted }) { notificationUtils.cancelNotificationMessage(null, SUMMARY_NOTIFICATION_ID) - } else { + } else if (hasNewEvent) { // FIXME roomIdToEventMap.size is not correct, this is the number of rooms val nbEvents = roomIdToEventMap.size + simpleEvents.size val sumTitle = stringProvider.getQuantityString(R.plurals.notification_compat_summary_title, nbEvents, nbEvents) From 8c590b50e3938abadc506bbdeb36ffccc32f4f10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Sun, 1 Aug 2021 14:51:00 +0200 Subject: [PATCH 007/656] Improve accessibility of voice messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Peter Vágner --- .../home/room/detail/composer/VoiceMessageRecorderView.kt | 5 +++++ .../home/room/detail/timeline/item/MessageVoiceItem.kt | 3 +++ .../src/main/res/layout/item_timeline_event_voice_stub.xml | 3 ++- vector/src/main/res/layout/view_voice_message_recorder.xml | 7 +++++-- vector/src/main/res/values/strings.xml | 6 +++--- 5 files changed, 18 insertions(+), 6 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt index ba6e0fbae7..a90c1c4d3a 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt @@ -20,6 +20,7 @@ import android.content.Context import android.text.format.DateUtils import android.util.AttributeSet import android.view.MotionEvent +import android.view.View import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.view.isInvisible import androidx.core.view.isVisible @@ -476,12 +477,14 @@ class VoiceMessageRecorderView @JvmOverloads constructor( views.voiceMessagePlaybackTimerIndicator.isVisible = true views.voicePlaybackControlButton.isVisible = false views.voiceMessageSendButton.isVisible = true + views.voicePlaybackWaveform.importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_YES renderToast(context.getString(R.string.voice_message_tap_to_stop_toast)) } private fun showPlaybackViews() { views.voiceMessagePlaybackTimerIndicator.isVisible = false views.voicePlaybackControlButton.isVisible = true + views.voicePlaybackWaveform.importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO callback?.onVoiceRecordingPlaybackModeOn() } @@ -507,12 +510,14 @@ class VoiceMessageRecorderView @JvmOverloads constructor( } is VoiceMessagePlaybackTracker.Listener.State.Playing -> { views.voicePlaybackControlButton.setImageResource(R.drawable.ic_play_pause_pause) + views.voicePlaybackControlButton.contentDescription = resources.getString(R.string.a11y_pause_voice_message) val formattedTimerText = DateUtils.formatElapsedTime((state.playbackTime / 1000).toLong()) views.voicePlaybackTime.text = formattedTimerText } is VoiceMessagePlaybackTracker.Listener.State.Paused, is VoiceMessagePlaybackTracker.Listener.State.Idle -> { views.voicePlaybackControlButton.setImageResource(R.drawable.ic_play_pause_play) + views.voicePlaybackControlButton.contentDescription = resources.getString(R.string.a11y_play_voice_message) } } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceItem.kt index dc204da291..fce2db2bfd 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceItem.kt @@ -98,16 +98,19 @@ abstract class MessageVoiceItem : AbsMessageItem() { private fun renderIdleState(holder: Holder) { holder.voicePlaybackControlButton.setImageResource(R.drawable.ic_play_pause_play) + holder.voicePlaybackControlButton.contentDescription = holder.view.context.resources.getString(R.string.a11y_play_voice_message) holder.voicePlaybackTime.text = formatPlaybackTime(duration) } private fun renderPlayingState(holder: Holder, state: VoiceMessagePlaybackTracker.Listener.State.Playing) { holder.voicePlaybackControlButton.setImageResource(R.drawable.ic_play_pause_pause) + holder.voicePlaybackControlButton.contentDescription = holder.view.context.resources.getString(R.string.a11y_pause_voice_message) holder.voicePlaybackTime.text = formatPlaybackTime(state.playbackTime) } private fun renderPausedState(holder: Holder, state: VoiceMessagePlaybackTracker.Listener.State.Paused) { holder.voicePlaybackControlButton.setImageResource(R.drawable.ic_play_pause_play) + holder.voicePlaybackControlButton.contentDescription = holder.view.context.resources.getString(R.string.a11y_play_voice_message) holder.voicePlaybackTime.text = formatPlaybackTime(state.playbackTime) } diff --git a/vector/src/main/res/layout/item_timeline_event_voice_stub.xml b/vector/src/main/res/layout/item_timeline_event_voice_stub.xml index 21705566e9..2c8ade173a 100644 --- a/vector/src/main/res/layout/item_timeline_event_voice_stub.xml +++ b/vector/src/main/res/layout/item_timeline_event_voice_stub.xml @@ -53,6 +53,7 @@ android:layout_height="0dp" android:layout_marginStart="8dp" android:layout_marginEnd="8dp" + android:importantForAccessibility="no" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@id/voicePlaybackTime" @@ -77,4 +78,4 @@ app:layout_constraintTop_toBottomOf="@+id/voicePlaybackLayout" tools:visibility="visible" /> - \ No newline at end of file + diff --git a/vector/src/main/res/layout/view_voice_message_recorder.xml b/vector/src/main/res/layout/view_voice_message_recorder.xml index d309761815..051928b73d 100644 --- a/vector/src/main/res/layout/view_voice_message_recorder.xml +++ b/vector/src/main/res/layout/view_voice_message_recorder.xml @@ -107,7 +107,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="28dp" - android:contentDescription="@string/a11y_lock_voice_message" + android:importantForAccessibility="no" android:src="@drawable/ic_voice_message_unlocked" android:visibility="gone" app:layout_constraintEnd_toEndOf="@id/voiceMessageMicButton" @@ -215,6 +215,8 @@ android:layout_height="0dp" android:layout_marginStart="8dp" android:layout_marginEnd="8dp" + android:contentDescription="@string/a11y_stop_voice_message" + android:importantForAccessibility="no" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@id/voicePlaybackTime" @@ -231,10 +233,11 @@ android:layout_height="wrap_content" android:layout_marginBottom="84dp" android:visibility="gone" + android:accessibilityLiveRegion="polite" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" tools:text="@string/voice_message_release_to_send_toast" tools:visibility="visible" /> - \ No newline at end of file + diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 8e6bf85eae..468c51bac8 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -3460,13 +3460,13 @@ Sorry, an error occurred while trying to join: %s - Start Voice Message + Record Voice Message Slide to cancel - Voice Message Lock Play Voice Message Pause Voice Message + Stop Recording Recording voice message - Delete recorded voice message + Delete recording Hold to record, release to send %1$ds left Tap on your recording to stop or listen From ebe1e28689604b7bf25f04dc20c2ec9cbdf7805c Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 23 Aug 2021 16:46:13 +0200 Subject: [PATCH 008/656] Sync: makes SyncResponse in public API --- .../session/sync/model/DeviceListResponse.kt | 5 +++-- .../sync/model/DeviceOneTimeKeysCountSyncResponse.kt | 4 ++-- .../session/sync/model/GroupSyncProfile.kt | 4 ++-- .../session/sync/model/GroupsSyncResponse.kt | 4 ++-- .../session/sync/model/InvitedGroupSync.kt | 4 ++-- .../session/sync/model/InvitedRoomSync.kt | 5 +++-- .../session/sync/model/LazyRoomSyncEphemeral.kt | 8 ++++---- .../session/sync/model/PresenceSyncResponse.kt | 4 ++-- .../session/sync/model/RoomInviteState.kt | 5 +++-- .../sdk/{internal => api}/session/sync/model/RoomSync.kt | 5 +++-- .../session/sync/model/RoomSyncAccountData.kt | 4 ++-- .../session/sync/model/RoomSyncEphemeral.kt | 4 ++-- .../{internal => api}/session/sync/model/RoomSyncState.kt | 4 ++-- .../session/sync/model/RoomSyncSummary.kt | 4 ++-- .../session/sync/model/RoomSyncTimeline.kt | 4 ++-- .../session/sync/model/RoomSyncUnreadNotifications.kt | 4 ++-- .../session/sync/model/RoomsSyncResponse.kt | 5 +++-- .../{internal => api}/session/sync/model/SyncResponse.kt | 4 ++-- .../session/sync/model/ToDeviceSyncResponse.kt | 4 ++-- .../android/sdk/internal/crypto/DefaultCryptoService.kt | 2 +- .../session/notification/ProcessEventForPushTask.kt | 2 +- .../internal/session/room/summary/RoomSummaryUpdater.kt | 4 ++-- .../sdk/internal/session/sync/CryptoSyncHandler.kt | 4 ++-- .../android/sdk/internal/session/sync/GroupSyncHandler.kt | 4 ++-- .../session/sync/RoomSyncEphemeralTemporaryStore.kt | 2 +- .../android/sdk/internal/session/sync/RoomSyncHandler.kt | 8 ++++---- .../matrix/android/sdk/internal/session/sync/SyncAPI.kt | 2 +- .../sdk/internal/session/sync/SyncResponseHandler.kt | 6 +++--- .../matrix/android/sdk/internal/session/sync/SyncTask.kt | 3 ++- .../internal/session/sync/UserAccountDataSyncHandler.kt | 2 +- .../session/sync/model/accountdata/UserAccountDataSync.kt | 2 +- .../parsing/DefaultLazyRoomSyncEphemeralJsonAdapter.kt | 4 ++-- .../session/sync/parsing/InitialSyncResponseParser.kt | 2 +- .../session/sync/parsing/RoomSyncAccountDataHandler.kt | 2 +- 34 files changed, 70 insertions(+), 64 deletions(-) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{internal => api}/session/sync/model/DeviceListResponse.kt (90%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{internal => api}/session/sync/model/DeviceOneTimeKeysCountSyncResponse.kt (87%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{internal => api}/session/sync/model/GroupSyncProfile.kt (91%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{internal => api}/session/sync/model/GroupsSyncResponse.kt (92%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{internal => api}/session/sync/model/InvitedGroupSync.kt (90%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{internal => api}/session/sync/model/InvitedRoomSync.kt (93%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{internal => api}/session/sync/model/LazyRoomSyncEphemeral.kt (77%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{internal => api}/session/sync/model/PresenceSyncResponse.kt (90%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{internal => api}/session/sync/model/RoomInviteState.kt (91%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{internal => api}/session/sync/model/RoomSync.kt (95%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{internal => api}/session/sync/model/RoomSyncAccountData.kt (90%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{internal => api}/session/sync/model/RoomSyncEphemeral.kt (91%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{internal => api}/session/sync/model/RoomSyncState.kt (91%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{internal => api}/session/sync/model/RoomSyncSummary.kt (95%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{internal => api}/session/sync/model/RoomSyncTimeline.kt (93%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{internal => api}/session/sync/model/RoomSyncUnreadNotifications.kt (92%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{internal => api}/session/sync/model/RoomsSyncResponse.kt (93%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{internal => api}/session/sync/model/SyncResponse.kt (95%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{internal => api}/session/sync/model/ToDeviceSyncResponse.kt (90%) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/DeviceListResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/DeviceListResponse.kt similarity index 90% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/DeviceListResponse.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/DeviceListResponse.kt index bfa8c342b6..c05e1e5187 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/DeviceListResponse.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/DeviceListResponse.kt @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model + +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.JsonClass @@ -21,7 +22,7 @@ import com.squareup.moshi.JsonClass * This class describes the device list response from a sync request */ @JsonClass(generateAdapter = true) -internal data class DeviceListResponse( +data class DeviceListResponse( // user ids list which have new crypto devices val changed: List = emptyList(), // List of user ids who are no more tracked. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/DeviceOneTimeKeysCountSyncResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/DeviceOneTimeKeysCountSyncResponse.kt similarity index 87% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/DeviceOneTimeKeysCountSyncResponse.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/DeviceOneTimeKeysCountSyncResponse.kt index d5b435ac27..930cfb153f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/DeviceOneTimeKeysCountSyncResponse.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/DeviceOneTimeKeysCountSyncResponse.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) -internal data class DeviceOneTimeKeysCountSyncResponse( +data class DeviceOneTimeKeysCountSyncResponse( @Json(name = "signed_curve25519") val signedCurve25519: Int? = null ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/GroupSyncProfile.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/GroupSyncProfile.kt similarity index 91% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/GroupSyncProfile.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/GroupSyncProfile.kt index ee6aabb0a9..581e6824ee 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/GroupSyncProfile.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/GroupSyncProfile.kt @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) -internal data class GroupSyncProfile( +data class GroupSyncProfile( /** * The name of the group, if any. May be nil. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/GroupsSyncResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/GroupsSyncResponse.kt similarity index 92% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/GroupsSyncResponse.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/GroupsSyncResponse.kt index 4c2dce3ba8..fd8710bbda 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/GroupsSyncResponse.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/GroupsSyncResponse.kt @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) -internal data class GroupsSyncResponse( +data class GroupsSyncResponse( /** * Joined groups: An array of groups ids. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/InvitedGroupSync.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/InvitedGroupSync.kt similarity index 90% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/InvitedGroupSync.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/InvitedGroupSync.kt index 148c2aeab9..d41df9f0f6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/InvitedGroupSync.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/InvitedGroupSync.kt @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) -internal data class InvitedGroupSync( +data class InvitedGroupSync( /** * The identifier of the inviter. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/InvitedRoomSync.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/InvitedRoomSync.kt similarity index 93% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/InvitedRoomSync.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/InvitedRoomSync.kt index c21a73abc2..dc63c5ba07 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/InvitedRoomSync.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/InvitedRoomSync.kt @@ -13,14 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model + +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass // InvitedRoomSync represents a room invitation during server sync v2. @JsonClass(generateAdapter = true) -internal data class InvitedRoomSync( +data class InvitedRoomSync( /** * The state of a room that the user has been invited to. These state events may only have the 'sender', 'type', 'state_key' diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/LazyRoomSyncEphemeral.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/LazyRoomSyncEphemeral.kt similarity index 77% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/LazyRoomSyncEphemeral.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/LazyRoomSyncEphemeral.kt index 83006c646b..087a5f52dc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/LazyRoomSyncEphemeral.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/LazyRoomSyncEphemeral.kt @@ -1,11 +1,11 @@ /* - * Copyright (c) 2021 The Matrix.org Foundation C.I.C. + * Copyright 2020 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = false) -internal sealed class LazyRoomSyncEphemeral { +sealed class LazyRoomSyncEphemeral { data class Parsed(val _roomSyncEphemeral: RoomSyncEphemeral) : LazyRoomSyncEphemeral() object Stored : LazyRoomSyncEphemeral() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/PresenceSyncResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/PresenceSyncResponse.kt similarity index 90% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/PresenceSyncResponse.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/PresenceSyncResponse.kt index 92d09aa4f5..d632552888 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/PresenceSyncResponse.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/PresenceSyncResponse.kt @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.JsonClass import org.matrix.android.sdk.api.session.events.model.Event // PresenceSyncResponse represents the updates to the presence status of other users during server sync v2. @JsonClass(generateAdapter = true) -internal data class PresenceSyncResponse( +data class PresenceSyncResponse( /** * List of presence events (array of Event with type m.presence). diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomInviteState.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomInviteState.kt similarity index 91% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomInviteState.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomInviteState.kt index ded9e2a350..59b4b4fc32 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomInviteState.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomInviteState.kt @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model + +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @@ -21,7 +22,7 @@ import org.matrix.android.sdk.api.session.events.model.Event // RoomInviteState represents the state of a room that the user has been invited to. @JsonClass(generateAdapter = true) -internal data class RoomInviteState( +data class RoomInviteState( /** * List of state events (array of MXEvent). diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSync.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSync.kt similarity index 95% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSync.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSync.kt index 9aed0d37d6..e3d07602c7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSync.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSync.kt @@ -13,14 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model + +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass // RoomSync represents the response for a room during server sync v2. @JsonClass(generateAdapter = true) -internal data class RoomSync( +data class RoomSync( /** * The state updates for the room. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncAccountData.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncAccountData.kt similarity index 90% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncAccountData.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncAccountData.kt index a2375507d8..f2c4ed551c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncAccountData.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncAccountData.kt @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass import org.matrix.android.sdk.api.session.events.model.Event @JsonClass(generateAdapter = true) -internal data class RoomSyncAccountData( +data class RoomSyncAccountData( /** * List of account data events (array of Event). */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncEphemeral.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncEphemeral.kt similarity index 91% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncEphemeral.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncEphemeral.kt index f2135db6b7..f4d831c16f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncEphemeral.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncEphemeral.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @@ -22,7 +22,7 @@ import org.matrix.android.sdk.api.session.events.model.Event // RoomSyncEphemeral represents the ephemeral events in the room that aren't recorded in the timeline or state of the room (e.g. typing). @JsonClass(generateAdapter = true) -internal data class RoomSyncEphemeral( +data class RoomSyncEphemeral( /** * List of ephemeral events (array of Event). */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncState.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncState.kt similarity index 91% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncState.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncState.kt index f86f05d000..7822467564 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncState.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncState.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @@ -22,7 +22,7 @@ import org.matrix.android.sdk.api.session.events.model.Event // RoomSyncState represents the state updates for a room during server sync v2. @JsonClass(generateAdapter = true) -internal data class RoomSyncState( +data class RoomSyncState( /** * List of state events (array of Event). The resulting state corresponds to the *start* of the timeline. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncSummary.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncSummary.kt similarity index 95% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncSummary.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncSummary.kt index 228a71ec28..7216a0c992 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncSummary.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncSummary.kt @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) -internal data class RoomSyncSummary( +data class RoomSyncSummary( /** * Present only if the room has no m.room.name or m.room.canonical_alias. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncTimeline.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncTimeline.kt similarity index 93% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncTimeline.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncTimeline.kt index 27bbc4343f..82d29a52e2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncTimeline.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncTimeline.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @@ -22,7 +22,7 @@ import org.matrix.android.sdk.api.session.events.model.Event // RoomSyncTimeline represents the timeline of messages and state changes for a room during server sync v2. @JsonClass(generateAdapter = true) -internal data class RoomSyncTimeline( +data class RoomSyncTimeline( /** * List of events (array of Event). diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncUnreadNotifications.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncUnreadNotifications.kt similarity index 92% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncUnreadNotifications.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncUnreadNotifications.kt index f01534b884..6618bceacd 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncUnreadNotifications.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncUnreadNotifications.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @@ -24,7 +24,7 @@ import org.matrix.android.sdk.api.session.events.model.Event * `MXRoomSyncUnreadNotifications` represents the unread counts for a room. */ @JsonClass(generateAdapter = true) -internal data class RoomSyncUnreadNotifications( +data class RoomSyncUnreadNotifications( /** * List of account data events (array of Event). */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomsSyncResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomsSyncResponse.kt similarity index 93% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomsSyncResponse.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomsSyncResponse.kt index dd2f96c988..ff3ed54264 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomsSyncResponse.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomsSyncResponse.kt @@ -13,14 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model + +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass // RoomsSyncResponse represents the rooms list in server sync v2 response. @JsonClass(generateAdapter = true) -internal data class RoomsSyncResponse( +data class RoomsSyncResponse( /** * Joined rooms: keys are rooms ids. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/SyncResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/SyncResponse.kt similarity index 95% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/SyncResponse.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/SyncResponse.kt index f2b2fb7e8f..e9863e1cd1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/SyncResponse.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/SyncResponse.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @@ -22,7 +22,7 @@ import org.matrix.android.sdk.internal.session.sync.model.accountdata.UserAccoun // SyncResponse represents the request response for server sync v2. @JsonClass(generateAdapter = true) -internal data class SyncResponse( +data class SyncResponse( /** * The user private data. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/ToDeviceSyncResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/ToDeviceSyncResponse.kt similarity index 90% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/ToDeviceSyncResponse.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/ToDeviceSyncResponse.kt index 8f3af56cde..082460cc2d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/ToDeviceSyncResponse.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/ToDeviceSyncResponse.kt @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.JsonClass import org.matrix.android.sdk.api.session.events.model.Event // ToDeviceSyncResponse represents the data directly sent to one of user's devices. @JsonClass(generateAdapter = true) -internal data class ToDeviceSyncResponse( +data class ToDeviceSyncResponse( /** * List of direct-to-device events. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 563c890950..c28ccda00a 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -87,7 +87,7 @@ import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.extensions.foldToCallback import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask -import org.matrix.android.sdk.internal.session.sync.model.SyncResponse +import org.matrix.android.sdk.api.session.sync.model.SyncResponse import org.matrix.android.sdk.internal.task.TaskExecutor import org.matrix.android.sdk.internal.task.TaskThread import org.matrix.android.sdk.internal.task.configureWith diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt index 0ece07fc15..be89554f2f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt @@ -19,7 +19,7 @@ package org.matrix.android.sdk.internal.session.notification import org.matrix.android.sdk.api.pushrules.rest.PushRule import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.internal.di.UserId -import org.matrix.android.sdk.internal.session.sync.model.RoomsSyncResponse +import org.matrix.android.sdk.api.session.sync.model.RoomsSyncResponse import org.matrix.android.sdk.internal.task.Task import timber.log.Timber import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt index 842c9d3aba..c626e472e6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt @@ -61,8 +61,8 @@ import org.matrix.android.sdk.internal.session.room.accountdata.RoomAccountDataD import org.matrix.android.sdk.internal.session.room.membership.RoomDisplayNameResolver import org.matrix.android.sdk.internal.session.room.membership.RoomMemberHelper import org.matrix.android.sdk.internal.session.room.relationship.RoomChildRelationInfo -import org.matrix.android.sdk.internal.session.sync.model.RoomSyncSummary -import org.matrix.android.sdk.internal.session.sync.model.RoomSyncUnreadNotifications +import org.matrix.android.sdk.api.session.sync.model.RoomSyncSummary +import org.matrix.android.sdk.api.session.sync.model.RoomSyncUnreadNotifications import timber.log.Timber import javax.inject.Inject import kotlin.system.measureTimeMillis diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/CryptoSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/CryptoSyncHandler.kt index 411a9c5c06..a81a7d681e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/CryptoSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/CryptoSyncHandler.kt @@ -27,8 +27,8 @@ import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult import org.matrix.android.sdk.internal.crypto.model.event.OlmEventContent import org.matrix.android.sdk.internal.crypto.verification.DefaultVerificationService import org.matrix.android.sdk.internal.session.initsync.ProgressReporter -import org.matrix.android.sdk.internal.session.sync.model.SyncResponse -import org.matrix.android.sdk.internal.session.sync.model.ToDeviceSyncResponse +import org.matrix.android.sdk.api.session.sync.model.SyncResponse +import org.matrix.android.sdk.api.session.sync.model.ToDeviceSyncResponse import timber.log.Timber import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/GroupSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/GroupSyncHandler.kt index 02362bf050..701f6314ab 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/GroupSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/GroupSyncHandler.kt @@ -25,8 +25,8 @@ import org.matrix.android.sdk.internal.database.query.getOrCreate import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.session.initsync.ProgressReporter import org.matrix.android.sdk.internal.session.initsync.mapWithProgress -import org.matrix.android.sdk.internal.session.sync.model.GroupsSyncResponse -import org.matrix.android.sdk.internal.session.sync.model.InvitedGroupSync +import org.matrix.android.sdk.api.session.sync.model.GroupsSyncResponse +import org.matrix.android.sdk.api.session.sync.model.InvitedGroupSync import javax.inject.Inject internal class GroupSyncHandler @Inject constructor() { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncEphemeralTemporaryStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncEphemeralTemporaryStore.kt index c6ff71cfcf..038b92d729 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncEphemeralTemporaryStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncEphemeralTemporaryStore.kt @@ -21,7 +21,7 @@ import com.squareup.moshi.Moshi import okio.buffer import okio.source import org.matrix.android.sdk.internal.di.SessionFilesDirectory -import org.matrix.android.sdk.internal.session.sync.model.RoomSyncEphemeral +import org.matrix.android.sdk.api.session.sync.model.RoomSyncEphemeral import org.matrix.android.sdk.internal.util.md5 import timber.log.Timber import java.io.File diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt index c3586bcea7..487ccbbfc3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt @@ -58,10 +58,10 @@ import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryUpdater import org.matrix.android.sdk.internal.session.room.timeline.PaginationDirection import org.matrix.android.sdk.internal.session.room.timeline.TimelineInput import org.matrix.android.sdk.internal.session.room.typing.TypingEventContent -import org.matrix.android.sdk.internal.session.sync.model.InvitedRoomSync -import org.matrix.android.sdk.internal.session.sync.model.LazyRoomSyncEphemeral -import org.matrix.android.sdk.internal.session.sync.model.RoomSync -import org.matrix.android.sdk.internal.session.sync.model.RoomsSyncResponse +import org.matrix.android.sdk.api.session.sync.model.InvitedRoomSync +import org.matrix.android.sdk.api.session.sync.model.LazyRoomSyncEphemeral +import org.matrix.android.sdk.api.session.sync.model.RoomSync +import org.matrix.android.sdk.api.session.sync.model.RoomsSyncResponse import org.matrix.android.sdk.internal.session.sync.parsing.RoomSyncAccountDataHandler import org.matrix.android.sdk.internal.util.computeBestChunkSize import timber.log.Timber diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncAPI.kt index 2616803463..86ecdf8b56 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncAPI.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncAPI.kt @@ -19,7 +19,7 @@ package org.matrix.android.sdk.internal.session.sync import okhttp3.ResponseBody import org.matrix.android.sdk.internal.network.NetworkConstants import org.matrix.android.sdk.internal.network.TimeOutInterceptor -import org.matrix.android.sdk.internal.session.sync.model.SyncResponse +import org.matrix.android.sdk.api.session.sync.model.SyncResponse import retrofit2.Call import retrofit2.http.GET import retrofit2.http.Header diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt index a4468a96c9..cf50f89f54 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt @@ -30,9 +30,9 @@ import org.matrix.android.sdk.internal.session.group.GetGroupDataWorker import org.matrix.android.sdk.internal.session.initsync.ProgressReporter import org.matrix.android.sdk.internal.session.initsync.reportSubtask import org.matrix.android.sdk.internal.session.notification.ProcessEventForPushTask -import org.matrix.android.sdk.internal.session.sync.model.GroupsSyncResponse -import org.matrix.android.sdk.internal.session.sync.model.RoomsSyncResponse -import org.matrix.android.sdk.internal.session.sync.model.SyncResponse +import org.matrix.android.sdk.api.session.sync.model.GroupsSyncResponse +import org.matrix.android.sdk.api.session.sync.model.RoomsSyncResponse +import org.matrix.android.sdk.api.session.sync.model.SyncResponse import org.matrix.android.sdk.internal.util.awaitTransaction import org.matrix.android.sdk.internal.worker.WorkerParamsFactory import timber.log.Timber diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt index c80fbe60c1..f033fe31d7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt @@ -28,7 +28,8 @@ import org.matrix.android.sdk.internal.session.filter.FilterRepository import org.matrix.android.sdk.internal.session.homeserver.GetHomeServerCapabilitiesTask import org.matrix.android.sdk.internal.session.initsync.DefaultInitialSyncProgressService import org.matrix.android.sdk.internal.session.initsync.reportSubtask -import org.matrix.android.sdk.internal.session.sync.model.LazyRoomSyncEphemeral +import org.matrix.android.sdk.api.session.sync.model.LazyRoomSyncEphemeral +import org.matrix.android.sdk.api.session.sync.model.SyncResponse import org.matrix.android.sdk.internal.session.sync.parsing.InitialSyncResponseParser import org.matrix.android.sdk.internal.session.user.UserStore import org.matrix.android.sdk.internal.task.Task diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/UserAccountDataSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/UserAccountDataSyncHandler.kt index b8d987d500..d4be345b75 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/UserAccountDataSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/UserAccountDataSyncHandler.kt @@ -48,7 +48,7 @@ import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.session.room.RoomAvatarResolver import org.matrix.android.sdk.internal.session.room.membership.RoomDisplayNameResolver import org.matrix.android.sdk.internal.session.room.membership.RoomMemberHelper -import org.matrix.android.sdk.internal.session.sync.model.InvitedRoomSync +import org.matrix.android.sdk.api.session.sync.model.InvitedRoomSync import org.matrix.android.sdk.internal.session.sync.model.accountdata.BreadcrumbsContent import org.matrix.android.sdk.internal.session.sync.model.accountdata.DirectMessagesContent import org.matrix.android.sdk.internal.session.sync.model.accountdata.IgnoredUsersContent diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/accountdata/UserAccountDataSync.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/accountdata/UserAccountDataSync.kt index 05b50ab2c5..ffa9db06ff 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/accountdata/UserAccountDataSync.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/accountdata/UserAccountDataSync.kt @@ -21,6 +21,6 @@ import com.squareup.moshi.JsonClass import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent @JsonClass(generateAdapter = true) -internal data class UserAccountDataSync( +data class UserAccountDataSync( @Json(name = "events") val list: List = emptyList() ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/DefaultLazyRoomSyncEphemeralJsonAdapter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/DefaultLazyRoomSyncEphemeralJsonAdapter.kt index 940ea219fb..62c71d9e21 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/DefaultLazyRoomSyncEphemeralJsonAdapter.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/DefaultLazyRoomSyncEphemeralJsonAdapter.kt @@ -23,8 +23,8 @@ import com.squareup.moshi.JsonWriter import com.squareup.moshi.ToJson import org.matrix.android.sdk.internal.session.sync.InitialSyncStrategy import org.matrix.android.sdk.internal.session.sync.RoomSyncEphemeralTemporaryStore -import org.matrix.android.sdk.internal.session.sync.model.LazyRoomSyncEphemeral -import org.matrix.android.sdk.internal.session.sync.model.RoomSyncEphemeral +import org.matrix.android.sdk.api.session.sync.model.LazyRoomSyncEphemeral +import org.matrix.android.sdk.api.session.sync.model.RoomSyncEphemeral import timber.log.Timber internal class DefaultLazyRoomSyncEphemeralJsonAdapter { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/InitialSyncResponseParser.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/InitialSyncResponseParser.kt index 0b44887aed..331d4cc3fd 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/InitialSyncResponseParser.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/InitialSyncResponseParser.kt @@ -21,7 +21,7 @@ import okio.buffer import okio.source import org.matrix.android.sdk.internal.session.sync.InitialSyncStrategy import org.matrix.android.sdk.internal.session.sync.RoomSyncEphemeralTemporaryStore -import org.matrix.android.sdk.internal.session.sync.model.SyncResponse +import org.matrix.android.sdk.api.session.sync.model.SyncResponse import timber.log.Timber import java.io.File import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/RoomSyncAccountDataHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/RoomSyncAccountDataHandler.kt index 8bf9ad5b90..60bc68facc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/RoomSyncAccountDataHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/RoomSyncAccountDataHandler.kt @@ -29,7 +29,7 @@ import org.matrix.android.sdk.internal.database.query.getOrCreate import org.matrix.android.sdk.internal.session.room.read.FullyReadContent import org.matrix.android.sdk.internal.session.sync.RoomFullyReadHandler import org.matrix.android.sdk.internal.session.sync.RoomTagHandler -import org.matrix.android.sdk.internal.session.sync.model.RoomSyncAccountData +import org.matrix.android.sdk.api.session.sync.model.RoomSyncAccountData import javax.inject.Inject internal class RoomSyncAccountDataHandler @Inject constructor(private val roomTagHandler: RoomTagHandler, From a968a848b0cf7ac9c0d740f9a18115c937125bfa Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 23 Aug 2021 16:46:37 +0200 Subject: [PATCH 009/656] Sync: exposes ShareFlow from the SyncThread --- .../matrix/android/sdk/api/session/Session.kt | 7 +++++++ .../sdk/internal/session/DefaultSession.kt | 2 ++ .../sdk/internal/session/sync/SyncTask.kt | 21 ++++++++++++------- .../internal/session/sync/job/SyncThread.kt | 10 ++++++++- 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt index 2f981ffbbe..e0b48f1e07 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt @@ -18,6 +18,7 @@ package org.matrix.android.sdk.api.session import androidx.annotation.MainThread import androidx.lifecycle.LiveData +import kotlinx.coroutines.flow.SharedFlow import okhttp3.OkHttpClient import org.matrix.android.sdk.api.auth.data.SessionParams import org.matrix.android.sdk.api.failure.GlobalError @@ -57,6 +58,7 @@ import org.matrix.android.sdk.api.session.thirdparty.ThirdPartyService import org.matrix.android.sdk.api.session.typing.TypingUsersTracker import org.matrix.android.sdk.api.session.user.UserService import org.matrix.android.sdk.api.session.widgets.WidgetService +import org.matrix.android.sdk.api.session.sync.model.SyncResponse /** * This interface defines interactions with a session. @@ -143,6 +145,11 @@ interface Session : */ fun getSyncState(): SyncState + /** + * This method returns a flow of SyncResponse. New value will be pushed through the sync thread. + */ + fun syncFlow(): SharedFlow + /** * This methods return true if an initial sync has been processed */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt index c2bd1e24ed..2975cc7ad0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt @@ -223,6 +223,8 @@ internal class DefaultSession @Inject constructor( override fun getSyncStateLive() = getSyncThread().liveState() + override fun syncFlow() = getSyncThread().syncFlow() + override fun getSyncState() = getSyncThread().currentState() override fun hasAlreadySynced(): Boolean { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt index f033fe31d7..5684c2b1d6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt @@ -41,7 +41,7 @@ import java.io.File import java.net.SocketTimeoutException import javax.inject.Inject -internal interface SyncTask : Task { +internal interface SyncTask : Task { data class Params( val timeout: Long, @@ -69,13 +69,13 @@ internal class DefaultSyncTask @Inject constructor( private val workingDir = File(fileDirectory, "is") private val initialSyncStatusRepository: InitialSyncStatusRepository = FileInitialSyncStatusRepository(workingDir) - override suspend fun execute(params: SyncTask.Params) { - syncTaskSequencer.post { + override suspend fun execute(params: SyncTask.Params) : SyncResponse { + return syncTaskSequencer.post { doSync(params) } } - private suspend fun doSync(params: SyncTask.Params) { + private suspend fun doSync(params: SyncTask.Params): SyncResponse { Timber.v("Sync task started on Thread: ${Thread.currentThread().name}") val requestParams = HashMap() @@ -100,6 +100,7 @@ internal class DefaultSyncTask @Inject constructor( val readTimeOut = (params.timeout + TIMEOUT_MARGIN).coerceAtLeast(TimeOutInterceptor.DEFAULT_LONG_TIMEOUT) + var syncResponseToReturn: SyncResponse? = null if (isInitialSync) { Timber.d("INIT_SYNC with filter: ${requestParams["filter"]}") val initSyncStrategy = initialSyncStrategy @@ -108,7 +109,7 @@ internal class DefaultSyncTask @Inject constructor( roomSyncEphemeralTemporaryStore.reset() workingDir.mkdirs() val file = downloadInitSyncResponse(requestParams) - reportSubtask(initialSyncProgressService, InitSyncStep.ImportingAccount, 1, 0.7F) { + syncResponseToReturn = reportSubtask(initialSyncProgressService, InitSyncStep.ImportingAccount, 1, 0.7F) { handleSyncFile(file, initSyncStrategy) } // Delete all files @@ -122,10 +123,10 @@ internal class DefaultSyncTask @Inject constructor( ) } } - logDuration("INIT_SYNC Database insertion") { syncResponseHandler.handleResponse(syncResponse, token, initialSyncProgressService) } + syncResponseToReturn = syncResponse } } initialSyncProgressService.endAll() @@ -137,8 +138,11 @@ internal class DefaultSyncTask @Inject constructor( ) } syncResponseHandler.handleResponse(syncResponse, token, null) + syncResponseToReturn = syncResponse } Timber.v("Sync task finished on Thread: ${Thread.currentThread().name}") + // Should throw if null as it's a mandatory value. + return syncResponseToReturn!! } private suspend fun downloadInitSyncResponse(requestParams: Map): File { @@ -195,8 +199,8 @@ internal class DefaultSyncTask @Inject constructor( } } - private suspend fun handleSyncFile(workingFile: File, initSyncStrategy: InitialSyncStrategy.Optimized) { - logDuration("INIT_SYNC handleSyncFile()") { + private suspend fun handleSyncFile(workingFile: File, initSyncStrategy: InitialSyncStrategy.Optimized): SyncResponse { + return logDuration("INIT_SYNC handleSyncFile()") { val syncResponse = logDuration("INIT_SYNC Read file and parse") { syncResponseParser.parse(initSyncStrategy, workingFile) } @@ -210,6 +214,7 @@ internal class DefaultSyncTask @Inject constructor( syncResponseHandler.handleResponse(syncResponse, null, initialSyncProgressService) } initialSyncStatusRepository.setStep(InitialSyncStatus.STEP_SUCCESS) + syncResponse } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncThread.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncThread.kt index de8d009892..1b34b625ff 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncThread.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncThread.kt @@ -34,11 +34,14 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.cancelChildren import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import org.matrix.android.sdk.api.session.call.MxCall import org.matrix.android.sdk.internal.session.call.ActiveCallHandler import org.matrix.android.sdk.internal.session.sync.SyncPresence +import org.matrix.android.sdk.api.session.sync.model.SyncResponse import timber.log.Timber import java.net.SocketTimeoutException import java.util.Timer @@ -72,6 +75,8 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask, } } + private val _syncFlow = MutableSharedFlow() + init { updateStateTo(SyncState.Idle) } @@ -115,6 +120,8 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask, return liveState } + fun syncFlow(): SharedFlow = _syncFlow + override fun onConnectivityChanged() { retryNoNetworkTask?.cancel() synchronized(lock) { @@ -192,7 +199,8 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask, private suspend fun doSync(params: SyncTask.Params) { try { - syncTask.execute(params) + val syncResponse = syncTask.execute(params) + _syncFlow.emit(syncResponse) } catch (failure: Throwable) { if (failure is Failure.NetworkConnection) { canReachServer = false From fac9a19c017a8df3724803b057a6f333d228ac2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Fri, 3 Sep 2021 12:34:13 +0200 Subject: [PATCH 010/656] Add back a string that has been removed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Peter Vágner --- vector/src/main/res/values/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index e9b07763d4..0431b3dd8d 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -3477,6 +3477,7 @@ Record Voice Message Slide to cancel + Voice Message Lock Play Voice Message Pause Voice Message Stop Recording From 0e956f1f5ab9e966811e82d3e17d63eb85f026a5 Mon Sep 17 00:00:00 2001 From: Glandos Date: Thu, 9 Sep 2021 21:34:01 +0000 Subject: [PATCH 011/656] Translated using Weblate (French) Currently translated at 100.0% (2615 of 2615 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/fr/ --- vector/src/main/res/values-fr/strings.xml | 66 ++++++++++++++++++++--- 1 file changed, 60 insertions(+), 6 deletions(-) diff --git a/vector/src/main/res/values-fr/strings.xml b/vector/src/main/res/values-fr/strings.xml index 57c19f0488..8207a3575a 100644 --- a/vector/src/main/res/values-fr/strings.xml +++ b/vector/src/main/res/values-fr/strings.xml @@ -2509,7 +2509,7 @@ Niveau de confiance par défaut Sélectionné Vidéo - Ce salon a des brouillons non envoyés + a des brouillons non envoyés Certains messages n’ont pas été envoyés Supprimer l’avatar Changer l’avatar @@ -2539,7 +2539,7 @@ Rappeler Cet appel est terminé %1$s a refusé cet appel - Vous avez refusé cet appel %1$s + Vous avez refusé cet appel %s Vous êtes actuellement dans cet appel %1$s a lancé un appel Vous avez lancé un appel @@ -2772,7 +2772,7 @@ Gérer les salons Vous cherchez quelqu’un qui n’est pas dans %s \? %s vous invite - Ce salon est public + Salon public Envoyer le média en taille d’origine Envoyer la vidéo en taille originale @@ -2803,7 +2803,7 @@ Salon sans nom Espace privé Espace public - Cet espace est public + Espace public Personne inconnue Transférer à %1$s Ce serveur fait déjà partie de la liste @@ -2893,10 +2893,64 @@ Les conversations de groupe Les conversations privées chiffrées Les conversations privées - Les messages contenant mon nom d’utilisateur - Les messages contenant mon nom d’affichage + Mon nom d’utilisateur + Mon nom d’affichage Me notifier pour Autre Mentions et mots-clés Notifications par défaut + %s dans les paramètres pour recevoir les invitations directement dans Element. + Lier cet e-mail à votre compte + Cette invitation à cette espace a été envoyée à %s qui n’est pas associé à votre compte + Cette invitation à ce salon a été envoyée à %s qui n’est pas associé à votre compte + Pour aider les membres de l’espace à trouver des salons privés, allez aux paramètres du salons en touchant l’avatar. + Aidez les membres de l’espace à trouver des salons privés + Cela permet de garder facilement un salon privé dans un espace, tout en laissant la possibilité aux gens de trouver l’espace et de le rejoindre. Tous les nouveaux salons de cet espace auront cette option disponible. + Aide les personnes dans les espaces à trouver et rejoindre des salons privés tout seuls, sans avoir à les inviter manuellement. + Nouveau : aidez les personnes dans les espaces à trouver et rejoindre des salons privés + L’appel de groupe a démarré + Tous les salons dans lesquels vous vous trouvez seront affichés sur l’Accueil. + Montrer tous les salons dans Accueil + Faire glisser pour terminer l’appel + %1$s Toucher pour revenir + Appel en cours (%1$s) · + Appel vidéo en cours + Appel vocal en cours + + Appel en cours · + %1$d appels en cours · + + Connexion échouée + Pas de réponse + Appel vidéo manqué + Appel vocal manqué + Appel vidéo refusé + Appel vocal refusé + Appel vidéo terminé • %1$s + Appel vocal terminé • %1$s + Appel vidéo entrant + Appel vocal entrant + Vous avez refusé cet appel + Paramètres du compte + Vous pouvez gérer les notifications dans %1$s. + Veuillez noter que les notifications sur mentions et mots-clés ne sont pas disponible dans les salons chiffrés sur mobile. + Me notifier pour + Vous n’aurez aucune notifications sur mentions et mots-clés dans les salons chiffrés sur mobile. + Mots-clés + \@room + Les mots-clés ne peuvent pas contenir « %s » + Les mots-clés ne peuvent pas commencer par « . » + Ajouter un mot clé + Vos mots-clés + Aucun + Mentions et mots-clés seulement + Fin de l’appel… + Pas de réponse + L’utilisateur que vous avez appelé est occupé. + Utilisateur occupé + Appel audio avec %s + Appel vidéo avec %s + Appel en cours… + Espaces + En savoir plus \ No newline at end of file From 13ac4851fc7ffc2fb8a26fb7b6a23322f1502352 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Fri, 10 Sep 2021 06:28:00 +0000 Subject: [PATCH 012/656] Translated using Weblate (Ukrainian) Currently translated at 81.5% (2132 of 2615 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/uk/ --- vector/src/main/res/values-uk/strings.xml | 61 +++++++++++++---------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/vector/src/main/res/values-uk/strings.xml b/vector/src/main/res/values-uk/strings.xml index 524fb64cda..976f74f925 100644 --- a/vector/src/main/res/values-uk/strings.xml +++ b/vector/src/main/res/values-uk/strings.xml @@ -12,7 +12,7 @@ %1$s надсилає наліпку. %1$s запрошує вас %1$s приєднується - %1$s залишає кімнату + %1$s виходить з кімнати %1$s відхиляє запрошення %1$s викидає %2$s %1$s розблоковує %2$s @@ -68,15 +68,15 @@ \nІмпортування даних облікового запису Ви вийшли. Причина: %1$s %1$s виходить. Причина: %2$s - Ви залишили кімнату. Причина: %1$s - %1$s залишає кімнату. Причина: %2$s - %1$s залишає кімнату - Ви залишили кімнату - Ви залишили кімнату + Ви вийшли з кімнати. Причина: %1$s + %1$s виходить з кімнати. Причина: %2$s + %1$s виходить з кімнати + Ви вийшли з кімнати + Ви вийшли з кімнати Ви змінили адреси цієї кімнати. Ви змінили основну та альтернативну адреси цієї кімнати. Ви змінили альтернативні адреси для цієї кімнати. - Ви змінили рівень доступу на %1$s. + Ви змінили рівень повноважень %1$s. Ви змінили серверні списки контролю доступу для цієї кімнати. Ви змінили назву кімнати на: %1$s Ви змінили аватар кімнати @@ -190,7 +190,7 @@ Гаразд Скасувати Зберегти - Залишити + Вийти Надіслати Надіслати ще раз Прибрати @@ -425,8 +425,8 @@ Додати учасника 1 учасник - Залишити кімнату - Ви впевнені, що бажаєте залишити кімнату\? + Вийти з кімнати + Ви впевнені, що хочете вийти з кімнати\? Ви впевнені, що бажаєте вилучити %s з цієї кімнати\? Створити Online @@ -437,7 +437,7 @@ Особисті повідомлення СЕАНСИ Запросити - Залишити цю кімнату + Вийти з цієї кімнати Вилучити з цієї кімнати Заблокувати Розблокувати @@ -449,7 +449,8 @@ ID користувача, ім\'я або email Згадати Показати Список Пристроїв - Ви не зможете скасувати цю дію, оскільки надаєте користувачу той же рівень доступу, що й у вас.\nВи впевнені? + Ви не зможете скасувати цю дію, оскільки надаєте користувачу той же рівень повноважень, що й у вас. +\nВи впевнені\? Ви впевнені, що бажаєте запросити %s до цієї кімнати\? Запросити за ID @@ -529,7 +530,7 @@ Обране Не терміново Особиста бесіда - Залишити бесіду + Вийти з бесіди Забути Повідомлення @@ -778,7 +779,7 @@ Не вдалося створити розширення. Не вдалося надіслати запит. - Рівень доступу має бути цілим додатним числом. + Рівень повноважень має бути цілим додатним числом. Ви не перебуваєте в цій кімнаті. Ви не маєте дозволу виконувати цю дію у цій кімнаті. У запиті відсутній room_id. @@ -989,11 +990,11 @@ Показує дію Заблокувати користувача із вказаним ID Розблокувати користувача із вказаним ID - Визначити рівень доступу користувача + Визначити рівень повноважень користувача Скинути рівень доступу користувача із вказаним ID Запросити користувача із вказаним ID до поточної кімнати Приєднатися до кімнати із вказаним псевдонімом - Покинути кімнату + Вийти з кімнати Встановити тему кімнати Копнути користувача із вказаним ID Змінити Ваш псевдонім @@ -1217,7 +1218,7 @@ Вимкнути мікрофон Відерити бесіду Роль - Призначити роль + Визначити роль Надіслати Номери телефонів Електронні адреси @@ -1517,7 +1518,7 @@ Показати стан подій учасників кімнати Керування криптографічними ключами Використовуйте менеджер інтеграції для керування ботами, мостами, розширеннями та пакунками наліпок. -\nМенеджери інтеграції отримують дані конфігурації та можуть змінювати розширення, надсилати запрошення до кімнати та надавати права від вашого імені. +\nМенеджери інтеграції отримують дані конфігурації та можуть змінювати розширення, надсилати запрошення до кімнати та надавати рівень повноважень від вашого імені. Інтеграції %d секунда @@ -1540,7 +1541,7 @@ Режим фонової синхронізації Застосунки не потребують з\'єднання з homeserver у фоновому режимі, це має скоротити споживання батареї Нехтувати оптимізацією - Якщо користувач залишає пристрій від\'єднаним та нерухомим впродовж певного часу з вимкненим екраном, пристрій переходить у режим дрімання. Це запобігає доступу програм до мережі та відкладає їх завдання, синхронізацію та стандартні сигнали тривоги. + Якщо користувач залишає пристрій від\'єднаним та нерухомим впродовж певного часу з вимкненим екраном, пристрій переходить у режим сну. Це запобігає доступу застосунків до мережі та відкладає їхні завдання, синхронізацію та стандартні попередження. Оптимізація акумулятора не впливає на ${app_name}. Оптимізація акумулятора Вимкнути обмеження @@ -1766,10 +1767,10 @@ Виберіть ролі, необхідні для зміни різних частин кімнати Дозволи Перегляд та оновлення ролей, необхідних для зміни різних частин кімнати. - Залишити кімнату - Залишити кімнату - Залишити - Залишити поточну конференцію та перейти до іншої\? + Вийти з кімнати + Вийти з кімнати + Вийти + Вийти з поточної конференції та перейти до іншої\? Це не загальнодоступна кімната. Ви не зможете знову приєднатися без запрошення. У вас немає дозволу на ввімкнення шифрування в цій кімнаті. Дозволи кімнати @@ -2069,7 +2070,7 @@ Не типовий (%1$d) у %2$s Не типовий %1$s з %2$s до %3$s - %1$s змінює рівень доступу %2$s. + %1$s змінює рівень повноважень %2$s. Ви змінили відеоконференцію %1$s змінює відеоконференцію Ви завершили відеоконфернцію @@ -2080,7 +2081,7 @@ Запрошення Модератори Адміністратори - Залишення кімнати… + Вихід з кімнати… Типово у %1$s Модератор у %1$s Адміністратор у %1$s @@ -2201,8 +2202,8 @@ Проведіть пальцем, щоб скасувати Розпочати голосове повідомлення Розпочато груповий виклик - Ви впевнені, що хочете залишити простір\? - Залишити простір + Ви впевнені, що хочете вийти з простору\? + Вийти з простору Керувати кімнатами %s запрошує вас Вас запрошено @@ -2509,4 +2510,10 @@ Сканувати їхній код Скануйте код за допомогою іншого пристрою або перемкніться та скануйте за допомогою цього пристрою Зіскануйте код за допомогою пристрою іншого користувача, щоб надійно перевірити одне одного + Очікування на %s… + Ви прийняли + %s прийнято + Ви скасували + %s скасовано + Перевірка ключа \ No newline at end of file From 6a0cc66f4324d9c61b156a69ba02fa5696d77b19 Mon Sep 17 00:00:00 2001 From: Glandos Date: Thu, 9 Sep 2021 21:15:34 +0000 Subject: [PATCH 013/656] Translated using Weblate (French) Currently translated at 100.0% (29 of 29 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/fr/ --- fastlane/metadata/android/fr-FR/changelogs/40102000.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/fr-FR/changelogs/40102000.txt diff --git a/fastlane/metadata/android/fr-FR/changelogs/40102000.txt b/fastlane/metadata/android/fr-FR/changelogs/40102000.txt new file mode 100644 index 0000000000..504c3e24be --- /dev/null +++ b/fastlane/metadata/android/fr-FR/changelogs/40102000.txt @@ -0,0 +1,2 @@ +Principaux changements pour cette version : messages vocaux activés par défault. +Intégralité des changements : https://github.com/vector-im/element-android/releases/tag/v1.1.16 From 49821805d187a55de598e446554423dd8a391bfd Mon Sep 17 00:00:00 2001 From: Le Dang Trung Date: Fri, 10 Sep 2021 18:22:58 +0000 Subject: [PATCH 014/656] Translated using Weblate (Vietnamese) Currently translated at 44.9% (1175 of 2615 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/vi/ --- vector/src/main/res/values-vi/strings.xml | 275 +++++++++++++++++++++- 1 file changed, 274 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values-vi/strings.xml b/vector/src/main/res/values-vi/strings.xml index 0e83a210b3..9df037b846 100644 --- a/vector/src/main/res/values-vi/strings.xml +++ b/vector/src/main/res/values-vi/strings.xml @@ -483,7 +483,7 @@ Địa chỉ email được liên kết đến tài khoản của bạn phải được nhập. Để đặt lại mật khẩu, hãy nhập địa chỉ email được liên kết đến tài khoản của bạn: Tên người dùng đã được sử dụng - Máy chủ nhà này muốn chắc chắn là bạn không phải rô bốt + Máy chủ nhà này muốn chắc chắn bạn không phải rô bốt Việc đăng ký bằng cả email và số điện thoại ngay một lúc chưa được hỗ trợ cho đến khi api có tồn tại. Chỉ có số điện thoại sẽ được tính đến. \n \nBạn có thể thêm email vào hồ sơ của bạn trong cài đặt. @@ -1006,4 +1006,277 @@ Người dùng bạn vừa gọi đang bận. Người dụng bận Phòng chat của bạn được hiển thị ở đây. Bạn có thể tạo mới phòng chat hoặc tham gia các phòng cộng đồng hiện có. + Chọn một máy chủ + Hãy bắt đầu + Mở rộng và hiệu chỉnh trải nghiệm của bạn + Giữ cho hội thoải riêng tư với bảo mật đầu cuối + Chat với một người hoặc chat nhóm + Đây là hội thoại của bạn. Bạn sở hữu nó. + Tin nhắn chưa đọc + Bạn thiết lập phòng chỉ tham gia khi được mời. + %1$s thiết lập phòng chỉ tham gia khi được mời. + Bạn thiết lập phòng chỉ tham gia khi được mời. + %1$s thiết lập phòng chỉ tham gia khi được mời. + Bạn thiết lập phòng công khai cho bất kỳ ai biết đường dẫn. + %1$s thiết lập phòng công khai cho ai biết đường dẫn. + Chạm lâu vào một phòng để thấy nhiều lựa chọn + Bạn đang không lơ ai cả + Nhập từ khóa để tìm phản ứng. + Phá đám + Gửi tin phá đám + Bạn không tạo thay đổi + %1$s không tạo thay đổi + Thiết lập phòng + Rời phòng + Loại khỏi mục ưu tiên thấp + Thêm vào mục ưu tiên thấp + Loại khỏi mục yêu thích + Thêm vào mục yêu thích + Thiết lập + Im lặng + Chỉ tin nhắn được đề cập + Tất cả tin nhắn + Tất cả tin nhắn (ầm ĩ) + Lơ người dùng + Hiện không có kết nối mạng + ${app_name} cần được cấp quyền để lưu khóa bảo mật E2E keys trên bộ nhớ. +\n +\nVui lòng cấp quyền để App có thể xuất khẩu khóa bảo mật. + Nội dung này bị báo cáo không phù hợp. +\n +\nNếu bạn không muốn thấy thêm nội dung từ người dùng này, bạn có thể lơ họ để ẩn nội dung tin nhắn. + Bị báo cáo không phù hợp + Nội dung này bị báo cáo tin rác. +\n +\nNếu bạn không muốn thấy thêm nội dung từ người dùng này, bạn có thể lơ họ để ẩn nội dung tin nhắn. + Báo cáo tin rác + Nội dung này bị báo cáo. +\n +\nNếu bạn không muốn thấy thêm nội dung từ người dùng này, bạn có thể lơ họ để ẩn nội dung tin nhắn. + Nội dung bị báo cáo + LƠ NGƯỜI DÙNG + BÁO CÁO + Lí do báo cáo nội dung này + Báo cáo nội dung này + Báo cáo tùy chọn… + Tin nhắn không phù hợp + Tin nhắc rác + Không có tệp nào trong phòng này + %1$s vào lúc %2$s + Tệp + Không có media nào trong phòng này + MEDIA + %1$d của %2$d + Không thể xử lý dữ liệu chia sẻ + Xoay chiều và cắt bớt + Sticker + Bộ sưu tập + Âm thành + Máy ảnh + Liên hệ + Tệp + Thêm hình từ + Lỗi xảy ra khi hiển thị tệp đính kèm. + Tệp \'%1$s\' (%2$s) quá lớn để tải lên. Dung lượng tối đa là %3$s. + Tệp quá lớn để tải lên. + + %d người dùng đã đọc + + %s đã đọc + %1$s và %2$s đã đọc + %1$s, %2$s và %3$s đã đọc + + %1$s, %2$s và %3$d người khác đã đọc + + Chức năng thử nghiệm + Nhảy xuống đáy + Ẩn mật khẩu + Hiện mật khẩu + Đóng banner sao lưu khóa + Tạo phòng chat mới + Tạo phòng chat 1-1 bằng cách quét mã QR + Tạo mới phòng chat 1-1 theo ID Matrix + Tạo mới phòng chat 1-1 + Đóng menu tạo phòng… + Mở menu tạo phòng + Gửi tệp đính kèm + Bạn hiện đang sử dụng %1$s để khám phá và được khám phá bởi danh bạ hiện hữu. + Đổi máy chủ định danh + Cấu hình máy chủ định danh + Ngắt kết nối máy chủ định danh + Máy chủ định danh + Đọc lúc + Sử dụng Bot, cầu nối, widget hoặc sticker + Được khám phá bởi người khác + Xem lại Điều khoản + Điều khoản Dịch vụ + Xem lịch sử chỉnh sửa + Tham gia phòng… + Gợi ý + Danh bạ + Thành viên đã biết + Gần đây + Lọc theo tên đăng nhập hoặc ID… + Gõ phím để tìm kết quả + Mã QR + Thêm vào phòng bằng QR code + Thêm vào phòng bằng ID + Đường link được copy + Bật chức năng quẹt để Trả lời + Tìm Tên + Tìm theo tên hoặc ID + Tên hoặc ID + Xem danh mục phòng chat + Gửi tin nhắn tới phòng 1-1 + Tạo phòng chat mới + Không tìm thấy kết quả cần tìm\? + Không tìm thấy, sử dụng chức năng thêm thành viên bằng username. + Tạo phòng chat… + Chào mừng về nhà! + Tất cả tin nhắn đã được đọc + Bạn đã thấy tất cả tin nhắn! + Được mời bởi %s + Lời mời đã được gửi + Tham gia phòng chat để bắt đầu sử dụng app. + Thử lại + Phản hồi + Sửa + Hình phòng + Mãi mãi + 1 tháng + 1 tuần + 3 ngày + Bạn hiện không là thành viên của bất cứ cộng đồng nào. + Biểu tượng + Phát âm thanh shutter + Chọn + Nguồn media mặc định + Chọn + Nén dữ liệu mặc định + Media + Thông tin bổ sung: %s + Lỗi xảy ra khi xác thực số điện thoại của bạn. + + Lỗi khi xác thực số điện thoại + Nhập mã kích hoạt + Chúng tôi vừa gửi tin nhắn có mã kích hoạt. Vui lòng nhập mã này bên dưới. + Xác thực số điện thoại + Số điện thoại không hợp lệ với quốc gia này + Số điện thoại + Vui lòng chọn quốc gia + Quốc gia + Chọn quốc gia + Bạn có chắc muốn hủy %1$s %2$s\? + Bạn có chắc muốn hủy bỏ mục tiêu thông báo này\? + Quản lý email và số điện thoại liên kết với tài khoản Matrix + Email và số điện thoại + Mật khẩu không khớp + Hiện tất cả tin nhắn từ %s\? +\n +\nLưu ý rằng hành động này sẽ khởi động App và có thể mất nhiều thời gian. + Mật khẩu của bạn vừa được cập nhật + Mật khẩu này không hợp lệ + Cập nhật mật khẩu thất bại + Cập nhật mật khẩu + Xác nhận mật khẩu mới + Mật khẩu mới + Mật khẩu hiện tại + Đổi mật khẩu + Mật khẩu + Lỗi xảy ra khi xác thực địa chỉ email của bạn. + Số điện thoại này đã được sử dụng. + Địa chỉ email này không tìm thấy. + Địa chỉ Email này đã được sử dụng. + Chờ xác thực + Chọn ngôn ngữ + Ngôn ngữ + Giao diện người dùng + Bật \'Cho phép Tích hợp\' trong mục Thiết lập để thực thi tác vụ này. + Tích hợp đang bị tắt + Quản lý tích hợp + Cho phép tích hợp + Máy chủ định danh + Máy chủ + Đăng nhập tài khoản + Gửi + Mật khẩu: + Đăng nhập + Tác vụ này cần đăng nhập lại. +\nNhập mật khẩu để tiếp tục. + %1$s @ %2$s + Thấy lần cuối + Cập nhật Tên công khai + Tên công khai + ID + Thông tin phiên + Chế độ tiết kiệm dữ liệu + Có, Tôi muốn giúp! + Cho phép lấy dữ liệu phân tích để giúp cải thiện ${app_name}. + ${app_name} thu thập dữ liệu khuyết danh để giúp chúng tôi cải thiện app. + Gửi dữ liệu phân tích + Phân tích + Cấp quyền + Điều này sẽ thay thế Chìa khóa hoặc Chuỗi ký tự hiện tại. + Tạo Chìa khóa An toàn mới hoặc đặt Chuỗi từ An toàn để bảo vệ sao lưu hiện hữu. + Sao lưu các chìa khóa giải mã trên server của bạn để đảm bảo không mất dữ liệu và tin nhắn mã hóa. + Thiết lập trên thiết bị này + Đặt lại sao lưu an toàn + Thiết lập sao lưu an toàn + Quản lý + Sao lưu an toàn + Thêm nút trên dãy phím soạn tin để bật bàn phím emoji + Hiện bàn phím emoji + Nhấn Enter ở bàn phím ảo sẽ gửi tin thay vì thêm cách dòng mới + Gửi tin bằng phím Enter + Xem trước media trước khi gửi + Rung khi đề cập tên người dùng + Bao gồm thay đổi tên hiển thị và hình đại diện. + Hiện các sự kiện của tài khoản + Sự kiện mời, loại hoặc cấm thành viên không bị ảnh hưởng. + Hiện sự kiện tham gia hoặc rời phòng + Bao gồm sự kiện mời/tham gia/rời/loại thành viên/cấm thành viên và thay đổi tên/avatar. + Gõ lệnh /confetti hoặc gửi tin chứa ❄️ hoặc 🎉 + Hiện hiệu ứng chat + Hiện trạng thái hoạt động của thành viên phòng + Chạm vào thông báo tin đã đọc để xem chi tiết. + Hiện thông báo tin đã đọc + Hiện dấu thời gian theo chuẩn 12-giờ + Hiện Dấu thời gian cho tất cả tin nhắn + Định dạng tin nhắn theo chuẩn markdown trước khi gửi. + Định dạng markdown + Cho người dùng khác biết bạn đã gõ phím. + Gửi thông báo đang gõ tin nhắn + Xem trước trang web trong phòng chat nếu máy chủ bật hỗ trợ chức năng này. + Xem trước URL + Phiên làm việc + Ghim phòng có tin nhắn chưa đọc + Ghim phòng có thông báo nhỡ + Màn hình home + Danh bạ quốc gia + Quyền danh bạ + Danh bạ trên máy + Mục tiêu Thông báo + Quản lý Chìa khóa mã hóa bảo mật + Mã hóa bảo mật + Tích hợp + Nâng cao + Khác + Người dùng bị bỏ qua + Thông báo + Thiết lập người dùng + Xóa media cache + Xóa cache + Giữ media + Điều khoản riêng tư + Bản quyền + Lưu ý bên thứ 3 + Điều khoản Dịch vụ + Phiên bản olm + Phiên bản + + %d giây + + Thời gian chờ giữa 2 lần đồng bộ + %s +\nTiến trình đồng bộ có thể bị gián đoạn tùy thuộc vào lượng pin và trạng thái hoạt động của thiết bị. \ No newline at end of file From 370b9cabf78a217f2c471ab2289b28eb2ca94897 Mon Sep 17 00:00:00 2001 From: libexus Date: Sat, 11 Sep 2021 07:53:00 +0000 Subject: [PATCH 015/656] Translated using Weblate (German) Currently translated at 98.8% (2585 of 2615 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/de/ --- vector/src/main/res/values-de/strings.xml | 24 +++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index bfa44cf467..6700dc705a 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2958,4 +2958,28 @@ Sprachanruf mit %s Videoanruf mit %s Mehr erfahren + Gruppenanruf gestartet + Alle beigetretenen Räume werden auf der Startseite angezeigt. + Alle Räume auf der Startseite anzeigen + Wische, um den Anruf zu beenden + Aktiver Anruf (%1$s) · + + Aktiver Anruf · + %1$d aktive Anrufe · + + Verbindung fehlgeschlagen + Videoanruf abgelehnt + Sprachanruf abgelehnt + Videoanruf beendet • %1$s + Sprachanruf beendet • %1$s + Benachrichtige mich bei + \@room + Schlüsselwörter können nicht \"%s\" enthalten + Schlüsselwörter können nicht mit einem Punkt beginnen + Nichts + Nicht erreicht + Die angerufene Person ist beschäftigt. + Person beschäftigt + Klingeln… + Spaces \ No newline at end of file From b5c08a13ffe12fff39eb112e82984c997874e3d2 Mon Sep 17 00:00:00 2001 From: jannikac Date: Sat, 11 Sep 2021 07:50:23 +0000 Subject: [PATCH 016/656] Translated using Weblate (German) Currently translated at 98.8% (2585 of 2615 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/de/ --- vector/src/main/res/values-de/strings.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 6700dc705a..ba569e3987 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2982,4 +2982,15 @@ Person beschäftigt Klingeln… Spaces + Verpasster Videoanruf + Verpasster Sprachanruf + Aktiver Videoanruf + Aktiver Sprachanruf + Eingehender Videoanruf + Eingehender Sprachanruf + Du hast diesen Anruf abgelehnt + Kontoeinstellungen + Schlüsselwörter + Neues Schlüsselwort hinzufügen + Deine Schlüsselwörter \ No newline at end of file From 66ec25d8eb2cf4c63f176e64b9150e6b4185fbf5 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Sat, 11 Sep 2021 20:59:46 +0000 Subject: [PATCH 017/656] Translated using Weblate (Ukrainian) Currently translated at 81.5% (2132 of 2615 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/uk/ --- vector/src/main/res/values-uk/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-uk/strings.xml b/vector/src/main/res/values-uk/strings.xml index 976f74f925..6f5a77308a 100644 --- a/vector/src/main/res/values-uk/strings.xml +++ b/vector/src/main/res/values-uk/strings.xml @@ -759,7 +759,7 @@ Введіть сервер для показу каталогу публічних кімнат Ім\'я сервера Всі кімнати на сервері %s - Всі місцеві кімнати %s + Усі кімнати сервера %s Пошук в історії @@ -2483,7 +2483,7 @@ Сеанс отримав несподіване повідомлення SAS не збігається Користувач скасовує перевірку - %s хоче звірити сеанс + %s хоче звірити ваш сеанс Запит перевірки Запит перевірки Інтерактивна перевірка сеансу From e07e2c11a4e217ba114576880fa787d59a56d459 Mon Sep 17 00:00:00 2001 From: libexus Date: Sat, 11 Sep 2021 07:37:22 +0000 Subject: [PATCH 018/656] Translated using Weblate (German) Currently translated at 100.0% (29 of 29 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/de/ --- fastlane/metadata/android/de-DE/changelogs/40102000.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/de-DE/changelogs/40102000.txt diff --git a/fastlane/metadata/android/de-DE/changelogs/40102000.txt b/fastlane/metadata/android/de-DE/changelogs/40102000.txt new file mode 100644 index 0000000000..9375289279 --- /dev/null +++ b/fastlane/metadata/android/de-DE/changelogs/40102000.txt @@ -0,0 +1,2 @@ +Hauptänderungen: Sprachnachrichten standardmäßig aktiviert. +Ganze Änderungsliste: https://github.com/vector-im/element-android/releases/tag/v1.1.16 From 9c94fd26e22ce1e20a8d01934fe9f2d4e566926b Mon Sep 17 00:00:00 2001 From: Le Dang Trung Date: Sun, 12 Sep 2021 03:34:41 +0000 Subject: [PATCH 019/656] Translated using Weblate (Vietnamese) Currently translated at 47.8% (1250 of 2615 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/vi/ --- vector/src/main/res/values-vi/strings.xml | 86 ++++++++++++++++++++++- 1 file changed, 83 insertions(+), 3 deletions(-) diff --git a/vector/src/main/res/values-vi/strings.xml b/vector/src/main/res/values-vi/strings.xml index 9df037b846..c52c299184 100644 --- a/vector/src/main/res/values-vi/strings.xml +++ b/vector/src/main/res/values-vi/strings.xml @@ -15,7 +15,7 @@ %d người dùng Không có phòng - Thư mục phòng + Danh sách phòng Phòng Không còn kết quả nào nữa Lọc danh sách yêu thích @@ -25,7 +25,7 @@ Bạn chưa cho phép ${app_name} truy cập danh bạ của bạn Không có cuộc trò chuyện nào Chỉ những liên hệ Matrix - Thư mục người dùng + Danh sách người dùng Sổ địa chỉ địa phương Cuộc trò chuyện Cảnh báo hệ thống @@ -670,7 +670,7 @@ Xác minh địa chỉ email thất bại: hãy chắc chắn là bạn đã nhấn vào liên kết trong email Hiện tất cả phòng trong thư mục phòng, bao gồm cả các phòng có nội dung phản cảm. Hiện các phòng có nội dung phản cảm - Thư mục phòng + Danh sách phòng Mặc định hệ thống Bạn đã bật mã hoá đầu cuối (thuật toán không được nhận ra %1$s). %1$s đã bật mã hoá đầu cuối (thuật toán không được nhận ra %2$s). @@ -1279,4 +1279,84 @@ Thời gian chờ giữa 2 lần đồng bộ %s \nTiến trình đồng bộ có thể bị gián đoạn tùy thuộc vào lượng pin và trạng thái hoạt động của thiết bị. + Mã nhập vào không hợp lệ. Vui lòng kiểm tra. + Chúng tôi vừa gửi email tới %1$s. +\nClick vào đường link trong email để tiếp tục quá trình tạo tài khoản. + Hãy kiểm tra email của bạn + Chấp nhận điều khoản để tiếp tục + Hãy thực hiện thách thức captcha + Chọn một máy chủ khác + Chọn Dịch vụ Element Matrix + Chọn matrix.org + Tài khoản của bạn chưa được tạo. +\n +\nBạn muốn ngừng tiến trình đăng ký\? + Cảnh báo + Tên đăng nhập này đã được đăng ký + Tiếp + Mật khẩu + Tên đăng nhập + Username hoặc email + Đăng ký với %1$s + Số điện thoại có vẻ không hợp lệ. Hãy kiểm tra lại + Số điện thoại quốc tế phải bắt đầu với dấu \'+\' + Vui lòng dùng định dạng quốc tế (số điện thoại bắt đầu với \'+\') + Tiếp + Gửi lại + Nhập mã + Chúng tôi vừa gửi mã tới %1$s. Nhập mã để xác thực. + Xác nhận số điện thoại + Tiếp + Số điện thoại (tùy chọn) + Số điện thoại + Vui lòng sử dụng mẫu quốc tế. + Thêm số điện thoại để tùy chọn cho phép người khác tìm bạn qua số điện thoại. + Thêm số điện thoại + Tiếp + Email (tùy chọn) + Email + Thêm địa chỉ email để phục hồi tài khoản. Sau này bạn có thể tùy chọn cho phép người khác tìm mình qua email. + Thêm địa chỉ email + Mật khẩu chưa được thay đổi. +\n +\nBạn muốn ngừng tiến trình đổi mật khẩu\? + Cảnh báo + Trở lại Đăng nhập + Bạn vừa đăng xuất tất cả phiên đăng nhập và không còn nhận được thông báo đẩy. Đăng nhập lại để nhận thông báo trên thiết bị. + Mật khẩu của bạn đã được đặt lại. + Thành công! + Tôi đã xác minh địa chỉ email + Nhấp vào đường dẫn để xác nhận mật khẩu mới. Sau khi bạn nhâp vào đường dẫn, hãy nhấp vào bên dưới. + Email xác thực đã được gửi tới %1$s. + Kiểm tra mailbox + Email này không gắn với tài khoản nào + Tiếp tục + Đổi mật khẩu sẽ đặt lại tất cả khóa bảo mật trên tất cả phiên của bạn, làm cho lịch sử chat mã hóa không đọc được. Vui lòng Sao lưu Khóa hoặc xuất khẩu tất cả khóa bảo mật các phòng từ một phiên đăng nhập khác trước khi đặt lại mật khẩu. + Cảnh báo! + Mật khẩu mới + Email + Tiếp + Email xác thực thông tin đã được gửi tới bạn để xác nhận đặt lại mật khẩu mới. + Đặt lại mật khẩu ở %1$s + Địa chỉ email này không có trong hệ thống. + Địa chỉ + Địa chỉ Dịch vụ Element Matrix + Xóa lịch sử + Tiếp tục với SSO + Đăng Nhập + Đăng Ký + Đăng nhập vào %1$s + Kết nối tới máy chủ dịch vụ khác + Kết nối tới máy chủ dịch vụ + Kết nố tới %1$s + Tiếp tục + Single Sign-On + Đăng nhập với %s + Tạo tài khoản với %s + Tiếp tục với %s + Hoặc + Thiết lập tùy chỉnh và nâng cao + Khác + Xem thêm + Giống như email, tài khoản cần có nhà riêng, dù bạn có thể nói chuyện với bất kỳ ai \ No newline at end of file From 8d2f95d5db618426399593c77ffa38ffa3378efe Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 10 Sep 2021 14:27:39 +0200 Subject: [PATCH 020/656] Store device key in SharedSessionEntity Code review changes Fix database migraiton Fix wrong self assignement + comment --- .../algorithms/megolm/MXMegolmEncryption.kt | 10 ++++----- .../algorithms/megolm/SharedWithHelper.kt | 11 ++++++++-- .../internal/crypto/store/IMXCryptoStore.kt | 5 +++-- .../crypto/store/db/RealmCryptoStore.kt | 19 +++++++++++++--- .../store/db/RealmCryptoStoreMigration.kt | 20 ++++++++++++++++- .../store/db/model/SharedSessionEntity.kt | 1 + .../store/db/query/SharedSessionQueries.kt | 22 ++++++++++++++----- 7 files changed, 70 insertions(+), 18 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt index a756444475..540280d8a2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt @@ -170,7 +170,7 @@ internal class MXMegolmEncryption( val deviceIds = devicesInRoom.getUserDeviceIds(userId) for (deviceId in deviceIds!!) { val deviceInfo = devicesInRoom.getObject(userId, deviceId) - if (deviceInfo != null && !cryptoStore.getSharedSessionInfo(roomId, safeSession.sessionId, userId, deviceId).found) { + if (deviceInfo != null && !cryptoStore.getSharedSessionInfo(roomId, safeSession.sessionId, deviceInfo).found) { val devices = shareMap.getOrPut(userId) { ArrayList() } devices.add(deviceInfo) } @@ -270,8 +270,8 @@ internal class MXMegolmEncryption( // for dead devices on every message. val gossipingEventBuffer = arrayListOf() for ((userId, devicesToShareWith) in devicesByUser) { - for ((deviceId) in devicesToShareWith) { - session.sharedWithHelper.markedSessionAsShared(userId, deviceId, chainIndex) + for (deviceInfo in devicesToShareWith) { + session.sharedWithHelper.markedSessionAsShared(deviceInfo, chainIndex) gossipingEventBuffer.add( Event( type = EventType.ROOM_KEY, @@ -279,7 +279,7 @@ internal class MXMegolmEncryption( content = submap.apply { this["session_key"] = "" // we add a fake key for trail - this["_dest"] = "$userId|$deviceId" + this["_dest"] = "$userId|${deviceInfo.deviceId}" } )) } @@ -429,7 +429,7 @@ internal class MXMegolmEncryption( .also { Timber.w("## Crypto reshareKey: Device not found") } // Get the chain index of the key we previously sent this device - val wasSessionSharedWithUser = cryptoStore.getSharedSessionInfo(roomId, sessionId, userId, deviceId) + val wasSessionSharedWithUser = cryptoStore.getSharedSessionInfo(roomId, sessionId, deviceInfo) if (!wasSessionSharedWithUser.found) { // This session was never shared with this user // Send a room key with held diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/SharedWithHelper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/SharedWithHelper.kt index f17168a6d2..a64e5af0d3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/SharedWithHelper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/SharedWithHelper.kt @@ -16,6 +16,7 @@ package org.matrix.android.sdk.internal.crypto.algorithms.megolm +import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore @@ -28,7 +29,13 @@ internal class SharedWithHelper( return cryptoStore.getSharedWithInfo(roomId, sessionId) } - fun markedSessionAsShared(userId: String, deviceId: String, chainIndex: Int) { - cryptoStore.markedSessionAsShared(roomId, sessionId, userId, deviceId, chainIndex) + fun markedSessionAsShared(deviceInfo: CryptoDeviceInfo, chainIndex: Int) { + cryptoStore.markedSessionAsShared( + roomId = roomId, + sessionId = sessionId, + userId = deviceInfo.userId, + deviceId = deviceInfo.deviceId, + deviceIdentityKey = deviceInfo.identityKey() ?: "", + chainIndex = chainIndex) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt index 3d12e74fcd..238d06738c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt @@ -450,7 +450,8 @@ internal interface IMXCryptoStore { fun addWithHeldMegolmSession(withHeldContent: RoomKeyWithHeldContent) fun getWithHeldMegolmSession(roomId: String, sessionId: String): RoomKeyWithHeldContent? - fun markedSessionAsShared(roomId: String?, sessionId: String, userId: String, deviceId: String, chainIndex: Int) + fun markedSessionAsShared(roomId: String?, sessionId: String, userId: String, deviceId: String, + deviceIdentityKey: String, chainIndex: Int) /** * Query for information on this session sharing history. @@ -459,7 +460,7 @@ internal interface IMXCryptoStore { * in this case chainIndex is not nullindicates the ratchet position. * In found is false, chainIndex is null */ - fun getSharedSessionInfo(roomId: String?, sessionId: String, userId: String, deviceId: String): SharedSessionResult + fun getSharedSessionInfo(roomId: String?, sessionId: String, deviceInfo: CryptoDeviceInfo): SharedSessionResult data class SharedSessionResult(val found: Boolean, val chainIndex: Int?) fun getSharedWithInfo(roomId: String?, sessionId: String): MXUsersDevicesMap diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt index 3c8353e83e..860bba7404 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt @@ -1681,7 +1681,12 @@ internal class RealmCryptoStore @Inject constructor( } } - override fun markedSessionAsShared(roomId: String?, sessionId: String, userId: String, deviceId: String, chainIndex: Int) { + override fun markedSessionAsShared(roomId: String?, + sessionId: String, + userId: String, + deviceId: String, + deviceIdentityKey: String, + chainIndex: Int) { doRealmTransaction(realmConfiguration) { realm -> SharedSessionEntity.create( realm = realm, @@ -1689,14 +1694,22 @@ internal class RealmCryptoStore @Inject constructor( sessionId = sessionId, userId = userId, deviceId = deviceId, + deviceIdentityKey = deviceIdentityKey, chainIndex = chainIndex ) } } - override fun getSharedSessionInfo(roomId: String?, sessionId: String, userId: String, deviceId: String): IMXCryptoStore.SharedSessionResult { + override fun getSharedSessionInfo(roomId: String?, sessionId: String, deviceInfo: CryptoDeviceInfo): IMXCryptoStore.SharedSessionResult { return doWithRealm(realmConfiguration) { realm -> - SharedSessionEntity.get(realm, roomId, sessionId, userId, deviceId)?.let { + SharedSessionEntity.get( + realm = realm, + roomId = roomId, + sessionId = sessionId, + userId = deviceInfo.userId, + deviceId = deviceInfo.deviceId, + deviceIdentityKey = deviceInfo.identityKey() + )?.let { IMXCryptoStore.SharedSessionResult(true, it.chainIndex) } ?: IMXCryptoStore.SharedSessionResult(false, null) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStoreMigration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStoreMigration.kt index 2846be9932..f73cbaf480 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStoreMigration.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStoreMigration.kt @@ -55,7 +55,7 @@ internal object RealmCryptoStoreMigration : RealmMigration { // 0, 1, 2: legacy Riot-Android // 3: migrate to RiotX schema // 4, 5, 6, 7, 8, 9: migrations from RiotX (which was previously 1, 2, 3, 4, 5, 6) - const val CRYPTO_STORE_SCHEMA_VERSION = 13L + const val CRYPTO_STORE_SCHEMA_VERSION = 14L private fun RealmObjectSchema.addFieldIfNotExists(fieldName: String, fieldType: Class<*>): RealmObjectSchema { if (!hasField(fieldName)) { @@ -94,6 +94,7 @@ internal object RealmCryptoStoreMigration : RealmMigration { if (oldVersion <= 10) migrateTo11(realm) if (oldVersion <= 11) migrateTo12(realm) if (oldVersion <= 12) migrateTo13(realm) + if (oldVersion <= 13) migrateTo14(realm) } private fun migrateTo1Legacy(realm: DynamicRealm) { @@ -554,4 +555,21 @@ internal object RealmCryptoStoreMigration : RealmMigration { Timber.e("TrustLevelEntity cleanup: Something is not correct...") } } + + // Version 14L Update the way we remember key sharing + private fun migrateTo14(realm: DynamicRealm) { + Timber.d("Step 13 -> 14") + realm.schema.get("SharedSessionEntity") + ?.addField(SharedSessionEntityFields.DEVICE_IDENTITY_KEY, String::class.java) + ?.addIndex(SharedSessionEntityFields.DEVICE_IDENTITY_KEY) + ?.transform { + val sharedUserId = it.getString(SharedSessionEntityFields.USER_ID) + val sharedDeviceId = it.getString(SharedSessionEntityFields.DEVICE_ID) + val knownDevice = realm.where("DeviceInfoEntity") + .equalTo(DeviceInfoEntityFields.USER_ID, sharedUserId) + .equalTo(DeviceInfoEntityFields.DEVICE_ID, sharedDeviceId) + .findFirst() + it.setString(SharedSessionEntityFields.DEVICE_IDENTITY_KEY, knownDevice?.getString(DeviceInfoEntityFields.IDENTITY_KEY)) + } + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/SharedSessionEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/SharedSessionEntity.kt index c0ed1ac409..e2ae512afd 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/SharedSessionEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/SharedSessionEntity.kt @@ -30,6 +30,7 @@ internal open class SharedSessionEntity( @Index var sessionId: String? = null, @Index var userId: String? = null, @Index var deviceId: String? = null, + @Index var deviceIdentityKey: String? = null, var chainIndex: Int? = null ) : RealmObject() { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/SharedSessionQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/SharedSessionQueries.kt index fa37734fe5..39117512bb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/SharedSessionQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/SharedSessionQueries.kt @@ -16,15 +16,20 @@ package org.matrix.android.sdk.internal.crypto.store.db.query -import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM -import org.matrix.android.sdk.internal.crypto.store.db.model.SharedSessionEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.SharedSessionEntityFields import io.realm.Realm import io.realm.RealmResults import io.realm.kotlin.createObject import io.realm.kotlin.where +import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM +import org.matrix.android.sdk.internal.crypto.store.db.model.SharedSessionEntity +import org.matrix.android.sdk.internal.crypto.store.db.model.SharedSessionEntityFields -internal fun SharedSessionEntity.Companion.get(realm: Realm, roomId: String?, sessionId: String, userId: String, deviceId: String) +internal fun SharedSessionEntity.Companion.get(realm: Realm, + roomId: String?, + sessionId: String, + userId: String, + deviceId: String, + deviceIdentityKey: String?) : SharedSessionEntity? { return realm.where() .equalTo(SharedSessionEntityFields.ROOM_ID, roomId) @@ -32,6 +37,7 @@ internal fun SharedSessionEntity.Companion.get(realm: Realm, roomId: String?, se .equalTo(SharedSessionEntityFields.ALGORITHM, MXCRYPTO_ALGORITHM_MEGOLM) .equalTo(SharedSessionEntityFields.USER_ID, userId) .equalTo(SharedSessionEntityFields.DEVICE_ID, deviceId) + .equalTo(SharedSessionEntityFields.DEVICE_IDENTITY_KEY, deviceIdentityKey) .findFirst() } @@ -44,7 +50,12 @@ internal fun SharedSessionEntity.Companion.get(realm: Realm, roomId: String?, se .findAll() } -internal fun SharedSessionEntity.Companion.create(realm: Realm, roomId: String?, sessionId: String, userId: String, deviceId: String, chainIndex: Int) +internal fun SharedSessionEntity.Companion.create(realm: Realm, roomId: String?, + sessionId: String, + userId: String, + deviceId: String, + deviceIdentityKey: String, + chainIndex: Int) : SharedSessionEntity { return realm.createObject().apply { this.roomId = roomId @@ -52,6 +63,7 @@ internal fun SharedSessionEntity.Companion.create(realm: Realm, roomId: String?, this.sessionId = sessionId this.userId = userId this.deviceId = deviceId + this.deviceIdentityKey = deviceIdentityKey this.chainIndex = chainIndex } } From cccf812906268324eecff0af0be5420083eab58c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 13 Sep 2021 15:25:56 +0200 Subject: [PATCH 021/656] Version++ (1.2.2) --- vector/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/build.gradle b/vector/build.gradle index 9d3cc7ec3c..9576ba86c0 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -14,7 +14,7 @@ kapt { // Note: 2 digits max for each value ext.versionMajor = 1 ext.versionMinor = 2 -ext.versionPatch = 1 +ext.versionPatch = 2 static def getGitTimestamp() { def cmd = 'git show -s --format=%ct' From 0dc88c71ab328e2da59098e6d6d7ea768a854130 Mon Sep 17 00:00:00 2001 From: random Date: Tue, 14 Sep 2021 07:41:17 +0000 Subject: [PATCH 022/656] Translated using Weblate (Italian) Currently translated at 99.8% (2612 of 2615 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/it/ --- vector/src/main/res/values-it/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vector/src/main/res/values-it/strings.xml b/vector/src/main/res/values-it/strings.xml index 8d69b4ded9..472bcfd439 100644 --- a/vector/src/main/res/values-it/strings.xml +++ b/vector/src/main/res/values-it/strings.xml @@ -277,7 +277,7 @@ Invia Rispedisci Rimuovi - Citazione + Cita Condividi Ultimi Inoltra @@ -930,7 +930,7 @@ Tutti i messaggi (rumoroso) Tutti i messaggi - Solo le citazioni + Solo le menzioni Silenzioso Aggiungi alla schermata iniziale Anteprima degli URL @@ -1728,7 +1728,7 @@ Ignora utente Tutti i messaggi (rumoroso) Tutti i messaggi - Solo citazioni + Solo menzioni Silenzioso Impostazioni Esci dalla stanza From 59d5cfbb24ac920d42f67018ed659af552db487f Mon Sep 17 00:00:00 2001 From: Nikita Epifanov Date: Mon, 13 Sep 2021 08:12:13 +0000 Subject: [PATCH 023/656] Translated using Weblate (Russian) Currently translated at 99.3% (2597 of 2615 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ru/ --- vector/src/main/res/values-ru/strings.xml | 76 ++++++++++++++++++++--- 1 file changed, 66 insertions(+), 10 deletions(-) diff --git a/vector/src/main/res/values-ru/strings.xml b/vector/src/main/res/values-ru/strings.xml index 9220273767..c1fd65e4a8 100644 --- a/vector/src/main/res/values-ru/strings.xml +++ b/vector/src/main/res/values-ru/strings.xml @@ -2725,7 +2725,7 @@ Перезвонить Этот вызов закончился %1$s отменил(а) этот вызов - Вы отклонили этот вызов %1$s + Вы отклонили этот вызов %s Вы сейчас в этом вызове Вы начали вызов %1$s начал(а) вызов @@ -2751,7 +2751,7 @@ %1$d приостановленных вызовов Нет учётных данных, неправильная учётная запись пользователя и/или пароль - Вернуть + Вернуться Вы уверены, что хотите удалить все неотправленные сообщения в этой комнате\? Удалить неотправленные сообщения Сообщения не удалось отправить @@ -2789,7 +2789,7 @@ Уровень доверия по умолчанию Выбрано Видео - В этой комнате есть неотправленный черновик + есть неотправленный черновик Некоторые сообщения не были отправлены Удалить аватар Сменить аватар @@ -2812,7 +2812,7 @@ Покинуть текущую конференцию и перейти к другой\? Версия комнаты Показать все команты в списке комнат, в том числе с чувствительным содержанием. - Показать комнаты с чувствительным содержанием + Показать комнаты с деликатным содержанием Список комнат Новое значение Сменить @@ -2933,8 +2933,8 @@ Покинуть комнату с заданным id (или текущую комнату, если null) Присоединитесь к пространству с заданным id Создать пространство - Это пространство публичное - Эта комната публичная + Публичное пространство + Публичная комната Непроверенные Неизвестное лицо Перевести на %1$s @@ -2972,7 +2972,7 @@ Добавить новый сервер Ваш сервер Любой человек в пространстве с этой комнатой может найти её и присоединиться к ней. Только администраторы этой комнаты могут добавить её в пространство. - Пространства + Только участники пространства Любой желающий может найти комнату и присоединиться Публичный Только приглашенные люди могут найти и присоединиться @@ -3030,7 +3030,7 @@ Нажмите для изменения пространств Выбрать пространства Определите, какие пространства могут получить доступ к этой комнате. Если пространство выбрано, его участники смогут найти и присоединиться к комнате. - Пространства, к которым есть доступ + Пространства с доступом Разрешить участникам пространства находить и получать доступ. Участники пространства %s могут находить, просматривать и присоединяться. Приватная (только по приглашению) @@ -3041,11 +3041,67 @@ Групповых сообщениях Зашифрованных диалогах Диалогах - Сообщениях, содержащие мое имя пользователя - Сообщениях с моим именем + Мое имя пользователя + Мое отображаемое имя Уведомлять меня о Другое Упоминания и ключевые слова Уведомления по умолчанию Чтобы отправлять голосовые сообщения, предоставьте разрешение на Микрофон. + %s в настройках, чтобы получать приглашения непосредственно в Element. + Свяжите этот адрес электронной почты с вашей учетной записью + Приглашение в эту комнату было отправлено на %s, который не связан с вашей учетной записью + Приглашение в это пространство было отправлено на %s, который не связан с вашей учетной записью + Чтобы помочь участникам пространства найти и присоединиться к приватной комнате, перейдите в настройки этой комнаты, нажав на аватар. + Помогите участникам пространства в поиске приватных комнат + Это позволяет комнатам оставаться приватными для пространства, в то же время позволяя людям в пространстве находить их и присоединяться к ним. Все новые комнаты в пространстве будут иметь эту опцию. + Помогите людям в пространствах самим находить и присоединяться к приватным комнатам, без необходимости вручную приглашать всех. + Новое: Позвольте людям в пространствах находить и присоединяться к приватным комнатам + Начался групповой вызов + Все комнаты, в которых вы находитесь, будут отображаться в Начале. + Показать все комнаты в Начале + Проведите для завершения вызова + %1$s Нажмите, чтобы вернуться + Активный вызов (%1$s) · + + Активный вызов · + %1$d активных вызова · + %1$d активных вызовов · + %1$d активных вызовов · + + Не удалось установить соединение + Нет ответа + Пропущенный выдеовызов + Пропущенный голосовой вызов + Видеовызов отклонен + Голосовой вызов отклонен + Выдеовызов завершен • %1$s + Голосовой вызов завершен • %1$s + Активный видеовызов + Активный голосовой вызов + Входящий видеовызов + Входящий голосовой вызов + Вы отклонили этот вызов + Настройки учетной записи + Вы можете управлять уведомлениями в %1$s. + Обратите внимание, что уведомления об упоминаниях и ключевых словах недоступны в зашифрованных комнатах на мобильных устройствах. + Уведомлять меня о + Вы не будете получать уведомления об упоминаниях и ключевых словах в зашифрованных комнатах на мобильных устройствах. + Ключевые слова + \@room + Ключевые слова не могут содержать \'%s\' + Ключевые слова не могут начинаться с \'.\' + Добавить новое ключевое слово + Ваши ключевые слова + Ничего + Только упоминания и ключевые слова + Завершение вызова… + Нет ответа + Пользователь, которого вы вызвали, занят. + Пользователь занят + Аудиовызов с %s + Видеовызов с %s + Вызов… + Пространства + Подробнее \ No newline at end of file From b48dbd1a52902da96a824a957c102f6dcaf53640 Mon Sep 17 00:00:00 2001 From: Nikita Epifanov Date: Mon, 13 Sep 2021 07:40:30 +0000 Subject: [PATCH 024/656] Translated using Weblate (Russian) Currently translated at 100.0% (29 of 29 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/ru/ --- fastlane/metadata/android/ru-RU/changelogs/40101150.txt | 2 ++ fastlane/metadata/android/ru-RU/changelogs/40101160.txt | 2 ++ fastlane/metadata/android/ru-RU/changelogs/40102000.txt | 2 ++ 3 files changed, 6 insertions(+) create mode 100644 fastlane/metadata/android/ru-RU/changelogs/40101150.txt create mode 100644 fastlane/metadata/android/ru-RU/changelogs/40101160.txt create mode 100644 fastlane/metadata/android/ru-RU/changelogs/40102000.txt diff --git a/fastlane/metadata/android/ru-RU/changelogs/40101150.txt b/fastlane/metadata/android/ru-RU/changelogs/40101150.txt new file mode 100644 index 0000000000..cbf64e470b --- /dev/null +++ b/fastlane/metadata/android/ru-RU/changelogs/40101150.txt @@ -0,0 +1,2 @@ +Основные изменения в этой версии: реализация голосовых сообщений в настройках лабораторий. +Полный список изменений: https://github.com/vector-im/element-android/releases/tag/v1.1.15 diff --git a/fastlane/metadata/android/ru-RU/changelogs/40101160.txt b/fastlane/metadata/android/ru-RU/changelogs/40101160.txt new file mode 100644 index 0000000000..5f0e555d94 --- /dev/null +++ b/fastlane/metadata/android/ru-RU/changelogs/40101160.txt @@ -0,0 +1,2 @@ +Основные изменения в этой версии: Исправление ошибки при отправке зашифрованного сообщения, если кто-то в комнате выходит. +Полный список изменений: https://github.com/vector-im/element-android/releases/tag/v1.1.16 diff --git a/fastlane/metadata/android/ru-RU/changelogs/40102000.txt b/fastlane/metadata/android/ru-RU/changelogs/40102000.txt new file mode 100644 index 0000000000..ab0dd0237d --- /dev/null +++ b/fastlane/metadata/android/ru-RU/changelogs/40102000.txt @@ -0,0 +1,2 @@ +Основные изменения в этой версии: Голосовое сообщение включено по умолчанию. +Полный список изменений: https://github.com/vector-im/element-android/releases/tag/v1.1.16 From c69f0db5b4c2e456cf756fd5a1a1a5598dbda8b9 Mon Sep 17 00:00:00 2001 From: Le Dang Trung Date: Sun, 12 Sep 2021 11:46:31 +0000 Subject: [PATCH 025/656] Translated using Weblate (Vietnamese) Currently translated at 52.3% (1368 of 2615 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/vi/ --- vector/src/main/res/values-vi/strings.xml | 129 ++++++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/vector/src/main/res/values-vi/strings.xml b/vector/src/main/res/values-vi/strings.xml index c52c299184..c5619c5232 100644 --- a/vector/src/main/res/values-vi/strings.xml +++ b/vector/src/main/res/values-vi/strings.xml @@ -1359,4 +1359,133 @@ Khác Xem thêm Giống như email, tài khoản cần có nhà riêng, dù bạn có thể nói chuyện với bất kỳ ai + Thiết lập tùy chỉnh. + Khả dụng + Thông báo không được bật cho phiên này. +\nVui lòng kiểm tra trong thiết lập ứng dụng ${app_name}. + Thông báo được bật cho phiên này. + Thiết lập phiên. + Khả dụng + Thông báo bị tắt cho tài khoản của bạn. +\nVui lòng kiểm tra thiết lập. + Thông báo được bật cho tài khoản của bạn. + Thiết lập tài khoản. + Mở thiết lập + Thông báo bị tắt trong thiết lập hệ thống. +\nVui lòng kiểm tra thiết lập. + Thông báo được bật trong thiết lập hệ thống. + Thiết lập hệ thống. + Xử lý lỗi thông báo + Chính sách riêng tư của thông báo + Từ khóa không được chứa \'%s\' + Từ khóa không được bắt đầu với \'.\' + Thêm mới từ khóa + Từ khóa của bạn + Thông báo tôi về + Khác + Đề cập tới và từ khóa + Thông báo mặc định + Mức quan trọng của thông báo theo sự kiện + Thiết lập Thông báo nâng cao + Đảm bảo rằng bạn nhấp vào đường link trong email được gửi tới bạn. + Loại bỏ %s\? + Số điện thoại + Không có địa chỉ email nào trong tài khoản của bạn + Địa chỉ email + Yêu cầu đăng nhập + Bạn không thể làm việc này từ ứng dụng ${app_name} + Xác nhận mật khẩu + Hiển thị thông tin ứng dụng trong thiết lập hệ thống. + Thông tin ứng dụng + Thêm số điện thoại + Chưa có số điện thoại trong tài khoản của bạn + Điện thoại + Thêm địa chỉ email + Email + Tên hiển thị + Hình đại diện + Chính sách riêng tư + Bản quyền + Lưu ý bên thứ ba + Điều khoản sử dụng + Phiên bản %s + Phiên bản + Thiết lập + Tin nhắn + Thêm vào màn hình Home + Quên + Rời Hội thoại + Chat trực tiếp + Đặt ưu tiên thấp + Yêu thích + Không + Được đề cập và đúng từ khóa + Im lặng + Được đề cập tới + Tất cả tin + Tất cả tin (ầm ĩ) + Tìm trong danh mục… + + tìm thấy %1$s phòng cho %2$s + + + %d phòng + + Duyệt danh mục phòng + Nhập ID hoặc tên phòng + Tham gia phòng + Tham gia phòng + Tạo phòng + Bắt đầu chat + LỜI MỜI + ƯU TIÊN THẤP + PHÒNG + YÊU THÍCH + DANH MỤC + THAM GIA + Tìm kiếm trong phòng mã hóa chưa được hỗ trợ. + FILES + NGƯỜI + TIN NHẮN + PHÒNG + Không có kết quả + Lọc người dùng bị cấm + Lọc thành viên phòng + Tìm kiếm + Hủy tải xuống + Hủy tải lên + Bạn có muốn ẩn tất cả tin nhắn từ người dùng này\? +\n +\nLưu ý hành động này sẽ khởi động lại app và có thể tốn thời gian. + Lý do báo cáo nội dung này + GIA NHẬP + ĐƯỢC MỜI + + %d được chọn + + Thiết lập + Files + Người + Chi tiết Phòng + Thay đổi chủ đề + Nâng cấp phòng + Gửi sự kiện m.room.server_acl + Thay đổi quyền hạn + Thay đổi tên phòng + Thay đổi xem lịch sử phòng + Bật mã hóa phòng chat + Thay đổi địa chỉ chính của phòng + Thay đổi hình đại diện phòng + Thay đổi widget + Thông báo mọi người + Xóa tin nhắn gửi bởi người khác + Cấm người dùng + Loại người dùng + Thay đổi thiết lập + Mời người dùng + Gửi tin nhắn + Vai trò mặc định + Bạn không đủ quyền để thay đổi vai trò được yêu cầu để thay đổi thiết lập phòng + Chọn vai trò được yêu cầu để thay đổi thiết lập của phòng + Quyền hạn \ No newline at end of file From 7142cd899bc946ec7e7399fa872515975faa9692 Mon Sep 17 00:00:00 2001 From: Valere Date: Tue, 14 Sep 2021 12:01:08 +0200 Subject: [PATCH 026/656] Use in memory cache when adding inBoundGroupSession --- changelog.d/4011.bugfix | 1 + .../sdk/internal/crypto/InboundGroupSessionStore.kt | 11 +++++++++-- .../matrix/android/sdk/internal/crypto/MXOlmDevice.kt | 6 ++++-- 3 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 changelog.d/4011.bugfix diff --git a/changelog.d/4011.bugfix b/changelog.d/4011.bugfix new file mode 100644 index 0000000000..04e8fe0329 --- /dev/null +++ b/changelog.d/4011.bugfix @@ -0,0 +1 @@ +Messages are displayed as unable to decrypt then decrypted a few seconds later #4011 \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/InboundGroupSessionStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/InboundGroupSessionStore.kt index 06c667ee4a..c7b0e68ed6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/InboundGroupSessionStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/InboundGroupSessionStore.kt @@ -22,6 +22,7 @@ import kotlinx.coroutines.launch import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.internal.crypto.model.OlmInboundGroupSessionWrapper2 import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore +import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers import timber.log.Timber import java.util.Timer @@ -71,18 +72,24 @@ internal class InboundGroupSessionStore @Inject constructor( } @Synchronized - fun storeInBoundGroupSession(wrapper: OlmInboundGroupSessionWrapper2) { + fun storeInBoundGroupSession(wrapper: OlmInboundGroupSessionWrapper2, sessionId: String, senderKey: String) { Timber.v("## Inbound: getInboundGroupSession mark as dirty ${wrapper.roomId}-${wrapper.senderKey}") // We want to batch this a bit for performances dirtySession.add(wrapper) + if (sessionCache[CacheKey(sessionId, senderKey)] == null) { + // first time seen, put it in memory cache while waiting for batch insert + // If it's already known, no need to update cache it's already there + sessionCache.put(CacheKey(sessionId, senderKey), wrapper) + } + timerTask?.cancel() timerTask = object : TimerTask() { override fun run() { batchSave() } } - timer.schedule(timerTask!!, 2_000) + timer.schedule(timerTask!!, 300) } @Synchronized diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt index b8f1a9abea..f845b7cf73 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt @@ -577,7 +577,9 @@ internal class MXOlmDevice @Inject constructor( session.keysClaimed = keysClaimed session.forwardingCurve25519KeyChain = forwardingCurve25519KeyChain - store.storeInboundGroupSessions(listOf(session)) + + inboundGroupSessionStore.storeInBoundGroupSession(session, sessionId, senderKey) +// store.storeInboundGroupSessions(listOf(session)) return true } @@ -703,7 +705,7 @@ internal class MXOlmDevice @Inject constructor( timelineSet.add(messageIndexKey) } - inboundGroupSessionStore.storeInBoundGroupSession(session) + inboundGroupSessionStore.storeInBoundGroupSession(session, sessionId, senderKey) val payload = try { val adapter = MoshiProvider.providesMoshi().adapter(JSON_DICT_PARAMETERIZED_TYPE) val payloadString = convertFromUTF8(decryptResult.mDecryptedMessage) From 2badb9725df057a550dd8e922091f4202af41e7f Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 14 Sep 2021 15:56:04 +0200 Subject: [PATCH 027/656] Improve pull request checklist and notice --- .github/PULL_REQUEST_TEMPLATE.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 8fbc5602fe..2048b823f0 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,10 +1,16 @@ ### Pull Request Checklist - + - [ ] Changes has been tested on an Android device or Android emulator with API 21 - [ ] UI change has been tested on both light and dark themes +- [ ] Accessibility has been taken into account. See https://github.com/vector-im/element-android/blob/develop/CONTRIBUTING.md#accessibility - [ ] Pull request is based on the develop branch - [ ] Pull request includes a new file under ./changelog.d. See https://github.com/vector-im/element-android/blob/develop/CONTRIBUTING.md#changelog - [ ] Pull request includes screenshots or videos if containing UI changes - [ ] Pull request includes a [sign off](https://github.com/matrix-org/synapse/blob/master/CONTRIBUTING.md#sign-off) +- [ ] You've made a self review of your PR +- [ ] If you have modified the screen flow, or added new screens to the application, you have updated the test [UiAllScreensSanityTest.allScreensTest()](https://github.com/vector-im/element-android/blob/main/vector/src/androidTest/java/im/vector/app/ui/UiAllScreensSanityTest.kt#L73) \ No newline at end of file From 1c2997e40eeccc3c06a5368fb6d6607e7a082277 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 14 Sep 2021 15:57:24 +0200 Subject: [PATCH 028/656] `SpUsage` lint rule is more about a11y --- vector/lint.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/lint.xml b/vector/lint.xml index 3fca617dee..dde29af62e 100644 --- a/vector/lint.xml +++ b/vector/lint.xml @@ -21,12 +21,12 @@ + - From 7ca089b3d7a19c62176c26e3eef7872ad86ce591 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 14 Sep 2021 15:59:53 +0200 Subject: [PATCH 029/656] Update section about a11y --- CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 610a6227b7..e1d213e6b7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -148,6 +148,8 @@ The string will be removed during the next sync with Weblate. Please consider accessibility as an important point. As a minimum requirement, in layout XML files please use attributes such as `android:contentDescription` and `android:importantForAccessibility`, and test with a screen reader if it's working well. You can add new string resources, dedicated to accessibility, in this case, please prefix theirs id with `a11y_`. +For instance, when updating the image `src` of an ImageView, please also consider updating its `contentDescription`. A good example is a play pause button. + ### Layout When adding or editing layouts, make sure the layout will render correctly if device uses a RTL (Right To Left) language. From bd9a18759751697c55526d07b60f34a00b35ba72 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 16 Sep 2021 10:27:49 +0200 Subject: [PATCH 030/656] Fix sticky end call notification #4019 --- changelog.d/4019.bugfix | 1 + .../vector/app/core/services/CallService.kt | 31 ++++++++++--------- .../notifications/NotificationUtils.kt | 1 - 3 files changed, 18 insertions(+), 15 deletions(-) create mode 100644 changelog.d/4019.bugfix diff --git a/changelog.d/4019.bugfix b/changelog.d/4019.bugfix new file mode 100644 index 0000000000..0bb2e7d828 --- /dev/null +++ b/changelog.d/4019.bugfix @@ -0,0 +1 @@ +Fix sticky end call notification \ No newline at end of file diff --git a/vector/src/main/java/im/vector/app/core/services/CallService.kt b/vector/src/main/java/im/vector/app/core/services/CallService.kt index d8cf8cf6b8..cd3845f41b 100644 --- a/vector/src/main/java/im/vector/app/core/services/CallService.kt +++ b/vector/src/main/java/im/vector/app/core/services/CallService.kt @@ -50,7 +50,7 @@ private val loggerTag = LoggerTag("CallService", LoggerTag.VOIP) class CallService : VectorService() { private val connections = mutableMapOf() - private val knownCalls = mutableSetOf() + private val knownCalls = mutableMapOf() private val connectedCallIds = mutableSetOf() private lateinit var notificationManager: NotificationManagerCompat @@ -190,7 +190,7 @@ class CallService : VectorService() { } else { notificationManager.notify(callId.hashCode(), notification) } - knownCalls.add(callInformation) + knownCalls[callId] = callInformation } private fun handleCallTerminated(intent: Intent) { @@ -198,20 +198,22 @@ class CallService : VectorService() { val endCallReason = intent.getSerializableExtra(EXTRA_END_CALL_REASON) as EndCallReason val rejected = intent.getBooleanExtra(EXTRA_END_CALL_REJECTED, false) alertManager.cancelAlert(callId) - val terminatedCall = knownCalls.firstOrNull { it.callId == callId } + val terminatedCall = knownCalls.remove(callId) if (terminatedCall == null) { - Timber.tag(loggerTag.value).v("Call terminated for unknown call $callId$") + Timber.tag(loggerTag.value).v("Call terminated for unknown call $callId") handleUnexpectedState(callId) return } - knownCalls.remove(terminatedCall) + val notification = notificationUtils.buildCallEndedNotification(false) + val notificationId = callId.hashCode() + startForeground(notificationId, notification) if (knownCalls.isEmpty()) { + Timber.tag(loggerTag.value).v("No more call, stop the service") + stopForeground(true) mediaSession?.isActive = false myStopSelf() } val wasConnected = connectedCallIds.remove(callId) - val notification = notificationUtils.buildCallEndedNotification(terminatedCall.isVideoCall) - notificationManager.notify(callId.hashCode(), notification) if (!wasConnected && !terminatedCall.isOutgoing && !rejected && endCallReason != EndCallReason.ANSWERED_ELSEWHERE) { val missedCallNotification = notificationUtils.buildCallMissedNotification(terminatedCall) notificationManager.notify(MISSED_CALL_TAG, terminatedCall.nativeRoomId.hashCode(), missedCallNotification) @@ -243,7 +245,7 @@ class CallService : VectorService() { } else { notificationManager.notify(callId.hashCode(), notification) } - knownCalls.add(callInformation) + knownCalls[callId] = callInformation } /** @@ -267,18 +269,19 @@ class CallService : VectorService() { } else { notificationManager.notify(callId.hashCode(), notification) } - knownCalls.add(callInformation) + knownCalls[callId] = callInformation } private fun handleUnexpectedState(callId: String?) { Timber.tag(loggerTag.value).v("Fallback to clear everything") callRingPlayerIncoming?.stop() callRingPlayerOutgoing?.stop() - if (callId != null) { - notificationManager.cancel(callId.hashCode()) - } val notification = notificationUtils.buildCallEndedNotification(false) - startForeground(DEFAULT_NOTIFICATION_ID, notification) + if (callId != null) { + startForeground(callId.hashCode(), notification) + } else { + startForeground(DEFAULT_NOTIFICATION_ID, notification) + } if (knownCalls.isEmpty()) { mediaSession?.isActive = false myStopSelf() @@ -371,7 +374,7 @@ class CallService : VectorService() { putExtra(EXTRA_END_CALL_REASON, endCallReason) putExtra(EXTRA_END_CALL_REJECTED, rejected) } - ContextCompat.startForegroundService(context, intent) + context.startService(intent) } } diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt index a74c13a496..fdd4e39665 100755 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt @@ -468,7 +468,6 @@ class NotificationUtils @Inject constructor(private val context: Context, setSmallIcon(R.drawable.ic_call_answer) } } - // This is a trick to make the previous notification with same id disappear as cancel notification is not working with Foreground Service. .setTimeoutAfter(1) .setColor(ThemeUtils.getColor(context, android.R.attr.colorPrimary)) .setCategory(NotificationCompat.CATEGORY_CALL) From 226b0e6c9d0afdee1183d9c18fdb6ada4e2dd155 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 16 Sep 2021 12:04:18 +0200 Subject: [PATCH 031/656] Fix call screen stuck with some hanging up scenarios #4026 --- changelog.d/4026.bugfix | 1 + .../im/vector/app/features/call/webrtc/WebRtcCall.kt | 12 +++++++----- .../app/features/call/webrtc/WebRtcCallManager.kt | 6 +++++- 3 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 changelog.d/4026.bugfix diff --git a/changelog.d/4026.bugfix b/changelog.d/4026.bugfix new file mode 100644 index 0000000000..7404bfe966 --- /dev/null +++ b/changelog.d/4026.bugfix @@ -0,0 +1 @@ +Fix call screen stuck with some hanging up scenarios \ No newline at end of file diff --git a/vector/src/main/java/im/vector/app/features/call/webrtc/WebRtcCall.kt b/vector/src/main/java/im/vector/app/features/call/webrtc/WebRtcCall.kt index 2d39fda2e3..56368b8175 100644 --- a/vector/src/main/java/im/vector/app/features/call/webrtc/WebRtcCall.kt +++ b/vector/src/main/java/im/vector/app/features/call/webrtc/WebRtcCall.kt @@ -810,17 +810,19 @@ class WebRtcCall( } } - fun endCall(reason: EndCallReason = EndCallReason.USER_HANGUP) { + fun endCall(reason: EndCallReason = EndCallReason.USER_HANGUP, sendSignaling: Boolean = true) { sessionScope?.launch(dispatcher) { if (mxCall.state is CallState.Ended) { return@launch } val reject = mxCall.state is CallState.LocalRinging terminate(reason, reject) - if (reject) { - mxCall.reject() - } else { - mxCall.hangUp(reason) + if (sendSignaling) { + if (reject) { + mxCall.reject() + } else { + mxCall.hangUp(reason) + } } } } diff --git a/vector/src/main/java/im/vector/app/features/call/webrtc/WebRtcCallManager.kt b/vector/src/main/java/im/vector/app/features/call/webrtc/WebRtcCallManager.kt index 73a6c07d6a..d276549765 100644 --- a/vector/src/main/java/im/vector/app/features/call/webrtc/WebRtcCallManager.kt +++ b/vector/src/main/java/im/vector/app/features/call/webrtc/WebRtcCallManager.kt @@ -424,7 +424,11 @@ class WebRtcCallManager @Inject constructor( override fun onCallManagedByOtherSession(callId: String) { Timber.tag(loggerTag.value).v("onCallManagedByOtherSession: $callId") - onCallEnded(callId, EndCallReason.ANSWERED_ELSEWHERE, false) + val call = callsByCallId[callId] + ?: return Unit.also { + Timber.tag(loggerTag.value).w("onCallManagedByOtherSession for non active call? $callId") + } + call.endCall(EndCallReason.ANSWERED_ELSEWHERE, sendSignaling = false) } override fun onCallAssertedIdentityReceived(callAssertedIdentityContent: CallAssertedIdentityContent) { From 653acee9ded9f45cf3ea7a592ffca29ec09d9321 Mon Sep 17 00:00:00 2001 From: Linerly Date: Wed, 15 Sep 2021 16:30:06 +0000 Subject: [PATCH 032/656] Translated using Weblate (Indonesian) Currently translated at 53.0% (1386 of 2615 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/id/ --- vector/src/main/res/values-in/strings.xml | 236 ++++++++++++++++++++++ 1 file changed, 236 insertions(+) diff --git a/vector/src/main/res/values-in/strings.xml b/vector/src/main/res/values-in/strings.xml index c0d421f493..f5ac4f0753 100644 --- a/vector/src/main/res/values-in/strings.xml +++ b/vector/src/main/res/values-in/strings.xml @@ -1335,4 +1335,240 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Anda mengubah ACL server untuk ruangan ini. %s mengubah ACL server untuk ruangan ini. • Server yang cocok dengan IP literal diizinkan. + tutup + buka + Maaf, terjadi kesalahan + Homeserver Anda belum mendukung lazy load anggota ruang. Coba nanti. + Tingkatkan kinerja dengan hanya memuat anggota ruang pada tampilan pertama. + Lazy load anggota ruangan + Mohon masukkan nama pengguna. + Diam + Penurunan harga telah dinonaktifkan. + Penurunan harga telah diaktifkan. + Perintah \"%s\" membutuhkan parameter tambahan, atau beberapa parameter salah. + Abaikan + Permintaan Pembagian Kunci + Bagikan + Verifikasi + Sesi yang belum diverifikasi meminta kunci enkripsi. +\nNama sesi: %1$s +\nTerakhir dilihat: %2$s +\nJika Anda tidak masuk pada sesi lain, abaikan permintaan ini. + Sesi baru meminta kunci enkripsi. +\nNama sesi: %1$s +\nTerakhir dilihat: %2$s +\nJika Anda tidak masuk pada sesi lain, abaikan permintaan ini. + Untuk melanjutkan, Anda harus menerima persyaratan layanan ini. + Opsi ini memerlukan aplikasi pihak ketiga untuk merekam pesan. + Mulai kamera sistem daripada layar kamera khusus. + Tidak ada widget yang aktif + Kelola Integrasi + Tidak ada pengelola integrasi yang dikonfigurasi. + Baca Media yang dilindungi DRM + Gunakan mikrofon + Gunakan kamera + Blokir Semua + Izinkan + Widget ini ingin menggunakan sumber daya berikut: + Tinggalkan konferensi saat ini dan beralih ke yang lain\? + Maaf, terjadi kesalahan saat mencoba bergabung konferensi + Maaf, panggilan konferensi dengan Jitsi tidak didukung di perangkat lama (perangkat dengan OS Android di bawah 6.0) + ID Ruangan + ID Widget + Tema Anda + User ID Anda + URL avatar Anda + Nama tampilan Anda + Cabut akses untuk saya + Buka di browser + Muat ulang widget + Gagal memuat widget. +\n%s + Menggunakannya dapat berbagi data dengan %s: + Menggunakannya dapat mengatur cookie dan berbagi data dengan %s: + Widget ini ditambahkan oleh: + Muat Widget + Widget + Widget aktif + LIHAT + + ** Gagal mengirim - mohon buka ruangan + Saya + Undangan Baru + Pesan Baru + Ruangan + Peristiwa Baru + %1$s dan %2$s + %1$s di %2$s dan %3$s + + %d notifikasi + + + %1$s: %2$d pesan + + + %d undangan + + Server ini sudah ada di dalam daftar + Tidak dapat menemukan server ini atau daftar ruangannya + Penemuan + Kelola setelan penemuan Anda. + Masukkan nama server baru yang ingin Anda jelajahi. + Tambahkan server baru + Server Anda + ip yang tidak diketahui + + %1$d/%2$d kunci berhasil diimpor. + + Kelola Cadangan Kunci + Pemulihan Pesan Terenkripsi + Kunci berhasil diekspor + Harap buat frasa sandi untuk mengenkripsi kunci yang diekspor. Anda harus memasukkan frasa sandi yang sama untuk dapat mengimpor kunci. + Nama publik sesi dapat dilihat oleh orang yang berkomunikasi dengan Anda + Nama publik (terlihat oleh orang yang berkomunikasi dengan Anda) + Versi ruangan + + %d pengguna yang dicekal + + Space atau ruangan lain yang mungkin tidak Anda ketahui + Space yang Anda tahu berisi ruangan ini + Tentukan siapa yang dapat menemukan dan bergabung ruangan ini. + Tap untuk mengedit space + Pilih space + Tentukan space mana yang dapat mengakses ruangan ini. Jika space dipilih, anggotanya dapat menemukan dan bergabung dengan nama Ruangan. + Space yang dapat diakses + Izinkan anggota space untuk menemukan dan akses. + Anggota Space %s bisa menemukan, pratinjau, dan bergabung. + Siapa saja di space dengan ruangan ini dapat menemukan dan bergabung. Hanya admin ruang ini yang dapat menambahkannya ke space. + Anggota space saja + Siapa saja dapat menemukan ruangan ini dan bergabung + Publik + Hanya orang yang diundang yang dapat menemukan dan bergabung + Pribadi (Undangan Saja) + Pribadi + Setelan akses yang tidak diketahui (%s) + Siapa saja dapat mengetuk ruangan, anggota kemudian dapat menerima atau menolak + Tidak dapat mengambil visibilitas direktori ruangan saat ini (%1$s). + Publikasikan ruangan ini ke publik di direktori ruangan %1$s\? + Batalkan publikasi alamat ini + Publikasikan alamat ini + Tambahkan alamat lokal + Ruangan ini tidak memiliki alamat lokal + Tetapkan alamat untuk ruangan ini sehingga pengguna dapat menemukan ruangan ini melalui homeserver Anda (%1$s) + Alamat Lokal + Alamat baru yang dipublikasikan (mis. #alias:server) + Belum ada alamat lain yang dipublikasikan. + Belum ada alamat lain yang dipublikasikan, tambahkan satu di bawah ini. + Publikasikan ruangan ini ke publik di direktori ruangan %1$s\? + Hapus alamat \"%1$s\"\? + Batalkan publikasi alamat \"%1$s\"\? + Publikasi + Publikasi alamat baru secara manual + Alamat lain yang dipublikasikan: + Ini alamat utamanya + Alamat utama + Alamat yang dipublikasikan dapat digunakan oleh siapa saja di server mana pun untuk bergabung ruangan Anda. Untuk memublikasikan alamat, alamat tersebut harus disetel sebagai alamat lokal terlebih dahulu. + Alamat yang Dipublikasikan + Alamat Ruangan + Lihat dan kelola alamat space ini. + Alamat space + Lihat dan kelola alamat ruangan ini dan visibilitasnya di direktori ruangan. + Alamat ruangan + Izinkan tamu untuk bergabung + Akses ruangan + Perubahan siapa yang dapat membaca riwayat hanya akan berlaku untuk pesan berikutnya di ruang ini. Visibilitas sejarah yang ada tidak akan berubah. + Setelan akun + Anda dapat mengelola notifikasi di %1$s. + Harap dicatat bahwa sebutan & pemberitahuan keyword tidak tersedia di ruangan terenkripsi di ponsel. + Beritahu saya untuk + Putar suara rana + Pilih + Sumber media default + Pilih + Kompresi default + Media + Info tambahan: %s + Terjadi kesalahan saat memverifikasi nomor telepon Anda. + Sandi tidak cocok + Kelola surel dan nomor telepon yang ditautkan ke akun Matrix Anda + Surel dan nomor telepon + Sandi tidak valid + Sandi + Perbarui Sandi + Terjadi kesalahan saat memverifikasi surel Anda. + Aktifkan \'Izinkan integrasi\' di Setelan untuk melakukan ini. + Integrasi dinonaktifkan + Pengelola integrasi + Berikan izin + Izinkan integrasi + Mode data saver menerapkan filter tertentu sehingga pembaruan kehadiran dan pemberitahuan ketikan difilter. + ${app_name} perlu menjaga koneksi latar belakang rendah agar memiliki notifikasi yang handal. +\nPada layar berikutnya Anda akan diminta untuk mengizinkan ${app_name} untuk selalu berjalan di latar belakang, mohon diterima. + Koneksi Latar Belakang + Ini akan menggantikan Kunci atau Frasa Anda saat ini. + Buat Kunci Keamanan baru atau atur Frasa Keamanan baru untuk cadangan yang ada. + Lindungi dari kehilangan akses ke pesan & data terenkripsi dengan mencadangkan kunci enkripsi di server Anda. + Siapkan di perangkat ini + Setel Ulang Cadangan Aman + Siapkan Cadangan Aman + Kelola + Cadangan Aman + Tambahkan tombol pada komposer pesan untuk membuka keyboard emoji + Tampilkan keyboard emoji + Tombol Enter pada keyboard akan mengirim pesan daripada menambahkan jeda baris + Kirim pesan dengan enter + Termasuk avatar dan perubahan nama tampilan. + Termasuk peristiwa undangan/gabung/keluar/pengeluaran/pencekalan dan avatar/tampilan perubahan nama. + Gunakan perintah /confetti atau kirim pesan yang berisi ❄️ atau 🎉 + Tampilkan efek chat + Tampilkan peristiwa keadaan anggota ruangan + Gunakan pengelola integrasi untuk mengelola bot, jembatan, widget, dan paket stiker. +\nPengelola integrasi menerima data konfigurasi, dan dapat memodifikasi widget, mengirim undangan ruang, dan mengatur tingkat daya dengan sepengetahuan Anda. + Integrasi + + %d detik + + %s +\nSinkronisasi mungkin ditunda tergantung pada sumber daya (baterai) atau status perangkat (tidur). + Interval Sinkronisasi Pilihan + Gagal memperbarui setelan. + Anda tidak akan diberitahu tentang pesan masuk saat aplikasi berada di latar belakang. + Tidak ada sinkronisasi latar belakang + ${app_name} akan disinkronkan di latar belakang secara berkala pada waktu yang tepat (dapat dikonfigurasi). +\nIni akan memengaruhi penggunaan radio dan baterai, dan ada juga pemberitahuan yang ditampilkan permanen menyatakan bahwa ${app_name} sedang mendengarkan peristiwa. + Anda tidak akan mendapatkan notifikasi untuk sebutan & keyword di ruang terenkripsi di ponsel. + Peningkatan ruangan + Pesan dari bot + Undangan ruangan + Keyword + \@room + Pesan grup terenkripsi + Pesan grup + Pesan terenkripsi langsung + Pesan langsung + Nama pengguna saya + Nama tampilan saya + Pesan yang berisi @room + Saat ruangan ditingkatkan + Pesan terenkripsi di obrolan grup + Pesan terenkripsi di chat satu-ke-satu + Keyword tidak boleh berisi \'%s\' + Keyword tidak boleh diawali dengan \'.\' + Tambahkan keyword baru + Keyword Anda + Beritahu saya untuk + Lainnya + Sebutan dan Keyword + Notifikasi Bawaan + Tidak Ada + Hanya Sebutan & Keyword + Mengakhiri panggilan… + Tidak ada jawaban + Pengguna yang Anda panggil sedang sibuk. + Pengguna sedang sibuk + Panggilan suara dengan %s + Panggilan video dengan %s + Panggilan berdering… + Spaces + Pelajari Lebih Lanjut \ No newline at end of file From 7bf414ec8c6800ad757aa361a22eeaab603593a1 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Thu, 16 Sep 2021 06:25:13 +0000 Subject: [PATCH 033/656] Translated using Weblate (Ukrainian) Currently translated at 82.8% (2167 of 2615 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/uk/ --- vector/src/main/res/values-uk/strings.xml | 46 ++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values-uk/strings.xml b/vector/src/main/res/values-uk/strings.xml index 6f5a77308a..a4c6e8b307 100644 --- a/vector/src/main/res/values-uk/strings.xml +++ b/vector/src/main/res/values-uk/strings.xml @@ -2441,7 +2441,7 @@ Обернути й обрізати Файл «%1$s» (%2$s) завеликий для вивантаження. Обмеження %3$s. Цей файл завеликий для вивантаження. - Це бета-можливість + Це бета-функція Сховати пароль Показати пароль Створити нову кімнату @@ -2516,4 +2516,48 @@ Ви скасували %s скасовано Перевірка ключа + Читати у + Нічого не знайдено, натисніть Додати за matrix-ID для пошуку на сервері. + Пошук за назвою + Ви користуєтеся бета-версією просторів. Ваш відгук допоможе поліпшити наступні версії. Ваша платформа та ім’я користувача будуть зазначені, щоб допомогти нам використати ваш відгук якнайефективніше. + Зареєструвати токен + Немає зареєстрованих push-шлюзів + Правила push-сповіщень не визначені + Правила push-сповіщень + Ви вже переглядаєте цю кімнату! + Інші примітки про треті сторони + Імпорт ключів e2e з файлу «%1$s». + Сталася помилка отримання ключів резервних копій даних + Під час отримання інформації про довіру сталася помилка + Попередній перегляд цієї кімнати недоступний. Бажаєте приєднатися до неї\? + Зараз ця кімната недоступна. +\nПовторіть спробу пізніше або попросіть адміністратора кімнати перевірити, чи маєте ви доступ. + Попередній перегляд цієї кімнати недоступний + Немає мережі. Перевірте інтернет-з\'єднання. + Хибна подія, неможливо показати + Перегляд реакцій + Тут буде показано ваші кімнати. Натисніть + унизу праворуч, щоб знайти наявні або створити власні. + Приєднайтеся до кімнати, щоб почати користуватися застосунком. + Схоже, ви намагаєтесь під\'єднатися до іншого домашнього сервера. Бажаєте вийти\? + Користувачі відрізняються + Ключі відрізняються + Отриманий хеш не збігається + Сеанс не може узгодити ключі, хеш, MAC або метод SAS + Сеанс не розпізнає про цю транзакцію + Час перевірки минув + Перевірте, порівнявши короткий текстовий рядок. + Ви вийшли з облікового запису через хибні або застарілі облікові дані. + Використати конфігурацію + ${app_name} виявив користувацьку конфігурацію сервера для вашого userID домену «%1$s»: +\n%2$s + Параметри сервера автозаповнення + + Резервне копіювання %d ключа… + Резервне копіювання %d ключів… + Резервне копіювання %d ключів… + Резервне копіювання %d ключів… + + Виявлено нову резервну копію ключа зашифрованих повідомлень. +\n +\nЯкщо ви не налаштовували новий метод відновлення, можливо, зловмисник намагається отримати доступ до вашого облікового запису. Змініть пароль свого облікового запису та негайно визначте новий спосіб відновлення в Налаштуваннях. \ No newline at end of file From 8092e8958dd8e32a261c4f836cde217117393a18 Mon Sep 17 00:00:00 2001 From: Quang Trung Date: Thu, 16 Sep 2021 01:23:55 +0000 Subject: [PATCH 034/656] Translated using Weblate (Vietnamese) Currently translated at 54.3% (1420 of 2615 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/vi/ --- vector/src/main/res/values-vi/strings.xml | 56 +++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/vector/src/main/res/values-vi/strings.xml b/vector/src/main/res/values-vi/strings.xml index c5619c5232..5da3dbe059 100644 --- a/vector/src/main/res/values-vi/strings.xml +++ b/vector/src/main/res/values-vi/strings.xml @@ -1488,4 +1488,60 @@ Bạn không đủ quyền để thay đổi vai trò được yêu cầu để thay đổi thiết lập phòng Chọn vai trò được yêu cầu để thay đổi thiết lập của phòng Quyền hạn + Việc này có thể có nghĩa là ai đó đang can thiệp vào lưu lượng của bạn, hoặc điện thoại của bạn không tin cậy chứng chỉ được máy chủ trên mạng cung cấp. + Không thể xác minh danh tính của máy chủ trên mạng. + Mã kiểm tra (%s): + Bỏ qua + Đăng xuất + Không tin cậy + Tin cậy + + %d tin nhắn mới + + Bạn không có quyền để đăng vào phòng này. + Không tìm thấy tệp + Xóa tin nhắn chưa gửi + Gửi lại tin nhắn chưa gửi + Hủy tất cả + Gửi lại tất cả + Tin nhắn không được gửi do có phiên làm việc không xác định. %1$s hoặc %2$s ngay\? + Tin nhắn không được gửi. %1$s hoặc %2$s ngay\? + Kết nối đến máy chủ đã bị mất. + Gửi câu trả lời (không mã hóa)… + Gửi câu trả lời mã hóa… + Gửi tin nhắn (không mã hóa)… + Gửi tin nhắn mã hóa… + %1$s & %2$s & những người khác đang gõ… + %1$s & %2$s đang gõ… + %s đang gõ… + Tìm kiếm + Email hoặc ID Matrix + Vui lòng nhập một hoặc nhiều địa chỉ email hoặc ID Matrix + Mời người dùng theo ID + Chỉ người dùng Matrix + THƯ MỤC NGƯỜI DÙNG (%s) + LIÊN HỆ CỤC BỘ (%d) + Mời theo ID + %1$s %2$s + %1$s và %2$s + "%1$s, " + Bạn có chắc bạn muốn mời %s vào cuộc trò chuyện này không\? + Lý do + Việc hủy cấm người dùng sẽ cho phép họ tham gia lại phòng. + Việc cấm người dùng sẽ đá họ ra khỏi phòng này và ngăn họ tham gia lại. + Hủy cấm người dùng + Lý do cấm + Cấm người dùng + việc đá người dùng sẽ xóa họ khỏi phòng. +\n +\nĐể ngăn họ tham gia lại, bạn nên cấm họ thay vì đá. + Lý do đá + Đá người dùng + Bạn có chắc bạn muốn hủy lời mời đối với người dùng này không\? + Hủy lời mời + Hủy làm ngơ + Việc hủy làm ngơ người dùng này sẽ hiện lại tất cả tin nhắn từ họ. + Cuộc gọi âm thanh với %s + Cuộc gọi video với %s + Cuộc gọi đang reo… \ No newline at end of file From 86ce92ddf6407d674398795e77d6c5962ce5b0ec Mon Sep 17 00:00:00 2001 From: Linerly Date: Wed, 15 Sep 2021 15:05:30 +0000 Subject: [PATCH 035/656] Translated using Weblate (Indonesian) Currently translated at 100.0% (29 of 29 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/id/ --- fastlane/metadata/android/id/changelogs/40101160.txt | 2 ++ fastlane/metadata/android/id/changelogs/40102000.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/id/changelogs/40101160.txt create mode 100644 fastlane/metadata/android/id/changelogs/40102000.txt diff --git a/fastlane/metadata/android/id/changelogs/40101160.txt b/fastlane/metadata/android/id/changelogs/40101160.txt new file mode 100644 index 0000000000..19209bacf2 --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/40101160.txt @@ -0,0 +1,2 @@ +Perubahan utama dalam versi ini: Memperbaiki kesalahan saat mengirim pesan terenkripsi jika seseorang yang ada di ruangan keluar. +Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.16 diff --git a/fastlane/metadata/android/id/changelogs/40102000.txt b/fastlane/metadata/android/id/changelogs/40102000.txt new file mode 100644 index 0000000000..2258b114e8 --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/40102000.txt @@ -0,0 +1,2 @@ +Perubahan utama dalam versi ini: Pesan Suara diaktifkan secara default +Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.16 From 82864b2b986a95bbfbee17a4f5c390f607af2c24 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 16 Sep 2021 18:53:41 +0200 Subject: [PATCH 036/656] Fix other call not always refreshed when ended #4028 --- changelog.d/4028.bugfix | 1 + .../ui/views/CurrentCallsViewPresenter.kt | 2 +- .../call/SharedKnownCallsViewModel.kt | 11 ++++++-- .../app/features/call/VectorCallViewModel.kt | 28 +++++++++++++------ .../features/call/webrtc/WebRtcCallManager.kt | 18 +++++++----- 5 files changed, 41 insertions(+), 19 deletions(-) create mode 100644 changelog.d/4028.bugfix diff --git a/changelog.d/4028.bugfix b/changelog.d/4028.bugfix new file mode 100644 index 0000000000..f351476b53 --- /dev/null +++ b/changelog.d/4028.bugfix @@ -0,0 +1 @@ +Fix other call not always refreshed when ended \ No newline at end of file diff --git a/vector/src/main/java/im/vector/app/core/ui/views/CurrentCallsViewPresenter.kt b/vector/src/main/java/im/vector/app/core/ui/views/CurrentCallsViewPresenter.kt index 5aee73ee69..13db5ddcb3 100644 --- a/vector/src/main/java/im/vector/app/core/ui/views/CurrentCallsViewPresenter.kt +++ b/vector/src/main/java/im/vector/app/core/ui/views/CurrentCallsViewPresenter.kt @@ -36,7 +36,7 @@ class CurrentCallsViewPresenter { this.currentCall = currentCall this.currentCall?.addListener(tickListener) this.calls = calls - val hasActiveCall = currentCall != null + val hasActiveCall = calls.isNotEmpty() currentCallsView?.isVisible = hasActiveCall currentCallsView?.render(calls, currentCall?.formattedDuration() ?: "") } diff --git a/vector/src/main/java/im/vector/app/features/call/SharedKnownCallsViewModel.kt b/vector/src/main/java/im/vector/app/features/call/SharedKnownCallsViewModel.kt index fb5e48af98..4b0ea412f3 100644 --- a/vector/src/main/java/im/vector/app/features/call/SharedKnownCallsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/call/SharedKnownCallsViewModel.kt @@ -41,7 +41,7 @@ class SharedKnownCallsViewModel @Inject constructor( } } - private val currentCallListener = object : WebRtcCallManager.CurrentCallListener { + private val callManagerListener = object : WebRtcCallManager.Listener { override fun onCurrentCallChange(call: WebRtcCall?) { val knownCalls = callManager.getCalls() liveKnownCalls.postValue(knownCalls) @@ -50,12 +50,17 @@ class SharedKnownCallsViewModel @Inject constructor( it.addListener(callListener) } } + + override fun onCallEnded(callId: String) { + val knownCalls = callManager.getCalls() + liveKnownCalls.postValue(knownCalls) + } } init { val knownCalls = callManager.getCalls() liveKnownCalls.postValue(knownCalls) - callManager.addCurrentCallListener(currentCallListener) + callManager.addListener(callManagerListener) knownCalls.forEach { it.addListener(callListener) } @@ -65,7 +70,7 @@ class SharedKnownCallsViewModel @Inject constructor( callManager.getCalls().forEach { it.removeListener(callListener) } - callManager.removeCurrentCallListener(currentCallListener) + callManager.removeListener(callManagerListener) super.onCleared() } } diff --git a/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt b/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt index 63ba83bdbc..90df595f8f 100644 --- a/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt @@ -134,7 +134,15 @@ class VectorCallViewModel @AssistedInject constructor( } ?: VectorCallViewState.TransfereeState.UnknownTransferee } - private val currentCallListener = object : WebRtcCallManager.CurrentCallListener { + private val callManagerListener = object : WebRtcCallManager.Listener { + + override fun onCallEnded(callId: String) { + withState { state -> + if (state.otherKnownCallInfo?.callId == callId) { + setState { copy(otherKnownCallInfo = null) } + } + } + } override fun onCurrentCallChange(call: WebRtcCall?) { if (call != null) { @@ -159,9 +167,7 @@ class VectorCallViewModel @AssistedInject constructor( } private fun updateOtherKnownCall(currentCall: WebRtcCall) { - val otherCall = callManager.getCalls().firstOrNull { - it.callId != currentCall.callId && it.mxCall.state is CallState.Connected - } + val otherCall = getOtherKnownCall(currentCall) setState { if (otherCall == null) { copy(otherKnownCallInfo = null) @@ -171,6 +177,12 @@ class VectorCallViewModel @AssistedInject constructor( } } + private fun getOtherKnownCall(currentCall: WebRtcCall): WebRtcCall? { + return callManager.getCalls().firstOrNull { + it.callId != currentCall.callId && it.mxCall.state is CallState.Connected + } + } + init { setupCallWithCurrentState() } @@ -184,7 +196,7 @@ class VectorCallViewModel @AssistedInject constructor( } } else { call = webRtcCall - callManager.addCurrentCallListener(currentCallListener) + callManager.addListener(callManagerListener) webRtcCall.addListener(callListener) val currentSoundDevice = callManager.audioManager.selectedDevice if (currentSoundDevice == CallAudioManager.Device.Phone) { @@ -230,7 +242,7 @@ class VectorCallViewModel @AssistedInject constructor( } override fun onCleared() { - callManager.removeCurrentCallListener(currentCallListener) + callManager.removeListener(callManagerListener) call?.removeListener(callListener) call = null proximityManager.stop() @@ -310,10 +322,10 @@ class VectorCallViewModel @AssistedInject constructor( VectorCallViewEvents.ShowCallTransferScreen ) } - VectorCallViewActions.TransferCall -> { + VectorCallViewActions.TransferCall -> { handleCallTransfer() } - is VectorCallViewActions.SwitchCall -> { + is VectorCallViewActions.SwitchCall -> { setState { VectorCallViewState(action.callArgs) } setupCallWithCurrentState() } diff --git a/vector/src/main/java/im/vector/app/features/call/webrtc/WebRtcCallManager.kt b/vector/src/main/java/im/vector/app/features/call/webrtc/WebRtcCallManager.kt index d276549765..9e620174f3 100644 --- a/vector/src/main/java/im/vector/app/features/call/webrtc/WebRtcCallManager.kt +++ b/vector/src/main/java/im/vector/app/features/call/webrtc/WebRtcCallManager.kt @@ -84,9 +84,10 @@ class WebRtcCallManager @Inject constructor( private val sessionScope: CoroutineScope? get() = currentSession?.coroutineScope - interface CurrentCallListener { - fun onCurrentCallChange(call: WebRtcCall?) {} - fun onAudioDevicesChange() {} + interface Listener { + fun onCallEnded(callId: String) = Unit + fun onCurrentCallChange(call: WebRtcCall?) = Unit + fun onAudioDevicesChange() = Unit } val supportedPSTNProtocol: String? @@ -106,13 +107,13 @@ class WebRtcCallManager @Inject constructor( protocolsChecker?.removeListener(listener) } - private val currentCallsListeners = CopyOnWriteArrayList() + private val currentCallsListeners = CopyOnWriteArrayList() - fun addCurrentCallListener(listener: CurrentCallListener) { + fun addListener(listener: Listener) { currentCallsListeners.add(listener) } - fun removeCurrentCallListener(listener: CurrentCallListener) { + fun removeListener(listener: Listener) { currentCallsListeners.remove(listener) } @@ -250,10 +251,13 @@ class WebRtcCallManager @Inject constructor( callsByRoomId[webRtcCall.signalingRoomId]?.remove(webRtcCall) callsByRoomId[webRtcCall.nativeRoomId]?.remove(webRtcCall) transferees.remove(callId) - if (getCurrentCall()?.callId == callId) { + if (currentCall.get()?.callId == callId) { val otherCall = getCalls().lastOrNull() currentCall.setAndNotify(otherCall) } + tryOrNull { + currentCallsListeners.forEach { it.onCallEnded(callId) } + } // There is no active calls if (getCurrentCall() == null) { Timber.tag(loggerTag.value).v("Dispose peerConnectionFactory as there is no need to keep one") From a3a49593e4cf9f9ecaf19b6915dc38c639b74f9b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Sep 2021 13:29:35 +0000 Subject: [PATCH 037/656] Bump media from 1.4.1 to 1.4.2 Bumps media from 1.4.1 to 1.4.2. --- updated-dependencies: - dependency-name: androidx.media:media dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- vector/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/build.gradle b/vector/build.gradle index afc6ac6a25..9d58b54045 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -334,7 +334,7 @@ dependencies { implementation libs.androidx.constraintLayout implementation "androidx.sharetarget:sharetarget:1.1.0" implementation libs.androidx.core - implementation "androidx.media:media:1.4.1" + implementation "androidx.media:media:1.4.2" implementation "androidx.transition:transition:1.4.1" implementation "org.threeten:threetenbp:1.4.0:no-tzdb" From afb49430be86d4ef9f75ded3e1f8c073985d675c Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Tue, 7 Sep 2021 15:59:59 +0200 Subject: [PATCH 038/656] Permalink: move method implementation from service to factory --- .../session/permalinks/DefaultPermalinkService.kt | 6 +----- .../sdk/internal/session/permalinks/PermalinkFactory.kt | 9 ++++----- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt index 134da4ce51..70e4faf356 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt @@ -18,7 +18,6 @@ package org.matrix.android.sdk.internal.session.permalinks import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.permalinks.PermalinkService -import org.matrix.android.sdk.api.session.permalinks.PermalinkService.Companion.MATRIX_TO_URL_BASE import javax.inject.Inject internal class DefaultPermalinkService @Inject constructor( @@ -42,9 +41,6 @@ internal class DefaultPermalinkService @Inject constructor( } override fun getLinkedId(url: String): String? { - return url - .takeIf { it.startsWith(MATRIX_TO_URL_BASE) } - ?.substring(MATRIX_TO_URL_BASE.length) - ?.substringBeforeLast("?") + return permalinkFactory.getLinkedId(url) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt index 639e45582a..9332751744 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt @@ -60,11 +60,10 @@ internal class PermalinkFactory @Inject constructor( } fun getLinkedId(url: String): String? { - val isSupported = url.startsWith(MATRIX_TO_URL_BASE) - - return if (isSupported) { - url.substring(MATRIX_TO_URL_BASE.length) - } else null + return url + .takeIf { it.startsWith(MATRIX_TO_URL_BASE) } + ?.substring(MATRIX_TO_URL_BASE.length) + ?.substringBeforeLast("?") } /** From 0d344fde03a68d3c1dd3d2a53796669813ffa7af Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Wed, 8 Sep 2021 17:23:48 +0200 Subject: [PATCH 039/656] Permalink: add client url field in MatrixConfiguration --- .../org/matrix/android/sdk/api/MatrixConfiguration.kt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt index ed809cdb04..bd47c34571 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt @@ -32,8 +32,12 @@ data class MatrixConfiguration( "https://scalar-staging.riot.im/scalar/api" ), /** - * Optional proxy to connect to the matrix servers - * You can create one using for instance Proxy(proxyType, InetSocketAddress.createUnresolved(hostname, port) + * Optional base url to create client permalinks instead of Matrix ones (matrix.to links). + */ + val clientPermalinkBaseUrl: String? = null, + /** + * Optional proxy to connect to the matrix servers. + * You can create one using for instance Proxy(proxyType, InetSocketAddress.createUnresolved(hostname, port). */ val proxy: Proxy? = null, /** @@ -47,7 +51,7 @@ data class MatrixConfiguration( ) { /** - * Can be implemented by your Application class + * Can be implemented by your Application class. */ interface Provider { fun providesMatrixConfiguration(): MatrixConfiguration From a73f0a9fa802243acc0d121e4e7fa65dfc461af2 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Thu, 9 Sep 2021 09:12:30 +0200 Subject: [PATCH 040/656] Permalink: use client base url if any --- .../session/permalinks/PermalinkService.kt | 15 ++- .../permalinks/DefaultPermalinkService.kt | 16 ++-- .../session/permalinks/PermalinkFactory.kt | 91 ++++++++++++++++--- .../room/send/LocalEchoEventFactory.kt | 8 +- 4 files changed, 99 insertions(+), 31 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt index a6d4583c76..7318b7b8e0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt @@ -19,7 +19,7 @@ package org.matrix.android.sdk.api.session.permalinks import org.matrix.android.sdk.api.session.events.model.Event /** - * Useful methods to create Matrix permalink (matrix.to links). + * Useful methods to create permalink (like matrix.to links or client permalinks). */ interface PermalinkService { @@ -32,10 +32,11 @@ interface PermalinkService { * Ex: "https://matrix.to/#/!nbzmcXAqpxBXjAdgoX:matrix.org/$1531497316352799BevdV:matrix.org" * * @param event the event + * @param forceMatrixTo whether we should force using matrix.to base URL * * @return the permalink, or null in case of error */ - fun createPermalink(event: Event): String? + fun createPermalink(event: Event, forceMatrixTo: Boolean = false): String? /** * Creates a permalink for an id (can be a user Id, etc.). @@ -43,18 +44,21 @@ interface PermalinkService { * Ex: "https://matrix.to/#/@benoit:matrix.org" * * @param id the id + * @param forceMatrixTo whether we should force using matrix.to base URL + * * @return the permalink, or null in case of error */ - fun createPermalink(id: String): String? + fun createPermalink(id: String, forceMatrixTo: Boolean = false): String? /** * Creates a permalink for a roomId, including the via parameters * * @param roomId the room id + * @param forceMatrixTo whether we should force using matrix.to base URL * * @return the permalink, or null in case of error */ - fun createRoomPermalink(roomId: String, viaServers: List? = null): String? + fun createRoomPermalink(roomId: String, viaServers: List? = null, forceMatrixTo: Boolean = false): String? /** * Creates a permalink for an event. If you have an event you can use [createPermalink] @@ -62,10 +66,11 @@ interface PermalinkService { * * @param roomId the id of the room * @param eventId the id of the event + * @param forceMatrixTo whether we should force using matrix.to base URL * * @return the permalink */ - fun createPermalink(roomId: String, eventId: String): String + fun createPermalink(roomId: String, eventId: String, forceMatrixTo: Boolean = false): String /** * Extract the linked id from the universal link diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt index 70e4faf356..144ebb5404 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt @@ -24,20 +24,20 @@ internal class DefaultPermalinkService @Inject constructor( private val permalinkFactory: PermalinkFactory ) : PermalinkService { - override fun createPermalink(event: Event): String? { - return permalinkFactory.createPermalink(event) + override fun createPermalink(event: Event, forceMatrixTo: Boolean): String? { + return permalinkFactory.createPermalink(event, forceMatrixTo) } - override fun createPermalink(id: String): String? { - return permalinkFactory.createPermalink(id) + override fun createPermalink(id: String, forceMatrixTo: Boolean): String? { + return permalinkFactory.createPermalink(id, forceMatrixTo) } - override fun createRoomPermalink(roomId: String, viaServers: List?): String? { - return permalinkFactory.createRoomPermalink(roomId, viaServers) + override fun createRoomPermalink(roomId: String, viaServers: List?, forceMatrixTo: Boolean): String? { + return permalinkFactory.createRoomPermalink(roomId, viaServers, forceMatrixTo) } - override fun createPermalink(roomId: String, eventId: String): String { - return permalinkFactory.createPermalink(roomId, eventId) + override fun createPermalink(roomId: String, eventId: String, forceMatrixTo: Boolean): String { + return permalinkFactory.createPermalink(roomId, eventId, forceMatrixTo) } override fun getLinkedId(url: String): String? { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt index 9332751744..39c1ddfdce 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt @@ -16,7 +16,11 @@ package org.matrix.android.sdk.internal.session.permalinks +import org.matrix.android.sdk.api.MatrixConfiguration +import org.matrix.android.sdk.api.MatrixPatterns import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.api.session.permalinks.PermalinkData +import org.matrix.android.sdk.api.session.permalinks.PermalinkParser import org.matrix.android.sdk.api.session.permalinks.PermalinkService.Companion.MATRIX_TO_URL_BASE import org.matrix.android.sdk.internal.di.UserId import javax.inject.Inject @@ -24,28 +28,44 @@ import javax.inject.Inject internal class PermalinkFactory @Inject constructor( @UserId private val userId: String, - private val viaParameterFinder: ViaParameterFinder + private val viaParameterFinder: ViaParameterFinder, + private val matrixConfiguration: MatrixConfiguration ) { - fun createPermalink(event: Event): String? { + fun createPermalink(event: Event, forceMatrixTo: Boolean): String? { if (event.roomId.isNullOrEmpty() || event.eventId.isNullOrEmpty()) { return null } - return createPermalink(event.roomId, event.eventId) + return createPermalink(event.roomId, event.eventId, forceMatrixTo) } - fun createPermalink(id: String): String? { - return if (id.isEmpty()) { - null - } else MATRIX_TO_URL_BASE + escape(id) + fun createPermalink(id: String, forceMatrixTo: Boolean): String? { + return when { + id.isEmpty() -> null + !useClientFormat(forceMatrixTo) -> MATRIX_TO_URL_BASE + escape(id) + else -> { + buildString { + append(matrixConfiguration.clientPermalinkBaseUrl) + when { + MatrixPatterns.isRoomId(id) || MatrixPatterns.isRoomAlias(id) -> append(ROOM_PATH) + MatrixPatterns.isUserId(id) -> append(USER_PATH) + MatrixPatterns.isGroupId(id) -> append(GROUP_PATH) + } + append(escape(id)) + } + } + } } - fun createRoomPermalink(roomId: String, via: List? = null): String? { + fun createRoomPermalink(roomId: String, via: List? = null, forceMatrixTo: Boolean): String? { return if (roomId.isEmpty()) { null } else { buildString { - append(MATRIX_TO_URL_BASE) + append(baseUrl(forceMatrixTo)) + if (useClientFormat(forceMatrixTo)) { + append(ROOM_PATH) + } append(escape(roomId)) append( via?.takeIf { it.isNotEmpty() }?.let { viaParameterFinder.asUrlViaParameters(it) } @@ -55,14 +75,33 @@ internal class PermalinkFactory @Inject constructor( } } - fun createPermalink(roomId: String, eventId: String): String { - return MATRIX_TO_URL_BASE + escape(roomId) + "/" + escape(eventId) + viaParameterFinder.computeViaParams(userId, roomId) + fun createPermalink(roomId: String, eventId: String, forceMatrixTo: Boolean): String { + return buildString { + append(baseUrl(forceMatrixTo)) + if (useClientFormat(forceMatrixTo)) { + append(ROOM_PATH) + } + append(escape(roomId)) + append("/") + append(escape(eventId)) + append(viaParameterFinder.computeViaParams(userId, roomId)) + } } fun getLinkedId(url: String): String? { - return url - .takeIf { it.startsWith(MATRIX_TO_URL_BASE) } - ?.substring(MATRIX_TO_URL_BASE.length) + val clientBaseUrl = matrixConfiguration.clientPermalinkBaseUrl + return when { + url.startsWith(MATRIX_TO_URL_BASE) -> url.substring(MATRIX_TO_URL_BASE.length) + clientBaseUrl != null && url.startsWith(clientBaseUrl) -> { + when (PermalinkParser.parse(url)) { + is PermalinkData.GroupLink -> url.substring(clientBaseUrl.length + GROUP_PATH.length) + is PermalinkData.RoomLink -> url.substring(clientBaseUrl.length + ROOM_PATH.length) + is PermalinkData.UserLink -> url.substring(clientBaseUrl.length + USER_PATH.length) + else -> null + } + } + else -> null + } ?.substringBeforeLast("?") } @@ -85,4 +124,28 @@ internal class PermalinkFactory @Inject constructor( private fun unescape(id: String): String { return id.replace("%2F", "/") } + + /** + * Get the permalink base URL according to the potential one in [MatrixConfiguration.clientPermalinkBaseUrl] + * and the [forceMatrixTo] parameter. + * + * @param forceMatrixTo whether we should force using matrix.to base URL. + * + * @return the permalink base URL. + */ + private fun baseUrl(forceMatrixTo: Boolean): String { + return matrixConfiguration.clientPermalinkBaseUrl + ?.takeUnless { forceMatrixTo } + ?: MATRIX_TO_URL_BASE + } + + private fun useClientFormat(forceMatrixTo: Boolean): Boolean { + return !forceMatrixTo && matrixConfiguration.clientPermalinkBaseUrl != null + } + + companion object { + private const val ROOM_PATH = "room/" + private const val USER_PATH = "user/" + private const val GROUP_PATH = "group/" + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt index c610326a94..8dd0c59387 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt @@ -165,8 +165,8 @@ internal class LocalEchoEventFactory @Inject constructor( newBodyAutoMarkdown: Boolean, msgType: String, compatibilityText: String): Event { - val permalink = permalinkFactory.createPermalink(roomId, originalEvent.root.eventId ?: "") - val userLink = originalEvent.root.senderId?.let { permalinkFactory.createPermalink(it) } ?: "" + val permalink = permalinkFactory.createPermalink(roomId, originalEvent.root.eventId ?: "", false) + val userLink = originalEvent.root.senderId?.let { permalinkFactory.createPermalink(it, false) } ?: "" val body = bodyForReply(originalEvent.getLastMessageContent(), originalEvent.isReply()) val replyFormatted = REPLY_PATTERN.format( @@ -350,9 +350,9 @@ internal class LocalEchoEventFactory @Inject constructor( autoMarkdown: Boolean): Event? { // Fallbacks and event representation // TODO Add error/warning logs when any of this is null - val permalink = permalinkFactory.createPermalink(eventReplied.root) ?: return null + val permalink = permalinkFactory.createPermalink(eventReplied.root, false) ?: return null val userId = eventReplied.root.senderId ?: return null - val userLink = permalinkFactory.createPermalink(userId) ?: return null + val userLink = permalinkFactory.createPermalink(userId, false) ?: return null val body = bodyForReply(eventReplied.getLastMessageContent(), eventReplied.isReply()) val replyFormatted = REPLY_PATTERN.format( From 21d0a28150630264268b6d825bf90720079386f3 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Thu, 9 Sep 2021 17:17:11 +0200 Subject: [PATCH 041/656] Permalink: move supported hosts to config file --- .../vector/app/features/link/LinkHandlerActivity.kt | 11 +---------- vector/src/main/res/values/config.xml | 11 +++++++++++ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt b/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt index a0b8efd5aa..487ce90dd9 100644 --- a/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt @@ -63,7 +63,7 @@ class LinkHandlerActivity : VectorBaseActivity() { if (uri.getQueryParameter(LoginConfig.CONFIG_HS_PARAMETER) != null) { handleConfigUrl(uri) - } else if (SUPPORTED_HOSTS.contains(uri.host)) { + } else if (resources.getStringArray(R.array.permalink_supported_hosts).contains(uri.host)) { handleSupportedHostUrl(uri) } else { // Other links are not yet handled, but should not come here (manifest configuration error?) @@ -175,15 +175,6 @@ class LinkHandlerActivity : VectorBaseActivity() { } companion object { - private val SUPPORTED_HOSTS = listOf( - // Regular Element Web instance - "app.element.io", - // Other known instances of Element Web - "develop.element.io", - "staging.element.io", - // Previous Web instance, kept for compatibility reason - "riot.im" - ) private val SUPPORTED_PATHS = listOf( "/#/room/", "/#/user/", diff --git a/vector/src/main/res/values/config.xml b/vector/src/main/res/values/config.xml index 30ca8d7f56..a8e80f82ed 100755 --- a/vector/src/main/res/values/config.xml +++ b/vector/src/main/res/values/config.xml @@ -26,4 +26,15 @@ gitter.im + + + + app.element.io + + develop.element.io + staging.element.io + + riot.im + + From e37fb313c0c6d6b8c1151dbc8773d9dce0ac9ccc Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Thu, 16 Sep 2021 15:11:46 +0200 Subject: [PATCH 042/656] Permalink: Merge LinkHandlerActivity with PermalinkHandlerActivity Also convert links to matrix.to before permalink parsing --- changelog.d/4027.feature | 1 + .../api/session/permalinks/MatrixToMapper.kt | 55 +++++++++ .../api/session/permalinks/PermalinkParser.kt | 21 ++-- vector/src/main/AndroidManifest.xml | 57 ++++----- .../im/vector/app/core/di/ScreenComponent.kt | 2 - .../vector/app/features/home/HomeActivity.kt | 26 ++--- .../app/features/link/LinkHandlerActivity.kt | 108 +++++++----------- .../features/permalink/PermalinkHandler.kt | 16 ++- .../permalink/PermalinkHandlerActivity.kt | 79 ------------- 9 files changed, 165 insertions(+), 200 deletions(-) create mode 100644 changelog.d/4027.feature create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixToMapper.kt delete mode 100644 vector/src/main/java/im/vector/app/features/permalink/PermalinkHandlerActivity.kt diff --git a/changelog.d/4027.feature b/changelog.d/4027.feature new file mode 100644 index 0000000000..fa45d07ef9 --- /dev/null +++ b/changelog.d/4027.feature @@ -0,0 +1 @@ +Add client base url config to customize permalinks \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixToMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixToMapper.kt new file mode 100644 index 0000000000..a1e7d09628 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixToMapper.kt @@ -0,0 +1,55 @@ +/* + * Copyright 2020 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.api.session.permalinks + +import android.net.Uri + +/** + * Mapping of an input URI to a matrix.to compliant URI. + */ +object MatrixToMapper { + + /** + * Try to convert a URL from an element web instance or from a client permalink to a matrix.to url. + * To be successfully converted, URL path should contain one of the [SUPPORTED_PATHS]. + * Examples: + * - https://riot.im/develop/#/room/#element-android:matrix.org -> https://matrix.to/#/#element-android:matrix.org + * - https://app.element.io/#/room/#element-android:matrix.org -> https://matrix.to/#/#element-android:matrix.org + * - https://www.example.org/#/room/#element-android:matrix.org -> https://matrix.to/#/#element-android:matrix.org + */ + fun map(uri: Uri): Uri? { + val uriString = uri.toString() + + return when { + // URL is already a matrix.to + uriString.startsWith(PermalinkService.MATRIX_TO_URL_BASE) -> uri + // Web or client url + SUPPORTED_PATHS.any { it in uriString } -> { + val path = SUPPORTED_PATHS.first { it in uriString } + Uri.parse(PermalinkService.MATRIX_TO_URL_BASE + uriString.substringAfter(path)) + } + // URL is not supported + else -> null + } + } + + private val SUPPORTED_PATHS = listOf( + "/#/room/", + "/#/user/", + "/#/group/" + ) +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt index 005a2edae7..9d16d09812 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt @@ -26,6 +26,7 @@ import java.net.URLDecoder * This class turns a uri to a [PermalinkData] * element-based domains (e.g. https://app.element.io/#/user/@chagai95:matrix.org) permalinks * or matrix.to permalinks (e.g. https://matrix.to/#/@chagai95:matrix.org) + * or client permalinks (e.g. https://www.example.com/#/user/@chagai95:matrix.org) */ object PermalinkParser { @@ -42,12 +43,14 @@ object PermalinkParser { * https://github.com/matrix-org/matrix-doc/blob/master/proposals/1704-matrix.to-permalinks.md */ fun parse(uri: Uri): PermalinkData { - if (!uri.toString().startsWith(PermalinkService.MATRIX_TO_URL_BASE)) { - return PermalinkData.FallbackLink(uri) - } + // the client or element-based domain permalinks (e.g. https://app.element.io/#/user/@chagai95:matrix.org) don't have the + // mxid in the first param (like matrix.to does - https://matrix.to/#/@chagai95:matrix.org) but rather in the second after /user/ so /user/mxid + // so convert URI to matrix.to to simplify parsing process + val matrixToUri = MatrixToMapper.map(uri) ?: return PermalinkData.FallbackLink(uri) + // We can't use uri.fragment as it is decoding to early and it will break the parsing // of parameters that represents url (like signurl) - val fragment = uri.toString().substringAfter("#") // uri.fragment + val fragment = matrixToUri.toString().substringAfter("#") // uri.fragment if (fragment.isNullOrEmpty()) { return PermalinkData.FallbackLink(uri) } @@ -61,20 +64,14 @@ object PermalinkParser { .map { URLDecoder.decode(it, "UTF-8") } .take(2) - // the element-based domain permalinks (e.g. https://app.element.io/#/user/@chagai95:matrix.org) don't have the - // mxid in the first param (like matrix.to does - https://matrix.to/#/@chagai95:matrix.org) but rather in the second after /user/ so /user/mxid - var identifier = params.getOrNull(0) - if (identifier.equals("user")) { - identifier = params.getOrNull(1) - } - + val identifier = params.getOrNull(0) val extraParameter = params.getOrNull(1) return when { identifier.isNullOrEmpty() -> PermalinkData.FallbackLink(uri) MatrixPatterns.isUserId(identifier) -> PermalinkData.UserLink(userId = identifier) MatrixPatterns.isGroupId(identifier) -> PermalinkData.GroupLink(groupId = identifier) MatrixPatterns.isRoomId(identifier) -> { - handleRoomIdCase(fragment, identifier, uri, extraParameter, viaQueryParameters) + handleRoomIdCase(fragment, identifier, matrixToUri, extraParameter, viaQueryParameters) } MatrixPatterns.isRoomAlias(identifier) -> { PermalinkData.RoomLink( diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml index 6c9453a564..0e84eb3bcd 100644 --- a/vector/src/main/AndroidManifest.xml +++ b/vector/src/main/AndroidManifest.xml @@ -180,7 +180,9 @@ - + @@ -196,6 +198,30 @@ + + + + + + + + + + + + + + + + @@ -230,27 +256,6 @@ - - - - - - - - - - - - - - - + android:supportsPictureInPicture="true" + android:taskAffinity=".features.call.VectorCallActivity" /> val resolvedLink = when { - deepLink.startsWith(PermalinkService.MATRIX_TO_URL_BASE) -> deepLink - deepLink.startsWith(MATRIX_TO_CUSTOM_SCHEME_URL_BASE) -> { - // This is a bit ugly, but for now just convert to matrix.to link for compatibility - when { + // Element custom scheme is not handled by the sdk, convert it to matrix.to link for compatibility + deepLink.startsWith(MATRIX_TO_CUSTOM_SCHEME_URL_BASE) -> { + val let = when { deepLink.startsWith(USER_LINK_PREFIX) -> deepLink.substring(USER_LINK_PREFIX.length) deepLink.startsWith(ROOM_LINK_PREFIX) -> deepLink.substring(ROOM_LINK_PREFIX.length) else -> null - }?.let { - activeSessionHolder.getSafeActiveSession()?.permalinkService()?.createPermalink(it) + }?.let { permalinkId -> + activeSessionHolder.getSafeActiveSession()?.permalinkService()?.createPermalink(permalinkId) } + let } - else -> return@let + else -> deepLink } - permalinkHandler.launch( context = this, deepLink = resolvedLink, @@ -290,9 +292,11 @@ class HomeActivity : .observeOn(AndroidSchedulers.mainThread()) .subscribe { isHandled -> if (!isHandled) { + val isMatrixToLink = deepLink.startsWith(PermalinkService.MATRIX_TO_URL_BASE) + || deepLink.startsWith(MATRIX_TO_CUSTOM_SCHEME_URL_BASE) MaterialAlertDialogBuilder(this) .setTitle(R.string.dialog_title_error) - .setMessage(R.string.permalink_malformed) + .setMessage(if (isMatrixToLink) R.string.permalink_malformed else R.string.universal_link_malformed) .setPositiveButton(R.string.ok, null) .show() } @@ -559,10 +563,6 @@ class HomeActivity : putExtra(MvRx.KEY_ARG, args) } } - - private const val MATRIX_TO_CUSTOM_SCHEME_URL_BASE = "element://" - private const val ROOM_LINK_PREFIX = "${MATRIX_TO_CUSTOM_SCHEME_URL_BASE}room/" - private const val USER_LINK_PREFIX = "${MATRIX_TO_CUSTOM_SCHEME_URL_BASE}user/" } override fun create(initialState: ActiveSpaceViewState) = promoteRestrictedViewModelFactory.create(initialState) diff --git a/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt b/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt index 487ce90dd9..39105185b1 100644 --- a/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt @@ -27,13 +27,12 @@ import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.utils.toast import im.vector.app.databinding.ActivityProgressBinding +import im.vector.app.features.home.HomeActivity import im.vector.app.features.login.LoginConfig import im.vector.app.features.permalink.PermalinkHandler -import io.reactivex.android.schedulers.AndroidSchedulers import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.permalinks.PermalinkService import timber.log.Timber -import java.util.concurrent.TimeUnit import javax.inject.Inject /** @@ -45,30 +44,38 @@ class LinkHandlerActivity : VectorBaseActivity() { @Inject lateinit var errorFormatter: ErrorFormatter @Inject lateinit var permalinkHandler: PermalinkHandler + override fun getBinding() = ActivityProgressBinding.inflate(layoutInflater) + override fun injectWith(injector: ScreenComponent) { injector.inject(this) } - override fun getBinding() = ActivityProgressBinding.inflate(layoutInflater) - override fun initUiAndData() { + handleIntent() + } + + override fun onNewIntent(intent: Intent?) { + super.onNewIntent(intent) + handleIntent() + } + + private fun handleIntent() { val uri = intent.data - - if (uri == null) { - // Should not happen - Timber.w("Uri is null") - finish() - return - } - - if (uri.getQueryParameter(LoginConfig.CONFIG_HS_PARAMETER) != null) { - handleConfigUrl(uri) - } else if (resources.getStringArray(R.array.permalink_supported_hosts).contains(uri.host)) { - handleSupportedHostUrl(uri) - } else { - // Other links are not yet handled, but should not come here (manifest configuration error?) - toast(R.string.universal_link_malformed) - finish() + when { + uri == null -> { + // Should not happen + Timber.w("Uri is null") + finish() + } + uri.getQueryParameter(LoginConfig.CONFIG_HS_PARAMETER) != null -> handleConfigUrl(uri) + uri.toString().startsWith(PermalinkService.MATRIX_TO_URL_BASE) -> handleSupportedHostUrl() + uri.toString().startsWith(PermalinkHandler.MATRIX_TO_CUSTOM_SCHEME_URL_BASE) -> handleSupportedHostUrl() + resources.getStringArray(R.array.permalink_supported_hosts).contains(uri.host) -> handleSupportedHostUrl() + else -> { + // Other links are not yet handled, but should not come here (manifest configuration error?) + toast(R.string.universal_link_malformed) + finish() + } } } @@ -81,53 +88,28 @@ class LinkHandlerActivity : VectorBaseActivity() { } } - private fun handleSupportedHostUrl(uri: Uri) { + private fun handleSupportedHostUrl() { + // If we are not logged in, open login screen. + // In the future, we might want to relaunch the process after login. if (!sessionHolder.hasActiveSession()) { - startLoginActivity(uri) - finish() - } else { - convertUriToPermalink(uri)?.let { permalink -> - startPermalinkHandler(permalink) - } ?: run { - // Host is correct but we do not recognize path - Timber.w("Unable to handle this uri: $uri") - finish() - } + startLoginActivity() + return } + + // We forward intent to HomeActivity (singleTask) to avoid the dueling app problem + // https://stackoverflow.com/questions/25884954/deep-linking-and-multiple-app-instances + intent.setClass(this, HomeActivity::class.java) + intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP + startActivity(intent) } /** - * Convert a URL of element web instance to a matrix.to url - * Examples: - * - https://riot.im/develop/#/room/#element-android:matrix.org -> https://matrix.to/#/#element-android:matrix.org - * - https://app.element.io/#/room/#element-android:matrix.org -> https://matrix.to/#/#element-android:matrix.org + * Start the login screen with identity server and homeserver pre-filled, if any */ - private fun convertUriToPermalink(uri: Uri): String? { - val uriString = uri.toString() - val path = SUPPORTED_PATHS.find { it in uriString } ?: return null - return PermalinkService.MATRIX_TO_URL_BASE + uriString.substringAfter(path) - } - - private fun startPermalinkHandler(permalink: String) { - permalinkHandler.launch(this, permalink, buildTask = true) - .delay(500, TimeUnit.MILLISECONDS) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe { isHandled -> - if (!isHandled) { - toast(R.string.universal_link_malformed) - } - finish() - } - .disposeOnDestroy() - } - - /** - * Start the login screen with identity server and homeserver pre-filled - */ - private fun startLoginActivity(uri: Uri) { + private fun startLoginActivity(uri: Uri? = null) { navigator.openLogin( context = this, - loginConfig = LoginConfig.parse(uri), + loginConfig = uri?.let { LoginConfig.parse(uri) }, flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK ) finish() @@ -173,12 +155,4 @@ class LinkHandlerActivity : VectorBaseActivity() { .setPositiveButton(R.string.ok) { _, _ -> finish() } .show() } - - companion object { - private val SUPPORTED_PATHS = listOf( - "/#/room/", - "/#/user/", - "/#/group/" - ) - } } diff --git a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt index ecaeea1899..fd5fea0fe8 100644 --- a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt +++ b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt @@ -29,6 +29,7 @@ import io.reactivex.schedulers.Schedulers import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.permalinks.PermalinkData import org.matrix.android.sdk.api.session.permalinks.PermalinkParser +import org.matrix.android.sdk.api.session.permalinks.PermalinkService import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomType import org.matrix.android.sdk.api.util.Optional @@ -55,7 +56,7 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti navigationInterceptor: NavigationInterceptor? = null, buildTask: Boolean = false ): Single { - if (deepLink == null) { + if (deepLink == null || !isPermalinkSupported(context, deepLink.toString())) { return Single.just(false) } return Single @@ -122,6 +123,13 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti } } + private fun isPermalinkSupported(context: Context, url: String): Boolean { + return url.startsWith(PermalinkService.MATRIX_TO_URL_BASE) + || context.resources.getStringArray(R.array.permalink_supported_hosts).any { + url.startsWith(it) + } + } + private fun PermalinkData.RoomLink.getRoomId(): Single> { val session = activeSessionHolder.getSafeActiveSession() return if (isRoomAlias && session != null) { @@ -179,6 +187,12 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti } } } + + companion object { + const val MATRIX_TO_CUSTOM_SCHEME_URL_BASE = "element://" + const val ROOM_LINK_PREFIX = "${MATRIX_TO_CUSTOM_SCHEME_URL_BASE}room/" + const val USER_LINK_PREFIX = "${MATRIX_TO_CUSTOM_SCHEME_URL_BASE}user/" + } } interface NavigationInterceptor { diff --git a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandlerActivity.kt b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandlerActivity.kt deleted file mode 100644 index ee4e0e05b5..0000000000 --- a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandlerActivity.kt +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2019 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package im.vector.app.features.permalink - -import android.content.Intent -import android.os.Bundle -import im.vector.app.R -import im.vector.app.core.di.ActiveSessionHolder -import im.vector.app.core.di.ScreenComponent -import im.vector.app.core.extensions.replaceFragment -import im.vector.app.core.platform.VectorBaseActivity -import im.vector.app.databinding.FragmentProgressBinding -import im.vector.app.features.home.HomeActivity -import im.vector.app.features.home.LoadingFragment -import javax.inject.Inject - -class PermalinkHandlerActivity : VectorBaseActivity() { - - @Inject lateinit var permalinkHandler: PermalinkHandler - @Inject lateinit var sessionHolder: ActiveSessionHolder - - override fun getBinding() = FragmentProgressBinding.inflate(layoutInflater) - - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_simple) - if (isFirstCreation()) { - replaceFragment(R.id.simpleFragmentContainer, LoadingFragment::class.java) - } - handleIntent() - } - - private fun handleIntent() { - // If we are not logged in, open login screen. - // In the future, we might want to relaunch the process after login. - if (!sessionHolder.hasActiveSession()) { - startLoginActivity() - return - } - // We forward intent to HomeActivity (singleTask) to avoid the dueling app problem - // https://stackoverflow.com/questions/25884954/deep-linking-and-multiple-app-instances - intent.setClass(this, HomeActivity::class.java) - intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP - startActivity(intent) - - finish() - } - - override fun onNewIntent(intent: Intent?) { - super.onNewIntent(intent) - handleIntent() - } - - private fun startLoginActivity() { - navigator.openLogin( - context = this, - flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK - ) - finish() - } -} From bc85ae4bc9106229c9e32e95a8a6c9e796b5d069 Mon Sep 17 00:00:00 2001 From: waclaw66 Date: Fri, 17 Sep 2021 10:28:19 +0000 Subject: [PATCH 043/656] Translated using Weblate (Czech) Currently translated at 100.0% (2615 of 2615 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/cs/ --- vector/src/main/res/values-cs/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-cs/strings.xml b/vector/src/main/res/values-cs/strings.xml index ca31bad408..69279aadb4 100644 --- a/vector/src/main/res/values-cs/strings.xml +++ b/vector/src/main/res/values-cs/strings.xml @@ -1573,7 +1573,7 @@ Jiná oznámení třetích stran Již se díváte do této místnosti! Rychlé reakce - Obecná + Obecné Možnosti Zabezpečení a soukromí Expert From a48813003e1e69fe7104664490b6944b792b6661 Mon Sep 17 00:00:00 2001 From: Linerly Date: Fri, 17 Sep 2021 15:12:40 +0000 Subject: [PATCH 044/656] Translated using Weblate (Indonesian) Currently translated at 70.6% (1848 of 2615 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/id/ --- vector/src/main/res/values-in/strings.xml | 528 ++++++++++++++++++++-- 1 file changed, 499 insertions(+), 29 deletions(-) diff --git a/vector/src/main/res/values-in/strings.xml b/vector/src/main/res/values-in/strings.xml index f5ac4f0753..5c4ca08d53 100644 --- a/vector/src/main/res/values-in/strings.xml +++ b/vector/src/main/res/values-in/strings.xml @@ -48,7 +48,7 @@ Daftar Masuk Copot akun - URL Server Mula + URL Homeserver Cari Mulai Obrolan Baru Ambil foto atau video @@ -89,7 +89,7 @@ Laporan bug Aplikasi gagal saat terakhir digunakan. Apakah Anda ingin membuka halaman laporan kegagalan\? Gabung di Ruang - URL Server Identity + URL Server Identitas Mulai Panggilan Suara Masuk Buat Akun @@ -102,8 +102,8 @@ Sepertinya alamat email tidak benar Sepertinya nomor telepon tidak benar Kata sandi tidak cocok - Serve Home ingin memastikan bahwa Anda bukan robot - Server Home: + Homeserver ini ingin memastikan bahwa Anda bukan robot + Homeserver: Saya sudah verifikasi alamat email saya Kata sandi baru perlu dimasukkan. URL diawali dengan http[s]:// @@ -145,7 +145,7 @@ Terbesar Ukuran font Sangat Kecil - URL server Home + Nama server Pilih direktori ruang Terdapat perangkat tidak diketahui di ruang Saya verifikasi bahwa kuncinya sesuai @@ -345,7 +345,7 @@ Ijinkan akses lewat halaman selanjutnya untuk menemukan pengguna ${app_name} yan Tunjukkan Daftar Perangkat Anda tidak akan dapat mengembalikan perubahan ini setelah Anda mengangkat pengguna ini agar memiliki kuasa yang setara dengan Anda. \nApakah anda yakin untuk melanjutkan\? - Melakukan banning pengguna akan mengeluarkannya dari ruangan ini dan mencegahnya untuk kembali masuk. + Melakukan pencekalan pengguna akan mengeluarkannya dari ruangan ini dan mencegahnya untuk kembali masuk. Apa benar Anda ingin mengundang %s ke percakapan ini? %1$s dan %2$s %1$s %2$s @@ -426,7 +426,7 @@ Ijinkan akses lewat halaman selanjutnya untuk menemukan pengguna ${app_name} yan Ketik id atau alias ruang Jelajahi direktori - %d ruang + %d ruangan %1$s ruang ditemukan untuk %2$s @@ -441,7 +441,7 @@ Ijinkan akses lewat halaman selanjutnya untuk menemukan pengguna ${app_name} yan Percakapan Langsung Tinggalkan Percakapan Lupakan - Tambahkan Shortcut pada Homescreen + Tambahkan ke Layar Utama Pesan Pengaturan Versi @@ -486,7 +486,7 @@ Ijinkan akses lewat halaman selanjutnya untuk menemukan pengguna ${app_name} yan versi olm Syarat & ketentuan - %d ruang + %d ruangan %1$s dalam %2$s Cari sejarah @@ -554,7 +554,7 @@ Ijinkan akses lewat halaman selanjutnya untuk menemukan pengguna ${app_name} yan %d anggota - %d ruang + %d ruangan Admin komunitas belum menyediakan deskripsi panjang untuk komunitas ini. Anda telah dikeluarkan dari %1$s oleh %2$s @@ -660,8 +660,8 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. \'%s\' bukanlah format alias yang valid Anda tidak akan mendapat alamat utama untuk ruang ini. Peringatan alamat utama - Tentukan sebagai Alamat Utama - Jangan tentukan sebagai Alamat Utama + Tentukan sebagai alamat utama + Tidak tentukan sebagai alamat utama Salin ID Ruang Salin Alamat Ruang Enkripsi diaktifkan untuk ruang ini. @@ -682,7 +682,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Informasi perangkat pengirim Nama perangkat Nama - ID Perangkat + ID Sesi Kunci perangkat Verifikasi Sidik jari Ed25519 @@ -745,7 +745,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Kata Sandi: Serahkan Masuk sebagai - Home Server + Homeserver Server Identitas Antarmuka pengguna Bahasa @@ -837,7 +837,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Gagal mengambil token FCM: \n%1$s Pendaftaran Token - Sukses mendaftarkan token FCM di HomeServer. + Berhasil mendaftarkan token FCM di homeserver. Gagal mendaftarkan token FCM ke homeserver: \n%1$s Layanan Pemberitahuan @@ -957,8 +957,8 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. %1$s mencekal %2$s Anda membatalkan pencekalan %1$s %1$s membatalkan pencekalan %2$s - Anda meng-kick %1$s - %1$s meng-kick %2$s + Anda mengeluarkan %1$s + %1$s mengeluarkan %2$s Anda menolak undangan %1$s menolak undangan Anda meninggalkan ruangan @@ -1010,7 +1010,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Mengirim event m.room.server_acl Mengirim pesan Mengundang pengguna - Meng-kick pengguna + Keluarkan pengguna Mencekal pengguna Mengubah izin Mengubah nama ruangan @@ -1032,11 +1032,11 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Batalkan pencekalan pengguna Alasan untuk mencekal Cekal pengguna - Pengguna yang di-kick akan menghilangkannya dari ruangan ini. + Pengguna yang dikeluarkan akan menghilangkannya dari ruangan ini. \n \nUntuk mencegah mereka bergabung lagi, Anda seharusnya mencekalnya. - Alasan untuk meng-kick - Kick user + Alasan untuk mengeluarkan + Keluarkan pengguna Apakah Anda yakin ingin membatalkan undangan untuk pengguna ini\? Batalkan undangan Membatalkan abaian pengguna ini akan menampilkan semua pesan dari mereka. @@ -1078,10 +1078,10 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Ini bukan alamat server Matrix yang valid URL ini tidak dapat dijangkau, silakan periksa Nomor telepon ini sudah ditentukan. - Tetapkan surel untuk pemulihan akun. Gunakan surel atau nomor telepon nanti untuk dapat ditemukan oleh orang-orang yang mengenal Anda secara opsional. - Tetapkan surel untuk pemulihan akun. Gunakan surel atau nomor telepon nanti untuk dapat ditemukan oleh orang-orang yang mengenal Anda secara opsional. + Tetapkan email untuk pemulihan akun. Gunakan email atau nomor telepon nanti untuk dapat ditemukan oleh orang-orang yang mengenal Anda secara opsional. + Tetapkan email untuk pemulihan akun. Gunakan email atau nomor telepon nanti untuk dapat ditemukan oleh orang-orang yang mengenal Anda secara opsional. Tetapkan nomor telepon, dan nanti dapat ditemukan oleh orang-orang yang mengenal Anda secara opsional. - Tetapkan surel untuk pemulihan akun, dan nanti dapat ditemukan oleh orang-orang yang mengenal Anda secara opsional. + Tetapkan email untuk pemulihan akun, dan nanti dapat ditemukan oleh orang-orang yang mengenal Anda secara opsional. Masuk dengan single sign-on Gunakan sebagai bawaan dan jangan tanya lagi Selalu tanya @@ -1194,7 +1194,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Anda menambahkan %1$s dan menghapus %2$s sebagai alamat untuk ruangan ini. %1$s menambahkan %2$s dan menghapus %3$s sebagai alamat untuk ruangan ini. - Anda menghapus %2$s sebagai alamat untuk ruangan ini. + Anda menghapus %1$s sebagai alamat untuk ruangan ini. %1$s menghapus %2$s sebagai alamat untuk ruangan ini. @@ -1323,7 +1323,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. 🎉 Semua server dilarang untuk berpartisipasi! Ruangan ini tidak lagi bisa digunakan. Tidak ada berubahan. Nomor telepon - Tidak ada surel yang ditambahkan ke akun Anda + Tidak ada email yang ditambahkan ke akun Anda Surel • Server yang cocok dengan literal IP sekarang dilarang. • Server yang cocok dengan %s sekarang dilarang. @@ -1391,7 +1391,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Widget Widget aktif LIHAT - + %1$s: %2$s ** Gagal mengirim - mohon buka ruangan Saya Undangan Baru @@ -1490,12 +1490,12 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Info tambahan: %s Terjadi kesalahan saat memverifikasi nomor telepon Anda. Sandi tidak cocok - Kelola surel dan nomor telepon yang ditautkan ke akun Matrix Anda + Kelola email dan nomor telepon yang ditautkan ke akun Matrix Anda Surel dan nomor telepon Sandi tidak valid Sandi Perbarui Sandi - Terjadi kesalahan saat memverifikasi surel Anda. + Terjadi kesalahan saat memverifikasi email Anda. Aktifkan \'Izinkan integrasi\' di Setelan untuk melakukan ini. Integrasi dinonaktifkan Pengelola integrasi @@ -1571,4 +1571,474 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Panggilan berdering… Spaces Pelajari Lebih Lanjut + Kami mengirimi Anda email konfirmasi ke %s, mohon periksa email Anda dan klik tautan konfirmasi + Opsi penemuan akan muncul setelah Anda menambahkan email. + Memutuskan sambungan dari server identitas Anda akan membuat Anda tidak dapat ditemukan oleh pengguna lain dan Anda tidak akan dapat mengundang orang lain melalui email atau nomor telepon. + Kirim email dan nomor telepon + Anda telah memberikan persetujuan untuk mengirim email dan nomor telepon ke server identitas ini untuk menemukan pengguna lain dari kontak Anda. + Anda belum memberikan persetujuan untuk mengirim email dan nomor telepon ke server identitas ini untuk menemukan pengguna lain dari kontak Anda. + Kirim email dan nomor telepon + Untuk menemukan kontak yang ada yang Anda kenal, apakah Anda setuju untuk mengirim data kontak Anda (nomor telepon dan/atau email) ke server identitas yang dikonfigurasi (%1$s)\? +\n +\nUntuk privasi lebih, data yang dikirim akan di-hash sebelum dikirim. + Anda sedang berbagi email atau nomor telepon di server identitas %1$s. Anda harus menyambungkan kembali ke %2$s untuk berhenti membagikannya. + Setujui Persyaratan Layanan server identitas (%s) agar Anda dapat ditemukan melalui email atau nomor telepon. + Kami mengirimi Anda email konfirmasi ke %s, periksa email Anda dan klik tautan konfirmasi + Setel ulang sandi di %1$s + Email ini tidak terkait dengan akun apapun. + Aplikasi tidak dapat membuat akun di homeserver ini. +\n +\nApakah Anda ingin mendaftar menggunakan client web\? + Maaf, server ini tidak menerima akun baru. + Aplikasi tidak dapat masuk ke homeserver ini. Homeserver mendukung jenis masuk berikut: %1$s. +\n +\nApakah Anda ingin masuk menggunakan client web\? + Ada kesalahan terjadi saat memuat halaman: %1$s (%2$d) + Masukkan alamat server yang ingin Anda gunakan + Masukkan alamat Modular Element atau Server yang ingin Anda gunakan + Hosting premium untuk organisasi + Alamat + Alamat Element Matrix Services + Hapus riwayat + Lanjutkan dengan login masuk-tunggal + Masuk + Daftar + Masuk ke %1$s + Hubungkan ke server kustom + Hubungkan ke Element Matrix Services + Hubungkan ke %1$s + Lanjutkan + login masuk-tunggal + Masuk dengan %s + Daftar dengan %s + Lanjutkan dengan %s + Atau + Pengaturan kustom & lanjutan + Lainnya + Pelajari lebih lanjut + Hosting premium untuk organisasi + Bergabunglah dengan jutaan orang secara gratis di server publik terbesar + Sama seperti email, akun memiliki satu tempat, tetapi Anda dapat berkomunikasi dengan siapa saja + Pilih server + Mulai + Luaskan & sesuaikan pengalaman Anda + Ini adalah percakapan Anda. Miliki percakapan Anda. + Jaga percakapan tetap pribadi dengan enkripsi + Chat dengan orang-orang secara langsung atau dalam grup + Pesan belum terbaca + Anda membuatnya khusus undangan. + %1$s membuatnya khusus undangan. + Anda membuat akses ruangan khusus undangan. + %1$s membuat akses ruangan khusus undangan. + Anda membuat ruang publik untuk siapa pun yang mengetahui tautannya. + %1$s membuat ruang publik untuk siapa pun yang mengetahui tautannya. + Tekan lama pada sebuah ruangan untuk melihat lebih banyak pilihan + Anda tidak mengabaikan pengguna apapun + Ketik keyword untuk mencari reaksi. + Spoiler + Mengirim pesan sebagai spoiler + Anda tidak membuat perubahan + %1$s tidak membuat perubahan + Pengaturan ruangan + Tinggalkan ruangan ini + Hilangkan dari prioritas rendah + Tambahkan ke prioritas rendah + Hilangkan dari favorit + Tambahkan ke favorit + Pengaturan + Bisu + Sebutan saja + Semua pesan + Semua pesan (brisik) + Abaikan pengguna + Tidak ada koneksi jaringan sekarang + ${app_name} memerlukan izin untuk menyimpan kunci E2E Anda di penyimpanan. +\n +\nHarap izinkan akses pada pop-up berikutnya untuk dapat mengekspor kunci Anda secara manual. + Konten ini telah dilaporkan sebagai tidak pantas. +\n +\nJika Anda tidak ingin melihat konten dari pengguna ini, Anda bisa mengabaikan pengguna itu untuk menyembunyikan pesan dari pengguna. + Dilaporkan sebagai tidak pantas + Konten ini telah dilaporkan. +\n +\nJika Anda tidak ingin melihat konten dari pengguna ini, Anda bisa mengabaikan pengguna itu untuk menyembunyikan pesan dari pengguna. + Konten ini telah dilaporkan sebagai spam. +\n +\nJika Anda tidak ingin melihat konten dari pengguna ini, Anda bisa mengabaikan pengguna itu untuk menyembunyikan pesan dari pengguna. + Dilaporkan sebagai spam + Konten dilaporkan + ABAIKAN PENGGUNA + LAPOR + Alasan untuk melaporkan konten ini + Laporkan konten ini + Laporan kustom… + Tidak pantas + Spam + Tidak ada file di ruangan ini + %1$s di %2$s + FILE + Tidak ada media di ruangan ini + MEDIA + %1$d dari %2$d + Tidak bisa menangani perbagian data + Putar dan krop + Stiker + Galeri + Suara + Kamera + Kontak + Ada kesalahan terjadi saat menerima lampiran. + Tambahkan gambar dari + File + %d+ + +%d + %1$s: %2$s + %1$s: + %1$s: %2$s %3$s + Tambahkan tab terdedikasi untuk notifikasi yang belum dibaca di layar utama. + File ini terlalu besar untuk diupload. + Cadangan mempunyai tanda tangan yang tidak valid dari sesi %s yang belum diverifikasi + Cadangan mempunyai tanda tangan yang tidak valid dari sesi %s yang terverifikasi + Cadangan mempunyai tanda tangan yang valid dari sesi %s yang belum diverifikasi + Mengirim gambar mini (%1$s / %2$s) + Mengunduh file %1$s… + File \'%1$s\' (%2$s) terlalu besar untuk diupload. Batasnya adalah %3$s. + + %d pengguna telah membaca + + %s telah membaca + %1$s, %2$s dan%3$s telah membaca + + %1$s, %2$s dan %3$d lainnya telah membaca + + %1$s dan %2$s telah membaca + Fitur ini masih dalam beta + Lompat ke bawah + Sembunyikan kata sandi + Tampilkan kata sandi + Tutup banner cadangan kunci + Buat ruangan baru + Buat pesan langsung baru dengan scan kode QR + Buat pesan langsung baru dengan ID Matrix + Buat pesan langsung baru + Tutup menu buat ruangan… + Buka menu buat ruangan + Buka laci navigasi + Kirim lampiran + Sepertinya server terlalu lama merespons, hal ini dapat disebabkan oleh konektivitas yang buruk atau kesalahan pada server. Silakan coba lagi dalam beberapa saat. + Silakan coba lagi setelah Anda menerima syarat dan ketentuan homeserver Anda. + Log verbose akan membantu pengembang dengan menyediakan lebih banyak log saat Anda mengirim RageShake. Bahkan ketika diaktifkan, aplikasi tidak mencatat isi pesan atau data pribadi lainnya. + Aktifkan log verbose. + Kode verifikasi salah. + Kode + Sebuah pesan teks telah dikirim ke %s. Silakan masukkan kode verifikasi yang ada di dalamnya. + Server identitas yang Anda pilih tidak memiliki persyaratan layanan apapun. Hanya lanjutkan jika Anda memercayai pemilik layanan + Server identitas tidak memiliki persyaratan layanan + Mohon masukkan URL server identitas + Tidak dapat terhubung ke server identitas + Masukkan URL server identitas + Berikan persetujuan + Cabut persetujuan saya + Tertunda + Nomor telepon yang dapat ditemukan + Opsi penemuan akan muncul setelah Anda menambahkan nomor telepon. + Surel yang dapat ditemukan + Saat ini Anda tidak menggunakan server identitas. Untuk menemukan dan dapat ditemukan oleh kontak yang Anda kenal, atur salah satu di bawah ini. + Saat ini Anda menggunakan %1$s untuk menemukan dan dapat ditemukan oleh kontak yang Anda kenal. + Ganti server identitas + Atur server identitas + Putuskan server identitas + Server identitas + Baca di + Gunakan bot, jembatan, widget, dan paket stiker + Bisa ditemukan oleh lain + Lihat Persyaratan + Persyaratan Layanan + Tampilkan Sejarah Suntingan + Menggabung ruangan… + Saran + Kontak + Pengguna yang Dikenal + Terkini + Saring oleh nama pengguna atau ID… + Mulai ketik untuk mendapatkan hasil + Tidak ada hasil, gunakan Tambah dengan ID Matrix untuk mencari di server. + Membuat ruangan… + Kode QR + Tambah dengan kode QR + Tambah dengan ID Matrix + Tautan disalin ke klipboard + Aktifkan geser untuk balas di linimasa + Cari Nama + Cari dengan nama atau ID + Nama atau ID (#contoh:matrix.org) + Tampilkan direktori ruangan + Kirim pesan langsung baru + Buat ruangan baru + Tidak bisa menemukan apa yang Anda cari\? + Saring obrolan… + Tidak ada suntingan yang ditemukan + Suntingan Pesan + (diedit) + File %1$s telah diunduh! + Mengompresi video %d%% + Mengompresi gambar… + Mengirim file (%1$s / %2$s) + Mengenkripsi file… + Tampilkan peristiwa tersembunyi di linimasa + Mengenkripsi gambar mini… + Menunggu… + Pesan Langsung + Tampilkan sejarah lengkap di ruangan terenkripsi + Beri Masukan + Masukan gagal dikirim (%s) + Terima kasih, saran Anda telah dikirim + Terima kasih, masukan Anda telah dikirim + Anda dapat menghubungi saya jika Anda memiliki pertanyaan lanjutan + Anda menggunakan versi beta space. Masukan Anda akan membantu menginformasikan versi berikutnya. Platform dan nama pengguna Anda akan dicatat untuk membantu kami menggunakan masukan Anda sebanyak yang kami bisa. + Masukan + Masukan spaces + Saran gagal dikirim (%s) + Jelaskan saran Anda di sini + Masukkan saran Anda di bawah. + Buat saran + Daftar token + Bantuan & Tentang + Suara & Video + Format: + Url: + session_name: + app_display_name: + push_key: + app_id: + Tidak ada gateway dorong terdaftar + Tidak ada aturan dorong ditentukan + Aturan Dorong + Ahli + Mengirim Anda undangan + Gabung ruangan untuk memulai menggunakan aplikasi. + Coba Lagi + Balas + Sunting + Sepertinya Anda mencoba menyambung ke homeserver lain. Apakah Anda ingin keluar\? + Tidak ada server identitas yang dikonfigurasikan, dibutuhkan untuk mengatur ulang kata sandi Anda. + Anda tidak menggunakan server identitas apapun + Kesalahan Tidak Diketahui + Ketidakcocokan pengguna + Ketidakcocokan kunci + Pesan yang tidak valid diterima + Sesi telah menerima pesan yang tidak terduga + SAS tidak cocok + Komitmen hash tidak cocok + Sesi tidak bisa setuju dengan persetujuan kunci, hash, MAC, atau metode SAS + Sesinya tidak tahu tentang transaksi itu + Waktu proses verifikasi habis + Pengguna telah membatalkan proses verifikasi + %s ingin memverifikasi sesi Anda + Permintaan Verifikasi + Verifikasi Sesi Interaktif + Proses verifikasi dibatalkan. +\nAlasan: %s + Pengguna telah membatalkan proses verifikasi. +\n%s + Permintaan Dibatalkan + Kunci Verifikasi + Gunakan verifikasi legacy. + Tidak ada yang muncul\? Belum semua client mendukung verifikasi interaktif. Gunakan verifikasi legacy. + Saya mengerti + Pesan aman dengan pengguna ini dienkripsi ujung-ke-ujung dan tidak bisa dibaca oleh pihak ketiga. + Anda telah berhasil memverifikasi sesi ini. + Terverifikasi! + Menunggu pengguna untuk konfirmasi… + Anda mempunyai permintaan verifikasi. + Verifikasi sesi ini dengan mengkonfirmasi angka yang ada di layar pengguna + Verifikasi sesi ini dengan mengkonfirmasi emoji yang ada di layar pengguna + Verifikasi sesi ini akan menandainya sebagai tepercaya, dan juga menandai sesi Anda sebagai terpercaya pada pengguna. + Verifikasi sesi ini untuk menandainya sebagai tepercaya. Mempercayai sesi pengguna membuat Anda tidak khawatir saat menggunakan pesan terenkripsi ujung-ke-ujung. + Permintaan Verifikasi Masuk + Mulai Verifikasi + Untuk keamanan maksimum, kami menyarankan Anda melakukan ini secara langsung atau menggunakan sarana komunikasi tepercaya lainnya. + Verifikasi dengan membandingkan string teks pendek. + Anda telah keluar karena kredensial yang tidak valid atau kedaluwarsa. + Gunakan Konfigurasi + ${app_name} mendeteksi konfigurasi server khusus untuk domain userId Anda \"%1$s\": +\n%2$s + Respons penemuan homeserver tidak valid + Opsi Server Pelengkapan Otomatis + Tanda Tangan + Algoritma + Versi + + Mencadangkan %d kunci… + + Semua kunci tercadangkan + Siapkan Cadangan Aman + Mencadangkan kunci Anda. Ini mungkin memakan beberapa menit… + Kelola di Cadangan Kunci + Kunci pesan aman baru + Cadangan Kunci Baru + Untuk menggunakan Cadangan Kunci di sesi ini, pulihkan dengan frasa sandi atau kunci pemulihan. + Gunakan Cadangan Kunci + Jangan kehilangan pesan terenkripsi + Lindungi dari kehilangan akses ke pesan & data terenkripsi + Cadangan Aman + Mulai menggunakan Kunci Pemulihan + Jangan kehilangan pesan terenkripsi + Itu saya + Cadangan kunci pesan aman baru telah terdeteksi. +\n +\nJika Anda tidak menyetel metode pemulihan baru, seseorang mungkin mencoba mengakses akun Anda. Ganti kata sandi akun Anda dan segera setel metode pemulihan baru di Pengaturan. + Hapus kunci enkripsi yang sudah dicadangkan dari server\? Anda akan tidak dapat menggunakan kunci pemulihan untuk membaca riwayat pesan terenkripsi. + Hapus Cadangan + Memeriksa status cadangan + Gagal untuk menghapus cadangan (%s) + Menghapus cadangan… + Gagal untuk mendapatkan info kepercayaan untuk cadangan (%s). + Cadangan mempunyai tanda tangan yang valid dari sesi %s yang terverifikasi. + Cadangan mempunyai tanda tangan yang valid dari sesi ini. + Cadangan mempunyai tanda tangan dari sesi tidak dikenal dengan ID %s. + Kunci Anda tidak dicadangkan dari sesi ini. + Cadangan Kunci belum aktif di sesi ini. + Cadangan Kunci telah disiapkan dengan benar untuk sesi ini. + Hapus Cadangan + Pulihkan dari Cadangan + Sesi kripto belum diaktifkan + Gagal untuk mendapatkan versi pemulihan kunci (%s). + + %d kunci baru telah ditambahkan ke sesi ini. + + + Dipulihkan cadangan dengan %d kunci. + + Cadangan Dipulihkan %s! + Cadangan tidak dapat didekripsi dengan frasa sandi ini: mohon cek bahwa Anda memasukkan frasa sandi pemulihan yang benar. + Mohon masukkan kunci pemulihan + Akses Sejarah + Mengimpor kunci… + Mengunduh kunci… + Mengkomputasikan kunci pemulihan… + Memulihkan cadangan: + Kesalahan jaringan: mohon cek koneksi Anda dan coba lagi. + Cadangan tidak dapat didekripsi dengan frasa sandi ini: mohon cek bahwa Anda memasukkan frasa sandi pemulihan yang benar. + Kehilangan kunci pemulihan\? Anda bisa menyiapkan yang baru di pengaturan. + Pemulihan Pesan + Masukkan Kunci Pemulihan + Gunakan frasa sandi pemulihan Anda untuk mengakses riwayat pesan terenkripsi Anda + Tidak tahu frasa sandi pemulihan Anda, Anda bisa %s. + gunakan kunci pemulihan Anda + Gunakan frasa sandi pemulihan Anda untuk mengakses riwayat pesan terenkripsi Anda + Mengambil versi cadangan… + Anda mungkin kehilangan akses ke pesan Anda jika Anda keluar atau kehilangan perangkat ini. + Yakin\? + Kunci enkripsi Anda sekarang sedang dicadangkan di latar belakang ke homeserver Anda. Pencadangan awal dapat memakan waktu beberapa menit. + Pencadangan Dimulai + Kesalahan tidak terduga + Kunci Pemulihan + Membuat Kunci Pemulihan menggunakan frasa sandi, proses ini bisa memakan beberapa detik. + Bagikan kunci pemulihan ke… + Mohon membuat salinan + Berhenti + Ganti + Sepertinya Anda sudah menyiapkan cadangan kunci dari sesi lain. Apakah Anda ingin menggantinya dengan yang Anda buat\? + Cadangan sudah ada di homeserver Anda + Kunci pemulihan sudah disimpan. + Kunci pemulihan telah disimpan ke \'%s\'. +\n +\nPeringatan: file ini dapat dihapus jika aplikasi dihapus. + Simpan sebagai File + Bagikan + Simpan Kunci Pemulihan + Saya sudah membuat salinan + Selesai + Simpan kunci pemulihan Anda di suatu tempat yang sangat aman, seperti manajer kata sandi (atau brankas) + Kunci pemulihan Anda adalah jaring pengaman — Anda dapat menggunakannya untuk memulihkan akses ke pesan terenkripsi Anda jika Anda lupa frasa sandi Anda. +\nSimpan kunci pemulihan Anda di suatu tempat yang sangat aman, seperti manajer kata sandi (atau brankas) + Kunci Anda sedang dicadangkan. + Berhasil! + (Lanjutan) Atur dengan Kunci Pemulihan + Atau, amankan cadangan Anda dengan Kunci Pemulihan, disimpan di tempat yang aman. + Membuat Cadangan + Atur Frasa Sandi + Kami akan menyimpan salinan kunci terenkripsi Anda di homeserver Anda. Lindungi cadangan Anda dengan frasa sandi supaya tetap aman. +\n +\nUntuk keamanan maksimum, ini harus berbeda dari kata sandi akun Anda. + Amankan cadangan Anda dengan frasa sandi. + Ekspor kunci secara manual + (Lanjutan) + Mulai menggunakan Cadangan Kunci + Pesan di ruangan terenkripsi diamankan dengan enkripsi ujung-ke-ujung. Hanya Anda dan penerima memiliki kunci untuk membaca pesan-pesan ini. +\n +\nCadangkan kunci Anda dengan aman untuk menghindari kehilangan kunci Anda. + Jangan pernah kehilangan pesan terenkripsi + Tidak ada sesi Matrix yang tersedia + Mohon hapus frasa sandinya jika Anda ingin ${app_name} untuk membuat kunci pemulihan. + Frasa sandi terlalu lemah + Mohon masukkan frasa sandi + Frasa sandi tidak cocok + Buat frasa sandi + Tidak menemukan APK Layanan Google Play yang valid. Notifikasi mungkin tidak berkerja dengan seharusnya. + Hanya untuk kesalahan + Untuk pesan dan kesalahan + Selalu + Keamanan & Privasi + Preferensi + Umum + Reaksi Cepat + Anda sudah menampilkan ruangan ini! + Pemberitahuan pihak ketiga lainnya + Versi SDK Matrix + Impor kunci E2E dari file \"%1$s\". + Sebuah kesalahan terjadi mendapatkan data cadangan kunci + Sebuah kesalahan terjadi mendapatkan info kepercyaan + Ruangan telah dibuat, tetapi beberapa undangan belum terkirim karena alasan berikut: +\n +\n%s + Publikasikan ruangan ini ke direktori ruangan + Direktori Ruangan + Siapa saja bisa bergabung ruangan ini + Publik + Pengaturan ruangan + Topik + Topik ruangan (opsional) + Nama + Nama ruangan + BUAT + Ruangan Baru + Pesan Langsung + Ruangan + Ruangan ini tidak bisa ditampilkan. Apakah Anda masih mau bergabung\? + Ruangan ini tidak bisa di akses di waktu ini. +\nCoba lagi nanti, atau tanya admin ruangan untuk memeriksa jika Anda punya akses. + Tampilan ruang yang dapat dibaca oleh dunia belum didukung di ${app_name} + Tampilkan permintaan + Tampilkan area info + Ruangan ini tidak bisa di tampilkan + Semua Komunitas + Mohon menunggu… + Ganti jaringan + Ganti + Tidak ada jaringan. Mohon cek koneksi Internet Anda. + Buat Ruangan Baru + Peristiwa salah, tidak bisa ditampilkan + Terakhir disunting oleh %1$s di %2$s + Peristiwa dihapus oleh admin ruangan + Peristiwa dihapus oleh pengguna + Tampilkan tempat penampung untuk pesan terhapus + Tampilkan pesan terhapus + Pesan dihapus + Reaksi + Tampilkan Reaksi + Tambah Reaksi + Suka + Setuju + Reaksi + Ruangan Anda akan ditampilkan di sini. Ketuk tombol + untuk memulai yang baru. + Ruangan + Obrolan pesan langsung Anda akan ditampilkan di sini. Ketuk tombol + untuk memulai yang baru. + Obrolan + Lihat pesan yang belum dibaca di sini + Selamat datang kembali! + Anda tidak mempunyai pesan yang belum dibaca + Anda sudah melihat semua! + Diundang oleh %s \ No newline at end of file From 2cc9d27902eac602824642dbed54e278cf4ae0fa Mon Sep 17 00:00:00 2001 From: Linerly Date: Fri, 17 Sep 2021 14:23:46 +0000 Subject: [PATCH 045/656] Translated using Weblate (Indonesian) Currently translated at 100.0% (29 of 29 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/id/ --- fastlane/metadata/android/id/full_description.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fastlane/metadata/android/id/full_description.txt b/fastlane/metadata/android/id/full_description.txt index 0a18b8d64a..75249c6a20 100644 --- a/fastlane/metadata/android/id/full_description.txt +++ b/fastlane/metadata/android/id/full_description.txt @@ -8,10 +8,10 @@ Element adalah perpesanan yang aman dan aplikasi kolaborasi tim produktivitas ya - Obrolan video dengan VoIP dan berbagi layar - Integrasi yang mudah dengan alat kolaborasi online favorit Anda, alat manajemen proyek, layanan VoIP dan aplikasi perpesanan tim lainnya -Element benar-benar berbeda dari aplikasi perpesanan dan kolaborasi lainnya. Ini beroperasi pada Matrix, jaringan terbuka untuk pengiriman pesan yang aman dan komunikasi terdesentralisasi. Ini memungkinkan hosting sendiri untuk memberi pengguna kepemilikan maksimum dan kontrol data dan pesan mereka. +Element benar-benar berbeda dari aplikasi perpesanan dan kolaborasi lainnya. Element beroperasi pada Matrix, jaringan terbuka untuk pengiriman pesan yang aman dan komunikasi terdesentralisasi. Matrix memungkinkan hosting sendiri untuk memberi pengguna kepemilikan maksimum dan kontrol data dan pesan mereka. Pesan privasi dan terenkripsi -Element melindungi Anda dari iklan yang tidak diinginkan, data penambangan dan taman berdinding. Ini juga mengamankan semua data Anda, komunikasi video dan suara satu-ke-satu melalui enkripsi ujung-ke-ujung dan verifikasi perangkat yang di-cross-signed. +Element melindungi Anda dari iklan yang tidak diinginkan, data penambangan dan taman berdinding. Element juga mengamankan semua data Anda, komunikasi video dan suara satu-ke-satu melalui enkripsi ujung-ke-ujung dan verifikasi perangkat yang ditanda tangani silang. Element memberi Anda kendali atas privasi Anda sambil memungkinkan Anda untuk berkomunikasi dengan aman dengan siapa pun di jaringan Matrix, atau alat kolaborasi bisnis lainnya dengan mengintegrasikan dengan aplikasi seperti Slack. @@ -30,7 +30,7 @@ Element menempatkan Anda dalam kendali dengan cara yang berbeda: Anda dapat mengobrol dengan siapa saja di jaringan Matrix, apakah mereka menggunakan Element, aplikasi Matrix lain atau bahkan jika mereka menggunakan aplikasi perpesanan yang berbeda. Sangat aman -Enkripsi ujung-ke-ujung beneran (hanya mereka yang dalam percakapan dapat mendekripsi pesan), dan verifikasi perangkat yang di-cross-signed. +Enkripsi ujung-ke-ujung beneran (hanya mereka yang dalam percakapan dapat mendekripsi pesan), dan verifikasi perangkat yang ditanda tangani silang. Komunikasi dan integrasi lengkap Perpesanan, panggilan suara dan video, berbagi file, berbagi layar dan banyak integrasi, bot dan widget. Buat ruangan, komunitas, tetap terhubung dan selesaikan hal-hal. From 8036f50a6e906506d0105a386ac8c495eee98cb0 Mon Sep 17 00:00:00 2001 From: Valere Date: Mon, 20 Sep 2021 12:07:45 +0200 Subject: [PATCH 046/656] Show mxto bottom sheet when tapping invite notification --- changelog.d/4043.bugfix | 1 + .../vector/app/features/home/HomeActivity.kt | 27 ++++++++++++++++--- .../notifications/NotificationUtils.kt | 2 +- 3 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 changelog.d/4043.bugfix diff --git a/changelog.d/4043.bugfix b/changelog.d/4043.bugfix new file mode 100644 index 0000000000..9da934b5d3 --- /dev/null +++ b/changelog.d/4043.bugfix @@ -0,0 +1 @@ +Spaces invitation system notifications don't take me to the join space toast \ No newline at end of file diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt index a302276f45..51d6ed79db 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt @@ -81,7 +81,8 @@ import javax.inject.Inject @Parcelize data class HomeActivityArgs( val clearNotification: Boolean, - val accountCreation: Boolean + val accountCreation: Boolean, + val inviteNotificationRoomId: String? = null ) : Parcelable class HomeActivity : @@ -229,6 +230,11 @@ class HomeActivity : if (args?.clearNotification == true) { notificationDrawerManager.clearAllEvents() } + if (args?.inviteNotificationRoomId != null) { + activeSessionHolder.getSafeActiveSession()?.permalinkService()?.createPermalink(args.inviteNotificationRoomId)?.let { + navigator.openMatrixToBottomSheet(this, it) + } + } homeActivityViewModel.observeViewEvents { when (it) { @@ -422,9 +428,17 @@ class HomeActivity : override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) - if (intent?.getParcelableExtra(MvRx.KEY_ARG)?.clearNotification == true) { + val parcelableExtra = intent?.getParcelableExtra(MvRx.KEY_ARG) + if (parcelableExtra?.clearNotification == true) { notificationDrawerManager.clearAllEvents() } + if (parcelableExtra?.inviteNotificationRoomId != null) { + activeSessionHolder.getSafeActiveSession() + ?.permalinkService() + ?.createPermalink(parcelableExtra.inviteNotificationRoomId)?.let { + navigator.openMatrixToBottomSheet(this, it) + } + } handleIntent(intent) } @@ -548,10 +562,15 @@ class HomeActivity : } companion object { - fun newIntent(context: Context, clearNotification: Boolean = false, accountCreation: Boolean = false): Intent { + fun newIntent(context: Context, + clearNotification: Boolean = false, + accountCreation: Boolean = false, + inviteNotificationRoomId: String? = null + ): Intent { val args = HomeActivityArgs( clearNotification = clearNotification, - accountCreation = accountCreation + accountCreation = accountCreation, + inviteNotificationRoomId = inviteNotificationRoomId ) return Intent(context, HomeActivity::class.java) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt index a74c13a496..5ccaee80bc 100755 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt @@ -679,7 +679,7 @@ class NotificationUtils @Inject constructor(private val context: Context, stringProvider.getString(R.string.join), joinIntentPendingIntent) - val contentIntent = HomeActivity.newIntent(context) + val contentIntent = HomeActivity.newIntent(context, inviteNotificationRoomId = inviteNotifiableEvent.roomId) contentIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP // pending intent get reused by system, this will mess up the extra params, so put unique info to avoid that contentIntent.data = Uri.parse("foobar://" + inviteNotifiableEvent.eventId) From fa3abecf8f3f96be288b8dc66bc4cab163887ec5 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Fri, 17 Sep 2021 16:44:18 +0200 Subject: [PATCH 047/656] Fix review --- .../android/sdk/api/MatrixConfiguration.kt | 6 ++++- ...MatrixToMapper.kt => MatrixToConverter.kt} | 4 ++-- .../api/session/permalinks/PermalinkParser.kt | 23 +++++++++---------- .../session/permalinks/PermalinkService.kt | 1 + vector/src/main/AndroidManifest.xml | 9 ++++++-- 5 files changed, 26 insertions(+), 17 deletions(-) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/{MatrixToMapper.kt => MatrixToConverter.kt} (97%) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt index bd47c34571..03f9f0b707 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt @@ -32,7 +32,11 @@ data class MatrixConfiguration( "https://scalar-staging.riot.im/scalar/api" ), /** - * Optional base url to create client permalinks instead of Matrix ones (matrix.to links). + * Optional base url to create client permalinks (eg. https://www.example.com/#/) instead of Matrix ones (matrix.to links). + * Do not forget to add the "#" which is required by the permalink parser. + * + * Note: this field is only used for permalinks creation, you will also have to edit the string-array `permalink_supported_hosts` in the config file + * and add it to your manifest to handle these links in the application. */ val clientPermalinkBaseUrl: String? = null, /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixToMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixToConverter.kt similarity index 97% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixToMapper.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixToConverter.kt index a1e7d09628..a904e89681 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixToMapper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixToConverter.kt @@ -21,7 +21,7 @@ import android.net.Uri /** * Mapping of an input URI to a matrix.to compliant URI. */ -object MatrixToMapper { +object MatrixToConverter { /** * Try to convert a URL from an element web instance or from a client permalink to a matrix.to url. @@ -31,7 +31,7 @@ object MatrixToMapper { * - https://app.element.io/#/room/#element-android:matrix.org -> https://matrix.to/#/#element-android:matrix.org * - https://www.example.org/#/room/#element-android:matrix.org -> https://matrix.to/#/#element-android:matrix.org */ - fun map(uri: Uri): Uri? { + fun convert(uri: Uri): Uri? { val uriString = uri.toString() return when { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt index 9d16d09812..edb748c76e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt @@ -26,7 +26,7 @@ import java.net.URLDecoder * This class turns a uri to a [PermalinkData] * element-based domains (e.g. https://app.element.io/#/user/@chagai95:matrix.org) permalinks * or matrix.to permalinks (e.g. https://matrix.to/#/@chagai95:matrix.org) - * or client permalinks (e.g. https://www.example.com/#/user/@chagai95:matrix.org) + * or client permalinks (e.g. user/@chagai95:matrix.org) */ object PermalinkParser { @@ -46,12 +46,12 @@ object PermalinkParser { // the client or element-based domain permalinks (e.g. https://app.element.io/#/user/@chagai95:matrix.org) don't have the // mxid in the first param (like matrix.to does - https://matrix.to/#/@chagai95:matrix.org) but rather in the second after /user/ so /user/mxid // so convert URI to matrix.to to simplify parsing process - val matrixToUri = MatrixToMapper.map(uri) ?: return PermalinkData.FallbackLink(uri) + val matrixToUri = MatrixToConverter.convert(uri) ?: return PermalinkData.FallbackLink(uri) // We can't use uri.fragment as it is decoding to early and it will break the parsing // of parameters that represents url (like signurl) val fragment = matrixToUri.toString().substringAfter("#") // uri.fragment - if (fragment.isNullOrEmpty()) { + if (fragment.isEmpty()) { return PermalinkData.FallbackLink(uri) } val safeFragment = fragment.substringBefore('?') @@ -122,12 +122,13 @@ object PermalinkParser { } } - private fun safeExtractParams(fragment: String) = fragment.substringAfter("?").split('&').mapNotNull { - val splitNameValue = it.split("=") - if (splitNameValue.size == 2) { - Pair(splitNameValue[0], URLDecoder.decode(splitNameValue[1], "UTF-8")) - } else null - } + private fun safeExtractParams(fragment: String) = + fragment.substringAfter("?").split('&').mapNotNull { + val splitNameValue = it.split("=") + if (splitNameValue.size == 2) { + Pair(splitNameValue[0], URLDecoder.decode(splitNameValue[1], "UTF-8")) + } else null + } private fun String.getViaParameters(): List { return UrlQuerySanitizer(this) @@ -135,9 +136,7 @@ object PermalinkParser { .filter { it.mParameter == "via" }.map { - it.mValue.let { - URLDecoder.decode(it, "UTF-8") - } + URLDecoder.decode(it.mValue, "UTF-8") } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt index 7318b7b8e0..920dc85c7a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt @@ -20,6 +20,7 @@ import org.matrix.android.sdk.api.session.events.model.Event /** * Useful methods to create permalink (like matrix.to links or client permalinks). + * See [org.matrix.android.sdk.api.MatrixConfiguration.clientPermalinkBaseUrl] to setup a custom permalink base url. */ interface PermalinkService { diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml index 0e84eb3bcd..b38df10ce0 100644 --- a/vector/src/main/AndroidManifest.xml +++ b/vector/src/main/AndroidManifest.xml @@ -105,8 +105,8 @@ @@ -122,8 +122,8 @@ @@ -180,8 +180,11 @@ + + @@ -198,8 +201,10 @@ + From 1591375aa20b47ac96e63201cc4fcb4ab7f152b0 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 20 Sep 2021 16:35:53 +0100 Subject: [PATCH 048/656] adding ability to remove push targets from the notification target screen --- .../features/settings/push/PushGateWayController.kt | 5 +++++ .../app/features/settings/push/PushGatewayAction.kt | 2 ++ .../app/features/settings/push/PushGatewayItem.kt | 12 ++++++++++++ .../features/settings/push/PushGatewaysFragment.kt | 4 ++++ .../features/settings/push/PushGatewaysViewModel.kt | 11 ++++++++++- vector/src/main/res/layout/item_pushgateway.xml | 7 ++++++- vector/src/main/res/values/strings.xml | 1 + 7 files changed, 40 insertions(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/settings/push/PushGateWayController.kt b/vector/src/main/java/im/vector/app/features/settings/push/PushGateWayController.kt index 679f406832..6cb19b13c5 100644 --- a/vector/src/main/java/im/vector/app/features/settings/push/PushGateWayController.kt +++ b/vector/src/main/java/im/vector/app/features/settings/push/PushGateWayController.kt @@ -26,6 +26,8 @@ class PushGateWayController @Inject constructor( private val stringProvider: StringProvider ) : TypedEpoxyController() { + var interactionListener: PushGatewayItemInteractions? = null + override fun buildModels(data: PushGatewayViewState?) { val host = this data?.pushGateways?.invoke()?.let { pushers -> @@ -39,6 +41,9 @@ class PushGateWayController @Inject constructor( pushGatewayItem { id("${it.pushKey}_${it.appId}") pusher(it) + host.interactionListener?.let { + interactions(it) + } } } } diff --git a/vector/src/main/java/im/vector/app/features/settings/push/PushGatewayAction.kt b/vector/src/main/java/im/vector/app/features/settings/push/PushGatewayAction.kt index 566a068a7d..034b0b5ac7 100644 --- a/vector/src/main/java/im/vector/app/features/settings/push/PushGatewayAction.kt +++ b/vector/src/main/java/im/vector/app/features/settings/push/PushGatewayAction.kt @@ -17,7 +17,9 @@ package im.vector.app.features.settings.push import im.vector.app.core.platform.VectorViewModelAction +import org.matrix.android.sdk.api.session.pushers.Pusher sealed class PushGatewayAction : VectorViewModelAction { object Refresh : PushGatewayAction() + data class RemovePusher(val pusher: Pusher) : PushGatewayAction() } diff --git a/vector/src/main/java/im/vector/app/features/settings/push/PushGatewayItem.kt b/vector/src/main/java/im/vector/app/features/settings/push/PushGatewayItem.kt index dc66e1983b..ec67e362ee 100644 --- a/vector/src/main/java/im/vector/app/features/settings/push/PushGatewayItem.kt +++ b/vector/src/main/java/im/vector/app/features/settings/push/PushGatewayItem.kt @@ -16,6 +16,7 @@ package im.vector.app.features.settings.push +import android.view.View import android.widget.TextView import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass @@ -30,6 +31,9 @@ abstract class PushGatewayItem : EpoxyModelWithHolder() @EpoxyAttribute lateinit var pusher: Pusher + @EpoxyAttribute + lateinit var interactions: PushGatewayItemInteractions + override fun bind(holder: Holder) { super.bind(holder) holder.kind.text = when (pusher.kind) { @@ -45,6 +49,9 @@ abstract class PushGatewayItem : EpoxyModelWithHolder() holder.url.text = pusher.data.url holder.format.text = pusher.data.format holder.deviceName.text = pusher.deviceDisplayName + holder.removeButton.setOnClickListener { + interactions.onRemovePushTapped(pusher) + } } class Holder : VectorEpoxyHolder() { @@ -55,8 +62,13 @@ abstract class PushGatewayItem : EpoxyModelWithHolder() val url by bind(R.id.pushGatewayURLValue) val appName by bind(R.id.pushGatewayAppNameValue) val appId by bind(R.id.pushGatewayAppIdValue) + val removeButton by bind(R.id.pushGatewayDeleteButton) } } +interface PushGatewayItemInteractions { + fun onRemovePushTapped(pusher: Pusher) +} + // // abstract class ReactionInfoSimpleItem : EpoxyModelWithHolder() { diff --git a/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysFragment.kt b/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysFragment.kt index be2457397d..696505cc52 100644 --- a/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysFragment.kt @@ -29,6 +29,7 @@ import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentGenericRecyclerBinding +import org.matrix.android.sdk.api.session.pushers.Pusher import javax.inject.Inject @@ -64,6 +65,9 @@ class PushGatewaysFragment @Inject constructor( override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + epoxyController.interactionListener = object : PushGatewayItemInteractions { + override fun onRemovePushTapped(pusher: Pusher) = viewModel.handle(PushGatewayAction.RemovePusher(pusher)) + } views.genericRecyclerView.configureWith(epoxyController, dividerDrawable = R.drawable.divider_horizontal) } diff --git a/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysViewModel.kt index 7981d71ce1..9910526878 100644 --- a/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysViewModel.kt @@ -16,6 +16,7 @@ package im.vector.app.features.settings.push +import androidx.lifecycle.viewModelScope import com.airbnb.mvrx.Async import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.MvRxState @@ -28,6 +29,7 @@ import dagger.assisted.AssistedFactory import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel +import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.pushers.Pusher import org.matrix.android.sdk.rx.RxSession @@ -70,10 +72,17 @@ class PushGatewaysViewModel @AssistedInject constructor(@Assisted initialState: override fun handle(action: PushGatewayAction) { when (action) { - is PushGatewayAction.Refresh -> handleRefresh() + is PushGatewayAction.Refresh -> handleRefresh() + is PushGatewayAction.RemovePusher -> removePusher(action.pusher) }.exhaustive } + private fun removePusher(pusher: Pusher) { + viewModelScope.launch { + session.removeHttpPusher(pusher.pushKey, pusher.appId) + } + } + private fun handleRefresh() { session.refreshPushers() } diff --git a/vector/src/main/res/layout/item_pushgateway.xml b/vector/src/main/res/layout/item_pushgateway.xml index 28bcef1ee2..b1cec859b1 100644 --- a/vector/src/main/res/layout/item_pushgateway.xml +++ b/vector/src/main/res/layout/item_pushgateway.xml @@ -120,7 +120,6 @@ android:text="@string/push_gateway_item_format" android:textStyle="bold" /> - +